Rupert Swarbrick | d8bfaf1 | 2020-09-21 12:53:35 +0100 | [diff] [blame] | 1 | // Copyright lowRISC contributors. |
| 2 | // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| 3 | // SPDX-License-Identifier: Apache-2.0 |
| 4 | // |
| 5 | module tb; |
Rupert Swarbrick | 3548b1e | 2020-10-08 16:55:44 +0100 | [diff] [blame] | 6 | // dep packages (test) |
Rupert Swarbrick | d8bfaf1 | 2020-09-21 12:53:35 +0100 | [diff] [blame] | 7 | import uvm_pkg::*; |
| 8 | import dv_utils_pkg::*; |
| 9 | import otbn_env_pkg::*; |
| 10 | import otbn_test_pkg::*; |
| 11 | |
Rupert Swarbrick | 3548b1e | 2020-10-08 16:55:44 +0100 | [diff] [blame] | 12 | // dep packages (rtl) |
| 13 | import otbn_reg_pkg::*; |
Greg Chadwick | b168ae9 | 2021-04-14 16:04:03 +0100 | [diff] [blame] | 14 | import edn_pkg::*; |
Rupert Swarbrick | 3548b1e | 2020-10-08 16:55:44 +0100 | [diff] [blame] | 15 | |
Rupert Swarbrick | d8bfaf1 | 2020-09-21 12:53:35 +0100 | [diff] [blame] | 16 | // macro includes |
| 17 | `include "uvm_macros.svh" |
| 18 | `include "dv_macros.svh" |
| 19 | |
| 20 | wire clk, rst_n; |
Rupert Swarbrick | 41fd2b0 | 2020-12-03 12:16:39 +0000 | [diff] [blame] | 21 | wire idle, intr_done; |
Rupert Swarbrick | 3548b1e | 2020-10-08 16:55:44 +0100 | [diff] [blame] | 22 | wire [NUM_MAX_INTERRUPTS-1:0] interrupts; |
Rupert Swarbrick | d8bfaf1 | 2020-09-21 12:53:35 +0100 | [diff] [blame] | 23 | |
| 24 | // interfaces |
Rupert Swarbrick | 3548b1e | 2020-10-08 16:55:44 +0100 | [diff] [blame] | 25 | clk_rst_if clk_rst_if (.clk(clk), .rst_n(rst_n)); |
| 26 | tl_if tl_if (.clk(clk), .rst_n(rst_n)); |
| 27 | pins_if #(1) idle_if (idle); |
| 28 | pins_if #(NUM_MAX_INTERRUPTS) intr_if (interrupts); |
Rupert Swarbrick | 41fd2b0 | 2020-12-03 12:16:39 +0000 | [diff] [blame] | 29 | assign interrupts[0] = {intr_done}; |
Rupert Swarbrick | 3548b1e | 2020-10-08 16:55:44 +0100 | [diff] [blame] | 30 | |
Rupert Swarbrick | b0d28af | 2020-10-29 17:10:02 +0000 | [diff] [blame] | 31 | otbn_model_if #( |
| 32 | .ImemSizeByte (otbn_reg_pkg::OTBN_IMEM_SIZE) |
| 33 | ) model_if ( |
| 34 | .clk_i (clk), |
| 35 | .rst_ni (rst_n) |
| 36 | ); |
| 37 | |
Weicai Yang | 0ae8ef5 | 2020-11-17 20:53:29 -0800 | [diff] [blame] | 38 | `DV_ALERT_IF_CONNECT |
Rupert Swarbrick | d8bfaf1 | 2020-09-21 12:53:35 +0100 | [diff] [blame] | 39 | |
Greg Chadwick | b168ae9 | 2021-04-14 16:04:03 +0100 | [diff] [blame] | 40 | // Mock up EDN that just instantly returns fixed data when requested |
| 41 | // TODO: Provide a proper EDN agent |
| 42 | edn_req_t edn_rnd_req; |
| 43 | edn_rsp_t edn_rnd_rsp; |
| 44 | |
| 45 | edn_req_t edn_urnd_req; |
| 46 | edn_rsp_t edn_urnd_rsp; |
| 47 | |
| 48 | assign edn_rnd_rsp.edn_ack = edn_rnd_req.edn_req; |
| 49 | assign edn_rnd_rsp.edn_fips = 1'b0; |
| 50 | assign edn_rnd_rsp.edn_bus = 32'h99999999; |
| 51 | |
| 52 | assign edn_urnd_rsp.edn_ack = edn_urnd_req.edn_req; |
| 53 | assign edn_urnd_rsp.edn_fips = 1'b0; |
| 54 | assign edn_urnd_rsp.edn_bus = 32'h99999999; |
| 55 | |
Rupert Swarbrick | d8bfaf1 | 2020-09-21 12:53:35 +0100 | [diff] [blame] | 56 | // dut |
| 57 | otbn dut ( |
Rupert Swarbrick | 3548b1e | 2020-10-08 16:55:44 +0100 | [diff] [blame] | 58 | .clk_i (clk), |
| 59 | .rst_ni (rst_n), |
Rupert Swarbrick | d8bfaf1 | 2020-09-21 12:53:35 +0100 | [diff] [blame] | 60 | |
Rupert Swarbrick | 3548b1e | 2020-10-08 16:55:44 +0100 | [diff] [blame] | 61 | .tl_i (tl_if.h2d), |
| 62 | .tl_o (tl_if.d2h), |
| 63 | |
| 64 | .idle_o (idle), |
| 65 | |
| 66 | .intr_done_o (intr_done), |
Rupert Swarbrick | 3548b1e | 2020-10-08 16:55:44 +0100 | [diff] [blame] | 67 | |
| 68 | .alert_rx_i (alert_rx), |
Greg Chadwick | b168ae9 | 2021-04-14 16:04:03 +0100 | [diff] [blame] | 69 | .alert_tx_o (alert_tx), |
Rupert Swarbrick | 3548b1e | 2020-10-08 16:55:44 +0100 | [diff] [blame] | 70 | |
Greg Chadwick | b168ae9 | 2021-04-14 16:04:03 +0100 | [diff] [blame] | 71 | .clk_edn_i (clk), |
| 72 | .rst_edn_ni (rst_n), |
| 73 | .edn_rnd_o ( edn_rnd_req ), |
| 74 | .edn_rnd_i ( edn_rnd_rsp ), |
| 75 | |
| 76 | .edn_urnd_o ( edn_urnd_req ), |
| 77 | .edn_urnd_i ( edn_urnd_rsp ) |
Rupert Swarbrick | d8bfaf1 | 2020-09-21 12:53:35 +0100 | [diff] [blame] | 78 | ); |
| 79 | |
Rupert Swarbrick | 5c9aa75 | 2021-06-03 12:03:59 +0100 | [diff] [blame] | 80 | bind dut.u_otbn_core otbn_trace_if #( |
Rupert Swarbrick | 660baa9 | 2020-12-15 17:00:55 +0000 | [diff] [blame] | 81 | .ImemAddrWidth (ImemAddrWidth), |
| 82 | .DmemAddrWidth (DmemAddrWidth) |
| 83 | ) i_otbn_trace_if (.*); |
| 84 | |
Rupert Swarbrick | 5c9aa75 | 2021-06-03 12:03:59 +0100 | [diff] [blame] | 85 | bind dut.u_otbn_core otbn_tracer u_otbn_tracer(.*, .otbn_trace(i_otbn_trace_if)); |
Greg Chadwick | b168ae9 | 2021-04-14 16:04:03 +0100 | [diff] [blame] | 86 | |
Rupert Swarbrick | e97c4f5 | 2021-06-03 12:30:54 +0100 | [diff] [blame^] | 87 | bind dut.u_otbn_core.u_otbn_controller.u_otbn_loop_controller |
| 88 | otbn_loop_if i_otbn_loop_if ( |
| 89 | .clk_i (clk_i), |
| 90 | .rst_ni (rst_ni), |
| 91 | // The insn_addr_i signal in the loop controller is of width ImemAddrWidth. We expand it to a |
| 92 | // 32-bit address here to avoid having to parameterise the type of the interface. |
| 93 | .insn_addr (32'(insn_addr_i)), |
| 94 | .at_current_loop_end_insn (at_current_loop_end_insn) |
| 95 | ); |
| 96 | |
Rupert Swarbrick | b0d28af | 2020-10-29 17:10:02 +0000 | [diff] [blame] | 97 | // OTBN model, wrapping an ISS. |
| 98 | // |
| 99 | // Note that we pull the "start" signal out of the DUT. This is because it's much more difficult |
| 100 | // to grab the decoded signal from TL transactions on the cycle it happens. We have an explicit |
| 101 | // check in the scoreboard to ensure that this gets asserted at the time we expect (to spot any |
| 102 | // decoding errors). |
Greg Chadwick | 3b58f20 | 2021-04-30 12:14:21 +0100 | [diff] [blame] | 103 | assign model_if.start = dut.start_q; |
Rupert Swarbrick | b0d28af | 2020-10-29 17:10:02 +0000 | [diff] [blame] | 104 | |
Greg Chadwick | b168ae9 | 2021-04-14 16:04:03 +0100 | [diff] [blame] | 105 | // Internally otbn_core uses a 256-bit width interface for EDN data. This maps to muliple EDN |
| 106 | // requests at this level (via a packing FIFO internal to otbn). The model works with the internal |
| 107 | // otbn_core interface so probe into it here to provide the relevant signals to the model. |
| 108 | logic edn_rnd_data_valid; |
| 109 | logic edn_urnd_data_valid; |
| 110 | |
| 111 | assign edn_rnd_data_valid = dut.edn_rnd_req & dut.edn_rnd_ack; |
| 112 | assign edn_urnd_data_valid = dut.edn_urnd_req & dut.edn_urnd_ack; |
| 113 | |
Rupert Swarbrick | b0d28af | 2020-10-29 17:10:02 +0000 | [diff] [blame] | 114 | otbn_core_model #( |
| 115 | .DmemSizeByte (otbn_reg_pkg::OTBN_DMEM_SIZE), |
| 116 | .ImemSizeByte (otbn_reg_pkg::OTBN_IMEM_SIZE), |
Rupert Swarbrick | 04b1c25 | 2021-03-18 12:22:34 +0000 | [diff] [blame] | 117 | .MemScope ("..dut"), |
| 118 | .DesignScope ("..dut.u_otbn_core") |
Rupert Swarbrick | b0d28af | 2020-10-29 17:10:02 +0000 | [diff] [blame] | 119 | ) u_model ( |
| 120 | .clk_i (model_if.clk_i), |
| 121 | .rst_ni (model_if.rst_ni), |
| 122 | |
Rupert Swarbrick | b0d28af | 2020-10-29 17:10:02 +0000 | [diff] [blame] | 123 | .start_i (model_if.start), |
| 124 | .done_o (model_if.done), |
| 125 | .start_addr_i (model_if.start_addr), |
Greg Chadwick | b168ae9 | 2021-04-14 16:04:03 +0100 | [diff] [blame] | 126 | .err_o (model_if.err), |
| 127 | |
| 128 | .edn_rnd_data_valid_i (edn_rnd_data_valid), |
| 129 | .edn_rnd_data_i (dut.edn_rnd_data), |
| 130 | .edn_urnd_data_valid_i (edn_urnd_data_valid) |
Rupert Swarbrick | b0d28af | 2020-10-29 17:10:02 +0000 | [diff] [blame] | 131 | ); |
| 132 | |
Rupert Swarbrick | d8bfaf1 | 2020-09-21 12:53:35 +0100 | [diff] [blame] | 133 | initial begin |
| 134 | // drive clk and rst_n from clk_if |
| 135 | clk_rst_if.set_active(); |
Rupert Swarbrick | 3548b1e | 2020-10-08 16:55:44 +0100 | [diff] [blame] | 136 | |
Rupert Swarbrick | d8bfaf1 | 2020-09-21 12:53:35 +0100 | [diff] [blame] | 137 | uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "clk_rst_vif", clk_rst_if); |
Rupert Swarbrick | 3548b1e | 2020-10-08 16:55:44 +0100 | [diff] [blame] | 138 | uvm_config_db#(virtual tl_if)::set(null, "*.env.m_tl_agent*", "vif", tl_if); |
| 139 | uvm_config_db#(idle_vif)::set(null, "*.env", "idle_vif", idle_if); |
| 140 | uvm_config_db#(intr_vif)::set(null, "*.env", "intr_vif", intr_if); |
Rupert Swarbrick | b0d28af | 2020-10-29 17:10:02 +0000 | [diff] [blame] | 141 | uvm_config_db#(virtual otbn_model_if)::set(null, "*.env.model_agent", "vif", model_if); |
Rupert Swarbrick | 3548b1e | 2020-10-08 16:55:44 +0100 | [diff] [blame] | 142 | |
Rupert Swarbrick | 5c9aa75 | 2021-06-03 12:03:59 +0100 | [diff] [blame] | 143 | uvm_config_db#(virtual otbn_trace_if)::set(null, "*.env", "trace_vif", |
| 144 | dut.u_otbn_core.i_otbn_trace_if); |
Rupert Swarbrick | e97c4f5 | 2021-06-03 12:30:54 +0100 | [diff] [blame^] | 145 | uvm_config_db#(virtual otbn_loop_if)::set( |
| 146 | null, "*.env", "loop_vif", |
| 147 | dut.u_otbn_core.u_otbn_controller.u_otbn_loop_controller.i_otbn_loop_if); |
Rupert Swarbrick | 5c9aa75 | 2021-06-03 12:03:59 +0100 | [diff] [blame] | 148 | |
Rupert Swarbrick | d8bfaf1 | 2020-09-21 12:53:35 +0100 | [diff] [blame] | 149 | $timeformat(-12, 0, " ps", 12); |
| 150 | run_test(); |
| 151 | end |
| 152 | |
| 153 | endmodule |