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