summaryrefslogblamecommitdiff
path: root/bench/tb_base_point_multiplier.v
blob: 7d8de3ba5e6ff83c51eb2d7fe4411c1fd19ffa6b (plain) (tree)




































































































































































































































































                                                                                  
//------------------------------------------------------------------------------
//
// tb_base_point_multiplier.v
// -----------------------------------------------------------------------------
// Testbench for Ed25519 base point scalar multiplier.
//
// Authors: Pavel Shatov
//
// Copyright (c) 2018, NORDUnet A/S
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// - Redistributions of source code must retain the above copyright notice,
//   this list of conditions and the following disclaimer.
//
// - Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// - Neither the name of the NORDUnet nor the names of its contributors may be
//   used to endorse or promote products derived from this software without
//   specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
`timescale 1ns / 1ps
//------------------------------------------------------------------------------

module tb_base_point_multiplier;


        //
        // Test Vectors
        //
    `include "ed25519_test_vectors.v"


        //
        // Core Parameters
        //
    localparam  WORD_COUNTER_WIDTH  = 3;
    localparam  OPERAND_NUM_WORDS   = 8;


        //
        // Clock (100 MHz)
        //
`define CLOCK_PERIOD        10.0
`define CLOCK_HALF_PERIOD   (0.5 * `CLOCK_PERIOD)

    reg clk = 1'b0;
    always #`CLOCK_HALF_PERIOD clk = ~clk;


        //
        // Inputs, Outputs
        //
    reg     rst_n;
    reg     ena;
    wire    rdy;


        //
        // Buffers (K, QY)
        //
    wire    [WORD_COUNTER_WIDTH-1:0]    core_k_addr;
    wire    [WORD_COUNTER_WIDTH-1:0]    core_qy_addr;
    
    wire                                core_qy_wren;
    
    wire    [                32-1:0]    core_k_data;
    wire    [                32-1:0]    core_qy_data;
    
    reg     [WORD_COUNTER_WIDTH-1:0]    tb_k_addr;
    reg     [WORD_COUNTER_WIDTH-1:0]    tb_qy_addr;
    
    reg                                 tb_k_wren;
    
    reg     [                32-1:0]    tb_k_data;
    wire    [                32-1:0]    tb_qy_data;
    
    bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH))
    bram_k
    (   .clk(clk),
        .a_addr(tb_k_addr),   .a_wr(tb_k_wren), .a_in(tb_k_data), .a_out(),
        .b_addr(core_k_addr), .b_out(core_k_data)
    );
        
    bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH))
    bram_qy
    (   .clk(clk),
        .a_addr(core_qy_addr), .a_wr(core_qy_wren), .a_in(core_qy_data), .a_out(),
        .b_addr(tb_qy_addr),   .b_out(tb_qy_data)
    );
    
    
        //
        // UUT
        //
    ed25519_multiplier uut
    (
        .clk        (clk),
        .rst_n      (rst_n),
        
        .ena        (ena),
        .rdy        (rdy),
        
        .k_addr     (core_k_addr),
        .qy_addr    (core_qy_addr),
        
        .qy_wren    (core_qy_wren),
        
        .k_din      (core_k_data),
        .qy_dout    (core_qy_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 */
        $display("1. Q = d * G...");
        test_base_point_multiplier(ED25519_D_HASHED_LSB_1, ED25519_Q_Y_1);
        
            /* print result */
        if (ok) $display("tb_base_point_multiplier: SUCCESS");
        else    $display("tb_base_point_multiplier: FAILURE");
        //
        #10000;
        //
        //$finish;
        //
    end
    
    
        //
        // Test Task
        //  
    task test_base_point_multiplier;
    
        input   [255:0] k;
        input   [255:0] qy;
        
        reg     [255:0] k_shreg;
        reg     [255:0] qy_shreg;
        reg             qy_ok;
        
        integer         w;

        begin
        
                /* initialize result */
            qy_ok = 0;

                /* initialize shift registers */
            k_shreg = k;

                /* start filling memories */
            tb_k_wren = 1;
            
                /* write all the words */
            for (w=0; w<OPERAND_NUM_WORDS; w=w+1) begin
                
                    /* set addresses */
                tb_k_addr = w[WORD_COUNTER_WIDTH-1:0];
                
                    /* set data words */
                tb_k_data   = k_shreg[31:0];
                
                    /* shift inputs */
                k_shreg = {{32{1'bX}}, k_shreg[255:32]};
                
                    /* wait for 1 clock tick */
                #`CLOCK_PERIOD;
                
            end
            
                /* stop filling memories */
            tb_k_wren = 0;

                /* wipe addresses */
            tb_k_addr = {WORD_COUNTER_WIDTH{1'bX}};
            
                /* wipe data words */
            tb_k_data = {32{1'bX}};
                        
                /* start operation */
            ena = 1;
            
                /* clear flag */
            #`CLOCK_PERIOD ena = 0;
            
                /* wait for operation to complete */
            while (!rdy) #`CLOCK_PERIOD;
            
//                /* read result */
//            for (w=0; w<OPERAND_NUM_WORDS; w=w+1) begin
//                
//                    /* set address */
//                tb_qxy_addr = w[WORD_COUNTER_WIDTH-1:0];
//                
//                    /* wait for 1 clock tick */
//                #10;
//                
//                    /* store data word */
//                qx_shreg = {tb_qx_data, qx_shreg[255:32]};
//                qy_shreg = {tb_qy_data, qy_shreg[255:32]};
//
//            end
//            
//                /* compare */
//            q_ok =  (qx_shreg == qx) &&
//                        (qy_shreg == qy);
//
                /* display results */
            if (qy_ok)  $display("test_base_point_multiplier(): CORRECT RESULT");
            else        $display("test_base_point_multiplier(): WRONG RESULT");
            
                /* update global flag */
            ok = ok & qy_ok;
        
        end
        
    endtask
    
endmodule


//------------------------------------------------------------------------------
// End-of-File
//------------------------------------------------------------------------------