[dv/lc_ctrl] add jtag agent to lc_ctrl testbench

This PR connects jtag agent to lc_ctrl testbench. To actually drive
jtag interface, will need further support in jtag agent.

This PR also removes the jtags `tdo_oe` pin from jtag_agent.

Signed-off-by: Cindy Chen <chencindy@google.com>
diff --git a/hw/dv/sv/jtag_agent/jtag_driver.sv b/hw/dv/sv/jtag_agent/jtag_driver.sv
index d2760e1..d99f2d3 100644
--- a/hw/dv/sv/jtag_agent/jtag_driver.sv
+++ b/hw/dv/sv/jtag_agent/jtag_driver.sv
@@ -27,7 +27,6 @@
     end
     else begin
       `DEVICE_CB.tdo <= 1'b0;
-      `DEVICE_CB.tdo_oe <= 1'b0;
     end
   endtask
 
diff --git a/hw/dv/sv/jtag_agent/jtag_if.sv b/hw/dv/sv/jtag_agent/jtag_if.sv
index 083b2bd..5a99074 100644
--- a/hw/dv/sv/jtag_agent/jtag_if.sv
+++ b/hw/dv/sv/jtag_agent/jtag_if.sv
@@ -11,7 +11,6 @@
   wire  tms;
   wire  tdi;
   wire  tdo;
-  wire  tdo_oe;
 
   // generate local tck
   bit   tck_en;
@@ -21,7 +20,6 @@
     output  tms;
     output  tdi;
     input   tdo;
-    input   tdo_oe;
   endclocking
   modport host_mp(clocking host_cb, output trst_n);
 
@@ -29,7 +27,6 @@
     input  tms;
     input  tdi;
     output tdo;
-    output tdo_oe;
   endclocking
   modport device_mp(clocking device_cb, input trst_n);
 
@@ -38,8 +35,7 @@
     input trst_n,
     input tms,
     input tdi,
-    input tdo,
-    input tdo_oe
+    input tdo
   );
 
   // debug signals
@@ -60,6 +56,7 @@
   // Generate the tck, with UartDefaultClkPeriodNs period as default
   initial begin
     tck = 1'b1;
+    do_trst_n($urandom_range(1, 10));
     forever begin
       if (tck_en) begin
         #(tck_period_ns / 2);
diff --git a/hw/ip/lc_ctrl/dv/env/lc_ctrl_env.core b/hw/ip/lc_ctrl/dv/env/lc_ctrl_env.core
index 9c5d18c..73ab837 100644
--- a/hw/ip/lc_ctrl/dv/env/lc_ctrl_env.core
+++ b/hw/ip/lc_ctrl/dv/env/lc_ctrl_env.core
@@ -9,6 +9,7 @@
     depend:
       - lowrisc:dv:ralgen
       - lowrisc:dv:cip_lib
+      - lowrisc:dv:jtag_agent
     files:
       - lc_ctrl_env_pkg.sv
       - lc_ctrl_if.sv
diff --git a/hw/ip/lc_ctrl/dv/env/lc_ctrl_env.sv b/hw/ip/lc_ctrl/dv/env/lc_ctrl_env.sv
index fae8152..424b170 100644
--- a/hw/ip/lc_ctrl/dv/env/lc_ctrl_env.sv
+++ b/hw/ip/lc_ctrl/dv/env/lc_ctrl_env.sv
@@ -15,6 +15,7 @@
   push_pull_agent#(.HostDataWidth(lc_ctrl_pkg::LcTokenWidth)) m_otp_token_pull_agent;
   alert_esc_agent m_esc_wipe_secrets_agent;
   alert_esc_agent m_esc_scrap_state_agent;
+  jtag_agent      m_jtag_agent;
 
   `uvm_component_new
 
@@ -36,6 +37,9 @@
     uvm_config_db#(alert_esc_agent_cfg)::set(this, "m_esc_scrap_state_agent", "cfg",
                                              cfg.m_esc_scrap_state_agent_cfg);
 
+    m_jtag_agent = jtag_agent::type_id::create("m_jtag_agent", this);
+    uvm_config_db#(jtag_agent_cfg)::set(this, "m_jtag_agent", "cfg", cfg.m_jtag_agent_cfg);
+
     m_otp_prog_pull_agent = push_pull_agent#(.HostDataWidth(OTP_PROG_HDATA_WIDTH),
         .DeviceDataWidth(OTP_PROG_DDATA_WIDTH))::type_id::create("m_otp_prog_pull_agent", this);
     uvm_config_db#(push_pull_agent_cfg#(.HostDataWidth(OTP_PROG_HDATA_WIDTH),
@@ -54,6 +58,7 @@
     virtual_sequencer.otp_token_pull_sequencer_h = m_otp_token_pull_agent.sequencer;
     virtual_sequencer.esc_wipe_secrets_sequencer_h = m_esc_wipe_secrets_agent.sequencer;
     virtual_sequencer.esc_scrap_state_sequencer_h = m_esc_scrap_state_agent.sequencer;
+    virtual_sequencer.jtag_sequencer_h = m_jtag_agent.sequencer;
     if (cfg.en_scb) begin
       m_otp_prog_pull_agent.monitor.analysis_port.connect(
           scoreboard.otp_prog_fifo.analysis_export);
diff --git a/hw/ip/lc_ctrl/dv/env/lc_ctrl_env_cfg.sv b/hw/ip/lc_ctrl/dv/env/lc_ctrl_env_cfg.sv
index 4494c2b..33c1474 100644
--- a/hw/ip/lc_ctrl/dv/env/lc_ctrl_env_cfg.sv
+++ b/hw/ip/lc_ctrl/dv/env/lc_ctrl_env_cfg.sv
@@ -10,6 +10,7 @@
   push_pull_agent_cfg#(.HostDataWidth(lc_ctrl_pkg::LcTokenWidth)) m_otp_token_pull_agent_cfg;
   alert_esc_agent_cfg m_esc_wipe_secrets_agent_cfg;
   alert_esc_agent_cfg m_esc_scrap_state_agent_cfg;
+  jtag_agent_cfg      m_jtag_agent_cfg;
 
   // ext interfaces
   pwr_lc_vif  pwr_lc_vif;
@@ -45,6 +46,9 @@
         "m_esc_scrap_state_agent_cfg");
     `DV_CHECK_RANDOMIZE_FATAL(m_esc_scrap_state_agent_cfg)
     m_esc_scrap_state_agent_cfg.is_alert = 0;
+
+    m_jtag_agent_cfg = jtag_agent_cfg::type_id::create("m_jtag_agent_cfg");
+    `DV_CHECK_RANDOMIZE_FATAL(m_jtag_agent_cfg)
   endfunction
 
 endclass
diff --git a/hw/ip/lc_ctrl/dv/env/lc_ctrl_env_pkg.sv b/hw/ip/lc_ctrl/dv/env/lc_ctrl_env_pkg.sv
index 9df716c..76f7e0a 100644
--- a/hw/ip/lc_ctrl/dv/env/lc_ctrl_env_pkg.sv
+++ b/hw/ip/lc_ctrl/dv/env/lc_ctrl_env_pkg.sv
@@ -16,6 +16,7 @@
   import otp_ctrl_pkg::*;
   import push_pull_agent_pkg::*;
   import alert_esc_agent_pkg::*;
+  import jtag_agent_pkg::*;
 
   // macro includes
   `include "uvm_macros.svh"
diff --git a/hw/ip/lc_ctrl/dv/env/lc_ctrl_if.sv b/hw/ip/lc_ctrl/dv/env/lc_ctrl_if.sv
index e728315..4586d3d 100644
--- a/hw/ip/lc_ctrl/dv/env/lc_ctrl_if.sv
+++ b/hw/ip/lc_ctrl/dv/env/lc_ctrl_if.sv
@@ -9,6 +9,7 @@
   import otp_ctrl_pkg::*;
   import otp_ctrl_part_pkg::*;
 
+  logic tdo_oe; // TODO: add assertions
   otp_ctrl_pkg::otp_lc_data_t     otp_i;
   otp_ctrl_part_pkg::otp_hw_cfg_t otp_hw_cfg_i;
 
diff --git a/hw/ip/lc_ctrl/dv/env/lc_ctrl_virtual_sequencer.sv b/hw/ip/lc_ctrl/dv/env/lc_ctrl_virtual_sequencer.sv
index 6aff2d3..9b9a4ff 100644
--- a/hw/ip/lc_ctrl/dv/env/lc_ctrl_virtual_sequencer.sv
+++ b/hw/ip/lc_ctrl/dv/env/lc_ctrl_virtual_sequencer.sv
@@ -15,6 +15,8 @@
   alert_esc_sequencer esc_wipe_secrets_sequencer_h;
   alert_esc_sequencer esc_scrap_state_sequencer_h;
 
+  jtag_sequencer jtag_sequencer_h;
+
   `uvm_component_new
 
 endclass
diff --git a/hw/ip/lc_ctrl/dv/tb.sv b/hw/ip/lc_ctrl/dv/tb.sv
index 305c300..1ac9db1 100644
--- a/hw/ip/lc_ctrl/dv/tb.sv
+++ b/hw/ip/lc_ctrl/dv/tb.sv
@@ -10,6 +10,7 @@
   import lc_ctrl_test_pkg::*;
   import lc_ctrl_pkg::*;
   import otp_ctrl_pkg::*;
+  import jtag_agent_pkg::*;
 
   // macro includes
   `include "uvm_macros.svh"
@@ -23,13 +24,14 @@
   wire otp_ctrl_pkg::lc_otp_token_rsp_t   otp_token_rsp;
 
   // interfaces
-  clk_rst_if clk_rst_if(.clk(clk), .rst_n(rst_n));
-  pins_if #(1) devmode_if(devmode);
-  pins_if #(LcPwrIfWidth) pwr_lc_if(pwr_lc);
-  tl_if tl_if(.clk(clk), .rst_n(rst_n));
-  lc_ctrl_if lc_ctrl_if(.clk(clk), .rst_n(rst_n));
+  clk_rst_if   clk_rst_if(.clk(clk), .rst_n(rst_n));
+  pins_if      #(1) devmode_if(devmode);
+  pins_if      #(LcPwrIfWidth) pwr_lc_if(pwr_lc);
+  tl_if        tl_if(.clk(clk), .rst_n(rst_n));
+  lc_ctrl_if   lc_ctrl_if(.clk(clk), .rst_n(rst_n));
   alert_esc_if esc_wipe_secrets_if(.clk(clk), .rst_n(rst_n));
   alert_esc_if esc_scrap_state_if(.clk(clk), .rst_n(rst_n));
+  jtag_if      jtag_if();
   push_pull_if #(.HostDataWidth(OTP_PROG_HDATA_WIDTH), .DeviceDataWidth(OTP_PROG_DDATA_WIDTH))
                otp_prog_if(.clk(clk), .rst_n(rst_n));
   push_pull_if #(.HostDataWidth(lc_ctrl_pkg::LcTokenWidth)) otp_token_if(.clk(clk), .rst_n(rst_n));
@@ -53,8 +55,8 @@
     .alert_rx_i                 (alert_rx ),
     .alert_tx_o                 (alert_tx ),
 
-    .jtag_i                     (4'b0),
-    .jtag_o                     (),
+    .jtag_i                     ({jtag_if.tck, jtag_if.tms, jtag_if.trst_n, jtag_if.tdi}),
+    .jtag_o                     ({jtag_if.tdo, lc_ctrl_if.tdo_oe}),
     .scanmode_i                 (1'b0     ),
 
     .esc_wipe_secrets_tx_i      (esc_wipe_secrets_if.esc_tx),
@@ -106,6 +108,7 @@
     uvm_config_db#(virtual tl_if)::set(null, "*.env.m_tl_agent*", "vif", tl_if);
     uvm_config_db#(pwr_lc_vif)::set(null, "*.env", "pwr_lc_vif", pwr_lc_if);
     uvm_config_db#(virtual lc_ctrl_if)::set(null, "*.env", "lc_ctrl_vif", lc_ctrl_if);
+    uvm_config_db#(virtual jtag_if)::set(null, "*env.m_jtag_agent*", "vif", jtag_if);
 
     uvm_config_db#(virtual alert_esc_if)::set(null, "*env.m_esc_wipe_secrets_agent*", "vif",
                                               esc_wipe_secrets_if);