aboutsummaryrefslogblamecommitdiff
path: root/bench/tb_modular_invertor.v
blob: 24f6db10a62f8797616f96963cab12ac8d94e4a9 (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