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

Compare with Previous | Blame | View Log

`include "pronoc_def.v"
    
    
/****************************************************************************
 * router_top.v
 ****************************************************************************/
  
/**
 * Module: router_top
 * 
 *  add optional bypass links to two stage router.
 */
module router_top #(
        parameter NOC_ID=0,
        parameter P=5
)(
        current_r_id,
        current_r_addr,
                                        
        chan_in,
        chan_out,
        
        router_event,
                                        
        clk,
        reset                                           
);

        `NOC_CONF    
        
        
        localparam DISABLED =P;

        input [RAw-1 :  0]  current_r_addr;
        input [31 : 0] current_r_id;
        
        
        input   smartflit_chanel_t chan_in [P-1 : 0];
        output  smartflit_chanel_t chan_out [P-1 : 0];
        
        output router_event_t router_event [P-1 : 0];
        
        
        
        input   clk,reset;      
        
        genvar i,j;
        
  
        //synthesis translate_off 
        //synopsys  translate_off
        /* verilator lint_off WIDTH */
        initial begin
                if((SSA_EN=="YES")  &&(SMART_EN==1'b1))begin
                        $display("ERROR: Only one of the SMART or SAA can be enabled at the same time");
                        $finish;        
                end
                if((SMART_EN==1'b1) && COMBINATION_TYPE!="COMB_NONSPEC")begin
                        $display("ERROR: SMART only works with non-speculative VSA");
                        $finish;        
                end     
                if((MIN_PCK_SIZE > 1) &&(PCK_TYPE == "SINGLE_FLIT")) begin 
                        $display("ERROR: The minimum packet size must be set as one for single-flit packet type NoC");
                        $finish;        
                end
                if(((SSA_EN=="YES")  ||(SMART_EN==1'b1)) && CAST_TYPE!="UNICAST") begin
                        $display("ERROR: SMART or SAA do not support muticast/braodcast packets");
                        $finish;        
                end
                
        end     
        /* verilator lint_on WIDTH */
        
        
        
        
        
        logic report_active_ivcs = 0;
        
        generate 
        for(i=0; i<P; i=i+1) begin :P1_
                for(j=0; j<V; j=j+1) begin :V_          
                        always @(posedge report_active_ivcs) begin 
                                if(ivc_info[i][j].ivc_req) $display("%t : The IVC in router[%h] port[%d] VC [%d] is not empty",$time,current_r_addr,i,j);
                        end
                end             
        end
        endgenerate
                
        //synopsys  translate_on
        //synthesis translate_on 
        
        
        
        generate 
        for(i=0; i<P; i=i+1) begin :P2_
                assign router_event[i].flit_wr_i = chan_in[i].flit_chanel.flit_wr;
                assign router_event[i].bypassed_num = chan_in[i].smart_chanel.bypassed_num;
                assign router_event[i].pck_wr_i  = chan_in[i].flit_chanel.flit_wr & chan_in[i].flit_chanel.flit.hdr_flag;
                assign router_event[i].flit_wr_o = chan_out[i].flit_chanel.flit_wr;
                assign router_event[i].pck_wr_o  = chan_out[i].flit_chanel.flit_wr & chan_out[i].flit_chanel.flit.hdr_flag;
                assign router_event[i].flit_in_bypassed = chan_out[i].smart_chanel.flit_in_bypassed;
`ifdef ACTIVE_LOW_RESET_MODE 
        assign router_event[i].active_high_reset = 1'b0;
 `else 
        assign router_event[i].active_high_reset = 1'b1;
`endif                  
        end
        endgenerate
        
        
        flit_chanel_t r2_chan_in  [P-1 : 0];
        flit_chanel_t r2_chan_out [P-1 : 0];
        
        ivc_info_t       ivc_info    [P-1 : 0][V-1 : 0];
        ovc_info_t   ovc_info    [P-1 : 0][V-1 : 0];
        iport_info_t iport_info  [P-1 : 0];
        oport_info_t oport_info  [P-1 : 0]; 
        smart_chanel_t smart_chanel_new  [P-1 : 0];
        smart_chanel_t smart_chanel_in   [P-1 : 0];
        smart_chanel_t smart_chanel_out  [P-1 : 0]; 
        smart_ctrl_t   smart_ctrl        [P-1 : 0];
        

        ctrl_chanel_t ctrl_in  [P-1 : 0];
        ctrl_chanel_t ctrl_out [P-1 : 0];
        
        generate 
                for(i=0; i<P; i=i+1) begin :Pt_         
                        assign  ctrl_in [i] = chan_in[i].ctrl_chanel;
                        assign  chan_out[i].ctrl_chanel= ctrl_out [i];  
                        
                end
        endgenerate 
        
        // synthesis translate_off
        
        //header flit info, it is useful for debugin 
        hdr_flit_t hdr_flit_i [P-1 : 0]; // the received packet header flit info 
        hdr_flit_t hdr_flit_o [P-1 : 0]; // the sent packet header flit info 
                
        generate 
                for(i=0; i<P; i=i+1) begin :Port_                               
                                        
                        header_flit_info #(
                                .NOC_ID(NOC_ID)
                        ) in_extract(
                                .flit(chan_in[i].flit_chanel.flit),
                                .hdr_flit( hdr_flit_i[i]),              
                                .data_o()
                        );
                
                        header_flit_info #(
                                .NOC_ID(NOC_ID)
                        ) out_extract(
                                .flit(chan_out[i].flit_chanel.flit),
                                .hdr_flit( hdr_flit_o[i]),
                                .data_o()
                        );
                        
                        if(DEBUG_EN) begin :dbg
                                check_flit_chanel_type_is_in_order #(
                                        .V(V),
                                        .PCK_TYPE(PCK_TYPE),
                                        .MIN_PCK_SIZE(MIN_PCK_SIZE)
                                ) IVC_flit_type_check(
                                        .clk(clk),
                                        .reset(reset),
                                        .hdr_flg_in(chan_in[i].flit_chanel.flit.hdr_flag),
                                        .tail_flg_in(chan_in[i].flit_chanel.flit.tail_flag),
                                        .flit_in_wr(chan_in[i].flit_chanel.flit_wr),
                                        .vc_num_in(chan_in[i].flit_chanel.flit.vc)
                                );
                                
                                check_pck_size #(
                                        .NOC_ID(NOC_ID),
                                        .V(V),
                                        .MIN_PCK_SIZE(MIN_PCK_SIZE),
                                        .Fw(Fw),
                                        .DAw(DAw),
                                        .CAST_TYPE(CAST_TYPE),
                                        .NE(NE),
                                        .B(B),
                                        .LB(LB)
                                ) check_pck_siz(
                                        .clk(clk),
                                        .reset(reset),
                                        .hdr_flg_in(chan_in[i].flit_chanel.flit.hdr_flag),
                                        .tail_flg_in(chan_in[i].flit_chanel.flit.tail_flag),
                                        .flit_in_wr(chan_in[i].flit_chanel.flit_wr),
                                        .vc_num_in(chan_in[i].flit_chanel.flit.vc),
                                        .dest_e_addr_in(chan_in[i].flit_chanel.flit.payload[E_DST_MSB : E_DST_LSB])
                                );                              
                
                        end             
                
                end
        endgenerate
        // synthesis translate_on
        
        
        
        
        
        wire [V-1 : 0] ovc_locally_requested [P-1 : 0]; 
        flit_chanel_t ss_flit_chanel [P-1 : 0]; //flit  bypass link goes to straight port

        router_two_stage  #(//r2
                        .NOC_ID(NOC_ID),
                        .P(P)
                )router_ref(
                        .ivc_info(ivc_info),
                        .ovc_info(ovc_info),
                        .iport_info(iport_info),
                        .oport_info(oport_info),
                        .smart_ctrl_in(smart_ctrl),
                        .current_r_addr(current_r_addr),
                        .current_r_id(current_r_id),
                        .chan_in(r2_chan_in), 
                        .chan_out(r2_chan_out), 
                        .ctrl_in(ctrl_in),
                        .ctrl_out(ctrl_out),
                        .clk(clk), 
                        .reset(reset)                   
                );                

        generate 
                
                if(SMART_EN) begin :smart
                
                
                        smart_forward_ivc_info  #(
                                .NOC_ID(NOC_ID),
                                .P(P)
                        ) forward_ivc(                  
                                .ivc_info(ivc_info),
                                .iport_info(iport_info),
                                .oport_info(oport_info),
                                .smart_chanel(smart_chanel_new),
                                .ovc_locally_requested(ovc_locally_requested),
                                .reset(reset),
                                .clk(clk)
                        );
                
                        smart_bypass_chanels #(
                                .NOC_ID(NOC_ID),
                                .P(P)
                        ) smart_bypass(                 
                                .ivc_info(ivc_info),
                                .iport_info(iport_info),
                                .oport_info(oport_info),
                                .smart_chanel_new(smart_chanel_new),
                                .smart_chanel_in(smart_chanel_in),
                                .smart_chanel_out(smart_chanel_out),
                                .smart_req(),
                                .reset(reset),
                                .clk(clk)                       
                        );      
                
                        wire  [RAw-1:  0]  neighbors_r_addr [P-1: 0];   
                        wire  [V-1  :  0]  credit_out [P-1 : 0];
                        wire  [V-1  :  0]  ivc_smart_en [P-1 : 0];
                        for(i=0;i<P;i=i+1)begin : Port_
                                localparam SS_PORT = strieght_port(P,i);
                                if(SS_PORT == DISABLED) begin: smart_dis 
                                        assign r2_chan_in[i]   =  chan_in[i].flit_chanel;
                                        assign chan_out[i].flit_chanel     =  r2_chan_out[i];   
                                        assign smart_ctrl[i]={SMART_CTRL_w{1'b0}};                                      
                                end 
                                else begin :smart_en
                                        assign neighbors_r_addr [i] = chan_in[i].ctrl_chanel.neighbors_r_addr;
                                        //smart allocator
                                        smart_allocator_per_iport #(
                                                .NOC_ID(NOC_ID),
                                                .P(P), 
                                                .SW_LOC(i), 
                                                .SS_PORT_LOC(SS_PORT)
                                        ) smart_allocator (
                                                .clk(clk), 
                                                .reset(reset), 
                                                .current_r_addr_i(current_r_addr), 
                                                .neighbors_r_addr_i(neighbors_r_addr), 
                                                .smart_chanel_i(chan_in[i].smart_chanel), 
                                                .flit_chanel_i(chan_in[i].flit_chanel), 
                                                .ivc_info (ivc_info[i]), 
                                                .ss_ovc_info(ovc_info[SS_PORT]),
                                                .ovc_locally_requested(ovc_locally_requested[SS_PORT]),
                                                .ss_smart_chanel_new (smart_chanel_new[SS_PORT]),
                                                .ss_port_link_reg_flit_wr(r2_chan_out[SS_PORT].flit_wr), 
                                                        
                                                .smart_ivc_single_flit_pck_o(smart_ctrl[i].ivc_single_flit_pck),
                                                .smart_destport_o(smart_ctrl[i].destport),      
                                                .smart_lk_destport_o(smart_ctrl[i].lk_destport),        
                                                .smart_hdr_flit_req_o(smart_ctrl[i].hdr_flit_req),
                                                .smart_ivc_smart_en_o(ivc_smart_en[i]),                         
                                                .smart_credit_o(smart_ctrl[i].credit_out),              
                                                .smart_buff_space_decreased_o(smart_ctrl[SS_PORT].buff_space_decreased), 
                                                .smart_ivc_num_getting_ovc_grant_o(smart_ctrl[i].ivc_num_getting_ovc_grant),
                                                .smart_ivc_reset_o(smart_ctrl[i].ivc_reset),
                                                .smart_ivc_granted_ovc_num_o(smart_ctrl[i].ivc_granted_ovc_num),
                                                .smart_ovc_single_flit_pck_o(smart_ctrl[SS_PORT].ovc_single_flit_pck),
                                                .smart_ss_ovc_is_allocated_o(smart_ctrl[SS_PORT].ovc_is_allocated),     
                                                .smart_ss_ovc_is_released_o     (smart_ctrl[SS_PORT].ovc_is_released), 
                                                .smart_mask_available_ss_ovc_o(smart_ctrl[SS_PORT].mask_available_ovc)  
                                        
                                        );
                                    
                                        assign smart_ctrl[i].ivc_smart_en = ivc_smart_en[i];
                                        assign smart_ctrl[i].smart_en = |ivc_smart_en[i];
                                        
                                   
                                
                                
                                        // synthesis translate_off
                                        //assign chan_out[i].smart_chanel =(smart_chanel[i].requests[0]) ? smart_chanel_new[i] : take ss shifted smart; 
                                        smart_chanel_check #(
                                                .NOC_ID(NOC_ID)
                                        ) check(
                                                .flit_chanel(chan_out[i].flit_chanel),
                                                .smart_chanel(chan_out[i].smart_chanel),
                                                .reset(reset),
                                                .clk(clk)               
                                        );
                                        // synthesis translate_on
                                        
                                        assign smart_chanel_in[i] =   chan_in[i].smart_chanel;
                                        
                                
                                        //r2 demux
                                        // flit_in_wr demux 
                                        always @(*) begin 
                                                chan_out[i].smart_chanel = smart_chanel_out[i];
                                                chan_out[i].smart_chanel.flit_in_bypassed =smart_ctrl[i].smart_en & chan_in[i].flit_chanel.flit_wr ;
                                                
                                                
                                                //mask only flit_wr if smart_en is asserted 
                                                r2_chan_in[i]   =  chan_in[i].flit_chanel;
                                                //can replace destport here and remove lk rout from internal router 
                                                if(smart_ctrl[i].smart_en) r2_chan_in[i].flit_wr = 1'b0;
                                                
                                        
                                                //send flit_in to straight out port. Replace lk destport in header flit
                                                ss_flit_chanel[SS_PORT] = chan_in[i].flit_chanel;
                                                if(smart_ctrl[i].hdr_flit_req) ss_flit_chanel[SS_PORT].flit[DST_P_MSB : DST_P_LSB] =  smart_ctrl[i].lk_destport;   
                                        end

                                        always @(*) begin 
                                                // mux out flit channel
                                                chan_out[i].flit_chanel = r2_chan_out[i];
                                                chan_out[i].flit_chanel.credit    =  credit_out[i] ;
                                                if(smart_ctrl[SS_PORT].smart_en) begin
                                                        chan_out[i].flit_chanel.flit    =  ss_flit_chanel[i].flit;
                                                        chan_out[i].flit_chanel.flit_wr =  ss_flit_chanel[i].flit_wr;
                                                
                                                end
                                        end
                                
                                        smart_credit_manage #(
                                                        .V(V), 
                                                        .B(B)
                                                ) smart_credit_manage(
                                                        .credit_in(r2_chan_out[i].credit), 
                                                        .smart_credit_in(smart_ctrl[i].credit_out), 
                                                        .credit_out( credit_out[i]), 
                                                        .reset(reset), 
                                                        .clk(clk));
                                
                                
                                
                                end //for
                        end//smart_en
                
                
                
                end else begin :no_smart
                        for(i=0;i<P;i=i+1)begin : Port_
                                assign r2_chan_in[i]   =  chan_in[i].flit_chanel;
                                assign chan_out[i].flit_chanel     =  r2_chan_out[i];   
                                assign smart_ctrl[i]={SMART_CTRL_w{1'b0}};
                        end//for
                end
        endgenerate     

        
//`ifdef VERILATOR
//      logic  nb_router_active [P-1 : 0] /*verilator public_flat_rd*/ ;
//      logic  router_is_ideal /*verilator public_flat_rd*/ ;
//      logic  not_ideal_next,not_ideal;
//      integer ii,jj;
//      always @(*) begin 
//              router_is_ideal = 1'b1;
//              not_ideal_next  = 1'b0;         
//              for(ii=0; ii<P; ii=ii+1) begin
//                      nb_router_active[ii]= 1'b0;
//                      if(chan_out[ii].flit_chanel.flit_wr) nb_router_active[ii]=1'b1;
//                      if(chan_out[ii].flit_chanel.credit > {V{1'b0}}) nb_router_active[ii]=1'b1;
//                      if(chan_out[ii].smart_chanel.requests > {SMART_NUM{1'b0}}) nb_router_active[ii]=1'b1;
//                      
//                      for(jj=0; jj<V; jj=jj+1) begin          
//                              //no active request is in any input queues
//                              if(ivc_info[ii][jj].ivc_req)begin 
//                                      router_is_ideal=1'b0;
//                                      not_ideal_next=1'b1;
//                              end
//                      end
//                      //no output flit wr 
//                      if(r2_chan_out[ii].flit_wr)  router_is_ideal=1'b0;
//              end
//              if(not_ideal) router_is_ideal =1'b0; // delay one clock cycle if the input req exist in last clock cycle bot not on the current one
//      end
//      pronoc_register #(      .W(1)) no_ideal_register(.in(not_ideal_next), .reset(reset),  .clk(clk), .out(not_ideal));
//`endif
        
        
        
endmodule 



module router_top_v //to be used as top module in veralator
#(
        parameter NOC_ID=0,
        parameter P=5
)(
        current_r_addr,
        current_r_id,
        
        chan_in,
        chan_out,
        
        router_event,
                        
        clk,
        reset
);
  
         
        `NOC_CONF       

        input  [RAw-1 : 0] current_r_addr;
        input [31:0] current_r_id;
    
        input   smartflit_chanel_t chan_in [P-1 : 0];
        output  smartflit_chanel_t chan_out [P-1 : 0];
        input   reset,clk;
        
        output router_event_t router_event [P-1 : 0];
        
        
        router_top #(
                .NOC_ID(NOC_ID),        
                .P(P)           
        ) router (
                .current_r_id(current_r_id),
                .current_r_addr(current_r_addr),
                .chan_in(chan_in),
                .chan_out(chan_out), 
                .router_event(router_event),
                .clk(clk),
                .reset(reset)
        );
        
                
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.