[edn/dv] csrng_agent device mode, edn_smoke_test

Signed-off-by: Steve Nelson <steve.nelson@wdc.com>
diff --git a/hw/dv/sv/csrng_agent/csrng_agent.core b/hw/dv/sv/csrng_agent/csrng_agent.core
index 455fec7..010ad78 100644
--- a/hw/dv/sv/csrng_agent/csrng_agent.core
+++ b/hw/dv/sv/csrng_agent/csrng_agent.core
@@ -22,6 +22,10 @@
       - csrng_device_driver.sv: {is_include_file: true}
       - csrng_monitor.sv: {is_include_file: true}
       - csrng_agent.sv: {is_include_file: true}
+      - seq_lib/csrng_seq_list.sv: {is_include_file: true}
+      - seq_lib/csrng_base_seq.sv: {is_include_file: true}
+      - seq_lib/csrng_device_seq.sv: {is_include_file: true}
+      - seq_lib/csrng_host_seq.sv: {is_include_file: true}
     file_type: systemVerilogSource
 
 targets:
diff --git a/hw/dv/sv/csrng_agent/csrng_agent.sv b/hw/dv/sv/csrng_agent/csrng_agent.sv
index 9b58da7..67f0729 100644
--- a/hw/dv/sv/csrng_agent/csrng_agent.sv
+++ b/hw/dv/sv/csrng_agent/csrng_agent.sv
@@ -61,10 +61,13 @@
 
   function void connect_phase(uvm_phase phase);
     super.connect_phase(phase);
-    // TODO
+
+    if (cfg.is_active) begin
+      if (cfg.if_mode == dv_utils_pkg::Device) begin
+        monitor.req_port.connect(sequencer.cmd_req_fifo.analysis_export);
+        sequencer.m_genbits_push_sequencer = m_genbits_push_agent.sequencer;
+      end
+    end
   endfunction
 
-  virtual task run_phase(uvm_phase phase);
-    // TODO
-  endtask
 endclass
diff --git a/hw/dv/sv/csrng_agent/csrng_agent_cfg.sv b/hw/dv/sv/csrng_agent/csrng_agent_cfg.sv
index 1f5c189..4fc6801 100644
--- a/hw/dv/sv/csrng_agent/csrng_agent_cfg.sv
+++ b/hw/dv/sv/csrng_agent/csrng_agent_cfg.sv
@@ -15,4 +15,8 @@
 
   `uvm_object_new
 
+  // TODO: set in testcase
+  uint   min_cmd_ack_dly=2, max_cmd_ack_dly=2;
+  uint   min_genbits_dly=10, max_genbits_dly=10;
+
 endclass
diff --git a/hw/dv/sv/csrng_agent/csrng_agent_pkg.sv b/hw/dv/sv/csrng_agent/csrng_agent_pkg.sv
index b6ca722..3226ccb 100644
--- a/hw/dv/sv/csrng_agent/csrng_agent_pkg.sv
+++ b/hw/dv/sv/csrng_agent/csrng_agent_pkg.sv
@@ -8,13 +8,12 @@
   import dv_utils_pkg::*;
   import dv_lib_pkg::*;
   import push_pull_agent_pkg::*;
+  import csrng_pkg::*;
 
   // macro includes
   `include "uvm_macros.svh"
   `include "dv_macros.svh"
 
-  // parameters
-
   // package sources
   `include "csrng_item.sv"
   `include "csrng_agent_cfg.sv"
@@ -24,6 +23,7 @@
   `include "csrng_host_driver.sv"
   `include "csrng_device_driver.sv"
   `include "csrng_monitor.sv"
+  `include "csrng_seq_list.sv"
   `include "csrng_agent.sv"
 
 endpackage
diff --git a/hw/dv/sv/csrng_agent/csrng_device_driver.sv b/hw/dv/sv/csrng_agent/csrng_device_driver.sv
index 6b8c5d8..5cb8627 100644
--- a/hw/dv/sv/csrng_agent/csrng_device_driver.sv
+++ b/hw/dv/sv/csrng_agent/csrng_device_driver.sv
@@ -6,22 +6,17 @@
   `uvm_component_utils(csrng_device_driver)
   `uvm_component_new
 
+  rand uint   cmd_ack_dly;
+
   virtual task run_phase(uvm_phase phase);
     // base class forks off reset_signals() and get_and_drive() tasks
     super.run_phase(phase);
   endtask
 
   // TODO: drive_trans
-  // reset signals
   virtual task reset_signals();
-    if (cfg.if_mode == Device) begin
-      cfg.vif.req_push_if.ready_int <= '0;
-      cfg.vif.genbits_push_if.valid_int <= '0;
-    end
-//    end else begin
-//      cfg.vif.ack_int   <= '0;
-//    end
-//    cfg.vif.d_data_int <= 'x;
+      cfg.vif.cmd_rsp_int.csrng_rsp_ack <= 1'b0;
+      cfg.vif.cmd_rsp_int.csrng_rsp_sts <= 1'b0;
   endtask
 
   // drive trans received from sequencer
@@ -30,10 +25,15 @@
       seq_item_port.get_next_item(req);
       $cast(rsp, req.clone());
       rsp.set_id_info(req);
-      `uvm_info(`gfn, $sformatf("rcvd item:\n%0s", req.sprint()), UVM_HIGH)
-      // TODO: do the driving part
-      //
-      // send rsp back to seq
+      `uvm_info(`gfn, $sformatf("rcvd item: %s", req.convert2string()), UVM_HIGH)
+      `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(
+          cmd_ack_dly, cmd_ack_dly inside {cfg.min_cmd_ack_dly, cfg.max_cmd_ack_dly};)
+      repeat(cmd_ack_dly) @(cfg.vif.device_cb);
+      cfg.vif.device_cb.cmd_rsp_int.csrng_rsp_ack <= 1'b1;
+      cfg.vif.device_cb.cmd_rsp_int.csrng_rsp_sts <= 1'b0;
+      @(cfg.vif.device_cb);
+      cfg.vif.device_cb.cmd_rsp_int.csrng_rsp_ack <= 1'b0;
+      cfg.vif.device_cb.cmd_rsp_int.csrng_rsp_sts <= 1'b0;
       `uvm_info(`gfn, "item sent", UVM_HIGH)
       seq_item_port.item_done(rsp);
     end
diff --git a/hw/dv/sv/csrng_agent/csrng_if.sv b/hw/dv/sv/csrng_agent/csrng_if.sv
index b5af1b4..6be80bb 100644
--- a/hw/dv/sv/csrng_agent/csrng_if.sv
+++ b/hw/dv/sv/csrng_agent/csrng_if.sv
@@ -6,11 +6,15 @@
 
   import csrng_pkg::*;
 
-  dv_utils_pkg::if_mode_e if_mode; // interface mode - Host or Device
+  dv_utils_pkg::if_mode_e   if_mode; // Host or Device
 
   // interface pins used to connect with DUT
-  wire csrng_req_t cmd_req;
-  wire csrng_rsp_t cmd_rsp;
+  wire csrng_req_t   cmd_req;
+  wire csrng_rsp_t   cmd_rsp;
+
+  // Internal versions for driving
+  csrng_req_t   cmd_req_int;
+  csrng_rsp_t   cmd_rsp_int;
 
   // interface pins used in driver/monitor
   push_pull_if #(.HostDataWidth(csrng_pkg::CSRNG_CMD_WIDTH))
@@ -18,18 +22,20 @@
   push_pull_if #(.HostDataWidth(csrng_pkg::FIPS_GENBITS_BUS_WIDTH))
        genbits_push_if(.clk(clk), .rst_n(rst_n));
 
+  // TODO: assigns, clocking blocks, ASSERTs
   // Device assigns
   assign cmd_rsp.csrng_req_ready = (if_mode == dv_utils_pkg::Device) ? req_push_if.ready : 'z;
   assign req_push_if.valid       = (if_mode == dv_utils_pkg::Device) ? cmd_req.csrng_req_valid : 'z;
   assign req_push_if.h_data      = (if_mode == dv_utils_pkg::Device) ? cmd_req.csrng_req_bus : 'z;
+  assign cmd_rsp.csrng_rsp_ack   = (if_mode == dv_utils_pkg::Device) ? cmd_rsp_int.csrng_rsp_ack : 'z;
+  assign cmd_rsp.csrng_rsp_sts   = (if_mode == dv_utils_pkg::Device) ? cmd_rsp_int.csrng_rsp_sts : 'z;
 
   assign genbits_push_if.ready   = (if_mode == dv_utils_pkg::Device) ? cmd_req.genbits_ready : 'z;
   assign cmd_rsp.genbits_valid   = (if_mode == dv_utils_pkg::Device) ? genbits_push_if.valid : 'z;
   assign cmd_rsp.genbits_bus     = (if_mode == dv_utils_pkg::Device) ?
-                                   genbits_push_if.h_data[csrng_pkg::FIPS_GENBITS_BUS_WIDTH-1:0] :
-                                   'z;
+                                   genbits_push_if.h_data[csrng_pkg::FIPS_GENBITS_BUS_WIDTH-2:0] : 'z;
   assign cmd_rsp.genbits_fips    = (if_mode == dv_utils_pkg::Device) ?
-                                   genbits_push_if.h_data[csrng_pkg::FIPS_GENBITS_BUS_WIDTH] : 'z;
+                                   genbits_push_if.h_data[csrng_pkg::FIPS_GENBITS_BUS_WIDTH-1] : 'z;
 
   // Host assigns
   assign req_push_if.ready       = (if_mode == dv_utils_pkg::Host) ? cmd_rsp.csrng_req_ready : 'z;
@@ -37,10 +43,19 @@
 
   assign genbits_push_if.valid   = (if_mode == dv_utils_pkg::Host) ? cmd_rsp.genbits_valid : 'z;
 
-  //TODO Temporary, put in driver
-  assign cmd_rsp.csrng_rsp_ack = 1'b0;
-  assign cmd_rsp.csrng_rsp_sts = 1'b0;
+  clocking mon_cb @(posedge clk);
+    input cmd_req;
+    input cmd_rsp;
+  endclocking
 
-  // TODO assigns, clocking blocks, ASSERTs
+  clocking device_cb @(posedge clk);
+    input  cmd_req;
+    output cmd_rsp_int;
+  endclocking
+
+  clocking host_cb @(posedge clk);
+    output cmd_req_int;
+    input  cmd_rsp;
+  endclocking
 
 endinterface
diff --git a/hw/dv/sv/csrng_agent/csrng_item.sv b/hw/dv/sv/csrng_agent/csrng_item.sv
index 6bc9456..d64f892 100644
--- a/hw/dv/sv/csrng_agent/csrng_item.sv
+++ b/hw/dv/sv/csrng_agent/csrng_item.sv
@@ -10,4 +10,18 @@
 
   `uvm_object_new
 
+  acmd_e       acmd;
+  bit [3:0]    clen, flags;
+  bit [18:0]   glen;
+
+  virtual function string convert2string();
+    string str = "";
+    str = {str, "\n"};
+    str = {str,  $sformatf("\n\t |********** csrng_item **********| \t")             };
+    str = {str,  $sformatf("\n\t |* acmd   :   %4s              *| \t", acmd.name()) };
+    str = {str,  $sformatf("\n\t |********************************| \t")             };
+    str = {str, "\n"};
+    return str;
+  endfunction
+
 endclass
diff --git a/hw/dv/sv/csrng_agent/csrng_monitor.sv b/hw/dv/sv/csrng_agent/csrng_monitor.sv
index 3c55c53..f9dd17b 100644
--- a/hw/dv/sv/csrng_agent/csrng_monitor.sv
+++ b/hw/dv/sv/csrng_agent/csrng_monitor.sv
@@ -20,6 +20,7 @@
   uvm_analysis_port#(csrng_item) rsp_port;
 
   `uvm_component_new
+  bit in_reset;
 
   function void build_phase(uvm_phase phase);
     super.build_phase(phase);
@@ -29,7 +30,53 @@
   endfunction
 
   task run_phase(uvm_phase phase);
-//    super.run_phase(phase);
+    @(posedge cfg.vif.rst_n);
+    fork
+      handle_reset();
+      // TODO: implement function
+      // collect_valid_trans();
+      // We only need to monitor incoming requests if the agent is configured
+      // in device mode.
+      if (cfg.if_mode == dv_utils_pkg::Device) begin
+        collect_request();
+      end
+    join_none
+  endtask
+
+  virtual protected task handle_reset();
+    forever begin
+      @(negedge cfg.vif.rst_n);
+      in_reset = 1;
+      // TODO: sample any reset-related covergroups
+      @(posedge cfg.vif.rst_n);
+      in_reset = 0;
+    end
+  endtask
+
+  // This task is only used for device agents responding
+  // It will pick up any incoming requests from the DUT and send a signal to the
+  // sequencer (in the form of a sequence item), which will then be forwarded to
+  // the sequence, which then generates the appropriate response item.
+  //
+  // TODO: This assumes no requests can be dropped, and might need to be fixed
+  //       if this is not allowed.
+  virtual protected task collect_request();
+    csrng_item   item;
+    forever begin
+      @(cfg.vif.req_push_if.mon_cb);
+      if (cfg.vif.req_push_if.mon_cb.valid) begin
+        // TODO: sample any covergroups
+	// TODO: Implement suggestion in PR #5456
+        item = csrng_item::type_id::create("item");
+        item.acmd = cfg.vif.mon_cb.cmd_req.csrng_req_bus[3:0];
+        `uvm_info(`gfn, $sformatf("Captured item: %s", item.convert2string()), UVM_HIGH)
+        req_port.write(item);
+        // After picking up a request, wait until a response is sent before
+        // detecting another request, as this is not a pipelined protocol.
+        `DV_SPINWAIT_EXIT(while (!cfg.vif.mon_cb.cmd_rsp.csrng_rsp_ack) @(cfg.vif.mon_cb);,
+                          wait(in_reset))
+       end
+    end
   endtask
 
   // TODO: collect_trans
diff --git a/hw/dv/sv/csrng_agent/csrng_sequencer.sv b/hw/dv/sv/csrng_agent/csrng_sequencer.sv
index eb83ee7..602d691 100644
--- a/hw/dv/sv/csrng_agent/csrng_sequencer.sv
+++ b/hw/dv/sv/csrng_agent/csrng_sequencer.sv
@@ -8,16 +8,19 @@
 );
   `uvm_component_param_utils(csrng_sequencer)
 
+  push_pull_sequencer#(.HostDataWidth(csrng_pkg::CSRNG_CMD_WIDTH))          m_req_push_sequencer;
+  push_pull_sequencer#(.HostDataWidth(csrng_pkg::FIPS_GENBITS_BUS_WIDTH))   m_genbits_push_sequencer;
+
   // Analysis port through which device monitors can send transactions
   // to the sequencer.
-  uvm_tlm_analysis_fifo#(csrng_item) csrng_req_fifo;
+  uvm_tlm_analysis_fifo#(csrng_item)   cmd_req_fifo;
 
   `uvm_component_new
 
   function void build_phase(uvm_phase phase);
     super.build_phase(phase);
     if (cfg.if_mode == dv_utils_pkg::Device) begin
-      csrng_req_fifo = new("csrng_req_fifo", this);
+      cmd_req_fifo = new("cmd_req_fifo", this);
     end
   endfunction
 
diff --git a/hw/dv/sv/csrng_agent/seq_lib/csrng_base_seq.sv b/hw/dv/sv/csrng_agent/seq_lib/csrng_base_seq.sv
new file mode 100644
index 0000000..ef4347c
--- /dev/null
+++ b/hw/dv/sv/csrng_agent/seq_lib/csrng_base_seq.sv
@@ -0,0 +1,18 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class csrng_base_seq extends dv_base_seq #(
+    .REQ         (csrng_item),
+    .CFG_T       (csrng_agent_cfg),
+    .SEQUENCER_T (csrng_sequencer)
+  );
+  `uvm_object_utils(csrng_base_seq)
+
+  `uvm_object_new
+
+  virtual task body();
+    `uvm_fatal(`gtn, "Need to override this when you extend from this class!")
+  endtask
+
+endclass
diff --git a/hw/dv/sv/csrng_agent/seq_lib/csrng_device_seq.sv b/hw/dv/sv/csrng_agent/seq_lib/csrng_device_seq.sv
new file mode 100644
index 0000000..4f0e0a4
--- /dev/null
+++ b/hw/dv/sv/csrng_agent/seq_lib/csrng_device_seq.sv
@@ -0,0 +1,46 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// Response sequence for csrng protocols.
+// This sequence will infinitely pol for any DUT requests detected by
+// the monitor, and trigger the response driver anytime a request is detected.
+
+class csrng_device_seq extends csrng_base_seq;
+
+  `uvm_object_utils(csrng_device_seq)
+  `uvm_object_new
+
+  csrng_item   req_q[$];
+  push_pull_host_seq#(csrng_pkg::FIPS_GENBITS_BUS_WIDTH)   m_genbits_seq;
+
+  virtual task body();
+    fork
+      forever begin
+        csrng_item   req;
+        p_sequencer.cmd_req_fifo.get(req);
+        req_q.push_back(req);
+      end
+
+      forever begin
+        csrng_item   rsp;
+        wait(req_q.size);
+        rsp = req_q.pop_front();
+        case (rsp.acmd)
+          GEN: begin
+            m_genbits_seq = push_pull_host_seq#(csrng_pkg::FIPS_GENBITS_BUS_WIDTH)::type_id::
+                create("m_genbits_seq");
+            cfg.m_genbits_push_agent_cfg.host_delay_min = cfg.min_genbits_dly;
+            cfg.m_genbits_push_agent_cfg.host_delay_max = cfg.max_genbits_dly;
+            // TODO: randomize genbits
+            cfg.m_genbits_push_agent_cfg.add_h_user_data(32'hdeadbeef);
+            m_genbits_seq.start(p_sequencer.m_genbits_push_sequencer);
+          end
+        endcase
+        start_item(rsp);
+        finish_item(rsp);
+      end
+    join
+  endtask
+
+endclass
diff --git a/hw/dv/sv/csrng_agent/seq_lib/csrng_host_seq.sv b/hw/dv/sv/csrng_agent/seq_lib/csrng_host_seq.sv
new file mode 100644
index 0000000..c5795d8
--- /dev/null
+++ b/hw/dv/sv/csrng_agent/seq_lib/csrng_host_seq.sv
@@ -0,0 +1,17 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class csrng_host_seq extends csrng_base_seq;
+  `uvm_object_utils(csrng_host_seq)
+
+  `uvm_object_new
+
+  task body();
+    req = csrng_item::type_id::create("req");
+    start_item(req);
+    finish_item(req);
+    get_response(rsp);
+  endtask
+
+endclass
diff --git a/hw/dv/sv/csrng_agent/seq_lib/csrng_seq_list.sv b/hw/dv/sv/csrng_agent/seq_lib/csrng_seq_list.sv
new file mode 100644
index 0000000..b71c06c
--- /dev/null
+++ b/hw/dv/sv/csrng_agent/seq_lib/csrng_seq_list.sv
@@ -0,0 +1,7 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+`include "csrng_base_seq.sv"
+`include "csrng_host_seq.sv"
+`include "csrng_device_seq.sv"
diff --git a/hw/ip/edn/dv/env/edn_env.sv b/hw/ip/edn/dv/env/edn_env.sv
index 83148ab..627af5d 100644
--- a/hw/ip/edn/dv/env/edn_env.sv
+++ b/hw/ip/edn/dv/env/edn_env.sv
@@ -32,17 +32,23 @@
                     "cfg", cfg.m_endpoint_agent_cfg[i]);
       cfg.m_endpoint_agent_cfg[i].agent_type = push_pull_agent_pkg::PullAgent;
       cfg.m_endpoint_agent_cfg[i].if_mode    = dv_utils_pkg::Host;
+      // TODO: Move these
+      cfg.m_endpoint_agent_cfg[i].zero_delays = 1'b1;
     end
   endfunction
 
   function void connect_phase(uvm_phase phase);
     super.connect_phase(phase);
+
+    virtual_sequencer.csrng_sequencer_h = m_csrng_agent.sequencer;
+
     if (cfg.en_scb) begin
       for (int i = 0; i < NUM_ENDPOINTS; i++) begin
         m_endpoint_agent[i].monitor.analysis_port.connect
         (scoreboard.endpoint_fifo[i].analysis_export);
       end
     end
+
     for (int i = 0; i < NUM_ENDPOINTS; i++) begin
       if (cfg.m_endpoint_agent_cfg[i].is_active) begin
         virtual_sequencer.endpoint_sequencer_h[i] = m_endpoint_agent[i].sequencer;
diff --git a/hw/ip/edn/dv/env/edn_env_cfg.sv b/hw/ip/edn/dv/env/edn_env_cfg.sv
index 2d566ec..ae470bb 100644
--- a/hw/ip/edn/dv/env/edn_env_cfg.sv
+++ b/hw/ip/edn/dv/env/edn_env_cfg.sv
@@ -26,7 +26,7 @@
     for (int i = 0; i < NUM_ENDPOINTS; i++) begin
       m_endpoint_agent_cfg[i] = push_pull_agent_cfg#(.HostDataWidth(edn_pkg::
                                 FIPS_ENDPOINT_BUS_WIDTH))::type_id::create
-                                ($sformatf("m_endpoint_agent_cfg[$0d]", i));
+                                ($sformatf("m_endpoint_agent_cfg[%0d]", i));
     end
 
     // set num_interrupts & num_alerts
diff --git a/hw/ip/edn/dv/env/edn_virtual_sequencer.sv b/hw/ip/edn/dv/env/edn_virtual_sequencer.sv
index 99f9ce5..835ab21 100644
--- a/hw/ip/edn/dv/env/edn_virtual_sequencer.sv
+++ b/hw/ip/edn/dv/env/edn_virtual_sequencer.sv
@@ -11,6 +11,8 @@
   push_pull_sequencer#(.HostDataWidth(edn_pkg::FIPS_ENDPOINT_BUS_WIDTH))
        endpoint_sequencer_h[NUM_ENDPOINTS-1:0];
 
+  csrng_sequencer   csrng_sequencer_h;
+
   `uvm_component_new
 
 endclass
diff --git a/hw/ip/edn/dv/env/seq_lib/edn_base_vseq.sv b/hw/ip/edn/dv/env/seq_lib/edn_base_vseq.sv
index 6e38ab4..9da34a1 100644
--- a/hw/ip/edn/dv/env/seq_lib/edn_base_vseq.sv
+++ b/hw/ip/edn/dv/env/seq_lib/edn_base_vseq.sv
@@ -10,14 +10,28 @@
   );
   `uvm_object_utils(edn_base_vseq)
 
-  // various knobs to enable certain routines
-  bit do_edn_init = 1'b1;
-
   `uvm_object_new
 
+  task body();
+    // Start csrng_device_seq
+    device_init();
+    // Initialize DUT
+    dut_init();
+  endtask
+
+  virtual task device_init();
+    csrng_device_seq   m_dev_seq;
+
+    m_dev_seq = csrng_device_seq::type_id::create("m_dev_seq");
+    `uvm_info(`gfn, "Start csrng_device sequence", UVM_DEBUG)
+
+    fork
+      m_dev_seq.start(p_sequencer.csrng_sequencer_h);
+    join_none
+  endtask
+
   virtual task dut_init(string reset_kind = "HARD");
     super.dut_init();
-    if (do_edn_init) edn_init();
   endtask
 
   virtual task dut_shutdown();
@@ -25,8 +39,4 @@
     // TODO
   endtask
 
-  // setup basic edn features
-  virtual task edn_init();
-  endtask
-
 endclass : edn_base_vseq
diff --git a/hw/ip/edn/dv/env/seq_lib/edn_smoke_vseq.sv b/hw/ip/edn/dv/env/seq_lib/edn_smoke_vseq.sv
index 091d08f..9a93de4 100644
--- a/hw/ip/edn/dv/env/seq_lib/edn_smoke_vseq.sv
+++ b/hw/ip/edn/dv/env/seq_lib/edn_smoke_vseq.sv
@@ -2,16 +2,26 @@
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
 
-// smoke test vseq
 class edn_smoke_vseq extends edn_base_vseq;
   `uvm_object_utils(edn_smoke_vseq)
 
   `uvm_object_new
 
+  push_pull_host_seq#(edn_pkg::FIPS_ENDPOINT_BUS_WIDTH)   m_endpoint_pull_seq;
+
   task body();
-    // TODO: Temporary for creating edn environnment
+    super.body();
+
     // Enable edn
     csr_wr(.csr(ral.ctrl), .value(1'b1));
-  endtask : body
 
-endclass : edn_smoke_vseq
+    m_endpoint_pull_seq = push_pull_host_seq#(edn_pkg::FIPS_ENDPOINT_BUS_WIDTH)::type_id::
+        create("m_endpoint_pull_seq");
+    m_endpoint_pull_seq.start(p_sequencer.endpoint_sequencer_h[edn_env_pkg::NUM_ENDPOINTS-1]);
+
+    // TODO: Compare to genbits from csrng_device_seq
+    assert (cfg.m_endpoint_agent_cfg[edn_env_pkg::NUM_ENDPOINTS-1].vif.d_data == {1'b0, 32'hdeadbeef}) else
+      `uvm_error(`gfn, $sformatf("endpoint_data (%0h) != fips_genbits_data (0x0_deadbeef)", cfg.m_endpoint_agent_cfg[edn_env_pkg::NUM_ENDPOINTS-1].vif.d_data))
+  endtask
+
+endclass
diff --git a/hw/ip/edn/dv/tb.sv b/hw/ip/edn/dv/tb.sv
index e0847a9..6e3fe7a 100755
--- a/hw/ip/edn/dv/tb.sv
+++ b/hw/ip/edn/dv/tb.sv
@@ -27,7 +27,7 @@
   tl_if tl_if(.clk(clk), .rst_n(rst_n));
   csrng_if csrng_if(.clk(clk), .rst_n(rst_n));
   push_pull_if#(.HostDataWidth(edn_pkg::FIPS_ENDPOINT_BUS_WIDTH))
-       endpoint_if[NUM_ENDPOINTS-1:0]();
+       endpoint_if[NUM_ENDPOINTS-1:0](.clk(clk), .rst_n(rst_n));
 
   // dut
   edn#(.NumEndPoints(NUM_ENDPOINTS)) dut (
@@ -52,6 +52,8 @@
 
   for (genvar i = 0; i < NUM_ENDPOINTS; i++) begin : gen_endpoint_if
     assign endpoint_req[i].edn_req = endpoint_if[i].req;
+    assign endpoint_if[i].ack = endpoint_rsp[i].edn_ack;
+    assign endpoint_if[i].d_data = {endpoint_rsp[i].edn_fips, endpoint_rsp[i].edn_bus};
     initial begin
       uvm_config_db#(virtual push_pull_if#(.HostDataWidth(edn_pkg::FIPS_ENDPOINT_BUS_WIDTH)))::
           set(null, $sformatf("*.env.m_endpoint_agent[%0d]*", i),