aboutsummaryrefslogblamecommitdiff
path: root/src/tb/tb_wrapper.v
blob: 054333eec845b729368b9f73d18d5af88dc76228 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11



                     






                                                








                                                             
                 





                              
                   





                                                                                                        
                                                          

                                                             
 















                                                                         

           
                   
                             

                                              
                      
                   
                           






















                                                                       



















































































                                                                                        
                   
            

                       
                                                                      









                                                              













                                                                      

                        
                                                                      











                                                                      















                                                                      

          
`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