diff options
Diffstat (limited to 'bench/tb_wrapper.v')
-rw-r--r-- | bench/tb_wrapper.v | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/bench/tb_wrapper.v b/bench/tb_wrapper.v new file mode 100644 index 0000000..2000ec5 --- /dev/null +++ b/bench/tb_wrapper.v @@ -0,0 +1,221 @@ +`timescale 1ns / 1ps + +module tb_wrapper; + + + // + // Clocks + // + `define CLK_FREQUENCY_MHZ (100.0) + `define CLK_PERIOD_NS (1000.0 / `CLK_FREQUENCY_MHZ) + `define CLK_PERIOD_HALF_NS (0.5 * `CLK_PERIOD_NS) + `define CLK_PERIOD_QUARTER_NS (0.5 * `CLK_PERIOD_HALF_NS) + + `define CLK_BUS_FREQUENCY_MHZ (25.0) + `define CLK_BUS_PERIOD_NS (1000.0 / `CLK_BUS_FREQUENCY_MHZ) + `define CLK_BUS_PERIOD_HALF_NS (0.5 * `CLK_BUS_PERIOD_NS) + + reg clk = 1'b1; + reg clk_bus = 1'b1; + reg clk_bus_dly = 1'b0; + wire clk_bus_idle = clk_bus & clk_bus_dly; + + always #`CLK_PERIOD_HALF_NS clk <= ~clk; + always #`CLK_BUS_PERIOD_HALF_NS clk_bus <= ~clk_bus; + + always @(clk_bus) clk_bus_dly <= #(`CLK_BUS_PERIOD_HALF_NS - `CLK_PERIOD_QUARTER_NS) clk_bus; + + + // + // Clock Sync + // + task sync_clk_bus; + while (clk_bus_idle !== 1) _wait_quarter_clk_tick; + endtask + + + // + // Reset + // + reg rst_n = 1'b0; + + + // + // System Bus + // + reg bus_cs = 1'b0; + reg bus_we = 1'b0; + reg [11:0] bus_addr; + reg [31:0] bus_data_wr; + wire [31:0] bus_data_rd; + + + // + // UUT + // + modexpng_wrapper uut + ( + .clk (clk_bus), + .rst_n (rst_n), + + .clk_core (clk), + + .cs (bus_cs), + .we (bus_we), + + .address (bus_addr), + .write_data (bus_data_wr), + .read_data (bus_data_rd) + ); + + + // + // Script + // + initial main; + + + // + // Main Routine (Control/Status, Bus) + // + reg [31:0] ti, to; + task main; + begin + + sync_clk_bus; + wait_clk_bus_ticks(10); + rst_n = 1'b1; + wait_clk_bus_ticks(10); + + bus_read('h11, to); $display("modulus_bits = %0d", to); + ti = 100; bus_write('h11, ti); bus_read('h11, to); $display("modulus_bits = %0d -> %0d", ti, to); + ti = 510; bus_write('h11, ti); bus_read('h11, to); $display("modulus_bits = %0d -> %0d", ti, to); + ti = 511; bus_write('h11, ti); bus_read('h11, to); $display("modulus_bits = %0d -> %0d", ti, to); + ti = 512; bus_write('h11, ti); bus_read('h11, to); $display("modulus_bits = %0d -> %0d", ti, to); + ti = 513; bus_write('h11, ti); bus_read('h11, to); $display("modulus_bits = %0d -> %0d", ti, to); + ti = 514; bus_write('h11, ti); bus_read('h11, to); $display("modulus_bits = %0d -> %0d", ti, to); + + + ti = 1022; bus_write('h11, ti); bus_read('h11, to); $display("modulus_bits = %0d -> %0d", ti, to); + ti = 1023; bus_write('h11, ti); bus_read('h11, to); $display("modulus_bits = %0d -> %0d", ti, to); + ti = 1024; bus_write('h11, ti); bus_read('h11, to); $display("modulus_bits = %0d -> %0d", ti, to); + ti = 1025; bus_write('h11, ti); bus_read('h11, to); $display("modulus_bits = %0d -> %0d", ti, to); + ti = 1026; bus_write('h11, ti); bus_read('h11, to); $display("modulus_bits = %0d -> %0d", ti, to); + + ti = 4094; bus_write('h11, ti); bus_read('h11, to); $display("modulus_bits = %0d -> %0d", ti, to); + ti = 4095; bus_write('h11, ti); bus_read('h11, to); $display("modulus_bits = %0d -> %0d", ti, to); + ti = 4096; bus_write('h11, ti); bus_read('h11, to); $display("modulus_bits = %0d -> %0d", ti, to); + ti = 4097; bus_write('h11, ti); bus_read('h11, to); $display("modulus_bits = %0d -> %0d", ti, to); + ti = 4098; bus_write('h11, ti); bus_read('h11, to); $display("modulus_bits = %0d -> %0d", ti, to); + + + bus_read('h12, to); $display("exponent_bits = %0d", to); + ti = 0; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + ti = 1; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + ti = 2; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + ti = 3; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + ti = 4; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + ti = 5; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + ti = 6; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + ti = 7; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + ti = 8; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + + ti = 100; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + ti = 510; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + ti = 511; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + ti = 512; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + ti = 513; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + ti = 514; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + + + ti = 1022; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + ti = 1023; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + ti = 1024; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + ti = 1025; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + ti = 1026; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + + ti = 4094; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + ti = 4095; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + ti = 4096; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + ti = 4097; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + ti = 4098; bus_write('h12, ti); bus_read('h12, to); $display("exponent_bits = %0d -> %0d", ti, to); + + + end + endtask + + + // + // _bus_drive() + // + task _bus_drive; + input cs; + input we; + input [11:0] addr; + input [31:0] data; + {bus_cs, bus_we, bus_addr, bus_data_wr} <= {cs, we, addr, data}; + endtask + + + // + // bus_write() + // + task bus_write; + input [ 9:0] offset; + input [31:0] data; + begin + _bus_drive(1'b1, 1'b1, {2'b00, offset}, data); + wait_clk_bus_tick; + _bus_drive(1'b0, 1'b0, 12'hXXX, 32'hXXXXXXXX); + end + endtask + + + // + // bus_read() + // + task bus_read; + input [ 9:0] offset; + output [31:0] data; + begin + _bus_drive(1'b1, 1'b0, {2'b00, offset}, 32'hXXXXXXXX); + wait_clk_bus_tick; + data = bus_data_rd; + _bus_drive(1'b0, 1'b0, 12'hXXX, 32'hXXXXXXXX); + end + endtask + + + // + // Variables + // + integer _n; + + + // + // _wait_quarter_clk_tick() + // + task _wait_quarter_clk_tick; + #`CLK_PERIOD_QUARTER_NS; + endtask + + + // + // wait_clk_bus_tick() + // + task wait_clk_bus_tick; + #`CLK_BUS_PERIOD_NS; + endtask + + + // + // wait_clk_bus_ticks() + // + task wait_clk_bus_ticks; + input integer num_ticks; + for (_n=0; _n<num_ticks; _n=_n+1) + wait_clk_bus_tick; + endtask + + +endmodule |