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/] [header_flit.sv] - Rev 56

Compare with Previous | Blame | View Log

`include "pronoc_def.v"
/**********************************************************************
**  File:  header_flit.sv
**  Date:2017-07-11   
**    
**  Copyright (C) 2014-2017  Alireza Monemi
**    
**  This file is part of ProNoC 
**
**  ProNoC ( stands for Prototype Network-on-chip)  is free software: 
**  you can redistribute it and/or modify it under the terms of the GNU
**  Lesser General Public License as published by the Free Software Foundation,
**  either version 2 of the License, or (at your option) any later version.
**
**  ProNoC is distributed in the hope that it will be useful, but WITHOUT
**  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
**  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
**  Public License for more details.
**
**  You should have received a copy of the GNU Lesser General Public
**  License along with ProNoC. If not, see <http:**www.gnu.org/licenses/>.
**
**
**  Description: 
**  This file contains modules related to header flit 
******************************************************************/

/***************
*   header_flit_generator
***************/

module header_flit_generator #(
    parameter NOC_ID=0,
    parameter DATA_w=9 // header flit can carry Optional data. The data will be placed after control data.  Fpay >= DATA_w + CTRL_BITS_w  
)(    
    flit_out,    
    src_e_addr_in,
    dest_e_addr_in,
    destport_in,
    class_in,
    weight_in, 
    vc_num_in,
    be_in,
    data_in    
);      
    
        `NOC_CONF   
 
    localparam    HDR_FLAG  =   2'b10;        

    localparam 
        Dw = (DATA_w==0)? 1 : DATA_w,      
        DATA_LSB= MSB_BE+1,               DATA_MSB= (DATA_LSB + DATA_w)<FPAYw ? DATA_LSB + Dw-1 : FPAYw-1;
        
    output   [Fw-1  :   0] flit_out; 
    input    [Cw-1  :   0] class_in;    
    input    [DAw-1 :   0] dest_e_addr_in;
    input    [EAw-1 :   0] src_e_addr_in;
    input    [V-1   :   0] vc_num_in;
    input    [WEIGHTw-1 :   0] weight_in;
    input    [DSTPw-1   :   0] destport_in;
    input    [BEw-1 : 0] be_in;
    input    [Dw-1  :   0] data_in;
 
   // assign flit_out [W+Cw+P_1+Xw+Yw+Xw+Yw-1 :0] = {weight_i,class_i,destport_i,x_dst_i,y_dst_i,x_src_i,y_src_i};
    assign flit_out [E_SRC_MSB : E_SRC_LSB] = src_e_addr_in;
    assign flit_out [E_DST_MSB : E_DST_LSB] = dest_e_addr_in;
    assign flit_out [DST_P_MSB : DST_P_LSB] = destport_in; 
    
   
    generate
    if(C>1)begin :have_class 
        assign flit_out [CLASS_MSB :CLASS_LSB] = class_in; 
    end 

    /* verilator lint_off WIDTH */
    if(SWA_ARBITER_TYPE != "RRA")begin  : wrra_b
    /* verilator lint_on WIDTH */
        assign flit_out [WEIGHT_MSB :WEIGHT_LSB] = weight_in;   
    end 
    
    if( BYTE_EN ) begin : be_1
        assign flit_out [BE_MSB : BE_LSB] = be_in;    
    end
    
    
    if (DATA_w ==0) begin :no_data
        if(FPAYw>DATA_LSB) begin: dontcare
                 assign flit_out [FPAYw-1 : DATA_LSB] = {(FPAYw-DATA_LSB){1'bX}};        
        end
    end else begin :have_data
                 assign flit_out [DATA_MSB : DATA_LSB] = data_in[DATA_MSB-DATA_LSB : 0]; // we have enough space for adding whole of the data                 
    end    
    endgenerate    
     
    assign flit_out [FPAYw+V-1    :   FPAYw] = vc_num_in;
    assign flit_out [Fw-1        :    Fw-2] = HDR_FLAG;  
    
    
    //synthesis translate_off 
    //synopsys  translate_off
    initial begin
        if((DATA_LSB + DATA_w)-1 > FPAYw)begin
            $display("%t: ERROR: The reqired header flit size is %d which is larger than %d payload size   ",$time,(DATA_LSB + DATA_w)-1,FPAYw);
            $finish;        
        end
    end    
    //synopsys  translate_on
    //synthesis translate_on     

endmodule


module extract_header_flit_info # (
    parameter NOC_ID=0,
    parameter DATA_w = 0
) (
    //inputs
    flit_in,
    flit_in_wr,
    //outputs
    src_e_addr_o,
    dest_e_addr_o,
    destport_o,
    class_o,
    weight_o, 
    data_o,   
    tail_flg_o,
    hdr_flg_o,   
    vc_num_o,  
    hdr_flit_wr_o,
    be_o    
);      
    
        `NOC_CONF
       
    localparam       
        W = WEIGHTw,
        Dw = (DATA_w==0)? 1 : DATA_w,
        DATA_LSB= MSB_BE+1,               DATA_MSB= (DATA_LSB + DATA_w)<FPAYw ? DATA_LSB + Dw-1 : FPAYw-1,
        OFFSETw = DATA_MSB - DATA_LSB +1; 
     
    
    input [Fw-1 : 0] flit_in;
    input flit_in_wr;
    
    output [EAw-1 : 0] src_e_addr_o;
    output [DAw-1 : 0] dest_e_addr_o;
    output [DSTPw-1 : 0] destport_o;    
    output [Cw-1 : 0] class_o;
    output [W-1  : 0] weight_o;
    output tail_flg_o;
    output hdr_flg_o;    
    output [V-1 : 0] vc_num_o;
    output [V-1 : 0] hdr_flit_wr_o;
    output [BEw-1 : 0] be_o;
    output [Dw-1  :   0] data_o;
    
    
   
   
   
    wire [OFFSETw-1 : 0 ] offset;
  
    assign src_e_addr_o = flit_in [E_SRC_MSB : E_SRC_LSB];
    assign dest_e_addr_o = flit_in [E_DST_MSB : E_DST_LSB];
    assign destport_o = flit_in [DST_P_MSB : DST_P_LSB];
    
   
    generate
    if(C>1)begin :have_class 
        assign class_o = flit_in [CLASS_MSB : CLASS_LSB];
    end else begin : no_class
     assign class_o = {Cw{1'b0}};
    end   

    /* verilator lint_off WIDTH */
    if(SWA_ARBITER_TYPE != "RRA")begin  : wrra_b
    /* verilator lint_on WIDTH */
        assign weight_o =  flit_in [WEIGHT_MSB : WEIGHT_LSB];    
    end else begin : rra_b
        assign weight_o = {WEIGHTw{1'bX}};        
    end 
    
    if( BYTE_EN ) begin : be_1
        assign be_o = flit_in [BE_MSB : BE_LSB];    
    end else begin : be_0    
        assign be_o = {BEw{1'bX}};
    end
    
    
    assign offset = flit_in [DATA_MSB : DATA_LSB];    
    
    
    if(Dw > OFFSETw) begin : if1     
        assign data_o={{(Dw-OFFSETw){1'b0}},offset};
    end else begin : if2 
        assign data_o=offset[Dw-1 : 0];
    end    
    
    endgenerate          
   
   /* verilator lint_off WIDTH */     
    assign hdr_flg_o  = (PCK_TYPE == "MULTI_FLIT") ? flit_in [Fw-1]  : 1'b1;
    assign tail_flg_o = (PCK_TYPE == "MULTI_FLIT") ? flit_in [Fw-2]  : 1'b1;
   /* verilator lint_on WIDTH */    
   
   
    assign vc_num_o = flit_in [FPAYw+V-1 : FPAYw];
    assign hdr_flit_wr_o= (flit_in_wr & hdr_flg_o )? vc_num_o : {V{1'b0}};

endmodule






/***********************************    
*  flit_update
*  update the header flit look ahead routing and output VC
**********************************/

module header_flit_update_lk_route_ovc #(
    parameter NOC_ID=0,
    parameter P = 5
)
(
    flit_in ,
    flit_out,
    vc_num_in,
    lk_dest_all_in,
    assigned_ovc_num,
    any_ivc_sw_request_granted,
    lk_dest_not_registered,
    sel,
    reset,
    clk
);

        `NOC_CONF
        
    localparam  
        VDSTPw = V * DSTPw,
        VV = V * V;        

    input [Fw-1 : 0]  flit_in;
    output reg [Fw-1 : 0]  flit_out;
    input [V-1 : 0]  vc_num_in;
    input [VDSTPw-1 : 0]  lk_dest_all_in;
    input                           reset,clk;
    input [VV-1 : 0]  assigned_ovc_num;
    input [V-1 : 0]  sel;
    input                    any_ivc_sw_request_granted;
    input [DSTPw-1 : 0]  lk_dest_not_registered;
    
    wire hdr_flag;
    logic [V-1 : 0]  vc_num_delayed;
    wire [V-1 : 0]  ovc_num; 
    wire [DSTPw-1 : 0]  lk_dest,dest_coded;
    wire [DSTPw-1 : 0]  lk_mux_out;

    pronoc_register #(.W(V)) reg1 (.in(vc_num_in), .out(vc_num_delayed), .reset(reset), .clk(clk));   

    /* verilator lint_off WIDTH */
    assign hdr_flag = ( PCK_TYPE == "MULTI_FLIT")? flit_in[Fw-1]: 1'b1;
    /* verilator lint_on WIDTH */
      
    onehot_mux_1D #(
        .W(DSTPw),
        .N(V) 
    )
    lkdest_mux
    (
        .in(lk_dest_all_in),
        .out(lk_mux_out),
        .sel(vc_num_delayed)
    );

    generate 
    /* verilator lint_off WIDTH */
    if( SSA_EN == "YES" ) begin : predict // bypass the lk fifo when no ivc is granted
    /* verilator lint_on WIDTH */
        logic ivc_any_delayed;
        
        pronoc_register #(.W(1)) reg2 (.in(any_ivc_sw_request_granted ), .out(ivc_any_delayed), .reset(reset), .clk(clk));
       
        assign lk_dest = (ivc_any_delayed == 1'b0)? lk_dest_not_registered : lk_mux_out;

    end else begin : no_predict
        assign lk_dest =lk_mux_out;
    end 
    endgenerate

   onehot_mux_1D #(
        .W(V),
        .N(V) 
    )
    ovc_num_mux
    (
        .in(assigned_ovc_num),
        .out(ovc_num),
        .sel(vc_num_delayed)
    );
       
    generate 
    /* verilator lint_off WIDTH */ 
    if((TOPOLOGY == "MESH" || TOPOLOGY == "FMESH" || TOPOLOGY == "TORUS"  || TOPOLOGY ==  "RING") && ROUTE_TYPE != "DETERMINISTIC" )begin :coded
    /* verilator lint_on WIDTH */ 
        mesh_torus_adaptive_lk_dest_encoder #(
            .V(V),
            .P(P),
            .DSTPw(DSTPw),
            .Fw(Fw),
            .DST_P_MSB(DST_P_MSB),
            .DST_P_LSB(DST_P_LSB)
        )
        dest_encoder
        (
            .sel(sel),
            .dest_coded_out(dest_coded),
            .vc_num_delayed(vc_num_delayed),
            .lk_dest(lk_dest),
            .flit_in(flit_in)
        );
    
    
    end else begin : dtrmn1
        assign dest_coded = lk_dest;
        /*
         mesh_torus_dtrmn_dest_encoder #(
            .P(P),
            .DSTPw(DSTPw),
            .Fw(Fw),
            .DST_P_MSB(DST_P_MSB),
            .DST_P_LSB(DST_P_LSB)
        )
         dest_encoder
        (
                .dest_coded_out(dest_coded),
                .lk_dest(lk_dest),
                .flit_in(flit_in)
         );
         */
    end
        
    always @(*)begin 
         flit_out = {flit_in[Fw-1 : Fw-2],ovc_num,flit_in[FPAYw-1 :0]};
         if(hdr_flag) flit_out[DST_P_MSB : DST_P_LSB]= dest_coded;
    end
      
    
    endgenerate


    

endmodule

/******************
 *  hdr_flit_weight_update
 * ****************/

module hdr_flit_weight_update #(
    parameter NOC_ID = 0
) (
    new_weight,
    flit_in,
    flit_out    
);

        `NOC_CONF
    
    input [WEIGHTw-1 : 0] new_weight;
    input [Fw-1 : 0] flit_in;
    output [Fw-1 : 0] flit_out;
    
    assign flit_out =  {flit_in[Fw-1 : WEIGHT_LSB+WEIGHTw ] ,new_weight, flit_in[WEIGHT_LSB-1 : 0] };

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.