aboutsummaryrefslogblamecommitdiff
path: root/rtl/dev/temp.txt
blob: 987bd86ad66d1131724b761efbedc6ef1a79ca51 (plain) (tree)































































































































































































































































































































































































                                                                                                                                  
    //
    // Helper Functions
    //
    /*
    function  [INDEX_WIDTH-1:0] calc_preset_a_index;
        input [INDEX_WIDTH-4:0] col_in;
        input integer           x_in;
              integer           index_out;
        begin
            index_out = col_in * NUM_MULTS + x_in;
            calc_preset_a_index = index_out[INDEX_WIDTH-1:0];
        end
    endfunction

    function  [INDEX_WIDTH-1:0] calc_rotate_a_index;
        input [INDEX_WIDTH-1:0] current_index_in;
        input [INDEX_WIDTH-1:0] last_index_in;
        begin
            if (current_index_in > {INDEX_WIDTH{1'b0}})
                calc_rotate_a_index = current_index_in - 1'b1;
            else
                calc_rotate_a_index = last_index_in;
        end
    endfunction
    */

 /*
    //
    // Narrow Counters
    //
    reg        [INDEX_WIDTH-1:0] din_addr_narrow_reg;
    reg        [INDEX_WIDTH-1:0] din_addr_narrow_dly;
    localparam [INDEX_WIDTH-1:0] din_addr_narrow_zero = {INDEX_WIDTH{1'b0}};
    wire       [INDEX_WIDTH-1:0] din_addr_narrow_next = (din_addr_narrow_reg < index_last) ?
        din_addr_narrow_reg + 1'b1 : din_addr_narrow_zero;
    wire                         din_addr_narrow_done = din_addr_narrow_reg == index_last;
    
    assign din_addr_narrow = din_addr_narrow_reg;
    
    always @(posedge clk)
        //
        din_addr_narrow_dly <= din_addr_narrow_reg;
    
    always @(posedge clk)
        //
        case (fsm_state_next)
            FSM_STATE_MULT_SQUARE_COL_0_TRIG:   din_addr_narrow_reg <= din_addr_narrow_zero;
            FSM_STATE_MULT_SQUARE_COL_0_BUSY:   din_addr_narrow_reg <= din_addr_narrow_next;
            FSM_STATE_MULT_SQUARE_COL_N_TRIG:   din_addr_narrow_reg <= din_addr_narrow_zero;
            FSM_STATE_MULT_SQUARE_COL_N_BUSY:   din_addr_narrow_reg <= din_addr_narrow_next;
        endcase
    

    //
    // Helper Functions
    //
    function  [NUM_MULTS-1:0] calc_mac_clear_bitmask;
        input [2:0] t;
        begin
            case (t)
                3'd0: calc_mac_clear_bitmask = 8'b00000001;
                3'd1: calc_mac_clear_bitmask = 8'b00000010;
                3'd2: calc_mac_clear_bitmask = 8'b00000100;
                3'd3: calc_mac_clear_bitmask = 8'b00001000;
                3'd4: calc_mac_clear_bitmask = 8'b00010000;
                3'd5: calc_mac_clear_bitmask = 8'b00100000;
                3'd6: calc_mac_clear_bitmask = 8'b01000000;
                3'd7: calc_mac_clear_bitmask = 8'b10000000;
            endcase
        end
    endfunction
    
    function  [NUM_MULTS:0] calc_mac_clear_square;
        input [INDEX_WIDTH-4:0] current_col_index;
        input [INDEX_WIDTH-1:0] b_addr_prev;
        begin
            if (b_addr_prev[INDEX_WIDTH-1:3] == current_col_index)
                calc_mac_clear_square = {1'b0, calc_mac_clear_bitmask(b_addr_prev[2:0])};
            else
                calc_mac_clear_square = {1'b0, {NUM_MULTS{1'b0}}};
        end
    endfunction
        
        
    //
    // Wide Counters
    //
    reg [INDEX_WIDTH-1:0] din_addr_wide_reg[0:NUM_MULTS-1];
 
    integer xi;
    always @(posedge clk)
        //
        for (xi=0; xi<NUM_MULTS; xi=xi+1)
            //
            case (fsm_state_next)
                //
                FSM_STATE_MULT_SQUARE_COL_0_TRIG: din_addr_wide_reg[xi] <= calc_preset_a_index(0, xi);
                FSM_STATE_MULT_SQUARE_COL_N_TRIG: din_addr_wide_reg[xi] <= calc_preset_a_index(col_index + 1'b1, xi);
                //
                FSM_STATE_MULT_SQUARE_COL_0_BUSY,
                FSM_STATE_MULT_SQUARE_COL_N_BUSY: din_addr_wide_reg[xi] <= calc_rotate_a_index(din_addr_wide_reg[xi], index_last);
                //
            endcase
        
 
    //
    // Enables
    //
    reg                 din_ena_narrow_reg = 1'b0;
    reg [NUM_MULTS-1:0] din_ena_wide_reg = {NUM_MULTS{1'b0}};
    
    assign din_ena_narrow = din_ena_narrow_reg;
    assign din_ena_wide   = din_ena_wide_reg;
    
    always @(posedge clk or negedge rst_n)
        //
        if (rst_n == 1'b0) din_ena_narrow_reg <= 1'b0;
        else case (fsm_state_next)
            FSM_STATE_MULT_SQUARE_COL_0_TRIG,
            FSM_STATE_MULT_SQUARE_COL_0_BUSY,
            FSM_STATE_MULT_SQUARE_COL_N_TRIG,
            FSM_STATE_MULT_SQUARE_COL_N_BUSY: din_ena_narrow_reg <= 1'b1;
            default:                          din_ena_narrow_reg <= 1'b0;
        endcase

    always @(posedge clk or negedge rst_n)
        //
        if (rst_n == 1'b0) din_ena_wide_reg <= {NUM_MULTS{1'b0}};
        else case (fsm_state_next)
            FSM_STATE_MULT_SQUARE_COL_0_TRIG,
            FSM_STATE_MULT_SQUARE_COL_0_BUSY,
            FSM_STATE_MULT_SQUARE_COL_N_TRIG,
            FSM_STATE_MULT_SQUARE_COL_N_BUSY: din_ena_wide_reg <= {NUM_MULTS{1'b1}};
            default:                          din_ena_wide_reg <= {NUM_MULTS{1'b0}};
        endcase
        
        
    //
    // Modes
    //
    reg [2-1:0] din_mode_wide_reg;
    reg [2-1:0] din_mode_narrow_reg;
    reg [2-1:0] dout_mode_wide_reg;
    reg [2-1:0] dout_mode_narrow_reg;

    assign din_mode_wide = din_mode_wide_reg;
    assign din_mode_narrow = din_mode_narrow_reg;

    always @(posedge clk)
        //
        case (fsm_state_next)
            FSM_STATE_MULT_SQUARE_COL_0_TRIG,
            FSM_STATE_MULT_SQUARE_COL_0_BUSY,
            FSM_STATE_MULT_SQUARE_COL_N_TRIG,
            FSM_STATE_MULT_SQUARE_COL_N_BUSY: din_mode_wide_reg <= MODEXPNG_MODE_A;
            default:                          din_mode_wide_reg <= 2'bXX;
        endcase

    always @(posedge clk)
        //
        case (fsm_state_next)
            FSM_STATE_MULT_SQUARE_COL_0_TRIG,
            FSM_STATE_MULT_SQUARE_COL_0_BUSY,
            FSM_STATE_MULT_SQUARE_COL_N_TRIG,
            FSM_STATE_MULT_SQUARE_COL_N_BUSY: din_mode_narrow_reg <= MODEXPNG_MODE_B;
            default:                          din_mode_narrow_reg <= 2'bXX;
        endcase


    //
    // MAC Array
    //
    wire [MODEXPNG_WORD_WIDTH-1:0] mac_din_a[0:NUM_MULTS];
    wire [MODEXPNG_WORD_WIDTH-1:0] mac_din_b;
    reg  [          NUM_MULTS  :0] mac_ce;
    reg  [          NUM_MULTS  :0] mac_clr;
    wire [ MODEXPNG_MAC_WIDTH-1:0] mac_p[0:NUM_MULTS];
    reg  [          NUM_MULTS  :0] mac_rdy_lsb;
    reg  [          NUM_MULTS  :0] mac_rdy_lsb_dly[MODEXPNG_MAC_LATENCY-1:0];
    
    //reg  [          NUM_MULTS  :0] mac_ce_dly[MODEXPNG_MAC_LATENCY-1:0];
    //wire [          NUM_MULTS  :0] mac_rdy;





    assign mac_din_b = din_narrow;
    
    
    genvar x;
    generate for (x=0; x<=NUM_MULTS; x=x+1)
        begin : gen_macs
            //
            //assign mac_rdy[x] = mac_ce_dly[MODEXPNG_MAC_LATENCY-1][x];
            //
            modexpng_mac mac_inst
            (
                .clk    (clk),
                .ce     (mac_ce[x]),
                .clr    (mac_clr[x]),
                .a      (mac_din_a[x]),
                .b      (mac_din_b),
                .p      (mac_p[x])
            );
            //
        end
        //
    endgenerate
    
    generate for (x=0; x<NUM_MULTS; x=x+1)
        begin : gen_mac_din_a
            //
            assign mac_din_a[x] = din_wide[x*MODEXPNG_WORD_WIDTH+:MODEXPNG_WORD_WIDTH];
            //
        end
    endgenerate

    generate for (x=0; x<NUM_MULTS; x=x+1)
        begin : gen_din_addr_wide
            //
            assign din_addr_wide[x*INDEX_WIDTH+:INDEX_WIDTH] = din_addr_wide_reg[x];
            //
        end
    endgenerate
 
 
    //
    // MAC Clock Enable Logic
    //
    always @(posedge clk or negedge rst_n)
        //
        if (rst_n == 1'b0) mac_ce <= {1'b0, {NUM_MULTS{1'b0}}};
        else case (fsm_state)
            FSM_STATE_MULT_SQUARE_COL_0_TRIG,
            FSM_STATE_MULT_SQUARE_COL_0_BUSY,
            FSM_STATE_MULT_SQUARE_COL_N_TRIG,
            FSM_STATE_MULT_SQUARE_COL_N_BUSY: mac_ce <= {1'b0, {NUM_MULTS{1'b1}}};
            default:                          mac_ce <= {1'b0, {NUM_MULTS{1'b0}}};
        endcase
    
    
    //
    // MAC Valid Logic
    //
    integer y;

    always @(posedge clk)
        //
        for (xi=0; xi<=NUM_MULTS; xi=xi+1) begin
            mac_rdy_lsb_dly[0][xi] <= mac_rdy_lsb[xi];
            for (y=1; y<MODEXPNG_MAC_LATENCY; y=y+1)
                mac_rdy_lsb_dly[y][xi] <= mac_rdy_lsb_dly[y-1][xi];
        end

    always @(posedge clk) begin
        //
        fsm_state_dly[0] <= fsm_state;
        for (y=1; y<=MODEXPNG_MAC_LATENCY; y=y+1)
            fsm_state_dly[y] <= fsm_state_dly[y-1];
    end

    */

    /*
    always @(posedge clk)
        //
        for (xi=0; xi<=NUM_MULTS; xi=xi+1) begin
            mac_ce_dly[0][xi] <= mac_ce[xi];
            for (y=1; y<MODEXPNG_MAC_LATENCY; y=y+1)
                mac_ce_dly[y][xi] <= mac_ce_dly[y-1][xi];
        end
    */
    /*
    always @(posedge clk)
        //
        for (xi=0; xi<=NUM_MULTS; xi=xi+1) begin
            mac_clr_dly[0][xi] <= mac_clr[xi];
            for (y=1; y<MODEXPNG_MAC_LATENCY; y=y+1)
                mac_clr_dly[y][xi] <= mac_clr_dly[y-1][xi];
        end
    */

  /*  
    //
    // MAC Clear Logic
    //
    always @(posedge clk)
        //
        case (fsm_state)
            FSM_STATE_MULT_SQUARE_COL_0_TRIG,
            FSM_STATE_MULT_SQUARE_COL_N_TRIG: mac_clr <= {1'b0, {NUM_MULTS{1'b1}}};
            FSM_STATE_MULT_SQUARE_COL_0_BUSY,
            FSM_STATE_MULT_SQUARE_COL_N_BUSY: mac_clr <= calc_mac_clear_square(col_index, din_addr_narrow_dly);
            default:                          mac_clr <= {1'bX, {NUM_MULTS{1'bX}}};
        endcase


    //
    // MAC Ready Logic
    //
    always @(posedge clk)
        //
        case (fsm_state)
            FSM_STATE_MULT_SQUARE_COL_0_TRIG,
            FSM_STATE_MULT_SQUARE_COL_N_TRIG,
            FSM_STATE_MULT_SQUARE_COL_0_BUSY,
            FSM_STATE_MULT_SQUARE_COL_N_BUSY: mac_rdy_lsb <= calc_mac_clear_square(col_index, din_addr_narrow);
            default:                          mac_rdy_lsb <= {1'bX, {NUM_MULTS{1'bX}}};
        endcase
 
 
 
    //
    // Recombinators
    //
    reg          rcmb_lsb_ce;
    reg          rcmb_lsb_clr;
    reg  [MODEXPNG_MAC_WIDTH-1: 0] rcmb_lsb_din;
    wire [15: 0] rcmb_lsb_dout;
    
    modexpng_part_recombinator recomb_lsb
    (
        .clk    (clk),
        .ce     (rcmb_lsb_ce),
        .clr    (rcmb_lsb_clr),
        .din    (rcmb_lsb_din),
        .dout   (rcmb_lsb_dout)
    );
 
 
    reg calc_rcmb_lsb_ce;
    always @*
        //
        calc_rcmb_lsb_ce = | mac_rdy_lsb_dly[MODEXPNG_MAC_LATENCY-1][NUM_MULTS-1:0];

    reg [MODEXPNG_MAC_WIDTH-1:0] calc_rcmb_lsb_din;
    
    always @*
        //
        casez (mac_rdy_lsb_dly[MODEXPNG_MAC_LATENCY-1][NUM_MULTS-1:0])
            8'b00000001: calc_rcmb_lsb_din = mac_p[0];
            8'b00000010: calc_rcmb_lsb_din = mac_p[1];
            8'b00000100: calc_rcmb_lsb_din = mac_p[2];
            8'b00001000: calc_rcmb_lsb_din = mac_p[3];
            8'b00010000: calc_rcmb_lsb_din = mac_p[4];
            8'b00100000: calc_rcmb_lsb_din = mac_p[5];
            8'b01000000: calc_rcmb_lsb_din = mac_p[6];
            8'b10000000: calc_rcmb_lsb_din = mac_p[7];
            default:     calc_rcmb_lsb_din = {MODEXPNG_MAC_WIDTH{1'bX}};
        endcase
 
    always @(posedge clk or negedge rst_n)
        //
        if (rst_n == 1'b0)
            rcmb_lsb_ce <= 1'b0;
        else case (fsm_state_dly[MODEXPNG_MAC_LATENCY])
            FSM_STATE_MULT_SQUARE_COL_0_TRIG,
            FSM_STATE_MULT_SQUARE_COL_N_TRIG,
            FSM_STATE_MULT_SQUARE_COL_0_BUSY,
            FSM_STATE_MULT_SQUARE_COL_N_BUSY: rcmb_lsb_ce <= calc_rcmb_lsb_ce;
            default:                          rcmb_lsb_ce <= 1'b0;
        endcase

    always @(posedge clk)
        //
        case (fsm_state_dly[MODEXPNG_MAC_LATENCY])
            FSM_STATE_MULT_SQUARE_COL_0_TRIG: rcmb_lsb_clr <= 1'b1;
            default:                          rcmb_lsb_clr <= 1'b0;
        endcase

    always @(posedge clk)
        //
        case (fsm_state_dly[MODEXPNG_MAC_LATENCY])
            FSM_STATE_MULT_SQUARE_COL_0_TRIG,
            FSM_STATE_MULT_SQUARE_COL_N_TRIG,
            FSM_STATE_MULT_SQUARE_COL_0_BUSY,
            FSM_STATE_MULT_SQUARE_COL_N_BUSY: rcmb_lsb_din <= calc_rcmb_lsb_din;
            default:                          rcmb_lsb_din <= {MODEXPNG_MAC_WIDTH{1'bX}};
        endcase
 
 

*/