[chip dv] Get ALL UART tests working

Write extra vseq for smoke test that facilitates the UART0 connection.

Refactor the tx rx vseq to reuse some other refactored code in its base
classes.

Tests passing with these changes:
- chip_sw_uart_smoketest
- chip_sw_uart_smoketest_signed
- chip_sw_uart_tx_rx
- chip_sw_uart_tx_rx_idx1
- chip_sw_uart_tx_rx_idx2
- chip_sw_uart_tx_rx_idx3

Tests that need to be debugged:
- chip_sw_uart_tx_rx_alt_clk_freq
- chip_sw_uart_tx_rx_alt_clk_freq_low_speed

Tests failing from before:
- chip_sw_uart_tx_rx_bootstrap

Signed-off-by: Srikrishna Iyer <sriyer@google.com>
diff --git a/hw/top_earlgrey/dv/chip_rom_tests.hjson b/hw/top_earlgrey/dv/chip_rom_tests.hjson
index 6d8591f..c401697 100644
--- a/hw/top_earlgrey/dv/chip_rom_tests.hjson
+++ b/hw/top_earlgrey/dv/chip_rom_tests.hjson
@@ -19,7 +19,7 @@
     // Signed chip-level tests to be run with ROM, instead of test ROM.
     {
       name: chip_sw_uart_smoketest_signed
-      uvm_test_seq: chip_sw_base_vseq
+      uvm_test_seq: chip_sw_uart_smoke_vseq
       sw_images: ["//sw/device/tests:uart_smoketest_signed:1:signed"]
       en_run_modes: ["sw_test_mode_rom"]
       run_opts: ["+sw_test_timeout_ns=20000000"]
diff --git a/hw/top_earlgrey/dv/chip_sim_cfg.hjson b/hw/top_earlgrey/dv/chip_sim_cfg.hjson
index 721a184..ac8209d 100644
--- a/hw/top_earlgrey/dv/chip_sim_cfg.hjson
+++ b/hw/top_earlgrey/dv/chip_sim_cfg.hjson
@@ -247,9 +247,7 @@
       // The tests using this mode only require the ROM init check to succeed.
       // The example_test_from_rom test is sufficient.
       sw_images: ["//sw/device/tests:example_test_from_rom:0:test_in_rom"]
-      run_opts: ["+create_jtag_riscv_map=1",
-                 // select DFT tap
-                 "+uart0_sel=0"]
+      run_opts: ["+create_jtag_riscv_map=1"]
       reseed: 5
     }
     {
diff --git a/hw/top_earlgrey/dv/chip_smoketests.hjson b/hw/top_earlgrey/dv/chip_smoketests.hjson
index 327a335..da11453 100644
--- a/hw/top_earlgrey/dv/chip_smoketests.hjson
+++ b/hw/top_earlgrey/dv/chip_smoketests.hjson
@@ -108,7 +108,7 @@
     }
     {
       name: chip_sw_uart_smoketest
-      uvm_test_seq: chip_sw_base_vseq
+      uvm_test_seq: chip_sw_uart_smoke_vseq
       sw_images: ["//sw/device/tests:uart_smoketest:1"]
       en_run_modes: ["sw_test_mode_test_rom"]
     }
diff --git a/hw/top_earlgrey/dv/env/chip_env.core b/hw/top_earlgrey/dv/env/chip_env.core
index 94b7b7d..c68e536 100644
--- a/hw/top_earlgrey/dv/env/chip_env.core
+++ b/hw/top_earlgrey/dv/env/chip_env.core
@@ -47,6 +47,7 @@
       - seq_lib/chip_prim_tl_access_vseq.sv: {is_include_file: true}
       - seq_lib/chip_tap_straps_vseq.sv: {is_include_file: true}
       - seq_lib/chip_sw_base_vseq.sv: {is_include_file: true}
+      - seq_lib/chip_sw_uart_smoke_vseq.sv: {is_include_file: true}
       - seq_lib/chip_jtag_base_vseq.sv: {is_include_file: true}
       - seq_lib/chip_sw_alert_handler_entropy_vseq.sv: {is_include_file: true}
       - seq_lib/chip_sw_alert_handler_escalation_vseq.sv: {is_include_file: true}
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 9106d9a..421cfe1 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
@@ -25,19 +25,14 @@
     super.dut_init(reset_kind);
   endtask
 
-  // Backdoor load the sw test image, setup UART, logger and test status interfaces.
+  // Backdoor load the sw test image, initialize memories, sw logger and test status interfaces.
   virtual task cpu_init();
      int size_bytes;
      int total_bytes;
 
-    `uvm_info(`gfn, "Started cpu_init", UVM_MEDIUM)
-    // TODO: Fixing this for now - need to find a way to pass this on to the SW test.
-    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
+    `uvm_info(`gfn, "Starting cpu_init", UVM_MEDIUM)
 
-    // initialize the sw logger interface
+    // Initialize the sw logger interface.
     foreach (cfg.sw_images[i]) begin
       cfg.sw_logger_vif.add_sw_log_db(cfg.sw_images[i]);
     end
@@ -45,12 +40,12 @@
     cfg.sw_logger_vif.write_sw_logs_to_file = cfg.write_sw_logs_to_file;
     cfg.sw_logger_vif.ready();
 
-    // initialize the sw test status
+    // Initialize the sw test status.
     cfg.sw_test_status_vif.sw_test_status_addr = SW_DV_TEST_STATUS_ADDR;
 
-    `uvm_info(`gfn, "Initializing RAM", UVM_MEDIUM)
+    `uvm_info(`gfn, "Initializing SRAMs", UVM_MEDIUM)
 
-    // Assume each tile contains the same number of bytes
+    // Assume each tile contains the same number of bytes.
     size_bytes = cfg.mem_bkdr_util_h[chip_mem_e'(RamMain0)].get_size_bytes();
     total_bytes = size_bytes * cfg.num_ram_main_tiles;
 
@@ -81,6 +76,7 @@
 `else
     cfg.mem_bkdr_util_h[Rom].load_mem_from_file({cfg.sw_images[SwTypeRom], ".39.scr.vmem"});
 `endif
+
     // TODO: the location of the main execution image should be randomized to either bank in future.
     if (cfg.sw_images.exists(SwTypeTest)) begin
       if (cfg.use_spi_load_bootstrap) begin
@@ -95,7 +91,7 @@
 
     config_jitter();
 
-    `uvm_info(`gfn, "CPU_init done", UVM_MEDIUM)
+    `uvm_info(`gfn, "cpu_init completed", UVM_MEDIUM)
   endtask
 
   // The jitter enable mechanism is different from test_rom and rom right now.
@@ -186,7 +182,7 @@
 
   virtual task body();
     cfg.sw_test_status_vif.set_num_iterations(num_trans);
-    // Initialize the CPU to kick off the sw test.
+    // Initialize the CPU to kick off the sw test. TODO: Should be called in pre_start() instead.
     cpu_init();
   endtask
 
diff --git a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_uart_rand_baudrate_vseq.sv b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_uart_rand_baudrate_vseq.sv
index 684fb47..65b98d8 100644
--- a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_uart_rand_baudrate_vseq.sv
+++ b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_uart_rand_baudrate_vseq.sv
@@ -32,15 +32,16 @@
     super.pre_randomize();
     void'($value$plusargs("use_extclk=%0d", use_extclk));
     void'($value$plusargs("extclk_low_speed_sel=%0d", extclk_low_speed_sel));
+
     if (use_extclk) begin
       // Uart bus clock is in div4 domain
       uart_clk_freq_khz = cfg.clk_freq_mhz * 1000 / 4;
-
       if (extclk_low_speed_sel) uart_clk_freq_khz = uart_clk_freq_khz * 2;
     end else begin
       // internal uart bus clock is 24Mhz
       uart_clk_freq_khz = 24_000;
     end
+
     `uvm_info(`gfn, $sformatf(
               "External clock freq: %0dmhz, use_extclk: %0d, extclk_low_speed_sel: %0d",
               cfg.clk_freq_mhz,
@@ -49,10 +50,10 @@
               ), UVM_LOW)
   endfunction
 
-  virtual task dut_init(string reset_kind = "HARD");
-    super.dut_init(reset_kind);
+  function void post_randomize();
+    super.post_randomize();
     cfg.uart_baud_rate = baud_rate;
-  endtask
+  endfunction
 
   virtual task cpu_init();
     // sw_symbol_backdoor_overwrite takes an array as the input
@@ -82,12 +83,12 @@
   endtask
 
   // When uart starts to send RX data, check if AST is using extclk if extclk is selected.
-  virtual task send_uart_rx_data(int size = -1, bit random = 0);
+  virtual task send_uart_rx_data(int instance_num, int size = -1, bit random = 0);
     if (use_extclk) begin
       `DV_CHECK(cfg.ast_ext_clk_vif.is_ext_clk_in_use(),
                 "expected the external clock to be used for io");
     end
-    super.send_uart_rx_data(size, random);
+    super.send_uart_rx_data(instance_num, size, random);
   endtask
 
 endclass : chip_sw_uart_rand_baudrate_vseq
diff --git a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_uart_smoke_vseq.sv b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_uart_smoke_vseq.sv
new file mode 100644
index 0000000..f1615cd
--- /dev/null
+++ b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_uart_smoke_vseq.sv
@@ -0,0 +1,42 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class chip_sw_uart_smoke_vseq extends chip_sw_base_vseq;
+  `uvm_object_utils(chip_sw_uart_smoke_vseq)
+
+  `uvm_object_new
+
+  rand int uart_idx;
+
+  constraint uart_idx_c {
+    uart_idx inside {[0:NUM_UARTS-1]};
+  }
+
+  // The smoke test only uses UART0, but it may change in future. Disable this constraint in
+  // extended classes.
+  constraint uart_idx_smoke_c {
+    uart_idx == 0;
+  }
+
+  virtual task body();
+    super.body();
+    configure_and_connect_uart(uart_idx);
+  endtask
+
+  // Configures the UART agent and connects uart_if to the chip IOs for the given instance.
+  virtual function void configure_and_connect_uart(int instance_num);
+    `DV_CHECK_FATAL(instance_num inside {[0:NUM_UARTS-1]})
+    `uvm_info(`gfn, $sformatf("Configuring and connecting UART%0d", instance_num), UVM_LOW)
+    cfg.m_uart_agent_cfgs[instance_num].set_parity(1'b0, 1'b0);
+    cfg.m_uart_agent_cfgs[instance_num].set_baud_rate(cfg.uart_baud_rate);
+    cfg.chip_vif.enable_uart(instance_num, 1);
+  endfunction
+
+  virtual task post_start();
+    super.post_start();
+    // Disconnect the UART interface.
+    cfg.chip_vif.enable_uart(uart_idx, 0);
+  endtask
+
+endclass : chip_sw_uart_smoke_vseq
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 dc17003..f80ef88 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
@@ -2,7 +2,7 @@
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
 
-class chip_sw_uart_tx_rx_vseq extends chip_sw_base_vseq;
+class chip_sw_uart_tx_rx_vseq extends chip_sw_uart_smoke_vseq;
   `uvm_object_utils(chip_sw_uart_tx_rx_vseq)
 
   `uvm_object_new
@@ -22,15 +22,14 @@
     uart_rx_data.size() == UART_DATASET_SIZE;
   }
 
-  rand int uart_idx;
-
-  constraint uart_idx_c {
-    uart_idx inside {[0 : NUM_UARTS-1]};
-  }
+  function void pre_randomize();
+    uart_idx_smoke_c.constraint_mode(0);
+    super.pre_randomize();
+  endfunction
 
   task pre_start();
     void'($value$plusargs("uart_idx=%0d", uart_idx));
-    `DV_CHECK_LT(uart_idx, NUM_UARTS)
+    `DV_CHECK_FATAL(uart_idx inside {[0:NUM_UARTS-1]})
     super.pre_start();
   endtask
 
@@ -47,9 +46,6 @@
   virtual task body();
     super.body();
 
-    // Connect the UART RX pin to the chip IOs.
-    cfg.chip_vif.enable_uart(uart_idx, 1);
-
     // Spawn off a thread to retrieve UART TX items.
     fork get_uart_tx_items(uart_idx); join_none
 
@@ -57,7 +53,7 @@
     `DV_WAIT(uart_tx_data_q.size() > 0)
 
     // Start sending uart_rx_data over RX.
-    send_uart_rx_data();
+    send_uart_rx_data(.instance_num(uart_idx));
 
     // Wait until we receive all bytes over TX.
     `DV_WAIT(uart_tx_data_q.size() == exp_uart_tx_data.size())
@@ -69,13 +65,14 @@
     end
 
     // Send UART_RX_FIFO_SIZE+1 random bytes over RX to create an overflow condition.
-    send_uart_rx_data(.size(UART_RX_FIFO_SIZE + 1), .random(1'b1));
+    send_uart_rx_data(.instance_num(uart_idx), .size(UART_RX_FIFO_SIZE + 1), .random(1'b1));
   endtask
 
   // Send data over RX.
-  virtual task send_uart_rx_data(int size = -1, bit random = 0);
+  virtual task send_uart_rx_data(int instance_num, int size = -1, bit random = 0);
     uart_default_seq send_rx_seq;
-    `uvm_create_on(send_rx_seq, p_sequencer.uart_sequencer_hs[uart_idx]);
+    `DV_CHECK_FATAL(instance_num inside {[0:NUM_UARTS-1]})
+    `uvm_create_on(send_rx_seq, p_sequencer.uart_sequencer_hs[instance_num]);
     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];
@@ -84,9 +81,4 @@
     end
   endtask
 
-  virtual task dut_shutdown();
-    super.dut_shutdown();
-    if (uart_idx > 0) cfg.chip_vif.enable_uart(uart_idx, 0);
-  endtask
-
 endclass : chip_sw_uart_tx_rx_vseq
diff --git a/hw/top_earlgrey/dv/env/seq_lib/chip_vseq_list.sv b/hw/top_earlgrey/dv/env/seq_lib/chip_vseq_list.sv
index 8f2f095..973d24f 100644
--- a/hw/top_earlgrey/dv/env/seq_lib/chip_vseq_list.sv
+++ b/hw/top_earlgrey/dv/env/seq_lib/chip_vseq_list.sv
@@ -10,6 +10,7 @@
 `include "chip_jtag_mem_vseq.sv"
 // This needs to be listed prior to all sequences that derive from it.
 `include "chip_sw_base_vseq.sv"
+`include "chip_sw_uart_smoke_vseq.sv"
 `include "chip_jtag_base_vseq.sv"
 `include "chip_prim_tl_access_vseq.sv"
 `include "chip_sw_all_escalation_resets_vseq.sv"