`timescale 1ns / 1ps module tb_wrapper; // // Test Vectors // `include "modexp_fpga_model_vectors.v"; /* * Settings */ localparam USE_OPERAND_ADDR_WIDTH = 7; localparam USE_SYSTOLIC_ARRAY_POWER = 1; /* * Clock (100 MHz) */ reg clk; initial clk = 1'b0; always #5 clk = ~clk; /* * Reset */ reg rst_n; /* * Access Bus */ reg bus_cs; reg bus_we; reg [USE_OPERAND_ADDR_WIDTH+3:0] bus_addr; reg [ 32-1:0] bus_wr_data; wire [ 32-1:0] bus_rd_data; modexpa7_wrapper # ( .OPERAND_ADDR_WIDTH (USE_OPERAND_ADDR_WIDTH), .SYSTOLIC_ARRAY_POWER (USE_SYSTOLIC_ARRAY_POWER) ) uut ( .clk (clk), .rst_n (rst_n), .cs (bus_cs), .we (bus_we), .address (bus_addr), .write_data (bus_wr_data), .read_data (bus_rd_data) ); integer i; reg [31: 0] tmp; reg [383:0] shreg; reg poll; initial begin // rst_n = 0; // bus_cs = 0; bus_we = 0; bus_addr = 'bX; bus_wr_data = 'bX; // #200; // rst_n = 1; // read_reg('h00, tmp); // NAME0 read_reg('h01, tmp); // NAME1 read_reg('h02, tmp); // VERSION // read_reg('h13, tmp); // BUFFER_BITS read_reg('h14, tmp); // ARRAY_BITS // write_reg('h12, 32'd384); // EXPONENT_BITS read_reg ('h12, tmp); // write_reg('h11, 32'd384); // MODULUS_BITS read_reg ('h11, tmp); // write_reg('h10, 32'd0); // MODE read_reg ('h10, tmp); // // pre-calculate 384-bit quantities // shreg = N_384; for (i=0; i<384/32; i=i+1) begin write_bank(3'b000, i[USE_OPERAND_ADDR_WIDTH-1:0], shreg[31:0]); shreg = shreg >> 32; end // write_reg('h08, 32'd0); // CONTROL.init = 0 write_reg('h08, 32'd1); // CONTROL.init = 1 // poll = 1; while (poll) begin #10; read_reg('h09, tmp); // tmp = STATUS poll = ~tmp[0]; // poll = STATUS.ready end // // fill banks // for (i=0; i<384/32; i=i+1) begin read_bank(3'b100, i[USE_OPERAND_ADDR_WIDTH-1:0], tmp); write_bank(3'b101, i[USE_OPERAND_ADDR_WIDTH-1:0], tmp); read_bank(3'b110, i[USE_OPERAND_ADDR_WIDTH-1:0], tmp); write_bank(3'b111, i[USE_OPERAND_ADDR_WIDTH-1:0], tmp); end // shreg = M_384; for (i=0; i<384/32; i=i+1) begin write_bank(3'b001, i[USE_OPERAND_ADDR_WIDTH-1:0], shreg[31:0]); shreg = shreg >> 32; end // shreg = D_384; for (i=0; i<384/32; i=i+1) begin write_bank(3'b010, i[USE_OPERAND_ADDR_WIDTH-1:0], shreg[31:0]); shreg = shreg >> 32; end // // wipe // shreg = {384{1'b0}}; for (i=0; i<384/32; i=i+1) begin write_bank(3'b000, i[USE_OPERAND_ADDR_WIDTH-1:0], shreg[31:0]); shreg = shreg >> 32; end // write_reg('h08, 32'd0); // CONTROL.init = 0 write_reg('h08, 32'd1); // CONTROL.init = 1 // poll = 1; while (poll) begin #10; read_reg('h09, tmp); // tmp = STATUS poll = ~tmp[0]; // poll = STATUS.ready end // // restore // shreg = N_384; for (i=0; i<384/32; i=i+1) begin write_bank(3'b000, i[USE_OPERAND_ADDR_WIDTH-1:0], shreg[31:0]); shreg = shreg >> 32; end // // // write_reg('h08, 32'd0); // CONTROL.next = 0 write_reg('h08, 32'd2); // CONTROL.next = 1 // poll = 1; while (poll) begin #10; read_reg('h09, tmp); // tmp = STATUS poll = ~tmp[1]; // poll = STATUS.valid end // for (i=0; i<384/32; i=i+1) begin read_bank(3'b011, i[USE_OPERAND_ADDR_WIDTH-1:0], tmp); shreg = {tmp, shreg[383:32]}; end // end task read_reg; input [USE_OPERAND_ADDR_WIDTH+2:0] addr; output [ 32-1:0] data; begin bus_cs = 1; bus_addr = {1'b0, addr}; #10; bus_cs = 0; bus_addr = 'bX; data = bus_rd_data; end endtask task read_bank; input [ 2:0] bank; input [USE_OPERAND_ADDR_WIDTH-1:0] addr; output [ 32-1:0] data; begin bus_cs = 1; bus_addr = {1'b1, bank, addr}; #10; bus_cs = 0; bus_addr = 'bX; data = bus_rd_data; end endtask task write_reg; input [USE_OPERAND_ADDR_WIDTH+2:0] addr; input [ 32-1:0] data; begin bus_cs = 1; bus_we = 1; bus_addr = {1'b0, addr}; bus_wr_data = data; #10; bus_cs = 0; bus_we = 0; bus_addr = 'bX; end endtask task write_bank; input [ 2:0] bank; input [USE_OPERAND_ADDR_WIDTH-1:0] addr; input [ 32-1:0] data; begin bus_cs = 1; bus_we = 1; bus_addr = {1'b1, bank, addr}; bus_wr_data = data; #10; bus_cs = 0; bus_we = 0; bus_addr = 'bX; end endtask endmodule