diff options
-rw-r--r-- | bench/tb_core_selector.v | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/bench/tb_core_selector.v b/bench/tb_core_selector.v new file mode 100644 index 0000000..a8a174b --- /dev/null +++ b/bench/tb_core_selector.v @@ -0,0 +1,192 @@ +`timescale 1ns / 1ps + +module tb_core_selector; + + + // + // System Clock, System Reset + // + `define SYS_CLK_FREQUENCY_MHZ ( 100.0 ) + `define SYS_CLK_PERIOD_NS (1000.0 / `SYS_CLK_FREQUENCY_MHZ) + `define SYS_CLK_PERIOD_HALF_NS ( 0.5 * `SYS_CLK_PERIOD_NS ) + + reg sys_clk = 1'b0; + initial forever #`SYS_CLK_PERIOD_HALF_NS sys_clk = ~sys_clk; + + `define SYS_RST_N_ACTIVE 1'b0 + `define SYS_RST_N_INACTIVE 1'b1 + + reg sys_rst_n = `SYS_RST_N_ACTIVE; + + + // + // System Bus + // + reg [23: 0] sys_fmc_addr; + reg sys_fmc_wr = 1'b0; + reg sys_fmc_rd = 1'b0; + wire [31: 0] sys_read_data; + reg [31: 0] sys_write_data; + wire sys_error; + + + // + // UUT + // + core_selector uut + ( + .sys_clk (sys_clk), + .sys_rst_n (sys_rst_n), + + .sys_fmc_addr (sys_fmc_addr), + .sys_fmc_wr (sys_fmc_wr), + .sys_fmc_rd (sys_fmc_rd), + .sys_read_data (sys_read_data), + .sys_write_data (sys_write_data), + .sys_error (sys_error), + + .mkm_sclk (), + .mkm_cs_n (), + .mkm_do (1'b0), + .mkm_di (), + + .core_clk (1'b0), + + .noise (1'b0), + .debug () + ); + + + // + // Script + // + + // + // Here's what the following routine does. We know that at address 0 there's always a BOARD_REGS core, which + // has a 32-bit dummy register at offset 255. ECDSA cores also have a 32-bit dummy register at offset 15. + // We write some values into the two dummy registers to test the address decoding logic (we write to two cores + // with different numbers, the offsets of registers are also different). Then we do a readback and compare + // the read value with the written one. The code assumes, that the default "hsm" core configuration is used, + // where the number of ECDSA-256 is 0x37. If this is not the case, adapt the first parameter passed to the + // sys_bus_write() calls. + // + + localparam [31:0] MAGIC_1 = 32'hCCAA5533; + localparam [31:0] MAGIC_2 = 32'hCA5335AC; + + reg [31:0] wr, rd; + initial begin + + wait_sys_clk_ticks(200); + sys_rst_n = `SYS_RST_N_INACTIVE; + wait_sys_clk_ticks(100); + + wr = MAGIC_1; + sys_bus_write(16'h0000, 8'd255, wr); + wait_sys_clk_ticks(10); + + wr = MAGIC_2; + sys_bus_write(16'h0037, 8'd15, wr); + wait_sys_clk_ticks(10); + + wr = MAGIC_1; + sys_bus_read(16'h0000, 8'd255, rd); + wait_sys_clk_ticks(10); + if (rd !== wr) begin + $display("ERROR: wr = 0x%08x, rd = 0x%08x", wr, rd); + wait_sys_clk_ticks(100); + $finish; + end + + wr = MAGIC_2; + sys_bus_read(16'h0037, 8'd15, rd); + wait_sys_clk_ticks(10); + if (rd !== wr) begin + $display("ERROR: wr = 0x%08x, rd = 0x%08x", wr, rd); + wait_sys_clk_ticks(100); + $finish; + end + + $display("Test passed."); + $finish; + + end + + + // + // _wait_half_sys_clk_tick() + // + task _wait_half_sys_clk_tick; + #`SYS_CLK_PERIOD_HALF_NS; + endtask + + + // + // wait_sys_clk_tick() + // + task wait_sys_clk_tick; + begin + _wait_half_sys_clk_tick; + _wait_half_sys_clk_tick; + end + endtask + + + // + // wait_sys_clk_ticks() + // + task wait_sys_clk_ticks; + input integer _num_ticks; + integer _n; + for (_n=0; _n<_num_ticks; _n=_n+1) + wait_sys_clk_tick; + endtask + + + // + // _sys_bus_drive() + // + task _sys_bus_drive; + input [23: 0] _addr; + input _wr; + input _rd; + input [31: 0] _write_data; + {sys_fmc_addr, sys_fmc_wr, sys_fmc_rd, sys_write_data} <= + { _addr, _wr, _rd, _write_data} ; + endtask + + + // + // sys_bus_read() + // + task sys_bus_read; + input [15:0] _num; + input [ 7:0] _reg; + output [31:0] _data; + begin + _sys_bus_drive({_num, _reg}, 1'b0, 1'b1, {32{1'bX}}); + wait_sys_clk_tick; + _sys_bus_drive(24'hXXXX, 1'b0, 1'b0, {32{1'bX}}); + wait_sys_clk_ticks(3); + _data = sys_read_data; + _sys_bus_drive(24'hXXXX, 1'b0, 1'b0, {32{1'bX}}); + end + endtask + + + // + // sys_bus_write() + // + task sys_bus_write; + input [15:0] _num; + input [ 7:0] _reg; + input [31:0] _data; + begin + _sys_bus_drive({_num, _reg}, 1'b1, 1'b0, _data); + wait_sys_clk_tick; + _sys_bus_drive(24'hXXXX, 1'b0, 1'b0, {32{1'bX}}); + end + endtask + + +endmodule |