From 564507f4d2c58112a236a56ca2e80284745372ea Mon Sep 17 00:00:00 2001 From: Marno van der Maas Date: Tue, 22 Oct 2024 16:49:42 +0100 Subject: [PATCH 1/2] Block diagram includes pinmux and other updates For example SRAM is 128 KiB, there's no DMA, there's no CHERIoT Debug module, there is a user USB etc. --- doc/img/sonata-development-system.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/img/sonata-development-system.svg b/doc/img/sonata-development-system.svg index 897bf89ba..cb4926103 100644 --- a/doc/img/sonata-development-system.svg +++ b/doc/img/sonata-development-system.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file From 1c6f76f9fa4a750560d30fadd37a7716cda2758e Mon Sep 17 00:00:00 2001 From: Adrian Lees Date: Thu, 7 Nov 2024 20:24:26 +0000 Subject: [PATCH 2/2] Sonata Trace Implement basic Sonata Trace functionality via Arduino ICSP connector. For now this just presents the microSD SPI traffic. --- data/pins_sonata.xdc | 6 ++ dv/verilator/top_verilator.sv | 8 ++- rtl/fpga/top_sonata.sv | 16 ++++- rtl/ip/strace/rtl/strace_top.sv | 105 ++++++++++++++++++++++++++++++++ rtl/system/sonata_system.sv | 62 ++++++++++++++++++- sonata_system.core | 1 + 6 files changed, 195 insertions(+), 3 deletions(-) create mode 100644 rtl/ip/strace/rtl/strace_top.sv diff --git a/data/pins_sonata.xdc b/data/pins_sonata.xdc index 5cea66eec..2f1202f8d 100644 --- a/data/pins_sonata.xdc +++ b/data/pins_sonata.xdc @@ -239,6 +239,12 @@ set_property PULLTYPE PULLUP [get_ports rph_g1] set_property PULLTYPE PULLUP [get_ports rph_g0] ## Arduino Shield +## ICSP - hijacked for Sonata Trace port. +set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports ah_tmpio14] +set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports ah_tmpio15] +set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports ah_tmpio17] +## GPIO +set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports ah_tmpio16] ## SPI SCLK set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 IO_BUFFER_TYPE NONE } [get_ports ah_tmpio13] ## SPI CIPO diff --git a/dv/verilator/top_verilator.sv b/dv/verilator/top_verilator.sv index d0ec78daf..7821adfa5 100644 --- a/dv/verilator/top_verilator.sv +++ b/dv/verilator/top_verilator.sv @@ -297,6 +297,10 @@ module top_verilator (input logic clk_i, rst_ni); wire [7:0] user_sw_n = '0; wire [2:0] sel_sw_n = '0; + // Sonata Trace Port functionality. + logic [3:0] strace; + wire strace_unused_ = ^strace; + // Instantiating the Sonata System. sonata_system #( .CheriErrWidth ( CheriErrWidth ), @@ -399,7 +403,9 @@ module top_verilator (input logic clk_i, rst_ni); .out_to_pins_o (out_to_pins ), .inout_from_pins_i (inout_from_pins ), .inout_to_pins_o (inout_to_pins ), - .inout_to_pins_en_o (inout_to_pins_en) + .inout_to_pins_en_o (inout_to_pins_en), + + .strace_o (strace) ); // I2C HAT ID DPI - this I2C bus is to the ID EEPROM of a Raspberry Pi HAT. diff --git a/rtl/fpga/top_sonata.sv b/rtl/fpga/top_sonata.sv index 0697b3399..1063a9a05 100644 --- a/rtl/fpga/top_sonata.sv +++ b/rtl/fpga/top_sonata.sv @@ -111,6 +111,12 @@ module top_sonata inout logic ah_tmpio8, inout logic ah_tmpio9, + // Sonata Trace port. + inout logic ah_tmpio14, + inout logic ah_tmpio15, + inout logic ah_tmpio16, + inout logic ah_tmpio17, + // Arduino shield SPI bus inout logic ah_tmpio10, // Chip select inout logic ah_tmpio11, // COPI @@ -266,6 +272,12 @@ module top_sonata logic rs485_rx, rs485_tx; logic rs485_rx_enable, rs485_tx_enable; + // Sonata Trace port + // - the signal ordering here ensures that when tracing an SPI bus the signals match the pin + // names and PCB legend since we're hijacking the ICSP connector which carries an SPI bus. + logic [3:0] strace; + assign {ah_tmpio14, ah_tmpio17, ah_tmpio15, ah_tmpio16} = strace; + sonata_system #( .CheriErrWidth ( 9 ), .SRAMInitFile ( SRAMInitFile ), @@ -366,7 +378,9 @@ module top_sonata .out_to_pins_o (out_to_pins ), .inout_from_pins_i (inout_from_pins ), .inout_to_pins_o (inout_to_pins ), - .inout_to_pins_en_o (inout_to_pins_en) + .inout_to_pins_en_o (inout_to_pins_en), + + .strace_o (strace) ); assign rgbled0 = ~rgbled_dout; diff --git a/rtl/ip/strace/rtl/strace_top.sv b/rtl/ip/strace/rtl/strace_top.sv new file mode 100644 index 000000000..4570caa8b --- /dev/null +++ b/rtl/ip/strace/rtl/strace_top.sv @@ -0,0 +1,105 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Sonata Trace Port functionality. +module strace_top +#( + // Number of I2C buses to trace. + parameter int unsigned I2C_NUM = 1, + // Number of SPI buses to trace. + parameter int unsigned SPI_NUM = 1 +) ( + input logic clk_i, + input logic rst_ni, + + // Configuration interface. + input logic cfg_re, + input logic cfg_we, + input logic [3:0] cfg_addr, + input logic [31:0] cfg_wdata, + output logic [31:0] cfg_rdata, + + // I2C bus(es). + input logic [I2C_NUM-1:0] i2c_scl, + input logic [I2C_NUM-1:0] i2c_sda, + + // SPI bus(es). + input logic [SPI_NUM-1:0] spi_cs, + input logic [SPI_NUM-1:0] spi_sck, + input logic [SPI_NUM-1:0] spi_copi, + input logic [SPI_NUM-1:0] spi_cipo, + + // TL-UL activity. + input logic [3:0] tlul_trace, + + // Trace output. + output logic [3:0] strace_o +); + +// TODO: We probably want to use structured data types to prevent awkward reordering of signals. + +// Re-time all of the inputs by running them through synchronizers. +// TODO: Simplify this by padding to 4 here? +localparam int unsigned TraceInW = 4 + SPI_NUM*4 + I2C_NUM*2; +logic [TraceInW-1:0] trace_in; +prim_flop_2sync #( + .Width (TraceInW) +) u_cdc ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .d_i ({tlul_trace, + spi_cipo, spi_copi, spi_sck, spi_cs, + i2c_sda, i2c_scl}), + .q_o (trace_in) +); + +// Instantiate the execution trace logic. + +// The configuration interface presently consists of nothing more than a control register. +reg [31:0] control; +wire enable = control[31]; // Enabling trace output? +wire [3:0] src_sel = control[3:0]; // Source selection. +always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin +// TODO: For now we want the strace to be on the microSD card output. +// control <= 32'b0; + control <= 32'h8000_0000 | 32'(I2C_NUM); + end else if (cfg_we) begin + case (cfg_addr) + default: control <= cfg_wdata; + endcase + end +end +assign cfg_rdata = control; // There's only a single register at present. + +// We may now choose the appropriate source. +localparam int unsigned SPI_OFST = I2C_NUM * 2; +logic [4:0] spi_idx = 5'(32'(src_sel) - I2C_NUM); +logic [3:0] sel_strace; +always_comb begin + if (32'(src_sel) < I2C_NUM) begin + sel_strace = {2'b00, trace_in[I2C_NUM + 32'(src_sel)], trace_in[{1'b0,src_sel}]}; + end else if (32'(src_sel) < I2C_NUM + SPI_NUM) begin : sel_spi + sel_strace = {trace_in[SPI_NUM*3 + SPI_OFST + 32'(spi_idx)], + trace_in[SPI_NUM*2 + SPI_OFST + 32'(spi_idx)], + trace_in[SPI_NUM + SPI_OFST + 32'(spi_idx)], + trace_in[ SPI_OFST + 32'(spi_idx)]}; + end else begin + sel_strace = trace_in[SPI_NUM*4 + I2C_NUM*2+3 -: 4]; + end +end + +// Output the trace signals. +always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + strace_o <= 4'b0; + end else if (enable) begin + strace_o <= sel_strace; + end +end + +logic unused_; +assign unused_ = cfg_re; + +endmodule : strace_top diff --git a/rtl/system/sonata_system.sv b/rtl/system/sonata_system.sv index 148c3df22..d7cf2561f 100644 --- a/rtl/system/sonata_system.sv +++ b/rtl/system/sonata_system.sv @@ -101,7 +101,9 @@ module sonata_system output sonata_out_pins_t out_to_pins_o, input sonata_inout_pins_t inout_from_pins_i, output sonata_inout_pins_t inout_to_pins_o, - output sonata_inout_pins_t inout_to_pins_en_o + output sonata_inout_pins_t inout_to_pins_en_o, + + output logic [3:0] strace_o ); /////////////////////////////////////////////// // Signals, types and parameters for system. // @@ -1208,6 +1210,64 @@ module sonata_system .rgbled_dout_o ); + // TODO: Tap onto the PWM device port for now. + wire strace_cfg_re = device_req[Pwm] & !device_we[Pwm] & device_addr[Pwm][7]; + wire strace_cfg_we = device_req[Pwm] & device_we[Pwm] & device_addr[Pwm][7]; + wire [3:0] strace_cfg_addr = device_addr[Pwm][3:0]; + wire [31:0] strace_cfg_wdata = device_wdata[Pwm]; + + // Collect the I2C buses and SPI buses. + logic [I2C_NUM-1:0] strace_i2c_scl; + logic [I2C_NUM-1:0] strace_i2c_sda; + logic [SPI_NUM-1:0] strace_spi_sck; + logic [SPI_NUM-1:0] strace_spi_cs; // TODO: require multi-CS support. + logic [SPI_NUM-1:0] strace_spi_copi; + logic [SPI_NUM-1:0] strace_spi_cipo; + always_comb begin + for (integer i = 0; i < I2C_NUM; i++) begin + strace_i2c_scl[i] = i2c_scl_d2h[i]; + strace_i2c_sda[i] = i2c_sda_d2h[i]; + end + for (integer i = 0; i < SPI_NUM; i++) begin + strace_spi_sck[i] = spi_sclk[i]; + strace_spi_cs[i] = spi_cs[i][1]; // TODO: Only interested in microSD presently! + strace_spi_copi[i] = spi_copi[i]; + strace_spi_cipo[i] = spi_cipo[i]; + end + end + + // Sonata Trace port. + strace_top #( + .I2C_NUM (I2C_NUM), + .SPI_NUM (SPI_NUM) + ) u_strace( + .clk_i (clk_sys_i), + .rst_ni (rst_sys_ni), + + // Configuration interface. + .cfg_re (strace_cfg_re), + .cfg_we (strace_cfg_we), + .cfg_addr (strace_cfg_addr), + .cfg_wdata (strace_cfg_wdata), + // TODO: make read data available; presently not done because of GPIO tap. + .cfg_rdata (), + + // I2C bus(es). + .i2c_scl (strace_i2c_scl), + .i2c_sda (strace_i2c_sda), + + // SPI bus(es). + .spi_cs (strace_spi_cs), + .spi_sck (strace_spi_sck), + .spi_copi (strace_spi_copi), + .spi_cipo (strace_spi_cipo), + + // TL-UL activity. + .tlul_trace (4'h0), + + .strace_o (strace_o) + ); + // Debug module top. dm_top #( .NrHarts ( 1 ), diff --git a/sonata_system.core b/sonata_system.core index 7fffb3f9b..4e61f5488 100644 --- a/sonata_system.core +++ b/sonata_system.core @@ -28,6 +28,7 @@ filesets: files: - rtl/system/sonata_pkg.sv - rtl/bus/sonata_xbar_main.sv + - rtl/ip/strace/rtl/strace_top.sv - rtl/system/jtag_id_pkg.sv - rtl/system/sonata_system.sv - rtl/system/dm_top.sv