aboutsummaryrefslogtreecommitdiff
path: root/bench
diff options
context:
space:
mode:
Diffstat (limited to 'bench')
-rw-r--r--bench/tb_core_selector.v192
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