[dv/top] Test uart multiple instances
Pick a uart to test, backdoor modify memory to let SW test the
uart we pick.
Update pinmux to enable the other 3 uarts
Remove uart mon connection with scb, which is unused
Signed-off-by: Weicai Yang <weicai@google.com>
diff --git a/hw/top_earlgrey/dv/chip_sim_cfg.hjson b/hw/top_earlgrey/dv/chip_sim_cfg.hjson
index 5ecdcc2..4b5e272 100644
--- a/hw/top_earlgrey/dv/chip_sim_cfg.hjson
+++ b/hw/top_earlgrey/dv/chip_sim_cfg.hjson
@@ -166,6 +166,31 @@
uvm_test_seq: chip_sw_uart_tx_rx_vseq
sw_images: ["sw/device/tests/uart_tx_rx_test:1"]
en_run_modes: ["sw_test_mode"]
+ reseed: 10
+ }
+ {
+ name: chip_sw_uart_tx_rx_idx1
+ uvm_test_seq: chip_sw_uart_tx_rx_vseq
+ sw_images: ["sw/device/tests/uart_tx_rx_test:1"]
+ en_run_modes: ["sw_test_mode"]
+ run_opts: ["+uart_idx=1"]
+ reseed: 10
+ }
+ {
+ name: chip_sw_uart_tx_rx_idx2
+ uvm_test_seq: chip_sw_uart_tx_rx_vseq
+ sw_images: ["sw/device/tests/uart_tx_rx_test:1"]
+ en_run_modes: ["sw_test_mode"]
+ run_opts: ["+uart_idx=2"]
+ reseed: 10
+ }
+ {
+ name: chip_sw_uart_tx_rx_idx3
+ uvm_test_seq: chip_sw_uart_tx_rx_vseq
+ sw_images: ["sw/device/tests/uart_tx_rx_test:1"]
+ en_run_modes: ["sw_test_mode"]
+ run_opts: ["+uart_idx=3"]
+ reseed: 10
}
{
name: chip_sw_uart_tx_rx_bootstrap
diff --git a/hw/top_earlgrey/dv/env/chip_env.sv b/hw/top_earlgrey/dv/env/chip_env.sv
index 33b01f4..d9f2043 100644
--- a/hw/top_earlgrey/dv/env/chip_env.sv
+++ b/hw/top_earlgrey/dv/env/chip_env.sv
@@ -10,7 +10,7 @@
);
`uvm_component_utils(chip_env)
- uart_agent m_uart_agent;
+ uart_agent m_uart_agents[NUM_UARTS];
jtag_riscv_agent m_jtag_riscv_agent;
spi_agent m_spi_agent;
@@ -62,8 +62,11 @@
end
// create components
- m_uart_agent = uart_agent::type_id::create("m_uart_agent", this);
- uvm_config_db#(uart_agent_cfg)::set(this, "m_uart_agent*", "cfg", cfg.m_uart_agent_cfg);
+ foreach (m_uart_agents[i]) begin
+ m_uart_agents[i] = uart_agent::type_id::create($sformatf("m_uart_agent%0d", i), this);
+ uvm_config_db#(uart_agent_cfg)::set(this, $sformatf("m_uart_agent%0d*", i), "cfg",
+ cfg.m_uart_agent_cfgs[i]);
+ end
m_jtag_riscv_agent = jtag_riscv_agent::type_id::create("m_jtag_riscv_agent", this);
uvm_config_db#(jtag_riscv_agent_cfg)::set(this, "m_jtag_riscv_agent*", "cfg",
@@ -81,12 +84,12 @@
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
if (cfg.en_scb) begin
- m_uart_agent.monitor.tx_analysis_port.connect(scoreboard.uart_tx_fifo.analysis_export);
- m_uart_agent.monitor.rx_analysis_port.connect(scoreboard.uart_rx_fifo.analysis_export);
m_jtag_riscv_agent.monitor.analysis_port.connect(scoreboard.jtag_fifo.analysis_export);
end
- if (cfg.is_active && cfg.m_uart_agent_cfg.is_active) begin
- virtual_sequencer.uart_sequencer_h = m_uart_agent.sequencer;
+ foreach (m_uart_agents[i]) begin
+ if (cfg.is_active && cfg.m_uart_agent_cfgs[i].is_active) begin
+ virtual_sequencer.uart_sequencer_hs[i] = m_uart_agents[i].sequencer;
+ end
end
if (cfg.is_active && cfg.m_jtag_riscv_agent_cfg.is_active) begin
virtual_sequencer.jtag_sequencer_h = m_jtag_riscv_agent.sequencer;
@@ -96,7 +99,10 @@
end
// Connect the DUT's UART TX TLM port to the sequencer.
- m_uart_agent.monitor.tx_analysis_port.connect(virtual_sequencer.uart_tx_fifo.analysis_export);
+ foreach (m_uart_agents[i]) begin
+ m_uart_agents[i].monitor.tx_analysis_port.connect(
+ virtual_sequencer.uart_tx_fifos[i].analysis_export);
+ end
endfunction
virtual function void end_of_elaboration_phase(uvm_phase phase);
diff --git a/hw/top_earlgrey/dv/env/chip_env_cfg.sv b/hw/top_earlgrey/dv/env/chip_env_cfg.sv
index 89c5e33..10ba957 100644
--- a/hw/top_earlgrey/dv/env/chip_env_cfg.sv
+++ b/hw/top_earlgrey/dv/env/chip_env_cfg.sv
@@ -58,13 +58,12 @@
sw_test_status_vif sw_test_status_vif;
// ext component cfgs
- rand uart_agent_cfg m_uart_agent_cfg;
+ rand uart_agent_cfg m_uart_agent_cfgs[NUM_UARTS];
rand jtag_riscv_agent_cfg m_jtag_riscv_agent_cfg;
rand spi_agent_cfg m_spi_agent_cfg;
`uvm_object_utils_begin(chip_env_cfg)
`uvm_field_int (stub_cpu, UVM_DEFAULT)
- `uvm_field_object(m_uart_agent_cfg, UVM_DEFAULT)
`uvm_field_object(m_jtag_riscv_agent_cfg, UVM_DEFAULT)
`uvm_field_object(m_spi_agent_cfg, UVM_DEFAULT)
`uvm_object_utils_end
@@ -89,7 +88,9 @@
m_tl_agent_cfg.valid_a_source_width = 6;
// create uart agent config obj
- m_uart_agent_cfg = uart_agent_cfg::type_id::create("m_uart_agent_cfg");
+ foreach (m_uart_agent_cfgs[i]) begin
+ m_uart_agent_cfgs[i] = uart_agent_cfg::type_id::create($sformatf("m_uart_agent_cfg%0d", i));
+ end
// create jtag agent config obj
m_jtag_riscv_agent_cfg = jtag_riscv_agent_cfg::type_id::create("m_jtag_riscv_agent_cfg");
diff --git a/hw/top_earlgrey/dv/env/chip_env_pkg.sv b/hw/top_earlgrey/dv/env/chip_env_pkg.sv
index 72b7c6b..427ed49 100644
--- a/hw/top_earlgrey/dv/env/chip_env_pkg.sv
+++ b/hw/top_earlgrey/dv/env/chip_env_pkg.sv
@@ -34,6 +34,7 @@
// local parameters and types
parameter uint NUM_GPIOS = 16;
+ parameter uint NUM_UARTS = 4;
// Buffer is half of SPI_DEVICE Dual Port SRAM
parameter uint SPI_FRAME_BYTE_SIZE = spi_device_reg_pkg::SPI_DEVICE_BUFFER_SIZE/2;
diff --git a/hw/top_earlgrey/dv/env/chip_scoreboard.sv b/hw/top_earlgrey/dv/env/chip_scoreboard.sv
index c3078ef..22a2df8 100644
--- a/hw/top_earlgrey/dv/env/chip_scoreboard.sv
+++ b/hw/top_earlgrey/dv/env/chip_scoreboard.sv
@@ -12,8 +12,6 @@
// local variables
// TLM agent fifos
- uvm_tlm_analysis_fifo #(uart_item) uart_tx_fifo;
- uvm_tlm_analysis_fifo #(uart_item) uart_rx_fifo;
uvm_tlm_analysis_fifo #(jtag_riscv_item) jtag_fifo;
// local queues to hold incoming packets pending comparison
@@ -25,8 +23,6 @@
function void build_phase(uvm_phase phase);
super.build_phase(phase);
- uart_tx_fifo = new("uart_tx_fifo", this);
- uart_rx_fifo = new("uart_rx_fifo", this);
jtag_fifo = new("jtag_fifo", this);
endfunction
diff --git a/hw/top_earlgrey/dv/env/chip_virtual_sequencer.sv b/hw/top_earlgrey/dv/env/chip_virtual_sequencer.sv
index cf5e17e..9c4bfad 100644
--- a/hw/top_earlgrey/dv/env/chip_virtual_sequencer.sv
+++ b/hw/top_earlgrey/dv/env/chip_virtual_sequencer.sv
@@ -8,18 +8,18 @@
);
`uvm_component_utils(chip_virtual_sequencer)
- uart_sequencer uart_sequencer_h;
+ uart_sequencer uart_sequencer_hs[NUM_UARTS];
jtag_riscv_sequencer jtag_sequencer_h;
spi_sequencer spi_sequencer_h;
// Grab packets from UART TX port for in-sequence checking.
- uvm_tlm_analysis_fifo #(uart_item) uart_tx_fifo;
+ uvm_tlm_analysis_fifo #(uart_item) uart_tx_fifos[NUM_UARTS];
`uvm_component_new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
- uart_tx_fifo = new("uart_tx_fifo", this);
+ foreach (uart_tx_fifos[i]) uart_tx_fifos[i] = new($sformatf("uart_tx_fifo%0d", i), this);
endfunction
endclass
diff --git a/hw/top_earlgrey/dv/env/seq_lib/chip_base_vseq.sv b/hw/top_earlgrey/dv/env/seq_lib/chip_base_vseq.sv
index 782b83c..765085c 100644
--- a/hw/top_earlgrey/dv/env/seq_lib/chip_base_vseq.sv
+++ b/hw/top_earlgrey/dv/env/seq_lib/chip_base_vseq.sv
@@ -80,10 +80,10 @@
endtask
// Grab packets sent by the DUT over the UART TX port.
- virtual task get_uart_tx_items();
+ virtual task get_uart_tx_items(int uart_idx = 0);
uart_item item;
forever begin
- p_sequencer.uart_tx_fifo.get(item);
+ p_sequencer.uart_tx_fifos[uart_idx].get(item);
`uvm_info(`gfn, $sformatf("Received UART data over TX:\n%0h", item.data), UVM_HIGH)
uart_tx_data_q.push_back(item.data);
end
diff --git a/hw/top_earlgrey/dv/env/seq_lib/chip_stub_cpu_base_vseq.sv b/hw/top_earlgrey/dv/env/seq_lib/chip_stub_cpu_base_vseq.sv
index 8945824..3997ced 100644
--- a/hw/top_earlgrey/dv/env/seq_lib/chip_stub_cpu_base_vseq.sv
+++ b/hw/top_earlgrey/dv/env/seq_lib/chip_stub_cpu_base_vseq.sv
@@ -19,9 +19,10 @@
// In top-level uart RX pin may be selected in pinmux. CSR tests may randomly enable line
// loopback, which will connect TX with RX. If RX isn't enabled in pinmux, it will be 0.
// moniter will start to check the TX data when it changes from 1 to 0. But the length of 0 may
- // be not right in CSR test.
- // In block-level, we always ties RX to 1 (idle) in CSR test. No need to disable the monitor
- cfg.m_uart_agent_cfg.en_tx_monitor = 0;
+ // be not right in CSR test, which causes a protocal error on TX
+ // In block-level, we always tie RX to 1 (idle) in CSR test so that we don't need to disable TX
+ // monitor in block-level
+ foreach (cfg.m_uart_agent_cfgs[i]) cfg.m_uart_agent_cfgs[i].en_tx_monitor = 0;
endtask
task post_start();
diff --git a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_base_vseq.sv b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_base_vseq.sv
index 8707f9b..4206cb9 100644
--- a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_base_vseq.sv
+++ b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_base_vseq.sv
@@ -17,8 +17,10 @@
// Backdoor load the sw test image, setup UART, logger and test status interfaces.
virtual task cpu_init();
// TODO: Fixing this for now - need to find a way to pass this on to the SW test.
- cfg.m_uart_agent_cfg.set_parity(1'b0, 1'b0);
- cfg.m_uart_agent_cfg.set_baud_rate(cfg.uart_baud_rate);
+ foreach (cfg.m_uart_agent_cfgs[i]) begin
+ cfg.m_uart_agent_cfgs[i].set_parity(1'b0, 1'b0);
+ cfg.m_uart_agent_cfgs[i].set_baud_rate(cfg.uart_baud_rate);
+ end
// initialize the sw logger interface
foreach (cfg.sw_images[i]) begin
diff --git a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_uart_tx_rx_vseq.sv b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_uart_tx_rx_vseq.sv
index 188f826..dc4e08d 100644
--- a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_uart_tx_rx_vseq.sv
+++ b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_uart_tx_rx_vseq.sv
@@ -22,17 +22,29 @@
uart_rx_data.size() == UART_DATASET_SIZE;
}
+ byte uart_idx = 0;
+
+ task pre_start();
+ void'($value$plusargs("uart_idx=%0d", uart_idx));
+ `DV_CHECK_LT(uart_idx, NUM_UARTS)
+ super.pre_start();
+ endtask
+
virtual task cpu_init();
+ // sw_symbol_backdoor_overwrite takes an array as the input
+ byte uart_idx_data[] = {uart_idx};
+
super.cpu_init();
- sw_symbol_backdoor_overwrite("uart_tx_data", exp_uart_tx_data);
- sw_symbol_backdoor_overwrite("exp_uart_rx_data", uart_rx_data);
+ sw_symbol_backdoor_overwrite("kUartTxData", exp_uart_tx_data);
+ sw_symbol_backdoor_overwrite("kExpUartRxData", uart_rx_data);
+ sw_symbol_backdoor_overwrite("kUartIdx", uart_idx_data);
endtask
virtual task body();
super.body();
// Spawn off a thread to retrieve UART TX items.
- fork get_uart_tx_items(); join_none
+ fork get_uart_tx_items(uart_idx); join_none
// Wait until we receive at least 1 byte from the DUT (SW test).
wait(uart_tx_data_q.size() > 0);
@@ -56,7 +68,7 @@
// Send data over RX.
virtual task send_uart_rx_data(int size = -1, bit random = 0);
uart_default_seq send_rx_seq;
- `uvm_create_on(send_rx_seq, p_sequencer.uart_sequencer_h);
+ `uvm_create_on(send_rx_seq, p_sequencer.uart_sequencer_hs[uart_idx]);
if (size == -1) size = uart_rx_data.size();
for (int i = 0; i < size; i++) begin
byte rx_data = random ? $urandom : uart_rx_data[i];
diff --git a/hw/top_earlgrey/dv/tb/tb.sv b/hw/top_earlgrey/dv/tb/tb.sv
index ce96884..9e99edb 100644
--- a/hw/top_earlgrey/dv/tb/tb.sv
+++ b/hw/top_earlgrey/dv/tb/tb.sv
@@ -40,7 +40,7 @@
wire usb_dp0, usb_dn0, usb_sense0, usb_dppullup0, usb_dnpullup0;
- wire uart_rx, uart_tx;
+ wire uart_rx[NUM_UARTS], uart_tx[NUM_UARTS];
bit stub_cpu;
bit en_sim_sram = 1'b1;
@@ -62,7 +62,7 @@
pins_if #(1) rst_n_mon_if(.pins(cpu_rst_n));
spi_if spi_if(.rst_n);
tl_if cpu_d_tl_if(.clk(cpu_clk), .rst_n(cpu_rst_n));
- uart_if uart_if();
+ uart_if uart_if[NUM_UARTS-1:0]();
jtag_if jtag_if();
// TODO: Replace with correct interfaces once
@@ -129,8 +129,8 @@
.IOC7(tie_off[7]), // MIO 29
.IOC8(tap_straps[0]), // MIO 30
.IOC9(tie_off[8]), // MIO 31
- .IOC10(uart_rx), // MIO 32
- .IOC11(uart_tx), // MIO 33
+ .IOC10(uart_rx[0]), // MIO 32
+ .IOC11(uart_tx[0]), // MIO 33
.IOC12(tie_off[9]), // MIO 34
// Bank R (VCC domain)
.IOR0(jtag_tms), // MIO 35
@@ -138,14 +138,14 @@
.IOR2(jtag_tdi), // MIO 37
.IOR3(jtag_tck), // MIO 38
.IOR4(jtag_trst_n), // MIO 39
- .IOR5(tie_off[10]), // MIO 40
- .IOR6(tie_off[11]), // MIO 41
- .IOR7(tie_off[12]), // MIO 42
- .IOR8(tie_off[13]), // MIO 43
- .IOR9(tie_off[14]), // MIO 44
- .IOR10(tie_off[15]), // MIO 45
- .IOR11(tie_off[16]), // MIO 46
- .IOR12(tie_off[17]), // MIO 47
+ .IOR5(uart_rx[1]), // MIO 40
+ .IOR6(uart_tx[1]), // MIO 41
+ .IOR7(uart_rx[2]), // MIO 42
+ .IOR8(tie_off[13]), // MIO 43, Dedicated sysrst_ctrl output (ec_rst_l)
+ .IOR9(tie_off[14]), // MIO 44, Dedicated sysrst_ctrl output (pwrb_out)
+ .IOR10(uart_tx[2]), // MIO 45
+ .IOR11(uart_rx[3]), // MIO 46
+ .IOR12(uart_tx[3]), // MIO 47
.IOR13(tie_off[18]), // MIO 48
// DCD (VCC domain)
.CC1(tie_off[19]),
@@ -180,13 +180,6 @@
assign spi_device_sdi_i = spi_if.sio[0];
assign spi_if.sio[1] = spi_device_sdo_o;
- // TODO: Replace this weak pull to a known value with initialization
- // in the agent/interface.
- assign (weak0, weak1) uart_rx = 1'b1;
- assign (weak0, weak1) uart_tx = 1'b1;
- assign uart_rx = uart_if.uart_rx;
- assign uart_if.uart_tx = uart_tx;
-
// TODO: USB-related signals, hookup an interface.
assign usb_rst_n = `USBDEV_HIER.rst_usb_48mhz_ni;
assign usb_dp0 = 1'b1;
@@ -248,7 +241,6 @@
// IO Interfaces
uvm_config_db#(virtual pins_if #(NUM_GPIOS))::set(null, "*.env", "gpio_vif", gpio_if);
- uvm_config_db#(virtual uart_if)::set(null, "*.env.m_uart_agent*", "vif", uart_if);
uvm_config_db#(virtual jtag_if)::set(null, "*.env.m_jtag_riscv_agent*", "vif", jtag_if);
uvm_config_db#(virtual spi_if)::set(null, "*.env.m_spi_agent*", "vif", spi_if);
uvm_config_db#(virtual tl_if)::set(null, "*.env.m_tl_agent*", "vif", cpu_d_tl_if);
@@ -278,6 +270,19 @@
run_test();
end
+ for (genvar i = 0; i < NUM_UARTS; i++) begin : gen_uart_if
+ // TODO: Replace this weak pull to a known value with initialization
+ // in the agent/interface.
+ assign (weak0, weak1) uart_rx[i] = 1'b1;
+ assign (weak0, weak1) uart_tx[i] = 1'b1;
+ assign uart_rx[i] = uart_if[i].uart_rx;
+ assign uart_if[i].uart_tx = uart_tx[i];
+
+ initial begin
+ uvm_config_db#(virtual uart_if)::set(null, $sformatf("*.env.m_uart_agent%0d*", i),
+ "vif", uart_if[i]);
+ end
+ end
`undef SIM_SRAM_IF
// Instantitate the memory backdoor util instances.
diff --git a/hw/top_earlgrey/dv/tests/chip_base_test.sv b/hw/top_earlgrey/dv/tests/chip_base_test.sv
index 1da340b..e3aa51b 100644
--- a/hw/top_earlgrey/dv/tests/chip_base_test.sv
+++ b/hw/top_earlgrey/dv/tests/chip_base_test.sv
@@ -38,8 +38,8 @@
// Knob to enable logging over UART (disabled by default).
void'($value$plusargs("en_uart_logger=%0b", cfg.en_uart_logger));
- cfg.m_uart_agent_cfg.en_logger = cfg.en_uart_logger;
- cfg.m_uart_agent_cfg.write_logs_to_file = cfg.write_sw_logs_to_file;
+ cfg.m_uart_agent_cfgs[0].en_logger = cfg.en_uart_logger;
+ cfg.m_uart_agent_cfgs[0].write_logs_to_file = cfg.write_sw_logs_to_file;
// Knob to set the sw_test_timeout_ns (set to 5ms by default).
void'($value$plusargs("sw_test_timeout_ns=%0d", cfg.sw_test_timeout_ns));