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_peripheral/] [ni/] [ni_master.sv] - Rev 56

Compare with Previous | Blame | View Log

//`define MONITOR_HDR_FLITS 
//`define MONITOR_DAT_FLITS 

/**********************************************************************
**      File:  ni.sv 
**      Date:2017-06-04
**    
**      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: multi-chanel DMA-based network interface for 
**  handling packetizing/depacketizing data to/form NoC. 
**  Can support CRC32 
**      
**
*******************************************************************/

`include "pronoc_def.v"


module  ni_master 
        #(    
    parameter NOC_ID=0,
    parameter MAX_TRANSACTION_WIDTH=10, // Maximum transaction size will be 2 power of MAX_DMA_TRANSACTION_WIDTH words 
    parameter MAX_BURST_SIZE =256, // in words
    parameter CRC_EN= "NO",// "YES","NO" if CRC is enable then the CRC32 of all packet data is calculated and sent via tail flit. 
    parameter HDATA_PRECAPw=0,  
    // The header Data pre capture width. It Will be enabled when it is larger than zero. The header data can optionally carry a short width Data. This data can be pre-captured (completely/partially) 
    // by the NI before saving the packet in a memory buffer. This can give some hints to the software regarding the incoming 
    // packet such as its type, or source port so the software can store the packet in its appropriate buffer.
        
    //wishbone port parameters
    parameter Dw            =   32,
    parameter S_Aw          =   7,
    parameter M_Aw          =   32,
    parameter TAGw          =   3,
    parameter SELw          =   4
)
(
    //general 
    reset,
    clk,  
      
    //noc interface  
    current_r_addr,
    current_e_addr,
    chan_in,
    chan_out,  
     
    //wishbone slave interface signals
    s_dat_i,
    s_sel_i,
    s_addr_i,  
    s_cti_i,
    s_stb_i,
    s_cyc_i,
    s_we_i,    
    s_dat_o,
    s_ack_o,
       
    //wishbone master rd interface signals
    m_send_sel_o,
    m_send_addr_o,
    m_send_cti_o,
    m_send_stb_o,
    m_send_cyc_o,
    m_send_we_o,
    m_send_dat_i,
    m_send_ack_i,
    
    //wishbone master wr interface signals
    m_receive_sel_o,
    m_receive_dat_o,
    m_receive_addr_o,
    m_receive_cti_o,
    m_receive_stb_o,
    m_receive_cyc_o,
    m_receive_we_o,
    m_receive_ack_i,
    
    //interrupt interface
    irq    

);

   `NOC_CONF

   
 
    input reset,clk;   


     // NOC interfaces
    input   [RAw-1   :   0]  current_r_addr;
    input   [EAw-1   :   0]  current_e_addr;
    
    input   smartflit_chanel_t  chan_in;
    output  smartflit_chanel_t  chan_out;    
    
    
   //wishbone slave interface signals
    input   [Dw-1       :   0]      s_dat_i;
    input   [SELw-1     :   0]      s_sel_i;
    input   [S_Aw-1     :   0]      s_addr_i;  
    input   [TAGw-1     :   0]      s_cti_i;
    input                           s_stb_i;
    input                           s_cyc_i;
    input                           s_we_i;
    
    output  reg    [Dw-1       :   0]  s_dat_o;
    output  reg                     s_ack_o;   
    
    //wishbone read master interface signals
    output  [SELw-1          :   0] m_send_sel_o;
    output  [M_Aw-1          :   0] m_send_addr_o;
    output  [TAGw-1          :   0] m_send_cti_o;
    output                          m_send_stb_o;
    output                          m_send_cyc_o;
    output                          m_send_we_o;
    input   [Dw-1           :  0]   m_send_dat_i;
    input                           m_send_ack_i;    
     
     //wishbone write master interface signals
    output  [SELw-1          :   0] m_receive_sel_o;
    output  [Dw-1            :   0] m_receive_dat_o;
    output  [M_Aw-1          :   0] m_receive_addr_o;
    output  [TAGw-1          :   0] m_receive_cti_o;
    output                          m_receive_stb_o;
    output                          m_receive_cyc_o;
    output                          m_receive_we_o;
    input                           m_receive_ack_i;   
    
      //Interrupt  interface
    output                          irq;  
  
    wire                            s_ack_o_next;    
    
    
    
    
    logic  [Fw-1   :   0]  flit_out;     
    logic                  flit_out_wr;   
    logic   [V-1    :   0]  credit_in;
    logic   [Fw-1   :   0]  flit_in; 
    logic                   flit_in_wr;   
    logic  [V-1    :   0]  credit_out;     
    
    
    assign      chan_out.flit_chanel.flit = flit_out; 
    assign  chan_out.flit_chanel.flit_wr = flit_out_wr;
    assign  chan_out.flit_chanel.credit = credit_out;
                
                
    assign flit_in   =  chan_in.flit_chanel.flit;   
    assign flit_in_wr=  chan_in.flit_chanel.flit_wr; 
    assign credit_in =  chan_in.flit_chanel.credit;  
    
    //old ni.v file    
    
    localparam 
        CTRL_FLGw=14,
        CHw=log2(V),
        BURST_SIZE_w= log2(MAX_BURST_SIZE+1),
        STATUS1w=  2 * CHw + 4;
    
/*   Wishbone bus slave address :
 
 VC specific registers       
       address bits       
 [4+Vw:4]      [3:0]                     
                1  :   CTRL_FLAGS    :  {invalid_send_req_err,burst_size_err_isr,send_data_size_err_isr,crc_miss_match_isr,rcive_buff_ovrflw_err_isr,got_packet_isr, packet_is_saved_isr, packet_is_sent_isr,got_any_errorint_en,got_packet_int_en, packet_is_saved_int_en, packet_is_sent_int_en,receive_is_busy, send_is_busy}; 
        
                2  :   SEND_DEST_WB_ADDR        // The destination router address
                3  :   SEND_POINTER_WB_ADDR,    // The address of data to be sent in byte 
 Virtual        4  :   SEND_DATA_SIZE,          // The size of data to be sent in byte  
 chanel        5  :   SEND_HDR_DATA            // The short width data that can be sent by header flit  
 number        
                8  :   RECEIVE_SRC_WB_ADDR       // The source router (the router which is sent this packet).
                9  :   RECEIVE_POINTER_WB_ADDR   // The address pointer of receiver memory in byte
                10 :   RECEIVE_DATA_SIZE_WB_ADDR // The size of received data in byte
                11 :   RECEIVE_MAX_BUFF_SIZ      // The receiver allocated buffer size in words. If the packet size is bigger than the buffer size the rest of it will be discarded
                12 :   RECEIVE_START_INDEX_WB_ADDR  // The received data is written on RECEIVE_POINTER_WB_ADDR + RECEIVE_START_INDEX_WB_ADDR. If the write address reach to the end of buffer pointer, it starts at the RECEIVE_POINTER_WB_ADDR.   
                13 :   RECEIVE_CTRL_WB_ADDR      // The NI receiver control register 
                14 :   RECEIVE_PRECAP_DATA_ADDR  // The port address to the header flit data which can be pre-captured before buffering the actual data. 
 
 Shared registers for all VCs
    address bits       
      [5:0]   
       0:    STATUS_WB_ADDR     // status1:  {send_vc_enable_binary, receive_vc_enable_binary, any_err_isr_en,any_got_packet_isr_en,any_packet_is_saved_isr_en,any_packet_is_sent_isr_en}  
       16:   BURST_SIZE_WB_ADDR  // The burst size in words        
       32: reserved 
      
*/
    localparam 
        chanel_ADDRw= 4,
        chanel_REGw = 4,
        GENRL_ADRw=2;
    
    wire [CHw-1 :   0] vc_addr = s_addr_i [chanel_REGw+CHw-1    :       chanel_REGw];
    wire [GENRL_ADRw-1 :   0] genrl_reg_addr = s_addr_i [chanel_REGw+GENRL_ADRw-1  :   chanel_REGw];
    wire [chanel_ADDRw-1     :   0] vc_s_addr_i = s_addr_i [chanel_ADDRw-1: 0];

//general registers     
    localparam [GENRL_ADRw-1  :   0]
        STATUS1_WB_ADDR  =   0,          // status1 
      //  STATUS2_WB_ADDR  =   1,          // status2 
     //   STATUS3_WB_ADDR  =   3,          // status3
        BURST_SIZE_WB_ADDR = 1;      
    
 //Readonly registers per VC
    localparam [chanel_ADDRw-1  :   0]
        GENERAL_REGS_WB_ADDR=0,
        CTRL_FLAGS_WB_ADDR=1,
        RECEIVE_SRC_WB_ADDR =8,         // The source router (the router which is sent this packet).
        RECEIVE_DATA_SIZE_WB_ADDR = 10,  // The size of received data in byte  
        RECEIVE_PRECAP_DATA_ADDR=14;
  
    
    localparam 
        WORLD_SIZE = Dw/8,
        OFFSETw= log2(WORLD_SIZE),        
        HDw = Fpay - (2*EAw) -  DSTPw - WEIGHTw,
        PRE_Dw = (HDATA_PRECAPw>0)? HDATA_PRECAPw : 1,
        MAX_PCK_SIZE_IN_BYTE = MAX_TRANSACTION_WIDTH + log2(Fpay/8);
      
        
 
    reg [BURST_SIZE_w-1  :   0] burst_size, burst_size_next,burst_counter,burst_counter_next;      
    wire [V-1 :   0] receive_vc_is_busy, send_vc_is_busy;
    wire [V-1 :   0] receive_vc_enable,send_vc_enable,vc_state_reg_enable;
    wire [V-1 :   0] vc_burst_counter_ld, vc_burst_counter_dec;
    wire [V-1 :   0] vc_fifo_wr, vc_fifo_rd;
    wire [V-1 :   0] vc_fifo_full, vc_fifo_nearly_full, vc_fifo_empty;
    wire [V-1 :   0] send_vc_is_active,receive_vc_is_active;
    wire [CHw-1:  0] send_vc_enable_binary,receive_vc_enable_binary;          
    wire  [SELw-1    :   0] vc_m_send_sel_o  [V-1 :   0];
    wire  [M_Aw-1    :   0] vc_m_send_addr_o [V-1 :   0];
    wire  [TAGw-1    :   0] vc_m_send_cti_o  [V-1 :   0];
    wire  [V-1 :   0] vc_m_send_stb_o; 
    wire  [V-1 :   0] vc_m_send_cyc_o; 
    wire  [V-1 :   0] vc_m_send_we_o; 
    wire  [V-1 :   0] save_hdr_info;              
    wire  [SELw-1    :   0] vc_m_receive_sel_o  [V-1 :   0];
    wire  [M_Aw-1    :   0] vc_m_receive_addr_o [V-1 :   0];
    wire  [TAGw-1    :   0] vc_m_receive_cti_o  [V-1 :   0];
    wire  [V-1 :   0] vc_m_receive_stb_o; 
    wire  [V-1 :   0] vc_m_receive_cyc_o; 
    wire  [V-1 :   0] vc_m_receive_we_o; 
    wire  [MAX_PCK_SIZE_IN_BYTE-1    :   0] receive_dat_size_in_byte [V-1 :   0];            
    wire  [V-1    :   0] send_vc_fsm_is_ideal,receive_vc_fsm_is_ideal;
    wire  [Dw-1   :   0] send_vc_pointer_addr [V-1   :  0];
    wire  [Dw-1   :   0] receive_vc_pointer_addr [V-1   :  0];
    wire  [V-1    :   0] receive_vc_got_packet,receive_vc_got_hdr_flit_at_head;    
    wire [MAX_TRANSACTION_WIDTH-1    :   0] send_vc_data_size [V-1   :  0];
    wire [MAX_TRANSACTION_WIDTH-1    :   0] receive_vc_max_buff_siz [V-1   :  0];
    wire [MAX_TRANSACTION_WIDTH-1    :   0] receive_vc_start_index  [V-1   :  0];
    wire [OFFSETw-1 : 0] receive_vc_start_index_offset [V-1   :  0];
    
    
    
    wire [V-1   :  0]   send_vc_start, receive_vc_start; 
    wire  received_flit_is_tail,received_flit_is_hdr;    
    wire [EAw-1  :   0]  vc_dest_e_addr [V-1   :  0];
    wire [Cw-1   :   0]  vc_pck_class [V-1   :  0]; 
    wire [WEIGHTw-1 : 0] vc_weight [V-1:0];  
    wire [BEw-1 : 0 ] vc_be_in  [V-1    :   0];   
    wire [HDw-1 : 0] vc_hdr_data [V-1:0];
    wire [V-1    :   0]  send_vc_send_hdr,send_vc_send_tail;
    wire [V-1    :   0]  send_vc_done,receive_vc_done;    
  
    wire [EAw-1   :   0]  dest_e_addr;
    wire [Cw-1   :   0]  pck_class;
    wire [BEw-1 : 0 ] be_in;
    wire send_hdr, send_tail;
    wire [Fw-1   :   0] hdr_flit_out;         
    wire burst_counter_ld = | vc_burst_counter_ld; 
    wire burst_counter_dec= | vc_burst_counter_dec;
    wire fifo_wr = | vc_fifo_wr; 
    wire fifo_rd = | vc_fifo_rd;
    
    
    
   
    
    wire last_burst = (burst_counter == 1);
    wire burst_is_set =  (burst_size>0);    
    wire [Cw-1   :   0] received_class_next;
    wire [EAw-1   :   0] received_src_e_addr_next;
    wire [BEw-1 : 0 ] received_be_next;
    wire [HDw-1 : 0 ] received_hdr_dat_next;
    wire [Fpay-1    :   0] tail_flit_out;   
    reg [Cw-1  : 0] class_in [V-1    :   0];
    reg [EAw-1 : 0] src_e_addr [V-1    :   0];
    reg [HDw-1 : 0] rsv_hdr_dat [V-1 : 0];
    reg [BEw-1 : 0] receive_vc_be [V-1 : 0];
    wire [CTRL_FLGw-1 : 0] vc_ctrl_flags [V-1 : 0];
    reg [V-1    :   0] crc_miss_match;    
    
    wire [V-1    :   0] burst_size_err,send_data_size_err,rcive_buff_ovrflw_err;
    wire [V-1    :   0] invalid_send_req_err;           
     
    wire [V-1 : 0] vc_irq;
   
  
            
    wire  [STATUS1w-1  :0] status1;
   // wire  [STATUS2w-1  :0] status2; 
  //  wire  [STATUS3w-1  :0] status3;
    
 
    wire [DSTPw-1 : 0] destport;
    wire [WEIGHTw-1 : 0] weight;  
    wire [HDw-1 : 0 ] hdr_data; 
   
    wire [V-1 :0] vc_any_err_isr        ;
    wire [V-1 :0] vc_got_packet_isr     ;
    wire [V-1 :0] vc_packet_is_saved_isr; 
    wire [V-1 :0] vc_packet_is_sent_isr ;   
    wire [PRE_Dw-1 : 0 ] recive_vc_precap_data [V-1 : 0];    
    wire any_err_isr,any_got_packet_isr,any_packet_is_saved_isr,any_packet_is_sent_isr;
    
    assign any_err_isr = |  vc_any_err_isr         ;
    assign any_got_packet_isr = |  vc_got_packet_isr      ;
    assign any_packet_is_saved_isr = |  vc_packet_is_saved_isr;
    assign any_packet_is_sent_isr  = |  vc_packet_is_sent_isr;
  //  assign status1= {vc_got_error_isr, receive_vc_got_packet_isr, receive_vc_packet_is_saved_isr, send_vc_packet_is_sent_isr};    
 //   assign status2= {vc_got_error_int_en, receive_vc_got_packet_int_en, receive_vc_packet_is_saved_int_en, send_vc_packet_is_sent_int_en};
    assign status1= {send_vc_enable_binary, receive_vc_enable_binary, any_err_isr,any_got_packet_isr,any_packet_is_saved_isr,any_packet_is_sent_isr};
      
    
    assign  irq =|vc_irq;
    
    wire [7: 0] temp;
    generate
    if (HDw >= 8) assign temp = rsv_hdr_dat [vc_addr][7:0];
    else assign temp = {{(8-HDw){1'b0}},rsv_hdr_dat [vc_addr]};
    endgenerate
                                
                   
    //read wb registers                
    always @(*)begin 
        s_dat_o ={Dw{1'b0}};
        case(vc_s_addr_i)
        GENERAL_REGS_WB_ADDR:begin // This is a general address. check the general address filed
            case(genrl_reg_addr)
            STATUS1_WB_ADDR: begin 
                s_dat_o = {{(Dw-STATUS1w){1'b0}}, status1};
            end 
            BURST_SIZE_WB_ADDR:begin
                s_dat_o = {{(Dw-BURST_SIZE_w){1'b0}}, burst_size};  
            end 
            default: begin 
                s_dat_o ={Dw{1'b0}};
            end
            endcase
        end//0
                
        CTRL_FLAGS_WB_ADDR: begin 
             s_dat_o[CTRL_FLGw-1     : 0] = vc_ctrl_flags[vc_addr];           
        end  
      
        RECEIVE_SRC_WB_ADDR: begin 
            
            s_dat_o[EAw-1: 0]   =   src_e_addr[vc_addr];   // first&second bytes
            s_dat_o[Cw+15: 16]  =   class_in[vc_addr];  //third byte  
            s_dat_o[31: 24] =       temp;   // 4th byte
        end 
        
        RECEIVE_DATA_SIZE_WB_ADDR: begin        
            s_dat_o   [MAX_PCK_SIZE_IN_BYTE-1    :   0] = receive_dat_size_in_byte[vc_addr];
        end        
        
        RECEIVE_PRECAP_DATA_ADDR: begin 
                s_dat_o[PRE_Dw-1 : 0 ] =  (HDATA_PRECAPw>0)? recive_vc_precap_data[vc_addr][PRE_Dw-1 : 0 ]: {{PRE_Dw{1'b0}}};        
        end
        default: begin 
             s_dat_o ={Dw{1'b0}};
        end       
        endcase      
    end      
     
   
   
    
    //write wb registers
    always @ (*)begin 
        burst_counter_next=burst_counter;
        burst_size_next= burst_size;
        if(burst_counter_ld)    burst_counter_next = burst_size;
        if(burst_counter_dec)   burst_counter_next= burst_counter- 1'b1;
         
        if((s_stb_i  &    s_we_i) && (vc_s_addr_i == GENERAL_REGS_WB_ADDR)) begin // This is a general address. check the general address filed
            case(genrl_reg_addr)
            BURST_SIZE_WB_ADDR: begin 
                if (send_vc_is_busy == {V{1'b0}}) burst_size_next=s_dat_i [BURST_SIZE_w-1 : 0];    
            end //BURST_SIZE_WB_ADDR
                                 
                    default begin

                    end                   
            endcase
        end//  if(s_stb_i  &    s_we_i)   
           
    end 
    
   
    
    
`ifdef SYNC_RESET_MODE 
    always @ (posedge clk )begin 
`else 
    always @ (posedge clk or posedge reset)begin 
`endif 
    
    
   
        if(reset) begin 
            burst_counter <= {BURST_SIZE_w{1'b0}};
            burst_size <= {BURST_SIZE_w{1'b1}};
            s_ack_o <= 1'b0;  
           
           
        end else begin 
            burst_counter<= burst_counter_next; 
            burst_size <= burst_size_next; 
            s_ack_o <= s_ack_o_next;  
            
            
        end 
    end 
    
   
    bin_to_one_hot #(
        .BIN_WIDTH(CHw),
        .ONE_HOT_WIDTH(V)
   )
   convert
   (
        .bin_code(vc_addr),
        .one_hot_code(vc_state_reg_enable)
   );
   
    assign s_ack_o_next    =   s_stb_i & (~s_ack_o);
    
    
    genvar i;
    generate
    
     wire [V-1 : 0 ] precap_hdr_flit_wr;
     wire [HDATA_PRECAPw-1 : 0 ] precap_din;
     wire [V-1 : 0] precap_hdr_flit_rd = (fifo_rd & received_flit_is_hdr) ?  receive_vc_enable : {V{1'b0}};
     wire [HDATA_PRECAPw-1 : 0 ] precap_dout  [V-1 : 0] ;    
     wire [V-1 : 0 ] precap_valid;
    
        
    //capture data before saving the actual flit in memory
    if(HDATA_PRECAPw > 0 ) begin : precap      
      
        wire [EAw-1 : 0] src_endp_addr;
        
        extract_header_flit_info #(
            .NOC_ID(NOC_ID),
            .DATA_w(HDATA_PRECAPw)           
        )
        data_extractor
        (
            .flit_in(flit_in),
            .flit_in_wr(flit_in_wr),
            .src_e_addr_o(src_endp_addr ),
            .dest_e_addr_o( ),
            .destport_o( ),
            .class_o( ),
            .weight_o( ),
            .tail_flg_o( ),
            .hdr_flg_o( ),
            .vc_num_o( ),
            .be_o( ),
            .hdr_flit_wr_o(precap_hdr_flit_wr),
            .data_o(precap_din)
        ); 
        
        
//synthesis translate_off
//synopsys  translate_off    
`ifdef MONITOR_HDR_FLITS 
always @(posedge clk) begin
    
    if(precap_hdr_flit_wr)begin 
        $display("%t: endp %d got a packet with port address %d from endp %d",$time,current_e_addr,precap_din,src_endp_addr);
    end
    
    if(send_hdr & flit_out_wr)begin 
        $display("%t: endp %d sends a packet with port address %d to endp %d",$time,current_e_addr,hdr_data,dest_e_addr);
    end
    
    
end
`endif

`ifdef MONITOR_DAT_FLITS 
    always @(posedge clk) begin
        if(flit_out_wr & ~send_hdr) begin 
            $display("%t: endp %u V %u sends %h",$time,current_e_addr,  flit_out [Fpay+V-1 : Fpay],  flit_out [Fpay-1 : 0 ]);    
        end
    end
`endif

//synopsys  translate_on 
//synthesis translate_on
        
        
        
       for (i=0;i<V; i=i+1) begin : vc__          
          
          fwft_fifo #(
            .DATA_WIDTH(HDATA_PRECAPw),
            .MAX_DEPTH(LB/MIN_PCK_SIZE),//maximum packet number which can be stored in buffer 
            .IGNORE_SAME_LOC_RD_WR_WARNING("YES")
          )
          precap_data_fifo
          (
            .din(precap_din),
            .wr_en(precap_hdr_flit_wr[i]),
            .rd_en(precap_hdr_flit_rd[i]),
            .dout(precap_dout[i]),
            .full( ),
            .nearly_full( ),
            .recieve_more_than_0(precap_valid[i] ),
            .recieve_more_than_1( ),
            .reset(reset),
            .clk(clk)
          );
      
          assign recive_vc_precap_data[i] = precap_dout[i]; 
      
        //synthesis translate_off
        //synopsys  translate_off  
        always @(posedge clk)begin 
             if(s_stb_i  &  ~s_we_i &  (vc_addr==i) & (vc_s_addr_i == RECEIVE_PRECAP_DATA_ADDR) )begin
                    if( precap_valid[i] == 1'b0) $display( "Warning: Reading invalid precap-data %m");    
             end           
        end     
        //synopsys  translate_on   
        //synthesis translate_on 
     
      
        end
           
    end    
    
      
    
    assign chan_out.ctrl_chanel.endp_port =1'b1;
    
    
    
    for (i=0;i<V; i=i+1) begin : vc_    
    
        
                assign chan_out.ctrl_chanel.credit_init_val[i]= LB;
    
       
       
       
        ni_vc_wb_slave_regs #(
            .MAX_TRANSACTION_WIDTH(MAX_TRANSACTION_WIDTH),
            .DEBUG_EN(DEBUG_EN),
            .EAw(EAw),
            .Fpay(Fpay),
            .DSTPw(DSTPw),
            .HDw(HDw),
            .CTRL_FLGw(CTRL_FLGw),
            .C(C),
            .Dw(Dw),
            .S_Aw(chanel_REGw),
            .WEIGHTw(WEIGHTw),
            .BYTE_EN(BYTE_EN)
            
        )        
        wb_slave_registers
        (
//synthesis translate_off
//synopsys  translate_off    
            .current_e_addr(current_e_addr),
//synopsys  translate_on   
//synthesis translate_on
            .clk(clk),
            .reset(reset),
            .state_reg_enable(vc_state_reg_enable[i]),
            .send_fsm_is_ideal(send_vc_fsm_is_ideal[i]),
            .receive_fsm_is_ideal(receive_vc_fsm_is_ideal[i]),
            .send_pointer_addr(send_vc_pointer_addr[i]),
            .be_in(vc_be_in[i]),
            .receive_pointer_addr(receive_vc_pointer_addr[i]),
            .receive_start_index(receive_vc_start_index[i]),
            .receive_start_index_offset(receive_vc_start_index_offset[i]),
            .receive_done(receive_vc_done[i]),
            .send_done(send_vc_done[i]),
           
            .send_data_size(send_vc_data_size[i]),
            .receive_max_buff_siz(receive_vc_max_buff_siz[i]),
            .dest_e_addr(vc_dest_e_addr[i]),
            .pck_class(vc_pck_class[i]),
            .weight(vc_weight[i]), 
            .hdr_data(vc_hdr_data[i]),
            .send_start(send_vc_start[i]),
            .receive_start(receive_vc_start[i]),
            .receive_vc_got_packet(receive_vc_got_packet[i]),
                   
                .burst_size_err(burst_size_err[i]),
            .send_data_size_err(send_data_size_err[i]),
            .rcive_buff_ovrflw_err(rcive_buff_ovrflw_err[i]),
                .crc_miss_match_err( crc_miss_match[i]),
                .invalid_send_req_err(invalid_send_req_err[i]),  
                
                .receive_vc_got_hdr_flit_at_head(receive_vc_got_hdr_flit_at_head[i]),
                .receive_is_busy(receive_vc_is_busy[i]),
                .send_is_busy(send_vc_is_busy[i]),              
                .ctrl_flags(vc_ctrl_flags[i]),
                                                                 
                .any_err_isr          (vc_any_err_isr        [i]),
                .got_packet_isr       (vc_got_packet_isr     [i]),
                .packet_is_saved_isr  (vc_packet_is_saved_isr[i]),
                .packet_is_sent_isr   (vc_packet_is_sent_isr [i]),
                
                
                .irq(vc_irq[i]),
                
                .s_dat_i(s_dat_i),
            .s_addr_i(s_addr_i[chanel_REGw-1:0]),
            .s_stb_i(s_stb_i),
            .s_cyc_i(s_cyc_i),
            .s_we_i(s_we_i)
        );   
    
    
        ni_vc_dma #(
            .CRC_EN(CRC_EN),
            .MAX_TRANSACTION_WIDTH(MAX_TRANSACTION_WIDTH),
            .Dw(Dw),
            .M_Aw(M_Aw),
            .TAGw(TAGw),
            .SELw(SELw),
            .Fpay(Fpay),
            .BYTE_EN(BYTE_EN)
        )
        vc_dma
        (
            .reset(reset),
            .clk(clk),
            .status(),            
            //active-enable signals
            .send_enable(send_vc_enable[i]),
            .receive_enable(receive_vc_enable[i]),
            .send_is_busy(send_vc_is_busy[i]),
            .receive_is_busy(receive_vc_is_busy[i]),
            .send_is_active(send_vc_is_active[i]),
            .receive_is_active(receive_vc_is_active[i]),
            .burst_counter_ld(vc_burst_counter_ld[i]),
            .burst_counter_dec(vc_burst_counter_dec[i]),
            .burst_size_is_set(burst_is_set),           
            .last_burst(last_burst),
            .send_hdr(send_vc_send_hdr[i]),
            .send_tail(send_vc_send_tail[i]),
            .receive_dat_size_in_byte(receive_dat_size_in_byte[i]),
            .receive_be(receive_vc_be[i]),
            .save_hdr_info(save_hdr_info[i]),
            .send_done(send_vc_done[i]),
            .receive_done(receive_vc_done[i]),                       
            .send_fsm_is_ideal(send_vc_fsm_is_ideal[i]),
            .receive_fsm_is_ideal(receive_vc_fsm_is_ideal[i]),
            .send_pointer_addr(send_vc_pointer_addr[i]),           
            .receive_pointer_addr(receive_vc_pointer_addr[i]),
            .receive_start_index(receive_vc_start_index[i]),
            .receive_start_index_offset(receive_vc_start_index_offset[i]),
            .send_data_size(send_vc_data_size[i]),
            .receive_max_buff_siz(receive_vc_max_buff_siz[i]),
            .send_start(send_vc_start[i]),
            .receive_start(receive_vc_start[i]),
            .received_flit_is_tail(received_flit_is_tail),
            //fifo
            .send_fifo_wr(vc_fifo_wr[i]), 
            .send_fifo_full(vc_fifo_full[i]),
            .send_fifo_nearly_full(vc_fifo_nearly_full[i]),
            .send_fifo_rd(credit_in[i]),
            .receive_fifo_empty(vc_fifo_empty[i]),
            .receive_fifo_rd(vc_fifo_rd[i]),          
         
            //errors
            .burst_size_err(burst_size_err[i]),
            .send_data_size_err(send_data_size_err[i]),
            .rcive_buff_ovrflw_err(rcive_buff_ovrflw_err[i]),
            .invalid_send_req_err(invalid_send_req_err[i]),                         
            //
            .m_send_sel_o(vc_m_send_sel_o[i]),
            .m_send_addr_o(vc_m_send_addr_o[i]),
            .m_send_cti_o(vc_m_send_cti_o[i]),
            .m_send_stb_o(vc_m_send_stb_o[i]),
            .m_send_cyc_o(vc_m_send_cyc_o[i]),
            .m_send_we_o(vc_m_send_we_o[i]),
        //  .m_send_dat_i(m_send_dat_i),
            .m_send_ack_i(m_send_ack_i),           
            
            .m_receive_sel_o(vc_m_receive_sel_o[i]),
        //  .m_receive_dat_o(vc_m_receive_dat_o[i]),
            .m_receive_addr_o(vc_m_receive_addr_o[i]),
            .m_receive_cti_o(vc_m_receive_cti_o[i]),
            .m_receive_stb_o(vc_m_receive_stb_o[i]),
            .m_receive_cyc_o(vc_m_receive_cyc_o[i]),
            .m_receive_we_o(vc_m_receive_we_o[i]),
            .m_receive_ack_i(m_receive_ack_i)
        );
     
`ifdef SYNC_RESET_MODE 
    always @ (posedge clk )begin 
`else 
    always @ (posedge clk or posedge reset)begin 
`endif         
             
            if(reset) begin 
                class_in[i]<= {Cw{1'b0}};
                src_e_addr[i]<= {EAw{1'b0}};
                rsv_hdr_dat[i]<={HDw{1'b0}};
                receive_vc_be[i] <= {BEw{1'b0}};
            end else if(save_hdr_info[i])begin 
                class_in[i]<= received_class_next;
                src_e_addr[i]<= received_src_e_addr_next;
                rsv_hdr_dat[i]<=received_hdr_dat_next;
                receive_vc_be[i]<= received_be_next;
            end
        end//always
   
    end  // for loop vc_
    
/* verilator lint_off WIDTH */ 
    if(  CRC_EN == "YES") begin :crc_blk
/* verilator lint_on WIDTH */
   
      reg fifo_rd_delayed;
`ifdef SYNC_RESET_MODE 
    always @ (posedge clk )begin 
`else 
    always @ (posedge clk or posedge reset)begin 
`endif   
        if(reset) fifo_rd_delayed <=1'b0;
        else fifo_rd_delayed <= fifo_rd;
      end
  
      wire send_crc_enable =  flit_out_wr & ~send_hdr &   ~send_tail;
      wire receive_crc_enable =  fifo_rd_delayed & ~ received_flit_is_tail & ~received_flit_is_hdr;
      wire [31:0]  send_crc_out,receive_crc_out;
                                        
        crc_32_multi_chanel #(
            .chanel(V)
        )
        send_crc
        (
            .reset(reset),
            .clk(clk),
            .crc_reset(send_hdr),
            .crc_enable(send_crc_enable),
            .chanel_in(send_vc_enable_binary),
            .data_in(m_send_dat_i [Fpay-1 : 0]),
            .crc_out(send_crc_out)
        );        
        
        crc_32_multi_chanel #(
                .chanel(V)
        )
         receive_crc
         (
                .reset(reset),
                .clk(clk),
                .crc_reset(received_flit_is_hdr),
                .crc_enable(receive_crc_enable),
                .chanel_in(receive_vc_enable_binary),
                .data_in(m_receive_dat_o[Fpay-1 : 0]),
                .crc_out(receive_crc_out)
        );
        
        for (i=0;i<V;i=i+1) begin: crc_v
        
`ifdef SYNC_RESET_MODE 
            always @ (posedge clk )begin 
`else 
            always @ (posedge clk or posedge reset)begin 
`endif 
                  
                if(reset) begin 
                    crc_miss_match[i] <= 1'b0;
                end else begin 
                    if(receive_vc_enable_binary==i && received_flit_is_tail && m_receive_stb_o ) begin 
                        crc_miss_match[i] <= receive_crc_out[31:0] != m_receive_dat_o[31 : 0];
                    end                
                end
            
            end
        end//for
        
        assign tail_flit_out[31 : 0]  =  send_crc_out;
    end   else begin : no_crc 
        assign tail_flit_out   =  m_send_dat_i [Fpay-1 : 0];
        //always @(*) crc_miss_match = {V{1'b0}};
        always @(posedge clk) crc_miss_match <= {V{1'b0}};
    end
      
  
    if(V> 1) begin : multi_chanel
    
        // round roubin arbiter
        bus_arbiter # (
            .M (V)
        )
        receive_arbiter
        (
            .request (receive_vc_is_active),
            .grant  (receive_vc_enable),
            .clk (clk),
            .reset (reset)
        );
                
        bus_arbiter # (
            .M (V)
        )
        send_arbiter
        (
            .request (send_vc_is_active),
            .grant  (send_vc_enable),
            .clk (clk),
            .reset (reset)
        );
        
        
        one_hot_to_bin #(
            .ONE_HOT_WIDTH(V),
            .BIN_WIDTH(CHw)
        )
        send_en_conv
        (
            .one_hot_code(send_vc_enable),
            .bin_code(send_vc_enable_binary)
        );
        
        
         one_hot_to_bin #(
            .ONE_HOT_WIDTH(V),
            .BIN_WIDTH(CHw)
        )
        receive_en_conv
        (
            .one_hot_code(receive_vc_enable),
            .bin_code(receive_vc_enable_binary)
        );
        
        
    end else begin : single_chanel // if we have just one chanel there is no need for arbitration
        assign receive_vc_enable =  receive_vc_is_active;
        assign send_vc_enable =  send_vc_is_active;
        assign send_vc_enable_binary = 1'b0;
        assign receive_vc_enable_binary = 1'b0;
    end
    endgenerate  
  
   
  
    conventional_routing #(
        .NOC_ID(NOC_ID),
        .TOPOLOGY(TOPOLOGY),
        .ROUTE_NAME(ROUTE_NAME),
        .ROUTE_TYPE(ROUTE_TYPE),  
        .T1(T1),
        .T2(T2),
        .T3(T3),
        .RAw(RAw),
        .EAw(EAw),
        .DSTPw(DSTPw),
        .LOCATED_IN_NI(1)
    ) route_compute (
        .reset(reset),
        .clk(clk),
        .current_r_addr(current_r_addr),
        .src_e_addr(current_e_addr),
        .dest_e_addr(dest_e_addr),
        .destport(destport)
    );
  
        
    header_flit_generator #(
        .NOC_ID(NOC_ID),
        .DATA_w(HDw)       
    ) hdr_flit_gen (
        .flit_out(hdr_flit_out),
        .class_in(pck_class),
        .dest_e_addr_in(dest_e_addr),
        .src_e_addr_in(current_e_addr),
        .destport_in(destport),
        .vc_num_in(send_vc_enable),
        .weight_in(weight),
        .be_in(be_in),
        .data_in(hdr_data)        
    );
    
  wire [V-1    :   0] wr_vc_send =  (fifo_wr) ? send_vc_enable : {V{1'b0}};  
  
  
  ovc_status #(
    .V(V),
    .B(LB),
    .CRDTw(CRDTw)    
  )
  the_ovc_status
  (
    .credit_init_val_in ( chan_in.ctrl_chanel.credit_init_val),
        .wr_in(wr_vc_send),
    .credit_in(credit_in),
    .full_vc(vc_fifo_full),
    .nearly_full_vc(vc_fifo_nearly_full),
    .empty_vc( ),
    .clk(clk),
    .reset(reset)
  );   
    
    // header info mux    
    assign dest_e_addr = vc_dest_e_addr[send_vc_enable_binary];
    assign pck_class  = vc_pck_class[send_vc_enable_binary];
    assign weight =   vc_weight[send_vc_enable_binary];  
    assign hdr_data = vc_hdr_data [send_vc_enable_binary]; 
    assign send_hdr = send_vc_send_hdr[send_vc_enable_binary]; 
    assign send_tail = send_vc_send_tail[send_vc_enable_binary]; 
    assign be_in = vc_be_in[send_vc_enable_binary];
    
    //wb multiplexors    
    assign m_send_sel_o  = vc_m_send_sel_o[send_vc_enable_binary];
    assign m_send_addr_o = vc_m_send_addr_o[send_vc_enable_binary];
    assign m_send_cti_o  = vc_m_send_cti_o[send_vc_enable_binary];
    assign m_send_stb_o  = vc_m_send_stb_o[send_vc_enable_binary];
    assign m_send_cyc_o  = vc_m_send_cyc_o[send_vc_enable_binary];
    assign m_send_we_o   = vc_m_send_we_o[send_vc_enable_binary];       
                        
    assign m_receive_sel_o = vc_m_receive_sel_o[receive_vc_enable_binary];
    assign m_receive_addr_o= vc_m_receive_addr_o[receive_vc_enable_binary];
    assign m_receive_cti_o = vc_m_receive_cti_o[receive_vc_enable_binary];
    assign m_receive_stb_o = vc_m_receive_stb_o[receive_vc_enable_binary];
    assign m_receive_cyc_o = vc_m_receive_cyc_o[receive_vc_enable_binary];
    assign m_receive_we_o  = vc_m_receive_we_o[receive_vc_enable_binary];    
          
    wire [V-1    :   0]  flit_in_vc_num = flit_in [Fpay+V-1    :   Fpay]; 
    wire [V-1    :   0]  ififo_vc_not_empty; 
    assign vc_fifo_empty = ~ ififo_vc_not_empty;
    assign receive_vc_got_packet = ififo_vc_not_empty;
    assign receive_vc_got_hdr_flit_at_head=  ififo_vc_not_empty & receive_vc_fsm_is_ideal;
        
    
    
    
    wire [Fw-1  :   0] fifo_dout;
    
    localparam LBw = log2(LB);
    
    flit_buffer #(
        .V(V),
        .B(LB),
        .SSA_EN("NO"),
        .Fw(Fw),
                .PCK_TYPE(PCK_TYPE),
                .CAST_TYPE(CAST_TYPE),
                .DEBUG_EN(DEBUG_EN)
     )
     the_ififo
     (
        .din(flit_in),     // Data in
        .vc_num_wr(flit_in_vc_num),//write virtual chanel    
        .wr_en(flit_in_wr),   // Write enable
        .vc_num_rd(receive_vc_enable),//read virtual chanel     
        .rd_en(fifo_rd),   // Read the next word
        .dout(fifo_dout),    // Data out
        .vc_not_empty(ififo_vc_not_empty),
        .reset(reset),
        .clk(clk),
        .ssa_rd({V{1'b0}}),
        .multiple_dest(),
        .sub_rd_ptr_ld()  
    ); 
    
   extract_header_flit_info #(
        .NOC_ID(NOC_ID),
        .DATA_w (HDw)      
    )
    extractor
    (
        .flit_in(fifo_dout),
        .flit_in_wr(),
        .class_o(received_class_next),
        .destport_o(),
        .dest_e_addr_o(),
        .src_e_addr_o(received_src_e_addr_next),
        .vc_num_o(),
        .hdr_flit_wr_o( ),
        .hdr_flg_o( ),
        .tail_flg_o( ),
        .weight_o(),
        .be_o(received_be_next),
        .data_o(received_hdr_dat_next)
    );  
  
  
 
  assign m_receive_dat_o = fifo_dout[Dw-1   :   0];
  assign received_flit_is_tail = fifo_dout[Fw-2];
  assign received_flit_is_hdr  = fifo_dout[Fw-1];  
//  assign any_vc_got_pck = |receive_vc_got_packet;

    localparam [1:0] 
        HDR_FLAG           =   2'b10,
        BDY_FLAG            =   2'b00,
        TAIL_FLAG          =   2'b01;
 
  assign credit_out = vc_fifo_rd;
  assign flit_out_wr= fifo_wr;  
  assign flit_out [Fpay+V-1 : Fpay] = send_vc_enable;    
  assign flit_out [Fpay-1   : 0   ] = (send_hdr)?  hdr_flit_out [Fpay-1 : 0] :
                                      (send_tail)? tail_flit_out :  m_send_dat_i [Fpay-1 : 0];
  assign flit_out [Fw-1 : Fw-2] =   (send_hdr)?  HDR_FLAG : 
                                    (send_tail)?  TAIL_FLAG    : BDY_FLAG;                                       
endmodule
 
 
  
/******************
*   ovc_status
*******************/
 
 module ovc_status #(
    parameter V     =   4,
    parameter B =   16,
    parameter CRDTw =4
)
(
   
        input   [V-1 : 0] [CRDTw-1 : 0 ] credit_init_val_in,
        input   [V-1            :0] wr_in,
    input   [V-1            :0] credit_in,
    output  [V-1            :0] full_vc,
    output  [V-1            :0] nearly_full_vc,
    output  [V-1            :0] empty_vc,
    input                       clk,
    input                       reset
);

 
         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  DEPTH_WIDTH =   log2(B+1);
 
    
         reg  [DEPTH_WIDTH-1 : 0] credit    [V-1 : 0];
         wire  [V-1 : 0] cand_vc_next;
        
    
         genvar i;
         generate
                for(i=0;i<V;i=i+1) begin : vc_loop
                `ifdef SYNC_RESET_MODE 
                        always @ (posedge clk )begin 
                `else 
                        always @ (posedge clk or posedge reset)begin 
                `endif  
                if(reset)begin
                credit[i]<= credit_init_val_in[i][DEPTH_WIDTH-1:0];
            end else begin
                if(  wr_in[i]  && ~credit_in[i])   credit[i] <= credit[i]-1'b1;
                if( ~wr_in[i]  &&  credit_in[i])   credit[i] <= credit[i]+1'b1;
            end //reset
            end//always

            assign  full_vc[i]   = (credit[i] == {DEPTH_WIDTH{1'b0}});
            assign  nearly_full_vc[i]=  (credit[i] == 1) |  full_vc[i];
            assign  empty_vc[i]  = (credit[i] == credit_init_val_in[i][DEPTH_WIDTH-1:0]);
      end//for
    endgenerate
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.