OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [rtl/] [src_noc/] [flit_buffer_reg_bas.v] - Rev 56

Compare with Previous | Blame | View Log

/**************************************
* Module: iport_regster_base
* Date:2020-02-21  
* Author: alireza     
*
* Description: 
***************************************/
`timescale 1ns / 1ps
 
module  flit_buffer_reg_base #(
    parameter NOC_ID = 0,
    parameter V        =   4,
    parameter B        =   4,   // buffer space :flit per VC 
    parameter Fpay     =   32,
    parameter PCK_TYPE = "MULTI_FLIT",
    parameter DEBUG_EN =   1,
    parameter C=1,
    parameter DSTPw=4,
    parameter SSA_EN="YES", // "YES" , "NO"  
    parameter CAST_TYPE="UNI_CAST"
 
)(
    din,
    vc_num_wr,
    wr_en,
    vc_num_rd,
    rd_en,
    dout, 
    vc_not_empty,
    reset,
    clk,    
 
    //header flit dat
    class_all
 
);
 
    function integer log2;
      input integer number; begin   
         log2=(number <=1) ? 1: 0;    
         while(2**log2<number) begin    
            log2=log2+1;    
         end       
      end   
    endfunction // log2 
 
    localparam
        Cw = (C>1)? log2(C): 1,
        Vw         =   log2(V),
        REGFw      =   2+Fpay,   //Fpay + headr flags
        Fw =2+V+Fpay,
        VFw        =   V * Fw,
        VCw        =   V * Cw,
        VDSTPw     =   V * DSTPw;
 
    input  [Fw-1      :0]   din;     // Data in    
    input  [V-1       :0]   vc_num_wr;//write vertual chanel   
    input                   wr_en;   // Write enable
 
 
    input  [V-1       :0]   vc_num_rd;//read vertual chanel    
    input                   rd_en;   // Read the next word
 
 
    output [Fw-1       :0]  dout;    // Data out
    output [V-1        :0]  vc_not_empty;
    input                   reset;
    input                   clk;
 
    output [VCw-1 : 0] class_all;
   // output [VDSTPw-1 :0 ] dest_port_encoded_all;
   // input  [V-1        :0]  ssa_rd;
 
    wire [Fw-1       :0]  dout_all [V-1 : 0];    // Data out
    wire [VCw-1 : 0] class_vc [V-1 : 0];
    reg  [VCw-1 : 0] class_vc_next [V-1 : 0];  
    wire [REGFw-1 : 0] flit_regs [V-1 : 0];   // a register array save the head of each quque
    reg  [REGFw-1 : 0] flit_regs_next [V-1 : 0];
    reg [V-1 : 0] valid,valid_next; // if valid is asseted it shows the VC queue has a flit waiting to be sent 
 
    wire [Fw-1 : 0] bram_dout;
    wire [V-1 : 0] bram_not_empty;
    wire bram_wr_en;
    wire [V-1 : 0] vc_num_wr_en,vc_num_rd_en;  
 
    wire[REGFw-1 : 0] flit_reg_mux_out;
    wire flit_reg_mux_sel;
    reg flit_reg_mux_sel_delay;
    wire [V-1 : 0] flit_reg_wr_en,pass_din_to_flit_reg,bram_empty;
    wire [V-1 : 0]  bram_out_is_valid; 
    wire bram_rd_en = |(vc_num_rd_en & bram_not_empty);
 
    //header flit info 
    wire [Cw-1:0] class_i;
    wire [DSTPw-1 : 0] destport_i;
 
    wire [Vw-1: 0] vc_num_rd_bin;
    reg [Vw-1 : 0] vc_num_rd_bin_delaied;
    reg [V-1 : 0]  bram_out_is_valid_delaied,pass_din_to_flit_reg_delaied;
 
    reg  [Fw-1      :0]   din_reg;
 
    assign bram_empty = ~bram_not_empty;
    assign vc_num_wr_en = (wr_en)?    vc_num_wr : {V{1'b0}};  
    assign vc_num_rd_en = (rd_en)?    vc_num_rd : {V{1'b0}};   
 
    assign pass_din_to_flit_reg = (vc_num_wr_en & ~valid)| // a write has been recived while the reg_flit is not valid
                            (vc_num_wr_en & valid & bram_empty & vc_num_rd_en); //or its valid but bram is empty and its got a read request
 
 
    assign flit_reg_mux_sel = | pass_din_to_flit_reg ;// 1 :din, 0: bram
    //2-1 mux. Select between the bram and input flit. 
    assign flit_reg_mux_out = (flit_reg_mux_sel_delay)?   {din[Fw-1:Fw-2],din_reg[Fpay-1:0]} : {bram_dout[Fw-1:Fw-2],bram_dout[Fpay-1:0]};
    assign bram_wr_en =  (flit_reg_mux_sel)?  1'b0 :wr_en ; //make sure not write on the Bram if the reg fifo is empty 
 
    assign  flit_reg_wr_en = pass_din_to_flit_reg | bram_out_is_valid;    
 
    assign  bram_out_is_valid = (bram_rd_en )? (vc_num_rd &  bram_not_empty): {V{1'b0}};
 
 
 
 
    one_hot_to_bin #(
    	.ONE_HOT_WIDTH(V),
    	.BIN_WIDTH(Vw)
    )
    conv
    (
    	.one_hot_code(vc_num_rd),
    	.bin_code(vc_num_rd_bin)
    );
 
    always @(posedge clk) vc_num_rd_bin_delaied<=vc_num_rd_bin;
    always @(posedge clk) pass_din_to_flit_reg_delaied<=pass_din_to_flit_reg;
    assign  dout = dout_all[vc_num_rd_bin_delaied];
 
 
    flit_buffer #(
		.V(V),
        .B(B),
        .SSA_EN("NO"),// should be "NO" even if SSA is enabled
        .Fw(Fw),
		.PCK_TYPE(PCK_TYPE),
		.CAST_TYPE(CAST_TYPE),
		.DEBUG_EN(DEBUG_EN)
    )
    flit_buffer
    (
        .din(din),
        .vc_num_wr(vc_num_wr),
        .wr_en(bram_wr_en),
 
        .vc_num_rd(vc_num_rd),
 
        .rd_en(bram_rd_en),
        .dout(bram_dout),
        .vc_not_empty(bram_not_empty),
        .reset(reset),
        .clk(clk),
        .ssa_rd({V{1'b0}}),
        .multiple_dest(),
        .sub_rd_ptr_ld(),
        .flit_is_tail()
 
 
    );
 
 
    always @(posedge clk) begin
        if(reset)  begin 
		valid<={V{1'b0}};
		bram_out_is_valid_delaied<={V{1'b0}};
	//	din_reg<={Fw{1'b0}};
	end 
        else begin 
	    valid<=valid_next;
		bram_out_is_valid_delaied<=bram_out_is_valid; 
		din_reg<=din;
		flit_reg_mux_sel_delay<=flit_reg_mux_sel;
 
	end
    end
    assign vc_not_empty = valid;
 
 
     extract_header_flit_info #(
        .NOC_ID(NOC_ID),
        .DATA_w(0)
     ) header_extractor (
         .flit_in({flit_reg_mux_out[REGFw-1:REGFw-2],flit_reg_wr_en,flit_reg_mux_out[Fpay-1 : 0]}),
         .flit_in_wr(),         
         .class_o(class_i),
         .destport_o(destport_i),
         .dest_e_addr_o( ),
         .src_e_addr_o( ),
         .vc_num_o(),
         .hdr_flit_wr_o(),
         .hdr_flg_o(),
         .tail_flg_o( ),
         .weight_o( ),
         .be_o( ),
         .data_o( )
     );    
 
 
    genvar i;
    generate
    for (i = 0; i < V; i = i + 1) begin : Vblock
       // assign  dout_all[(i+1)*Fw-1 : i*Fw] = {flit_regs [i][REGFw-1: REGFw-2],i[V-1:0] ,flit_regs[i][Fpay-1:0]};
        assign  dout_all[i] = {flit_regs [i][REGFw-1: REGFw-2],i[V-1:0] ,flit_regs[i][Fpay-1:0]};
        assign  class_all[(i+1)*Cw-1 : i*Cw] = class_vc[i];
 
 
      pronoc_register #(
           .W(REGFw)          
      ) reg1 ( 
           .in(flit_regs_next[i]),
           .reset(reset),    
           .clk(clk),      
           .out(flit_regs[i])
      );
 
 
       pronoc_register #(
           .W(Cw)           
      ) reg2 ( 
           .in(class_vc_next[i]),
           .reset(reset),    
           .clk(clk),      
           .out(class_vc[i])
      );
 
 
 
        always @ (*)begin 
            flit_regs_next[i] = flit_regs[i];
            class_vc_next[i]  = class_vc[i];
            if(pass_din_to_flit_reg_delaied[i]) flit_regs_next[i] = {din[Fw-1:Fw-2],din_reg[Fpay-1:0]} ;
            if(bram_out_is_valid_delaied[i])    flit_regs_next[i] = {bram_dout[Fw-1:Fw-2],bram_dout[Fpay-1:0]};
            if(flit_reg_wr_en[i] & flit_reg_mux_out[REGFw-1] ) class_vc_next[i] = class_i;// writing header flit 
        end 
 
 
 
        /* verilator lint_off WIDTH */
         /*
        if( ROUTE_TYPE=="DETERMINISTIC") begin : dtrmn_dest
        always @ (`pronoc_clk_reset_edge )begin 
               if(`pronoc_reset)begin  
 
                end else begin 
                    dest_port_encoded_vc[i]<= destport_in_encoded;  
                end
            end//always
       end  else begin : adptv_dest   
 
 
        */
 
 
 
 
        always @(*) begin
                valid_next[i] = valid[i];
                if(flit_reg_wr_en[i]) valid_next[i] =1'b1;
                else if( bram_empty[i] & vc_num_rd_en[i]) valid_next[i] =1'b0;
         end
 
    end //for  
 
     /* verilator lint_off WIDTH */  
  //  if(TOPOLOGY=="FATTREE" && ROUTE_NAME == "NCA_STRAIGHT_UP") begin : fat
    /* verilator lint_on WIDTH */  
 /*    
     fattree_destport_up_select #(
         .K(T1),
         .SW_LOC(SW_LOC)
     )
     static_sel
     (
        .destport_in(destport_in),
        .destport_o(destport_in_encoded)
     );
 
    end else begin : other
        assign destport_in_encoded = destport_in;    
    end
 
  */  
    endgenerate
 
 
 
    // Update header flit info registers
 
 
 
 
 
 
 
 
 
endmodule
 
 
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.