`timescale 1ns / 1ps module tb_modular_invertor; // // Test Vectors // localparam [255:0] Q = 256'hffffffff00000001000000000000000000000000ffffffffffffffffffffffff; localparam [255:0] A_1 = 256'hd3e73ccd63a5b10da308c615bb9ebd3f76e2c5fccc256fd9f629dcc956bf2382; localparam [255:0] A1_1 = 256'h93fb26d5d199bbb7232a4b7c98e97ba9bb7530d304b5f07736ea4027bbb57ecd; localparam [255:0] A_2 = 256'h57b6c628a5c4e870740b2517975ace2216acbe094ac54568b53212ef45e69d22; localparam [255:0] A1_2 = 256'hcd2af4766642d7d2f3f3f67d92c575c496772ef7d55c75eb46bd07e8d5f9a4aa; // // Clock // reg clk = 1'b0; always #5 clk = ~clk; // // Inputs, Outputs // reg rst_n; reg ena; wire rdy; // // Buffers (A, A1, Q) // wire [ 2: 0] core_a_addr; wire [ 2: 0] core_q_addr; wire [ 2: 0] core_a1_addr; wire core_a1_wren; wire [31: 0] core_a_data; wire [31: 0] core_q_data; wire [31: 0] core_a1_data; reg [ 2: 0] tb_aq_addr; reg tb_aq_wren; reg [ 2: 0] tb_a1_addr; reg [31: 0] tb_a_data; reg [31: 0] tb_q_data; wire [31: 0] tb_a1_data; bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3)) bram_a ( .clk(clk), .a_addr(tb_aq_addr), .a_wr(tb_aq_wren), .a_in(tb_a_data), .a_out(), .b_addr(core_a_addr), .b_out(core_a_data) ); bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3)) bram_q ( .clk(clk), .a_addr(tb_aq_addr), .a_wr(tb_aq_wren), .a_in(tb_q_data), .a_out(), .b_addr(core_q_addr), .b_out(core_q_data) ); bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3)) bram_a1 ( .clk(clk), .a_addr(core_a1_addr), .a_wr(core_a1_wren), .a_in(core_a1_data), .a_out(), .b_addr(tb_a1_addr), .b_out(tb_a1_data) ); // // UUT // modular_invertor # ( .MAX_OPERAND_WIDTH (256) ) uut ( .clk (clk), .rst_n (rst_n), .ena (ena), .rdy (rdy), .a_addr (core_a_addr), .q_addr (core_q_addr), .a1_addr (core_a1_addr), .a1_wren (core_a1_wren), .a_din (core_a_data), .q_din (core_q_data), .a1_dout (core_a1_data) ); // // Testbench Routine // reg ok = 1; initial begin /* initialize control inputs */ rst_n = 0; ena = 0; /* wait for some time */ #200; /* de-assert reset */ rst_n = 1; /* wait for some time */ #100; /* run tests */ test_modular_invertor(A_1, A1_1, Q); test_modular_invertor(A_2, A1_2, Q); /* print result */ if (ok) $display("tb_modular_invertor: SUCCESS"); else $display("tb_modular_invertor: FAILURE"); // //$finish; // end // // Test Task // reg a1_ok; integer w; task test_modular_invertor; input [255:0] a; input [255:0] a1; input [255:0] q; reg [255:0] a_shreg; reg [255:0] a1_shreg; reg [255:0] q_shreg; begin /* start filling memories */ tb_aq_wren = 1; /* initialize shift registers */ a_shreg = a; q_shreg = q; /* write all the words */ for (w=0; w<8; w=w+1) begin /* set addresses */ tb_aq_addr = w[2:0]; /* set data words */ tb_a_data = a_shreg[31:0]; tb_q_data = q_shreg[31:0]; /* shift inputs */ a_shreg = {{32{1'bX}}, a_shreg[255:32]}; q_shreg = {{32{1'bX}}, q_shreg[255:32]}; /* wait for 1 clock tick */ #10; end /* wipe addresses */ tb_aq_addr = {3{1'bX}}; /* wipe data words */ tb_a_data = {32{1'bX}}; tb_q_data = {32{1'bX}}; /* stop filling memories */ tb_aq_wren = 0; /* start operation */ ena = 1; /* clear flag */ #10 ena = 0; /* wait for operation to complete */ while (!rdy) #10; /* read result */ for (w=0; w<8; w=w+1) begin /* set address */ tb_a1_addr = w[2:0]; /* wait for 1 clock tick */ #10; /* store data word */ a1_shreg = {tb_a1_data, a1_shreg[255:32]}; end /* compare */ a1_ok = (a1_shreg == a1); /* display results */ $display("test_modular_invertor(): %s", a1_ok ? "OK" : "ERROR"); /* update global flag */ ok = ok && a1_ok; end endtask endmodule