Skip to content

Commit 1c6f76f

Browse files
committed
Sonata Trace
Implement basic Sonata Trace functionality via Arduino ICSP connector. For now this just presents the microSD SPI traffic.
1 parent 564507f commit 1c6f76f

File tree

6 files changed

+195
-3
lines changed

6 files changed

+195
-3
lines changed

data/pins_sonata.xdc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,12 @@ set_property PULLTYPE PULLUP [get_ports rph_g1]
239239
set_property PULLTYPE PULLUP [get_ports rph_g0]
240240

241241
## Arduino Shield
242+
## ICSP - hijacked for Sonata Trace port.
243+
set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports ah_tmpio14]
244+
set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports ah_tmpio15]
245+
set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports ah_tmpio17]
246+
## GPIO
247+
set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports ah_tmpio16]
242248
## SPI SCLK
243249
set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 IO_BUFFER_TYPE NONE } [get_ports ah_tmpio13]
244250
## SPI CIPO

dv/verilator/top_verilator.sv

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,10 @@ module top_verilator (input logic clk_i, rst_ni);
297297
wire [7:0] user_sw_n = '0;
298298
wire [2:0] sel_sw_n = '0;
299299

300+
// Sonata Trace Port functionality.
301+
logic [3:0] strace;
302+
wire strace_unused_ = ^strace;
303+
300304
// Instantiating the Sonata System.
301305
sonata_system #(
302306
.CheriErrWidth ( CheriErrWidth ),
@@ -399,7 +403,9 @@ module top_verilator (input logic clk_i, rst_ni);
399403
.out_to_pins_o (out_to_pins ),
400404
.inout_from_pins_i (inout_from_pins ),
401405
.inout_to_pins_o (inout_to_pins ),
402-
.inout_to_pins_en_o (inout_to_pins_en)
406+
.inout_to_pins_en_o (inout_to_pins_en),
407+
408+
.strace_o (strace)
403409
);
404410

405411
// I2C HAT ID DPI - this I2C bus is to the ID EEPROM of a Raspberry Pi HAT.

rtl/fpga/top_sonata.sv

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,12 @@ module top_sonata
111111
inout logic ah_tmpio8,
112112
inout logic ah_tmpio9,
113113

114+
// Sonata Trace port.
115+
inout logic ah_tmpio14,
116+
inout logic ah_tmpio15,
117+
inout logic ah_tmpio16,
118+
inout logic ah_tmpio17,
119+
114120
// Arduino shield SPI bus
115121
inout logic ah_tmpio10, // Chip select
116122
inout logic ah_tmpio11, // COPI
@@ -266,6 +272,12 @@ module top_sonata
266272
logic rs485_rx, rs485_tx;
267273
logic rs485_rx_enable, rs485_tx_enable;
268274

275+
// Sonata Trace port
276+
// - the signal ordering here ensures that when tracing an SPI bus the signals match the pin
277+
// names and PCB legend since we're hijacking the ICSP connector which carries an SPI bus.
278+
logic [3:0] strace;
279+
assign {ah_tmpio14, ah_tmpio17, ah_tmpio15, ah_tmpio16} = strace;
280+
269281
sonata_system #(
270282
.CheriErrWidth ( 9 ),
271283
.SRAMInitFile ( SRAMInitFile ),
@@ -366,7 +378,9 @@ module top_sonata
366378
.out_to_pins_o (out_to_pins ),
367379
.inout_from_pins_i (inout_from_pins ),
368380
.inout_to_pins_o (inout_to_pins ),
369-
.inout_to_pins_en_o (inout_to_pins_en)
381+
.inout_to_pins_en_o (inout_to_pins_en),
382+
383+
.strace_o (strace)
370384
);
371385

372386
assign rgbled0 = ~rgbled_dout;

rtl/ip/strace/rtl/strace_top.sv

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// Copyright lowRISC contributors.
2+
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
// Sonata Trace Port functionality.
6+
module strace_top
7+
#(
8+
// Number of I2C buses to trace.
9+
parameter int unsigned I2C_NUM = 1,
10+
// Number of SPI buses to trace.
11+
parameter int unsigned SPI_NUM = 1
12+
) (
13+
input logic clk_i,
14+
input logic rst_ni,
15+
16+
// Configuration interface.
17+
input logic cfg_re,
18+
input logic cfg_we,
19+
input logic [3:0] cfg_addr,
20+
input logic [31:0] cfg_wdata,
21+
output logic [31:0] cfg_rdata,
22+
23+
// I2C bus(es).
24+
input logic [I2C_NUM-1:0] i2c_scl,
25+
input logic [I2C_NUM-1:0] i2c_sda,
26+
27+
// SPI bus(es).
28+
input logic [SPI_NUM-1:0] spi_cs,
29+
input logic [SPI_NUM-1:0] spi_sck,
30+
input logic [SPI_NUM-1:0] spi_copi,
31+
input logic [SPI_NUM-1:0] spi_cipo,
32+
33+
// TL-UL activity.
34+
input logic [3:0] tlul_trace,
35+
36+
// Trace output.
37+
output logic [3:0] strace_o
38+
);
39+
40+
// TODO: We probably want to use structured data types to prevent awkward reordering of signals.
41+
42+
// Re-time all of the inputs by running them through synchronizers.
43+
// TODO: Simplify this by padding to 4 here?
44+
localparam int unsigned TraceInW = 4 + SPI_NUM*4 + I2C_NUM*2;
45+
logic [TraceInW-1:0] trace_in;
46+
prim_flop_2sync #(
47+
.Width (TraceInW)
48+
) u_cdc (
49+
.clk_i (clk_i),
50+
.rst_ni (rst_ni),
51+
.d_i ({tlul_trace,
52+
spi_cipo, spi_copi, spi_sck, spi_cs,
53+
i2c_sda, i2c_scl}),
54+
.q_o (trace_in)
55+
);
56+
57+
// Instantiate the execution trace logic.
58+
59+
// The configuration interface presently consists of nothing more than a control register.
60+
reg [31:0] control;
61+
wire enable = control[31]; // Enabling trace output?
62+
wire [3:0] src_sel = control[3:0]; // Source selection.
63+
always_ff @(posedge clk_i or negedge rst_ni) begin
64+
if (!rst_ni) begin
65+
// TODO: For now we want the strace to be on the microSD card output.
66+
// control <= 32'b0;
67+
control <= 32'h8000_0000 | 32'(I2C_NUM);
68+
end else if (cfg_we) begin
69+
case (cfg_addr)
70+
default: control <= cfg_wdata;
71+
endcase
72+
end
73+
end
74+
assign cfg_rdata = control; // There's only a single register at present.
75+
76+
// We may now choose the appropriate source.
77+
localparam int unsigned SPI_OFST = I2C_NUM * 2;
78+
logic [4:0] spi_idx = 5'(32'(src_sel) - I2C_NUM);
79+
logic [3:0] sel_strace;
80+
always_comb begin
81+
if (32'(src_sel) < I2C_NUM) begin
82+
sel_strace = {2'b00, trace_in[I2C_NUM + 32'(src_sel)], trace_in[{1'b0,src_sel}]};
83+
end else if (32'(src_sel) < I2C_NUM + SPI_NUM) begin : sel_spi
84+
sel_strace = {trace_in[SPI_NUM*3 + SPI_OFST + 32'(spi_idx)],
85+
trace_in[SPI_NUM*2 + SPI_OFST + 32'(spi_idx)],
86+
trace_in[SPI_NUM + SPI_OFST + 32'(spi_idx)],
87+
trace_in[ SPI_OFST + 32'(spi_idx)]};
88+
end else begin
89+
sel_strace = trace_in[SPI_NUM*4 + I2C_NUM*2+3 -: 4];
90+
end
91+
end
92+
93+
// Output the trace signals.
94+
always_ff @(posedge clk_i or negedge rst_ni) begin
95+
if (!rst_ni) begin
96+
strace_o <= 4'b0;
97+
end else if (enable) begin
98+
strace_o <= sel_strace;
99+
end
100+
end
101+
102+
logic unused_;
103+
assign unused_ = cfg_re;
104+
105+
endmodule : strace_top

rtl/system/sonata_system.sv

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,9 @@ module sonata_system
101101
output sonata_out_pins_t out_to_pins_o,
102102
input sonata_inout_pins_t inout_from_pins_i,
103103
output sonata_inout_pins_t inout_to_pins_o,
104-
output sonata_inout_pins_t inout_to_pins_en_o
104+
output sonata_inout_pins_t inout_to_pins_en_o,
105+
106+
output logic [3:0] strace_o
105107
);
106108
///////////////////////////////////////////////
107109
// Signals, types and parameters for system. //
@@ -1208,6 +1210,64 @@ module sonata_system
12081210
.rgbled_dout_o
12091211
);
12101212

1213+
// TODO: Tap onto the PWM device port for now.
1214+
wire strace_cfg_re = device_req[Pwm] & !device_we[Pwm] & device_addr[Pwm][7];
1215+
wire strace_cfg_we = device_req[Pwm] & device_we[Pwm] & device_addr[Pwm][7];
1216+
wire [3:0] strace_cfg_addr = device_addr[Pwm][3:0];
1217+
wire [31:0] strace_cfg_wdata = device_wdata[Pwm];
1218+
1219+
// Collect the I2C buses and SPI buses.
1220+
logic [I2C_NUM-1:0] strace_i2c_scl;
1221+
logic [I2C_NUM-1:0] strace_i2c_sda;
1222+
logic [SPI_NUM-1:0] strace_spi_sck;
1223+
logic [SPI_NUM-1:0] strace_spi_cs; // TODO: require multi-CS support.
1224+
logic [SPI_NUM-1:0] strace_spi_copi;
1225+
logic [SPI_NUM-1:0] strace_spi_cipo;
1226+
always_comb begin
1227+
for (integer i = 0; i < I2C_NUM; i++) begin
1228+
strace_i2c_scl[i] = i2c_scl_d2h[i];
1229+
strace_i2c_sda[i] = i2c_sda_d2h[i];
1230+
end
1231+
for (integer i = 0; i < SPI_NUM; i++) begin
1232+
strace_spi_sck[i] = spi_sclk[i];
1233+
strace_spi_cs[i] = spi_cs[i][1]; // TODO: Only interested in microSD presently!
1234+
strace_spi_copi[i] = spi_copi[i];
1235+
strace_spi_cipo[i] = spi_cipo[i];
1236+
end
1237+
end
1238+
1239+
// Sonata Trace port.
1240+
strace_top #(
1241+
.I2C_NUM (I2C_NUM),
1242+
.SPI_NUM (SPI_NUM)
1243+
) u_strace(
1244+
.clk_i (clk_sys_i),
1245+
.rst_ni (rst_sys_ni),
1246+
1247+
// Configuration interface.
1248+
.cfg_re (strace_cfg_re),
1249+
.cfg_we (strace_cfg_we),
1250+
.cfg_addr (strace_cfg_addr),
1251+
.cfg_wdata (strace_cfg_wdata),
1252+
// TODO: make read data available; presently not done because of GPIO tap.
1253+
.cfg_rdata (),
1254+
1255+
// I2C bus(es).
1256+
.i2c_scl (strace_i2c_scl),
1257+
.i2c_sda (strace_i2c_sda),
1258+
1259+
// SPI bus(es).
1260+
.spi_cs (strace_spi_cs),
1261+
.spi_sck (strace_spi_sck),
1262+
.spi_copi (strace_spi_copi),
1263+
.spi_cipo (strace_spi_cipo),
1264+
1265+
// TL-UL activity.
1266+
.tlul_trace (4'h0),
1267+
1268+
.strace_o (strace_o)
1269+
);
1270+
12111271
// Debug module top.
12121272
dm_top #(
12131273
.NrHarts ( 1 ),

sonata_system.core

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ filesets:
2828
files:
2929
- rtl/system/sonata_pkg.sv
3030
- rtl/bus/sonata_xbar_main.sv
31+
- rtl/ip/strace/rtl/strace_top.sv
3132
- rtl/system/jtag_id_pkg.sv
3233
- rtl/system/sonata_system.sv
3334
- rtl/system/dm_top.sv

0 commit comments

Comments
 (0)