aboutsummaryrefslogblamecommitdiff
path: root/bench/tb_modular_invertor.v
blob: 0ef7c880558185e2ff755a59a38e6d4063e3764a (plain) (tree)

































































































































































































































                                                                                                                         
`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