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.sv] - Diff between revs 54 and 56

Only display areas with differences | Details | Blame | View Log

Rev 54 Rev 56
`include "pronoc_def.v"
`include "pronoc_def.v"
/**********************************************************************
/**********************************************************************
 **     File:  flit_buffer.v
 **     File:  flit_buffer.v
 **
 **
 **     Copyright (C) 2014-2017  Alireza Monemi
 **     Copyright (C) 2014-2017  Alireza Monemi
 **
 **
 **     This file is part of ProNoC
 **     This file is part of ProNoC
 **
 **
 **     ProNoC ( stands for Prototype Network-on-chip)  is free software:
 **     ProNoC ( stands for Prototype Network-on-chip)  is free software:
 **     you can redistribute it and/or modify it under the terms of the GNU
 **     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,
 **     Lesser General Public License as published by the Free Software Foundation,
 **     either version 2 of the License, or (at your option) any later version.
 **     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
 **     ProNoC is distributed in the hope that it will be useful, but WITHOUT
 **     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 **     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 **     or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
 **     or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
 **     Public License for more details.
 **     Public License for more details.
 **
 **
 **     You should have received a copy of the GNU Lesser General Public
 **     You should have received a copy of the GNU Lesser General Public
 **     License along with ProNoC. If not, see .
 **     License along with ProNoC. If not, see .
 **
 **
 **
 **
 **     Description:
 **     Description:
 **     Input buffer module. All VCs located in the same router
 **     Input buffer module. All VCs located in the same router
 **     input port share one single FPGA BRAM
 **     input port share one single FPGA BRAM
 **
 **
 **************************************************************/
 **************************************************************/
module flit_buffer
module flit_buffer
                import pronoc_pkg::*;
 
        #(
        #(
                parameter B =4,
                parameter B =4,
                parameter SSA_EN="YES" // "YES" , "NO"
                parameter SSA_EN="YES", // "YES" , "NO"
 
                parameter Fw=32,
 
                parameter PCK_TYPE ="MULTI_FLIT",
 
                parameter CAST_TYPE = "UNICAST",
 
                parameter DEBUG_EN = 1,
 
                parameter V=1
                )
                )
                (
                (
                        din,     // Data in
                        din,     // Data in
                        vc_num_wr,//write virtual channel
                        vc_num_wr,//write virtual channel
                        vc_num_rd,//read virtual channel
                        vc_num_rd,//read virtual channel
                        wr_en,   // Write enable
                        wr_en,   // Write enable
                        rd_en,   // Read the next word
                        rd_en,   // Read the next word
                        dout,    // Data out
                        dout,    // Data out
                        vc_not_empty,
                        vc_not_empty,
                        reset,
                        reset,
                        clk,
                        clk,
                        ssa_rd,
                        ssa_rd,
                        //for multicast
                        //for multicast
                        multiple_dest, // incr rd-sub
                        multiple_dest, // incr rd-sub
                        sub_rd_ptr_ld,  // load rd_ptr to sub_rd_pt
                        sub_rd_ptr_ld,  // load rd_ptr to sub_rd_pt
                        flit_is_tail
                        flit_is_tail
                );
                );
 
 
 
     function  integer log2;
 
      input integer number; begin
 
         log2=(number <=1) ? 1: 0;
 
         while(2**log2
 
            log2=log2+1;
 
         end
 
      end
 
    endfunction // log2
 
 
        localparam
        localparam
                Bw      =   (B==1)? 1 : log2(B),
                Bw      =   (B==1)? 1 : log2(B),
                BV      =   B   *   V,
                BV      =   B   *   V,
                BVw              =   log2(BV),
                BVw              =   log2(BV),
                Vw               =  (V==1)? 1 : log2(V),
                Vw               =  (V==1)? 1 : log2(V),
                DEPTHw           =   log2(B+1),
                DEPTHw           =   log2(B+1),
                BwV              =   Bw * V,
                BwV              =   Bw * V,
                BVwV             =   BVw * V,
                BVwV             =   BVw * V,
                RESTw = Fw -2-V ,
                RESTw = Fw -2-V ,
                PTRw = ((2**Bw)==B)? Bw : BVw, // if B is power of 2 PTRw is Bw else is BVw
                PTRw = ((2**Bw)==B)? Bw : BVw, // if B is power of 2 PTRw is Bw else is BVw
                ARRAYw = PTRw * V,
                ARRAYw = PTRw * V,
                /* verilator lint_off WIDTH */
                /* verilator lint_off WIDTH */
                RAM_DATA_WIDTH   = (PCK_TYPE == "MULTI_FLIT")? Fw - V :  Fw - V -2;
                RAM_DATA_WIDTH   = (PCK_TYPE == "MULTI_FLIT")? Fw - V :  Fw - V -2;
        /* verilator lint_on WIDTH */
        /* verilator lint_on WIDTH */
        input  [Fw-1      :0]   din;     // Data in
        input  [Fw-1      :0]   din;     // Data in
        input  [V-1       :0]   vc_num_wr;//write virtual chanel
        input  [V-1       :0]   vc_num_wr;//write virtual chanel
        input  [V-1       :0]   vc_num_rd;//read virtual chanel
        input  [V-1       :0]   vc_num_rd;//read virtual chanel
        input                   wr_en;   // Write enable
        input                   wr_en;   // Write enable
        input                   rd_en;   // Read the next word
        input                   rd_en;   // Read the next word
        output [Fw-1       :0]  dout;    // Data out
        output [Fw-1       :0]  dout;    // Data out
        output [V-1        :0]  vc_not_empty;
        output [V-1        :0]  vc_not_empty;
        input                   reset;
        input                   reset;
        input                   clk;
        input                   clk;
        input  [V-1        :0]  ssa_rd;
        input  [V-1        :0]  ssa_rd;
        input  [V-1        :0]  multiple_dest;
        input  [V-1        :0]  multiple_dest;
        input  [V-1        :0]  sub_rd_ptr_ld;
        input  [V-1        :0]  sub_rd_ptr_ld;
        output [V-1 : 0]        flit_is_tail;
        output [V-1 : 0]        flit_is_tail;
        //pointers
        //pointers
        wire [PTRw- 1     :   0] rd_ptr [V-1          :0];
        wire [PTRw- 1     :   0] rd_ptr [V-1          :0];
        wire [PTRw- 1     :   0] wr_ptr [V-1          :0];
        wire [PTRw- 1     :   0] wr_ptr [V-1          :0];
        reg  [PTRw- 1     :   0] rd_ptr_next [V-1          :0];
        reg  [PTRw- 1     :   0] rd_ptr_next [V-1          :0];
        reg  [PTRw- 1     :   0] wr_ptr_next [V-1          :0];
        reg  [PTRw- 1     :   0] wr_ptr_next [V-1          :0];
        reg  [PTRw- 1     :   0] sub_rd_ptr_next [V-1          :0];
        reg  [PTRw- 1     :   0] sub_rd_ptr_next [V-1          :0];
        wire [PTRw- 1     :   0] sub_rd_ptr [V-1          :0];
        wire [PTRw- 1     :   0] sub_rd_ptr [V-1          :0];
        wire [PTRw-1      :   0] ptr_tmp  [V-1 : 0];
        wire [PTRw-1      :   0] ptr_tmp  [V-1 : 0];
        wire [ARRAYw-1    :   0] rd_ptr_array;
        wire [ARRAYw-1    :   0] rd_ptr_array;
        wire [ARRAYw-1    :   0] wr_ptr_array;
        wire [ARRAYw-1    :   0] wr_ptr_array;
        wire  [RAM_DATA_WIDTH-1     :   0] fifo_ram_din;
        wire  [RAM_DATA_WIDTH-1     :   0] fifo_ram_din;
        wire  [RAM_DATA_WIDTH-1     :   0] fifo_ram_dout;
        wire  [RAM_DATA_WIDTH-1     :   0] fifo_ram_dout;
        wire  [V-1                  :   0] wr;
        wire  [V-1                  :   0] wr;
        wire  [V-1                  :   0] rd;
        wire  [V-1                  :   0] rd;
        wire  [DEPTHw-1             :   0] depth      [V-1            :0];
        wire  [DEPTHw-1             :   0] depth      [V-1            :0];
        reg   [DEPTHw-1             :   0] depth_next [V-1            :0];
        reg   [DEPTHw-1             :   0] depth_next [V-1            :0];
        wire  [DEPTHw-1             :   0] sub_depth       [V-1            :0];
        wire  [DEPTHw-1             :   0] sub_depth       [V-1            :0];
        reg   [DEPTHw-1             :   0] sub_depth_next  [V-1            :0];
        reg   [DEPTHw-1             :   0] sub_depth_next  [V-1            :0];
        reg   [B-1 : 0] tail_fifo [V-1 : 0];
        reg   [B-1 : 0] tail_fifo [V-1 : 0];
        wire  [1  : 0] flgs_in, flgs_out;
        wire  [1  : 0] flgs_in, flgs_out;
        wire  [V-1: 0] vc_in;
        wire  [V-1: 0] vc_in;
        wire  [RESTw-1 :0      ] flit_rest_in,flit_rest_out;
        wire  [RESTw-1 :0      ] flit_rest_in,flit_rest_out;
        wire  [V-1       :   0] sub_rd;
        wire  [V-1       :   0] sub_rd;
        wire  [V-1       :   0] sub_restore;
        wire  [V-1       :   0] sub_restore;
        assign  wr  =   (wr_en)?  vc_num_wr : {V{1'b0}};
        assign  wr  =   (wr_en)?  vc_num_wr : {V{1'b0}};
        genvar i;
        genvar i;
        generate
        generate
        /* verilator lint_off WIDTH */
        /* verilator lint_off WIDTH */
                if (CAST_TYPE != "UNICAST") begin
                if (CAST_TYPE != "UNICAST") begin
                        /* verilator lint_on WIDTH */
                        /* verilator lint_on WIDTH */
                        assign  sub_rd  =  (rd_en)?  vc_num_rd  : ssa_rd;
                        assign  sub_rd  =  (rd_en)?  vc_num_rd  : ssa_rd;
                        assign  sub_restore = sub_rd_ptr_ld;
                        assign  sub_restore = sub_rd_ptr_ld;
                        assign  rd  =   (rd_en)?  vc_num_rd & ~multiple_dest : ssa_rd & ~multiple_dest;
                        assign  rd  =   (rd_en)?  vc_num_rd & ~multiple_dest : ssa_rd & ~multiple_dest;
                end else begin : unicast
                end else begin : unicast
                        assign  rd  =   (rd_en)?  vc_num_rd : ssa_rd;
                        assign  rd  =   (rd_en)?  vc_num_rd : ssa_rd;
                end
                end
                /* verilator lint_off WIDTH */
                /* verilator lint_off WIDTH */
                if (PCK_TYPE == "MULTI_FLIT") begin :multi
                if (PCK_TYPE == "MULTI_FLIT") begin :multi
                        /* verilator lint_on WIDTH */
                        /* verilator lint_on WIDTH */
                        assign {flgs_in,vc_in,flit_rest_in}=din;
                        assign {flgs_in,vc_in,flit_rest_in}=din;
                        assign fifo_ram_din = {flgs_in,flit_rest_in};
                        assign fifo_ram_din = {flgs_in,flit_rest_in};
                        assign {flgs_out,flit_rest_out} = fifo_ram_dout;
                        assign {flgs_out,flit_rest_out} = fifo_ram_dout;
                        assign dout = {flgs_out,{V{1'bX}},flit_rest_out};
                        assign dout = {flgs_out,{V{1'bX}},flit_rest_out};
                end else begin : single
                end else begin : single
                        assign fifo_ram_din = din[RAM_DATA_WIDTH-1     :   0];
                        assign fifo_ram_din = din[RAM_DATA_WIDTH-1     :   0];
                        assign dout = {2'b11,{V{1'bX}},fifo_ram_dout};
                        assign dout = {2'b11,{V{1'bX}},fifo_ram_dout};
                end
                end
                for(i=0;i
                for(i=0;i
                        assign  wr_ptr_array[(i+1)*PTRw- 1        :   i*PTRw]   =       wr_ptr[i];
                        assign  wr_ptr_array[(i+1)*PTRw- 1        :   i*PTRw]   =       wr_ptr[i];
                        /* verilator lint_off WIDTH */
                        /* verilator lint_off WIDTH */
                        if (CAST_TYPE != "UNICAST") begin
                        if (CAST_TYPE != "UNICAST") begin
                                /* verilator lint_on WIDTH */
                                /* verilator lint_on WIDTH */
                                assign  rd_ptr_array[(i+1)*PTRw- 1 :   i*PTRw]   =       sub_rd_ptr[i];
                                assign  rd_ptr_array[(i+1)*PTRw- 1 :   i*PTRw]   =       sub_rd_ptr[i];
                                localparam RESET_TO = ((2**Bw)==B)? 0 : B*i;
                                localparam RESET_TO = ((2**Bw)==B)? 0 : B*i;
                                pronoc_register #(.W(PTRw),.RESET_TO(RESET_TO)) reg4 (.in(sub_rd_ptr_next[i]), .out(sub_rd_ptr[i]), .reset(reset), .clk(clk));
                                pronoc_register #(.W(PTRw),.RESET_TO(RESET_TO)) reg4 (.in(sub_rd_ptr_next[i]), .out(sub_rd_ptr[i]), .reset(reset), .clk(clk));
                                pronoc_register #(.W(DEPTHw)) sub_depth_reg (.in(sub_depth_next[i] ), .out(sub_depth [i]), .reset(reset), .clk(clk));
                                pronoc_register #(.W(DEPTHw)) sub_depth_reg (.in(sub_depth_next[i] ), .out(sub_depth [i]), .reset(reset), .clk(clk));
                                always @ (*)begin
                                always @ (*)begin
                                        sub_depth_next  [i] = sub_depth   [i];
                                        sub_depth_next  [i] = sub_depth   [i];
                                        if(sub_restore[i]) sub_depth_next  [i]= depth_next[i];
                                        if(sub_restore[i]) sub_depth_next  [i]= depth_next[i];
                                        else if (wr[i] & ~sub_rd[i]) sub_depth_next [i] = sub_depth[i] + 1'h1;
                                        else if (wr[i] & ~sub_rd[i]) sub_depth_next [i] = sub_depth[i] + 1'h1;
                                        else if (~wr[i] & sub_rd[i]) sub_depth_next [i] = sub_depth[i] - 1'h1;
                                        else if (~wr[i] & sub_rd[i]) sub_depth_next [i] = sub_depth[i] - 1'h1;
                                end//always
                                end//always
                                assign  vc_not_empty    [i] =   (sub_depth[i] > 0);
                                assign  vc_not_empty    [i] =   (sub_depth[i] > 0);
                        end else begin : unicast
                        end else begin : unicast
                                assign  rd_ptr_array[(i+1)*PTRw- 1 :   i*PTRw]   =       rd_ptr[i];
                                assign  rd_ptr_array[(i+1)*PTRw- 1 :   i*PTRw]   =       rd_ptr[i];
                                assign  vc_not_empty    [i] =   (depth[i] > 0);
                                assign  vc_not_empty    [i] =   (depth[i] > 0);
                        end
                        end
                end//for
                end//for
                if((2**Bw)==B)begin :pow2
                if((2**Bw)==B)begin :pow2
                        /*****************
                        /*****************
          Buffer width is power of 2
          Buffer width is power of 2
                         ******************/
                         ******************/
                        wire [Bw-1     :    0]  vc_wr_addr;
                        wire [Bw-1     :    0]  vc_wr_addr;
                        wire [Bw-1     :    0]  vc_rd_addr;
                        wire [Bw-1     :    0]  vc_rd_addr;
                        wire [Vw-1     :    0]  wr_select_addr;
                        wire [Vw-1     :    0]  wr_select_addr;
                        wire [Vw-1     :    0]  rd_select_addr;
                        wire [Vw-1     :    0]  rd_select_addr;
                        wire [Bw+Vw-1  :    0]  wr_addr;
                        wire [Bw+Vw-1  :    0]  wr_addr;
                        wire [Bw+Vw-1  :    0]  rd_addr;
                        wire [Bw+Vw-1  :    0]  rd_addr;
                        assign  wr_addr =   {wr_select_addr,vc_wr_addr};
                        assign  wr_addr =   {wr_select_addr,vc_wr_addr};
                        assign  rd_addr =   {rd_select_addr,vc_rd_addr};
                        assign  rd_addr =   {rd_select_addr,vc_rd_addr};
                        onehot_mux_1D #(
                        onehot_mux_1D #(
                                        .W(Bw),
                                        .W(Bw),
                                        .N(V)
                                        .N(V)
                                )
                                )
                                wr_ptr_mux
                                wr_ptr_mux
                                (
                                (
                                        .in(wr_ptr_array),
                                        .in(wr_ptr_array),
                                        .out(vc_wr_addr),
                                        .out(vc_wr_addr),
                                        .sel(vc_num_wr)
                                        .sel(vc_num_wr)
                                );
                                );
                        onehot_mux_1D #(
                        onehot_mux_1D #(
                                        .W(Bw),
                                        .W(Bw),
                                        .N(V)
                                        .N(V)
                                )
                                )
                                rd_ptr_mux
                                rd_ptr_mux
                                (
                                (
                                        .in(rd_ptr_array),
                                        .in(rd_ptr_array),
                                        .out(vc_rd_addr),
                                        .out(vc_rd_addr),
                                        .sel(vc_num_rd)
                                        .sel(vc_num_rd)
                                );
                                );
                        one_hot_to_bin #(
                        one_hot_to_bin #(
                                        .ONE_HOT_WIDTH(V)
                                        .ONE_HOT_WIDTH(V)
                                )
                                )
                                wr_vc_start_addr
                                wr_vc_start_addr
                                (
                                (
                                        .one_hot_code(vc_num_wr),
                                        .one_hot_code(vc_num_wr),
                                        .bin_code(wr_select_addr)
                                        .bin_code(wr_select_addr)
                                );
                                );
                        one_hot_to_bin #(
                        one_hot_to_bin #(
                                        .ONE_HOT_WIDTH(V)
                                        .ONE_HOT_WIDTH(V)
                                )
                                )
                                rd_vc_start_addr
                                rd_vc_start_addr
                                (
                                (
                                        .one_hot_code(vc_num_rd),
                                        .one_hot_code(vc_num_rd),
                                        .bin_code(rd_select_addr)
                                        .bin_code(rd_select_addr)
                                );
                                );
                        fifo_ram    #(
                        fifo_ram    #(
                                        .DATA_WIDTH (RAM_DATA_WIDTH),
                                        .DATA_WIDTH (RAM_DATA_WIDTH),
                                        .ADDR_WIDTH (BVw ),
                                        .ADDR_WIDTH (BVw ),
                                        .SSA_EN(SSA_EN)
                                        .SSA_EN(SSA_EN)
                                )
                                )
                                the_queue
                                the_queue
                                (
                                (
                                        .wr_data(fifo_ram_din),
                                        .wr_data(fifo_ram_din),
                                        .wr_addr(wr_addr[BVw-1  :   0]),
                                        .wr_addr(wr_addr[BVw-1  :   0]),
                                        .rd_addr(rd_addr[BVw-1  :   0]),
                                        .rd_addr(rd_addr[BVw-1  :   0]),
                                        .wr_en(wr_en),
                                        .wr_en(wr_en),
                                        .rd_en(rd_en),
                                        .rd_en(rd_en),
                                        .clk(clk),
                                        .clk(clk),
                                        .rd_data(fifo_ram_dout)
                                        .rd_data(fifo_ram_dout)
                                );
                                );
                        for(i=0;i
                        for(i=0;i
                                always @(posedge clk) begin
                                always @(posedge clk) begin
                                        if(wr[i]) tail_fifo[i][wr_ptr[i]] <= din[Fw-2];
                                        if(wr[i]) tail_fifo[i][wr_ptr[i]] <= din[Fw-2];
                                end
                                end
                                pronoc_register #(.W(Bw    )) reg1 (.in(rd_ptr_next[i]), .out(rd_ptr[i]), .reset(reset), .clk(clk));
                                pronoc_register #(.W(Bw    )) reg1 (.in(rd_ptr_next[i]), .out(rd_ptr[i]), .reset(reset), .clk(clk));
                                pronoc_register #(.W(Bw    )) reg2 (.in(wr_ptr_next[i]), .out(wr_ptr[i]), .reset(reset), .clk(clk));
                                pronoc_register #(.W(Bw    )) reg2 (.in(wr_ptr_next[i]), .out(wr_ptr[i]), .reset(reset), .clk(clk));
                                pronoc_register #(.W(DEPTHw)) reg3 (.in(depth_next[i] ), .out(depth [i]), .reset(reset), .clk(clk));
                                pronoc_register #(.W(DEPTHw)) reg3 (.in(depth_next[i] ), .out(depth [i]), .reset(reset), .clk(clk));
                                always @ (*)begin
                                always @ (*)begin
                                        rd_ptr_next [i] = rd_ptr  [i];
                                        rd_ptr_next [i] = rd_ptr  [i];
                                        wr_ptr_next [i] = wr_ptr  [i];
                                        wr_ptr_next [i] = wr_ptr  [i];
                                        depth_next  [i] = depth   [i];
                                        depth_next  [i] = depth   [i];
                                        if (wr[i]  ) wr_ptr_next [i] = wr_ptr [i]+ 1'h1;
                                        if (wr[i]  ) wr_ptr_next [i] = wr_ptr [i]+ 1'h1;
                                        if (rd[i]  ) rd_ptr_next [i] = rd_ptr [i]+ 1'h1;
                                        if (rd[i]  ) rd_ptr_next [i] = rd_ptr [i]+ 1'h1;
                                        if (wr[i] & ~rd[i]) depth_next [i] = depth[i] + 1'h1;
                                        if (wr[i] & ~rd[i]) depth_next [i] = depth[i] + 1'h1;
                                        else if (~wr[i] & rd[i]) depth_next [i] = depth[i] - 1'h1;
                                        else if (~wr[i] & rd[i]) depth_next [i] = depth[i] - 1'h1;
                                end//always
                                end//always
                                /* verilator lint_off WIDTH */
                                /* verilator lint_off WIDTH */
                                if (CAST_TYPE != "UNICAST") begin :multicast
                                if (CAST_TYPE != "UNICAST") begin :multicast
                                        /* verilator lint_on WIDTH */
                                        /* verilator lint_on WIDTH */
                                        always @ (*)begin
                                        always @ (*)begin
                                                sub_rd_ptr_next[i] = sub_rd_ptr[i];
                                                sub_rd_ptr_next[i] = sub_rd_ptr[i];
                                                if (sub_restore[i]) sub_rd_ptr_next[i] = rd_ptr_next [i];
                                                if (sub_restore[i]) sub_rd_ptr_next[i] = rd_ptr_next [i];
                                                else if(sub_rd[i])  sub_rd_ptr_next[i] = sub_rd_ptr[i]+ 1'h1;
                                                else if(sub_rd[i])  sub_rd_ptr_next[i] = sub_rd_ptr[i]+ 1'h1;
                                        end
                                        end
                                        /* verilator lint_off WIDTH */
                                        /* verilator lint_off WIDTH */
                                        assign  flit_is_tail[i] = (PCK_TYPE == "MULTI_FLIT")? tail_fifo[i][sub_rd_ptr[i]]  : 1'b1;
                                        assign  flit_is_tail[i] = (PCK_TYPE == "MULTI_FLIT")? tail_fifo[i][sub_rd_ptr[i]]  : 1'b1;
                                        /* verilator lint_on WIDTH */
                                        /* verilator lint_on WIDTH */
                                end else begin : unicast
                                end else begin : unicast
                                        /* verilator lint_off WIDTH */
                                        /* verilator lint_off WIDTH */
                                        assign  flit_is_tail[i] = (PCK_TYPE == "MULTI_FLIT")?  tail_fifo[i][rd_ptr[i]] : 1'b1;
                                        assign  flit_is_tail[i] = (PCK_TYPE == "MULTI_FLIT")?  tail_fifo[i][rd_ptr[i]] : 1'b1;
                                        /* verilator lint_on WIDTH */
                                        /* verilator lint_on WIDTH */
                                end
                                end
                        end//for
                        end//for
                end  else begin :no_pow2
                end  else begin :no_pow2
                        /*****************
                        /*****************
        Buffer width is not power of 2
        Buffer width is not power of 2
                         ******************/
                         ******************/
                        // memory address
                        // memory address
                        wire [BVw- 1    :   0]  wr_addr;
                        wire [BVw- 1    :   0]  wr_addr;
                        wire [BVw- 1    :   0]  rd_addr;
                        wire [BVw- 1    :   0]  rd_addr;
                        for(i=0;i
                        for(i=0;i
                                pronoc_register #(.W(BVw),.RESET_TO(B*i)) reg1 (.in(rd_ptr_next[i]), .out(rd_ptr[i]), .reset(reset), .clk(clk));
                                pronoc_register #(.W(BVw),.RESET_TO(B*i)) reg1 (.in(rd_ptr_next[i]), .out(rd_ptr[i]), .reset(reset), .clk(clk));
                                pronoc_register #(.W(BVw),.RESET_TO(B*i)) reg2 (.in(wr_ptr_next[i]), .out(wr_ptr[i]), .reset(reset), .clk(clk));
                                pronoc_register #(.W(BVw),.RESET_TO(B*i)) reg2 (.in(wr_ptr_next[i]), .out(wr_ptr[i]), .reset(reset), .clk(clk));
                                pronoc_register #(.W(DEPTHw)            ) reg3 (.in(depth_next[i] ), .out(depth [i]), .reset(reset), .clk(clk));
                                pronoc_register #(.W(DEPTHw)            ) reg3 (.in(depth_next[i] ), .out(depth [i]), .reset(reset), .clk(clk));
                                always @(posedge clk) begin
                                always @(posedge clk) begin
                                        /* verilator lint_off WIDTH */
                                        /* verilator lint_off WIDTH */
                                        if(wr[i]) tail_fifo[i][wr_ptr[i]-(B*i)] <= din[Fw-2];
                                        if(wr[i]) tail_fifo[i][wr_ptr[i]-(B*i)] <= din[Fw-2];
                                        /* verilator lint_on WIDTH */
                                        /* verilator lint_on WIDTH */
                                end
                                end
                                always @ (*) begin
                                always @ (*) begin
                                        rd_ptr_next [i] = rd_ptr  [i];
                                        rd_ptr_next [i] = rd_ptr  [i];
                                        wr_ptr_next [i] = wr_ptr  [i];
                                        wr_ptr_next [i] = wr_ptr  [i];
                                        depth_next  [i] = depth   [i];
                                        depth_next  [i] = depth   [i];
                                        /* verilator lint_off WIDTH */
                                        /* verilator lint_off WIDTH */
                                        if (wr[i] ) wr_ptr_next[i] =(wr_ptr[i]==(B*(i+1))-1)? (B*i) : wr_ptr [i]+ 1'h1;
                                        if (wr[i] ) wr_ptr_next[i] =(wr_ptr[i]==(B*(i+1))-1)? (B*i) : wr_ptr [i]+ 1'h1;
                                        if (rd[i] ) rd_ptr_next[i] =(rd_ptr[i]==(B*(i+1))-1)? (B*i) : rd_ptr [i]+ 1'h1;
                                        if (rd[i] ) rd_ptr_next[i] =(rd_ptr[i]==(B*(i+1))-1)? (B*i) : rd_ptr [i]+ 1'h1;
                                        /* verilator lint_on WIDTH */
                                        /* verilator lint_on WIDTH */
                                        if (wr[i] & ~rd[i]) depth_next [i] = depth[i] + 1'h1;
                                        if (wr[i] & ~rd[i]) depth_next [i] = depth[i] + 1'h1;
                                        else if (~wr[i] & rd[i]) depth_next [i] = depth[i] - 1'h1;
                                        else if (~wr[i] & rd[i]) depth_next [i] = depth[i] - 1'h1;
                                end//always
                                end//always
                                /* verilator lint_off WIDTH */
                                /* verilator lint_off WIDTH */
                                if (CAST_TYPE != "UNICAST") begin :multicast
                                if (CAST_TYPE != "UNICAST") begin :multicast
                                /* verilator lint_on WIDTH */
                                /* verilator lint_on WIDTH */
                                        always @ (*)begin
                                        always @ (*)begin
                                                sub_rd_ptr_next[i] = sub_rd_ptr[i];
                                                sub_rd_ptr_next[i] = sub_rd_ptr[i];
                                                if (sub_restore[i]) sub_rd_ptr_next[i] = rd_ptr_next [i];
                                                if (sub_restore[i]) sub_rd_ptr_next[i] = rd_ptr_next [i];
                                                /* verilator lint_off WIDTH */
                                                /* verilator lint_off WIDTH */
                                                else if(sub_rd[i])  sub_rd_ptr_next[i] = (sub_rd_ptr[i]==(B*(i+1))-1)? (B*i) : sub_rd_ptr [i]+ 1'h1;
                                                else if(sub_rd[i])  sub_rd_ptr_next[i] = (sub_rd_ptr[i]==(B*(i+1))-1)? (B*i) : sub_rd_ptr [i]+ 1'h1;
                                                /* verilator lint_on WIDTH */
                                                /* verilator lint_on WIDTH */
                                        end
                                        end
                                        /* verilator lint_off WIDTH */
                                        /* verilator lint_off WIDTH */
                                        assign  ptr_tmp [i] = sub_rd_ptr[i]-(B*i);
                                        assign  ptr_tmp [i] = sub_rd_ptr[i]-(B*i);
                                        assign  flit_is_tail[i] = (PCK_TYPE == "MULTI_FLIT")?  tail_fifo[i][ptr_tmp [i]] :1'b1;
                                        assign  flit_is_tail[i] = (PCK_TYPE == "MULTI_FLIT")?  tail_fifo[i][ptr_tmp [i]] :1'b1;
                                        /* verilator lint_on WIDTH */
                                        /* verilator lint_on WIDTH */
                                end else begin : unicast
                                end else begin : unicast
                                        /* verilator lint_off WIDTH */
                                        /* verilator lint_off WIDTH */
                                        assign  flit_is_tail[i] = (PCK_TYPE == "MULTI_FLIT")?  tail_fifo[i][rd_ptr[i]-(B*i)] : 1'b1;
                                        assign  flit_is_tail[i] = (PCK_TYPE == "MULTI_FLIT")?  tail_fifo[i][rd_ptr[i]-(B*i)] : 1'b1;
                                        /* verilator lint_on WIDTH */
                                        /* verilator lint_on WIDTH */
                                end
                                end
                        end//FOR
                        end//FOR
                        onehot_mux_1D #(
                        onehot_mux_1D #(
                                        .W(BVw),
                                        .W(BVw),
                                        .N(V)
                                        .N(V)
                                )
                                )
                                wr_mux
                                wr_mux
                                (
                                (
                                        .in(wr_ptr_array),
                                        .in(wr_ptr_array),
                                        .out(wr_addr),
                                        .out(wr_addr),
                                        .sel(vc_num_wr)
                                        .sel(vc_num_wr)
                                );
                                );
                        onehot_mux_1D #(
                        onehot_mux_1D #(
                                        .W(BVw),
                                        .W(BVw),
                                        .N(V)
                                        .N(V)
                                )
                                )
                                rd_mux
                                rd_mux
                                (
                                (
                                        .in(rd_ptr_array),
                                        .in(rd_ptr_array),
                                        .out(rd_addr),
                                        .out(rd_addr),
                                        .sel(vc_num_rd)
                                        .sel(vc_num_rd)
                                );
                                );
                        fifo_ram_mem_size #(
                        fifo_ram_mem_size #(
                                        .DATA_WIDTH (RAM_DATA_WIDTH),
                                        .DATA_WIDTH (RAM_DATA_WIDTH),
                                        .MEM_SIZE (BV ),
                                        .MEM_SIZE (BV ),
                                        .SSA_EN(SSA_EN)
                                        .SSA_EN(SSA_EN)
                                )
                                )
                                the_queue
                                the_queue
                                (
                                (
                                        .wr_data        (fifo_ram_din),
                                        .wr_data        (fifo_ram_din),
                                        .wr_addr        (wr_addr),
                                        .wr_addr        (wr_addr),
                                        .rd_addr        (rd_addr),
                                        .rd_addr        (rd_addr),
                                        .wr_en          (wr_en),
                                        .wr_en          (wr_en),
                                        .rd_en          (rd_en),
                                        .rd_en          (rd_en),
                                        .clk            (clk),
                                        .clk            (clk),
                                        .rd_data        (fifo_ram_dout)
                                        .rd_data        (fifo_ram_dout)
                                );
                                );
                end
                end
        endgenerate
        endgenerate
        //synthesis translate_off
        //synthesis translate_off
        //synopsys  translate_off
        //synopsys  translate_off
        generate
        generate
                if(DEBUG_EN) begin :dbg
                if(DEBUG_EN) begin :dbg
                        always @(posedge clk) begin
                        always @(posedge clk) begin
                                if(wr_en && vc_num_wr == {V{1'b0}})begin
                                if(wr_en && vc_num_wr == {V{1'b0}})begin
                                        $display("%t: ERROR: Attempt to write when no wr VC is asserted: %m",$time);
                                        $display("%t: ERROR: Attempt to write when no wr VC is asserted: %m",$time);
                                        $finish;
                                        $finish;
                                end
                                end
                                if(rd_en && vc_num_rd == {V{1'b0}})begin
                                if(rd_en && vc_num_rd == {V{1'b0}})begin
                                        $display("%t: ERROR: Attempt to read when no rd VC is asserted: %m",$time);
                                        $display("%t: ERROR: Attempt to read when no rd VC is asserted: %m",$time);
                                        $finish;
                                        $finish;
                                end
                                end
                        end
                        end
                end //DEBUG_EN
                end //DEBUG_EN
                for(i=0;i
                for(i=0;i
                        /* verilator lint_off WIDTH */
                        /* verilator lint_off WIDTH */
                        if (CAST_TYPE != "UNICAST") begin :multicast
                        if (CAST_TYPE != "UNICAST") begin :multicast
                                /* verilator lint_on WIDTH */
                                /* verilator lint_on WIDTH */
                                always @(posedge clk) begin
                                always @(posedge clk) begin
                                        if (wr[i] && (sub_depth[i] == B [DEPTHw-1 : 0]) && !sub_rd[i]) begin
                                        if (wr[i] && (sub_depth[i] == B [DEPTHw-1 : 0]) && !sub_rd[i]) begin
                                                $display("%t: ERROR: Attempt to write to full FIFO:FIFO size is %d. %m",$time,B);
                                                $display("%t: ERROR: Attempt to write to full FIFO:FIFO size is %d. %m",$time,B);
                                                $finish;
                                                $finish;
                                        end
                                        end
                                        /* verilator lint_off WIDTH */
                                        /* verilator lint_off WIDTH */
                                        if (sub_rd[i] && (sub_depth[i] == {DEPTHw{1'b0}} &&  SSA_EN !="YES"  ))begin
                                        if (sub_rd[i] && (sub_depth[i] == {DEPTHw{1'b0}} &&  SSA_EN !="YES"  ))begin
                                                /* verilator lint_on WIDTH */
                                                /* verilator lint_on WIDTH */
                                                $display("%t: ERROR: Attempt to read an empty FIFO: %m",$time);
                                                $display("%t: ERROR: Attempt to read an empty FIFO: %m",$time);
                                                $finish;
                                                $finish;
                                        end
                                        end
                                        /* verilator lint_off WIDTH */
                                        /* verilator lint_off WIDTH */
                                        if (sub_rd[i] && !wr[i] && (sub_depth[i] == {DEPTHw{1'b0}} &&  SSA_EN =="YES" ))begin
                                        if (sub_rd[i] && !wr[i] && (sub_depth[i] == {DEPTHw{1'b0}} &&  SSA_EN =="YES" ))begin
                                                /* verilator lint_on WIDTH */
                                                /* verilator lint_on WIDTH */
                                                $display("%t: ERROR: Attempt to read an empty FIFO: %m",$time);
                                                $display("%t: ERROR: Attempt to read an empty FIFO: %m",$time);
                                                $finish;
                                                $finish;
                                        end
                                        end
                                end//always
                                end//always
                        end     //multicast
                        end     //multicast
                        always @(posedge clk) begin
                        always @(posedge clk) begin
                                if (wr[i] && (depth[i] == B [DEPTHw-1 : 0]) && !rd[i])begin
                                if (wr[i] && (depth[i] == B [DEPTHw-1 : 0]) && !rd[i])begin
                                        $display("%t: ERROR: Attempt to write to full FIFO:FIFO size is %d. %m",$time,B);
                                        $display("%t: ERROR: Attempt to write to full FIFO:FIFO size is %d. %m",$time,B);
                                        $finish;
                                        $finish;
                                end
                                end
                                /* verilator lint_off WIDTH */
                                /* verilator lint_off WIDTH */
                                if (rd[i] && (depth[i] == {DEPTHw{1'b0}} &&  SSA_EN !="YES"  ))begin
                                if (rd[i] && (depth[i] == {DEPTHw{1'b0}} &&  SSA_EN !="YES"  ))begin
                                        /* verilator lint_on WIDTH */
                                        /* verilator lint_on WIDTH */
                                        $display("%t: ERROR: Attempt to read an empty FIFO: %m",$time);
                                        $display("%t: ERROR: Attempt to read an empty FIFO: %m",$time);
                                        $finish;
                                        $finish;
                                end
                                end
                                /* verilator lint_off WIDTH */
                                /* verilator lint_off WIDTH */
                                if (rd[i] && !wr[i] && (depth[i] == {DEPTHw{1'b0}} &&  SSA_EN =="YES" ))begin
                                if (rd[i] && !wr[i] && (depth[i] == {DEPTHw{1'b0}} &&  SSA_EN =="YES" ))begin
                                        /* verilator lint_on WIDTH */
                                        /* verilator lint_on WIDTH */
                                        $display("%t: ERROR: Attempt to read an empty FIFO: %m",$time);
                                        $display("%t: ERROR: Attempt to read an empty FIFO: %m",$time);
                                        $finish;
                                        $finish;
                                end
                                end
                                //if (wr_en)       $display($time, " %h is written on fifo ",din);
                                //if (wr_en)       $display($time, " %h is written on fifo ",din);
                        end//always
                        end//always
                end//for
                end//for
        endgenerate
        endgenerate
        //synopsys  translate_on
        //synopsys  translate_on
        //synthesis translate_on
        //synthesis translate_on
endmodule
endmodule
/****************************
/****************************
     fifo_ram
     fifo_ram
 *****************************/
 *****************************/
module fifo_ram     #(
module fifo_ram     #(
                parameter DATA_WIDTH    = 32,
                parameter DATA_WIDTH    = 32,
                parameter ADDR_WIDTH    = 8,
                parameter ADDR_WIDTH    = 8,
                parameter SSA_EN="YES" // "YES" , "NO"
                parameter SSA_EN="YES" // "YES" , "NO"
                )
                )
                (
                (
                wr_data,
                wr_data,
                wr_addr,
                wr_addr,
                rd_addr,
                rd_addr,
                wr_en,
                wr_en,
                rd_en,
                rd_en,
                clk,
                clk,
                rd_data
                rd_data
                );
                );
        input [DATA_WIDTH-1         :       0]  wr_data;
        input [DATA_WIDTH-1         :       0]  wr_data;
        input [ADDR_WIDTH-1         :       0]  wr_addr;
        input [ADDR_WIDTH-1         :       0]  wr_addr;
        input [ADDR_WIDTH-1         :       0]  rd_addr;
        input [ADDR_WIDTH-1         :       0]  rd_addr;
        input                                   wr_en;
        input                                   wr_en;
        input                                   rd_en;
        input                                   rd_en;
        input                                   clk;
        input                                   clk;
        output [DATA_WIDTH-1   :       0]       rd_data;
        output [DATA_WIDTH-1   :       0]       rd_data;
        reg [DATA_WIDTH-1:0] memory_rd_data;
        reg [DATA_WIDTH-1:0] memory_rd_data;
        // memory
        // memory
        reg [DATA_WIDTH-1:0] queue [2**ADDR_WIDTH-1:0] /* synthesis ramstyle = "no_rw_check , M9K" */;
        reg [DATA_WIDTH-1:0] queue [2**ADDR_WIDTH-1:0] /* synthesis ramstyle = "no_rw_check , M9K" */;
        always @(posedge clk ) begin
        always @(posedge clk ) begin
                if (wr_en)
                if (wr_en)
                        queue[wr_addr] <= wr_data;
                        queue[wr_addr] <= wr_data;
                if (rd_en)
                if (rd_en)
                        memory_rd_data <=  queue[rd_addr];
                        memory_rd_data <=  queue[rd_addr];
        end
        end
        generate
        generate
        /* verilator lint_off WIDTH */
        /* verilator lint_off WIDTH */
                if(SSA_EN =="YES") begin :predict
                if(SSA_EN =="YES") begin :predict
                        /* verilator lint_on WIDTH */
                        /* verilator lint_on WIDTH */
                        //add bypass
                        //add bypass
                        reg [DATA_WIDTH-1:0]  bypass_reg;
                        reg [DATA_WIDTH-1:0]  bypass_reg;
                        reg rd_en_delayed;
                        reg rd_en_delayed;
                        always @(posedge clk ) begin
                        always @(posedge clk ) begin
                                bypass_reg      <=wr_data;
                                bypass_reg      <=wr_data;
                                rd_en_delayed   <=rd_en;
                                rd_en_delayed   <=rd_en;
                        end
                        end
                        assign rd_data = (rd_en_delayed)? memory_rd_data  : bypass_reg;
                        assign rd_data = (rd_en_delayed)? memory_rd_data  : bypass_reg;
                end else begin : no_predict
                end else begin : no_predict
                        assign rd_data =  memory_rd_data;
                        assign rd_data =  memory_rd_data;
                end
                end
        endgenerate
        endgenerate
endmodule
endmodule
/*********************
/*********************
 *
 *
 *   fifo_ram_mem_size
 *   fifo_ram_mem_size
 *
 *
 **********************/
 **********************/
module fifo_ram_mem_size     #(
module fifo_ram_mem_size     #(
                parameter DATA_WIDTH  = 32,
                parameter DATA_WIDTH  = 32,
                parameter MEM_SIZE    = 200,
                parameter MEM_SIZE    = 200,
                parameter SSA_EN  = "YES" // "YES" , "NO"
                parameter SSA_EN  = "YES" // "YES" , "NO"
                )
                )
                (
                (
                wr_data,
                wr_data,
                wr_addr,
                wr_addr,
                rd_addr,
                rd_addr,
                wr_en,
                wr_en,
                rd_en,
                rd_en,
                clk,
                clk,
                rd_data
                rd_data
                );
                );
        function integer log2;
        function integer log2;
                input integer number; begin
                input integer number; begin
                        log2=(number <=1) ? 1: 0;
                        log2=(number <=1) ? 1: 0;
                        while(2**log2
                        while(2**log2
                                log2=log2+1;
                                log2=log2+1;
                        end
                        end
                end
                end
        endfunction // log2
        endfunction // log2
        localparam ADDR_WIDTH=log2(MEM_SIZE);
        localparam ADDR_WIDTH=log2(MEM_SIZE);
        input  [DATA_WIDTH-1         :       0]  wr_data;
        input  [DATA_WIDTH-1         :       0]  wr_data;
        input  [ADDR_WIDTH-1         :       0]  wr_addr;
        input  [ADDR_WIDTH-1         :       0]  wr_addr;
        input  [ADDR_WIDTH-1         :       0]  rd_addr;
        input  [ADDR_WIDTH-1         :       0]  rd_addr;
        input                                    wr_en;
        input                                    wr_en;
        input                                    rd_en;
        input                                    rd_en;
        input                                    clk;
        input                                    clk;
        output [DATA_WIDTH-1        :       0]   rd_data;
        output [DATA_WIDTH-1        :       0]   rd_data;
        reg [DATA_WIDTH-1:0] memory_rd_data;
        reg [DATA_WIDTH-1:0] memory_rd_data;
        // memory
        // memory
        reg [DATA_WIDTH-1:0] queue [MEM_SIZE-1:0] /* synthesis ramstyle = "no_rw_check , M9K" */;
        reg [DATA_WIDTH-1:0] queue [MEM_SIZE-1:0] /* synthesis ramstyle = "no_rw_check , M9K" */;
        always @(posedge clk ) begin
        always @(posedge clk ) begin
                if (wr_en)
                if (wr_en)
                        queue[wr_addr] <= wr_data;
                        queue[wr_addr] <= wr_data;
                if (rd_en)
                if (rd_en)
                        memory_rd_data <=  queue[rd_addr];
                        memory_rd_data <=  queue[rd_addr];
        end
        end
        generate
        generate
        /* verilator lint_off WIDTH */
        /* verilator lint_off WIDTH */
                if(SSA_EN =="YES") begin :predict
                if(SSA_EN =="YES") begin :predict
                        /* verilator lint_on WIDTH */
                        /* verilator lint_on WIDTH */
                        //add bypass
                        //add bypass
                        reg [DATA_WIDTH-1:0]  bypass_reg;
                        reg [DATA_WIDTH-1:0]  bypass_reg;
                        reg rd_en_delayed;
                        reg rd_en_delayed;
                        always @(posedge clk ) begin
                        always @(posedge clk ) begin
                                bypass_reg     <=wr_data;
                                bypass_reg     <=wr_data;
                                rd_en_delayed  <=rd_en;
                                rd_en_delayed  <=rd_en;
                        end
                        end
                        assign rd_data = (rd_en_delayed)? memory_rd_data  : bypass_reg;
                        assign rd_data = (rd_en_delayed)? memory_rd_data  : bypass_reg;
                end else begin : no_predict
                end else begin : no_predict
                        assign rd_data =  memory_rd_data;
                        assign rd_data =  memory_rd_data;
                end
                end
        endgenerate
        endgenerate
endmodule
endmodule
/**********************************
/**********************************
An small  First Word Fall Through FIFO. The code will use LUTs
An small  First Word Fall Through FIFO. The code will use LUTs
    and  optimized for low LUTs utilization.
    and  optimized for low LUTs utilization.
 **********************************/
 **********************************/
module fwft_fifo #(
module fwft_fifo #(
                parameter DATA_WIDTH = 2,
                parameter DATA_WIDTH = 2,
                parameter MAX_DEPTH = 2,
                parameter MAX_DEPTH = 2,
                parameter IGNORE_SAME_LOC_RD_WR_WARNING="YES" // "YES" , "NO"
                parameter IGNORE_SAME_LOC_RD_WR_WARNING="YES" // "YES" , "NO"
                )
                )
                (
                (
                input [DATA_WIDTH-1:0] din,     // Data in
                input [DATA_WIDTH-1:0] din,     // Data in
                input          wr_en,   // Write enable
                input          wr_en,   // Write enable
                input          rd_en,   // Read the next word
                input          rd_en,   // Read the next word
                output [DATA_WIDTH-1:0]  dout,    // Data out
                output [DATA_WIDTH-1:0]  dout,    // Data out
                output         full,
                output         full,
                output         nearly_full,
                output         nearly_full,
                output          recieve_more_than_0,
                output          recieve_more_than_0,
                output          recieve_more_than_1,
                output          recieve_more_than_1,
                input          reset,
                input          reset,
                input          clk
                input          clk
                );
                );
        function integer log2;
        function integer log2;
                input integer number; begin
                input integer number; begin
                        log2=(number <=1) ? 1: 0;
                        log2=(number <=1) ? 1: 0;
                        while(2**log2
                        while(2**log2
                                log2=log2+1;
                                log2=log2+1;
                        end
                        end
                end
                end
        endfunction // log2
        endfunction // log2
        localparam DEPTH_DATA_WIDTH = log2(MAX_DEPTH +1);
        localparam DEPTH_DATA_WIDTH = log2(MAX_DEPTH +1);
        localparam MUX_SEL_WIDTH     = log2(MAX_DEPTH-1);
        localparam MUX_SEL_WIDTH     = log2(MAX_DEPTH-1);
        wire                                        out_ld ;
        wire                                        out_ld ;
        wire    [DATA_WIDTH-1                   :   0] dout_next;
        wire    [DATA_WIDTH-1                   :   0] dout_next;
        wire[DEPTH_DATA_WIDTH-1         :   0]  depth;
        wire[DEPTH_DATA_WIDTH-1         :   0]  depth;
        reg [DEPTH_DATA_WIDTH-1         :   0]  depth_next;
        reg [DEPTH_DATA_WIDTH-1         :   0]  depth_next;
        reg [DATA_WIDTH-1:0]  dout_next_ld;
        reg [DATA_WIDTH-1:0]  dout_next_ld;
        genvar i;
        genvar i;
        generate
        generate
                if(MAX_DEPTH>2) begin :mwb2
                if(MAX_DEPTH>2) begin :mwb2
                        wire    [MUX_SEL_WIDTH-1    :   0] mux_sel;
                        wire    [MUX_SEL_WIDTH-1    :   0] mux_sel;
                        wire    [DEPTH_DATA_WIDTH-1 :   0] depth_2;
                        wire    [DEPTH_DATA_WIDTH-1 :   0] depth_2;
                        wire                               empty;
                        wire                               empty;
                        wire                               out_sel ;
                        wire                               out_sel ;
                        if(DATA_WIDTH>1) begin :wb1
                        if(DATA_WIDTH>1) begin :wb1
                                wire    [MAX_DEPTH-2        :   0] mux_in  [DATA_WIDTH-1       :0];
                                wire    [MAX_DEPTH-2        :   0] mux_in  [DATA_WIDTH-1       :0];
                                wire    [DATA_WIDTH-1       :   0] mux_out;
                                wire    [DATA_WIDTH-1       :   0] mux_out;
                                reg     [MAX_DEPTH-2        :   0] shiftreg [DATA_WIDTH-1      :0];
                                reg     [MAX_DEPTH-2        :   0] shiftreg [DATA_WIDTH-1      :0];
                                for(i=0;i
                                for(i=0;i
                                        always @(posedge clk ) begin
                                        always @(posedge clk ) begin
                                                //if (reset) begin
                                                //if (`pronoc_reset) begin
                                                //  shiftreg[i] <= {MAX_DEPTH{1'b0}};
                                                //  shiftreg[i] <= {MAX_DEPTH{1'b0}};
                                                //end else begin
                                                //end else begin
                                                if(wr_en) shiftreg[i] <= {shiftreg[i][MAX_DEPTH-3   :   0]  ,din[i]};
                                                if(wr_en) shiftreg[i] <= {shiftreg[i][MAX_DEPTH-3   :   0]  ,din[i]};
                                                //end
                                                //end
                                        end
                                        end
                                        assign mux_in[i]    = shiftreg[i];
                                        assign mux_in[i]    = shiftreg[i];
                                        assign mux_out[i]   = mux_in[i][mux_sel];
                                        assign mux_out[i]   = mux_in[i][mux_sel];
                                        assign dout_next[i] = (out_sel) ? mux_out[i] : din[i];
                                        assign dout_next[i] = (out_sel) ? mux_out[i] : din[i];
                                end //for
                                end //for
                        end else begin :w1
                        end else begin :w1
                                wire    [MAX_DEPTH-2        :   0] mux_in;
                                wire    [MAX_DEPTH-2        :   0] mux_in;
                                wire    mux_out;
                                wire    mux_out;
                                reg     [MAX_DEPTH-2        :   0] shiftreg;
                                reg     [MAX_DEPTH-2        :   0] shiftreg;
                                always @(posedge clk ) begin
                                always @(posedge clk ) begin
                                        if(wr_en) shiftreg <= {shiftreg[MAX_DEPTH-3   :   0]  ,din};
                                        if(wr_en) shiftreg <= {shiftreg[MAX_DEPTH-3   :   0]  ,din};
                                end
                                end
                                assign mux_in    = shiftreg;
                                assign mux_in    = shiftreg;
                                assign mux_out   = mux_in[mux_sel];
                                assign mux_out   = mux_in[mux_sel];
                                assign dout_next = (out_sel) ? mux_out : din;
                                assign dout_next = (out_sel) ? mux_out : din;
                        end
                        end
                        assign full                         = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0];
                        assign full                         = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0];
                        assign nearly_full              = depth >= MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0] -1'b1;
                        assign nearly_full              = depth >= MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0] -1'b1;
                        assign empty     = depth == {DEPTH_DATA_WIDTH{1'b0}};
                        assign empty     = depth == {DEPTH_DATA_WIDTH{1'b0}};
                        assign recieve_more_than_0  = ~ empty;
                        assign recieve_more_than_0  = ~ empty;
                        assign recieve_more_than_1  = ~( depth == {DEPTH_DATA_WIDTH{1'b0}} ||  depth== 1 );
                        assign recieve_more_than_1  = ~( depth == {DEPTH_DATA_WIDTH{1'b0}} ||  depth== 1 );
                        assign out_sel                  = (recieve_more_than_1)  ? 1'b1 : 1'b0;
                        assign out_sel                  = (recieve_more_than_1)  ? 1'b1 : 1'b0;
                        assign out_ld                       = (depth !=0 )?  rd_en : wr_en;
                        assign out_ld                       = (depth !=0 )?  rd_en : wr_en;
                        assign depth_2                      = depth - 2;
                        assign depth_2                      = depth - 2;
                        assign mux_sel                  = depth_2[MUX_SEL_WIDTH-1   :   0]  ;
                        assign mux_sel                  = depth_2[MUX_SEL_WIDTH-1   :   0]  ;
                end else if  ( MAX_DEPTH == 2) begin :mw2
                end else if  ( MAX_DEPTH == 2) begin :mw2
                        reg     [DATA_WIDTH-1       :   0] register;
                        reg     [DATA_WIDTH-1       :   0] register;
                        always @(posedge clk ) begin
                        always @(posedge clk ) begin
                                if(wr_en) register <= din;
                                if(wr_en) register <= din;
                        end //always
                        end //always
                        assign full             = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0];
                        assign full             = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0];
                        assign nearly_full      = depth >= MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0] -1'b1;
                        assign nearly_full      = depth >= MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0] -1'b1;
                        assign out_ld           = (depth !=0 )?  rd_en : wr_en;
                        assign out_ld           = (depth !=0 )?  rd_en : wr_en;
                        assign recieve_more_than_0  =  (depth != {DEPTH_DATA_WIDTH{1'b0}});
                        assign recieve_more_than_0  =  (depth != {DEPTH_DATA_WIDTH{1'b0}});
                        assign recieve_more_than_1  = ~( depth == 0 ||  depth== 1 );
                        assign recieve_more_than_1  = ~( depth == 0 ||  depth== 1 );
                        assign dout_next        = (recieve_more_than_1) ? register  : din;
                        assign dout_next        = (recieve_more_than_1) ? register  : din;
                end else begin :mw1 // MAX_DEPTH == 1
                end else begin :mw1 // MAX_DEPTH == 1
                        assign out_ld       = wr_en;
                        assign out_ld       = wr_en;
                        assign dout_next    =   din;
                        assign dout_next    =   din;
                        assign full         = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0];
                        assign full         = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0];
                        assign nearly_full= 1'b1;
                        assign nearly_full= 1'b1;
                        assign recieve_more_than_0 = full;
                        assign recieve_more_than_0 = full;
                        assign recieve_more_than_1 = 1'b0;
                        assign recieve_more_than_1 = 1'b0;
                end
                end
        endgenerate
        endgenerate
        pronoc_register #(.W(DEPTH_DATA_WIDTH)) reg1 (.in(depth_next), .out(depth), .reset(reset), .clk(clk));
        pronoc_register #(.W(DEPTH_DATA_WIDTH)) reg1 (.in(depth_next), .out(depth), .reset(reset), .clk(clk));
        pronoc_register #(.W(DATA_WIDTH))       reg2 (.in(dout_next_ld), .out(dout ), .reset(reset), .clk(clk));
        pronoc_register #(.W(DATA_WIDTH))       reg2 (.in(dout_next_ld), .out(dout ), .reset(reset), .clk(clk));
        always @ (*)begin
        always @ (*)begin
                depth_next  =  depth;
                depth_next  =  depth;
                dout_next_ld   =  dout;
                dout_next_ld   =  dout;
                if (wr_en & ~rd_en) depth_next  =  depth + 1'h1;
                if (wr_en & ~rd_en) depth_next  =  depth + 1'h1;
                else if (~wr_en & rd_en) depth_next  =  depth - 1'h1;
                else if (~wr_en & rd_en) depth_next  =  depth - 1'h1;
                if (out_ld) dout_next_ld = dout_next;
                if (out_ld) dout_next_ld = dout_next;
        end//always
        end//always
        //synthesis translate_off
        //synthesis translate_off
        //synopsys  translate_off
        //synopsys  translate_off
        always @(posedge clk)
        always @(posedge clk)
        begin
        begin
                if (wr_en & ~rd_en & full) begin
                if (wr_en & ~rd_en & full) begin
                        $display("%t: ERROR: Attempt to write to full FIFO:FIFO size is %d. %m",$time,MAX_DEPTH);
                        $display("%t: ERROR: Attempt to write to full FIFO:FIFO size is %d. %m",$time,MAX_DEPTH);
                        $finish;
                        $finish;
                end
                end
                /* verilator lint_off WIDTH */
                /* verilator lint_off WIDTH */
                if (rd_en & !recieve_more_than_0 & IGNORE_SAME_LOC_RD_WR_WARNING == "NO") begin
                if (rd_en & !recieve_more_than_0 & IGNORE_SAME_LOC_RD_WR_WARNING == "NO") begin
                        $display("%t ERROR: Attempt to read an empty FIFO: %m", $time);
                        $display("%t ERROR: Attempt to read an empty FIFO: %m", $time);
                        $finish;
                        $finish;
                end
                end
                if (rd_en & ~wr_en & !recieve_more_than_0 & (IGNORE_SAME_LOC_RD_WR_WARNING == "YES")) begin
                if (rd_en & ~wr_en & !recieve_more_than_0 & (IGNORE_SAME_LOC_RD_WR_WARNING == "YES")) begin
                        $display("%t ERROR: Attempt to read an empty FIFO: %m", $time);
                        $display("%t ERROR: Attempt to read an empty FIFO: %m", $time);
                        $finish;
                        $finish;
                end
                end
                /* verilator lint_on WIDTH */
                /* verilator lint_on WIDTH */
        end // always @ (posedge clk)
        end // always @ (posedge clk)
        //synopsys  translate_on
        //synopsys  translate_on
        //synthesis translate_on
        //synthesis translate_on
endmodule
endmodule
/*********************
/*********************
    fwft_fifo_with_output_clear
    fwft_fifo_with_output_clear
    each individual output bit has
    each individual output bit has
    its own clear signal
    its own clear signal
 **********************/
 **********************/
module fwft_fifo_with_output_clear #(
module fwft_fifo_with_output_clear #(
                parameter DATA_WIDTH = 2,
                parameter DATA_WIDTH = 2,
                parameter MAX_DEPTH = 2,
                parameter MAX_DEPTH = 2,
                parameter IGNORE_SAME_LOC_RD_WR_WARNING="NO" // "YES" , "NO"
                parameter IGNORE_SAME_LOC_RD_WR_WARNING="NO" // "YES" , "NO"
                )
                )
                (
                (
                din,     // Data in
                din,     // Data in
                wr_en,   // Write enable
                wr_en,   // Write enable
                rd_en,   // Read the next word
                rd_en,   // Read the next word
                dout,    // Data out
                dout,    // Data out
                full,
                full,
                nearly_full,
                nearly_full,
                recieve_more_than_0,
                recieve_more_than_0,
                recieve_more_than_1,
                recieve_more_than_1,
                reset,
                reset,
                clk,
                clk,
                clear
                clear
                );
                );
        input   [DATA_WIDTH-1:0] din;
        input   [DATA_WIDTH-1:0] din;
        input          wr_en;
        input          wr_en;
        input          rd_en;
        input          rd_en;
        output  [DATA_WIDTH-1:0]  dout;
        output  [DATA_WIDTH-1:0]  dout;
        output         full;
        output         full;
        output         nearly_full;
        output         nearly_full;
        output         recieve_more_than_0;
        output         recieve_more_than_0;
        output         recieve_more_than_1;
        output         recieve_more_than_1;
        input          reset;
        input          reset;
        input          clk;
        input          clk;
        input    [DATA_WIDTH-1:0]  clear;
        input    [DATA_WIDTH-1:0]  clear;
        function integer log2;
        function integer log2;
                input integer number; begin
                input integer number; begin
                        log2=(number <=1) ? 1: 0;
                        log2=(number <=1) ? 1: 0;
                        while(2**log2
                        while(2**log2
                                log2=log2+1;
                                log2=log2+1;
                        end
                        end
                end
                end
        endfunction // log2
        endfunction // log2
        localparam DEPTH_DATA_WIDTH = log2(MAX_DEPTH +1);
        localparam DEPTH_DATA_WIDTH = log2(MAX_DEPTH +1);
        localparam MUX_SEL_WIDTH     = log2(MAX_DEPTH-1);
        localparam MUX_SEL_WIDTH     = log2(MAX_DEPTH-1);
        wire out_ld;
        wire out_ld;
        wire [DATA_WIDTH-1 : 0] dout_next;
        wire [DATA_WIDTH-1 : 0] dout_next;
        wire [DEPTH_DATA_WIDTH-1 : 0]  depth;
        wire [DEPTH_DATA_WIDTH-1 : 0]  depth;
        reg  [DEPTH_DATA_WIDTH-1 : 0]  depth_next;
        reg  [DEPTH_DATA_WIDTH-1 : 0]  depth_next;
        reg  [DATA_WIDTH-1:0]  dout_next_ld;
        reg  [DATA_WIDTH-1:0]  dout_next_ld;
        genvar i;
        genvar i;
        generate
        generate
                if(MAX_DEPTH>2) begin :mwb2
                if(MAX_DEPTH>2) begin :mwb2
                        wire    [MUX_SEL_WIDTH-1    :   0] mux_sel;
                        wire    [MUX_SEL_WIDTH-1    :   0] mux_sel;
                        wire    [DEPTH_DATA_WIDTH-1 :   0] depth_2;
                        wire    [DEPTH_DATA_WIDTH-1 :   0] depth_2;
                        wire                               empty;
                        wire                               empty;
                        wire                               out_sel ;
                        wire                               out_sel ;
                        if(DATA_WIDTH>1) begin :wb1
                        if(DATA_WIDTH>1) begin :wb1
                                wire    [MAX_DEPTH-2        :   0] mux_in  [DATA_WIDTH-1       :0];
                                wire    [MAX_DEPTH-2        :   0] mux_in  [DATA_WIDTH-1       :0];
                                wire    [DATA_WIDTH-1       :   0] mux_out;
                                wire    [DATA_WIDTH-1       :   0] mux_out;
                                reg     [MAX_DEPTH-2        :   0] shiftreg [DATA_WIDTH-1      :0];
                                reg     [MAX_DEPTH-2        :   0] shiftreg [DATA_WIDTH-1      :0];
                                for(i=0;i
                                for(i=0;i
                                        always @(posedge clk ) begin
                                        always @(posedge clk ) begin
                                                //if (reset) begin
                                                //if (`pronoc_reset) begin
                                                //  shiftreg[i] <= {MAX_DEPTH{1'b0}};
                                                //  shiftreg[i] <= {MAX_DEPTH{1'b0}};
                                                //end else begin
                                                //end else begin
                                                if(wr_en) shiftreg[i] <= {shiftreg[i][MAX_DEPTH-3   :   0]  ,din[i]};
                                                if(wr_en) shiftreg[i] <= {shiftreg[i][MAX_DEPTH-3   :   0]  ,din[i]};
                                                //end
                                                //end
                                        end
                                        end
                                        assign mux_in[i]    = shiftreg[i];
                                        assign mux_in[i]    = shiftreg[i];
                                        assign mux_out[i]   = mux_in[i][mux_sel];
                                        assign mux_out[i]   = mux_in[i][mux_sel];
                                        assign dout_next[i] = (out_sel) ? mux_out[i] : din[i];
                                        assign dout_next[i] = (out_sel) ? mux_out[i] : din[i];
                                end //for
                                end //for
                        end else begin :w1
                        end else begin :w1
                                wire    [MAX_DEPTH-2        :   0] mux_in;
                                wire    [MAX_DEPTH-2        :   0] mux_in;
                                wire    mux_out;
                                wire    mux_out;
                                reg     [MAX_DEPTH-2        :   0] shiftreg;
                                reg     [MAX_DEPTH-2        :   0] shiftreg;
                                always @(posedge clk ) begin
                                always @(posedge clk ) begin
                                        if(wr_en) shiftreg <= {shiftreg[MAX_DEPTH-3   :   0]  ,din};
                                        if(wr_en) shiftreg <= {shiftreg[MAX_DEPTH-3   :   0]  ,din};
                                end
                                end
                                assign mux_in    = shiftreg;
                                assign mux_in    = shiftreg;
                                assign mux_out   = mux_in[mux_sel];
                                assign mux_out   = mux_in[mux_sel];
                                assign dout_next = (out_sel) ? mux_out : din;
                                assign dout_next = (out_sel) ? mux_out : din;
                        end
                        end
                        assign full = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0];
                        assign full = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0];
                        assign nearly_full = depth >= MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0] -1'b1;
                        assign nearly_full = depth >= MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0] -1'b1;
                        assign empty  = depth == {DEPTH_DATA_WIDTH{1'b0}};
                        assign empty  = depth == {DEPTH_DATA_WIDTH{1'b0}};
                        assign recieve_more_than_0  = ~ empty;
                        assign recieve_more_than_0  = ~ empty;
                        assign recieve_more_than_1  = ~( depth == {DEPTH_DATA_WIDTH{1'b0}} ||  depth== 1 );
                        assign recieve_more_than_1  = ~( depth == {DEPTH_DATA_WIDTH{1'b0}} ||  depth== 1 );
                        assign out_sel  = (recieve_more_than_1)  ? 1'b1 : 1'b0;
                        assign out_sel  = (recieve_more_than_1)  ? 1'b1 : 1'b0;
                        assign out_ld = (depth !=0 )?  rd_en : wr_en;
                        assign out_ld = (depth !=0 )?  rd_en : wr_en;
                        assign depth_2 = depth-'d2;
                        assign depth_2 = depth-'d2;
                        assign mux_sel = depth_2[MUX_SEL_WIDTH-1   :   0]  ;
                        assign mux_sel = depth_2[MUX_SEL_WIDTH-1   :   0]  ;
                end else if  ( MAX_DEPTH == 2) begin :mw2
                end else if  ( MAX_DEPTH == 2) begin :mw2
                        reg     [DATA_WIDTH-1       :   0] register;
                        reg     [DATA_WIDTH-1       :   0] register;
                        always @(posedge clk ) begin
                        always @(posedge clk ) begin
                                if(wr_en) register <= din;
                                if(wr_en) register <= din;
                        end //always
                        end //always
                        assign full = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0];
                        assign full = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0];
                        assign nearly_full = depth >= MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0] -1'b1;
                        assign nearly_full = depth >= MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0] -1'b1;
                        assign out_ld = (depth !=0 )?  rd_en : wr_en;
                        assign out_ld = (depth !=0 )?  rd_en : wr_en;
                        assign recieve_more_than_0  =  (depth != {DEPTH_DATA_WIDTH{1'b0}});
                        assign recieve_more_than_0  =  (depth != {DEPTH_DATA_WIDTH{1'b0}});
                        assign recieve_more_than_1  = ~( depth == 0 ||  depth== 1 );
                        assign recieve_more_than_1  = ~( depth == 0 ||  depth== 1 );
                        assign dout_next = (recieve_more_than_1) ? register  : din;
                        assign dout_next = (recieve_more_than_1) ? register  : din;
                end else begin :mw1 // MAX_DEPTH == 1
                end else begin :mw1 // MAX_DEPTH == 1
                        assign out_ld       = wr_en;
                        assign out_ld       = wr_en;
                        assign dout_next    =   din;
                        assign dout_next    =   din;
                        assign full         = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0];
                        assign full         = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0];
                        assign nearly_full= 1'b1;
                        assign nearly_full= 1'b1;
                        assign recieve_more_than_0 = full;
                        assign recieve_more_than_0 = full;
                        assign recieve_more_than_1 = 1'b0;
                        assign recieve_more_than_1 = 1'b0;
                end
                end
        endgenerate
        endgenerate
        pronoc_register #(.W(DEPTH_DATA_WIDTH)) reg1 (.in(depth_next), .out(depth), .reset(reset), .clk(clk));
        pronoc_register #(.W(DEPTH_DATA_WIDTH)) reg1 (.in(depth_next), .out(depth), .reset(reset), .clk(clk));
        pronoc_register #(.W(DATA_WIDTH))       reg2 (.in(dout_next_ld), .out(dout ), .reset(reset), .clk(clk));
        pronoc_register #(.W(DATA_WIDTH))       reg2 (.in(dout_next_ld), .out(dout ), .reset(reset), .clk(clk));
        always @ (*)begin
        always @ (*)begin
                depth_next  =  depth;
                depth_next  =  depth;
                if (wr_en & ~rd_en) depth_next  =  depth + 1'h1;
                if (wr_en & ~rd_en) depth_next  =  depth + 1'h1;
                else if (~wr_en & rd_en) depth_next  =  depth - 1'h1;
                else if (~wr_en & rd_en) depth_next  =  depth - 1'h1;
        end//always
        end//always
        generate
        generate
                for(i=0;i
                for(i=0;i
                        always @(*)begin
                        always @(*)begin
                                dout_next_ld[i] = dout[i];
                                dout_next_ld[i] = dout[i];
                                if (clear[i]) dout_next_ld[i]   = 1'b0;
                                if (clear[i]) dout_next_ld[i]   = 1'b0;
                                else if (out_ld) dout_next_ld[i]   = dout_next[i];
                                else if (out_ld) dout_next_ld[i]   = dout_next[i];
                        end//always
                        end//always
                end
                end
        endgenerate
        endgenerate
        //synthesis translate_off
        //synthesis translate_off
        //synopsys  translate_off
        //synopsys  translate_off
        always @(posedge clk)
        always @(posedge clk)
        begin
        begin
                if(~reset)begin
                if(`pronoc_reset==0)begin
                        if (wr_en && ~rd_en && full) begin
                        if (wr_en && ~rd_en && full) begin
                                $display("%t: ERROR: Attempt to write to full FIFO:FIFO size is %d. %m",$time,MAX_DEPTH);
                                $display("%t: ERROR: Attempt to write to full FIFO:FIFO size is %d. %m",$time,MAX_DEPTH);
                                $finish;
                                $finish;
                        end
                        end
                        /* verilator lint_off WIDTH */
                        /* verilator lint_off WIDTH */
                        if (rd_en && !recieve_more_than_0 && IGNORE_SAME_LOC_RD_WR_WARNING == "NO") begin
                        if (rd_en && !recieve_more_than_0 && IGNORE_SAME_LOC_RD_WR_WARNING == "NO") begin
                                $display("%t ERROR: Attempt to read an empty FIFO: %m", $time);
                                $display("%t ERROR: Attempt to read an empty FIFO: %m", $time);
                                $finish;
                                $finish;
                        end
                        end
                        if (rd_en && ~wr_en && !recieve_more_than_0 && IGNORE_SAME_LOC_RD_WR_WARNING == "YES") begin
                        if (rd_en && ~wr_en && !recieve_more_than_0 && IGNORE_SAME_LOC_RD_WR_WARNING == "YES") begin
                                $display("%t ERROR: Attempt to read an empty FIFO: %m", $time);
                                $display("%t ERROR: Attempt to read an empty FIFO: %m", $time);
                                $finish;
                                $finish;
                        end
                        end
                        /* verilator lint_on WIDTH */
                        /* verilator lint_on WIDTH */
                end// ~reset
                end// ~reset
        end // always @ (posedge clk)
        end // always @ (posedge clk)
        //synopsys  translate_on
        //synopsys  translate_on
        //synthesis translate_on
        //synthesis translate_on
endmodule
endmodule
 
 
 
/***************
 
fwft_fifo_bram
 
****************/
 
 
 
 
 
 
 
 
module fwft_fifo_bram #(
module fwft_fifo_bram #(
                parameter DATA_WIDTH = 2,
                parameter DATA_WIDTH = 2,
                parameter MAX_DEPTH = 2,
                parameter MAX_DEPTH = 2,
                parameter IGNORE_SAME_LOC_RD_WR_WARNING="YES" // "YES" , "NO"
                parameter IGNORE_SAME_LOC_RD_WR_WARNING="YES" // "YES" , "NO"
                )
                )
                (
                (
                input [DATA_WIDTH-1:0] din,     // Data in
                input [DATA_WIDTH-1:0] din,     // Data in
                input          wr_en,   // Write enable
                input          wr_en,   // Write enable
                input          rd_en,   // Read the next word
                input          rd_en,   // Read the next word
                output [DATA_WIDTH-1:0]  dout,    // Data out
                output [DATA_WIDTH-1:0]  dout,    // Data out
                output         full,
                output         full,
                output         nearly_full,
                output         nearly_full,
                output         recieve_more_than_0,
                output         recieve_more_than_0,
                output         recieve_more_than_1,
                output         recieve_more_than_1,
                input          reset,
                input          reset,
                input          clk
                input          clk
                );
                );
        function integer log2;
        function integer log2;
                input integer number; begin
                input integer number; begin
                        log2=(number <=1) ? 1: 0;
                        log2=(number <=1) ? 1: 0;
                        while(2**log2
                        while(2**log2
                                log2=log2+1;
                                log2=log2+1;
                        end
                        end
                end
                end
        endfunction // log2
        endfunction // log2
        localparam DEPTH_DATA_WIDTH = log2(MAX_DEPTH +1);
        localparam DEPTH_DATA_WIDTH = log2(MAX_DEPTH +1);
        reg  valid_next;
        reg  valid_next;
        wire valid;
        wire valid;
        wire pass_din_to_out_reg, out_reg_wr_en, bram_out_is_valid_next;
        wire pass_din_to_out_reg, out_reg_wr_en, bram_out_is_valid_next;
        wire bram_out_is_valid;
        wire bram_out_is_valid;
        wire bram_empty, bram_rd_en, bram_wr_en;
        wire bram_empty, bram_rd_en, bram_wr_en;
        wire [DATA_WIDTH-1 : 0] bram_dout;
        wire [DATA_WIDTH-1 : 0] bram_dout;
        wire [DATA_WIDTH-1 : 0] out_reg;
        wire [DATA_WIDTH-1 : 0] out_reg;
        reg  [DATA_WIDTH-1 : 0] out_reg_next;
        reg  [DATA_WIDTH-1 : 0] out_reg_next;
 
 
 
        wire [DEPTH_DATA_WIDTH-1         :   0]  depth;
 
        reg  [DEPTH_DATA_WIDTH-1         :   0]  depth_next;
 
 
        assign dout = (bram_out_is_valid)?  bram_dout : out_reg;
        assign dout = (bram_out_is_valid)?  bram_dout : out_reg;
        assign  pass_din_to_out_reg = (wr_en & ~valid)| // a write has been recived while the reg_flit is not valid
        assign  pass_din_to_out_reg = (wr_en & ~valid)| // a write has been recived while the reg_flit is not valid
                (wr_en & valid & bram_empty & rd_en); //or its valid but bram is empty and its got a read request
                (wr_en & valid & bram_empty & rd_en); //or its valid but bram is empty and its got a read request
        assign bram_rd_en = (rd_en & ~bram_empty);
        assign bram_rd_en = (rd_en & ~bram_empty);
        assign bram_wr_en = (pass_din_to_out_reg)?  1'b0 :wr_en ; //make sure not write on the Bram if the reg fifo is empty
        assign bram_wr_en = (pass_din_to_out_reg)?  1'b0 :wr_en ; //make sure not write on the Bram if the reg fifo is empty
        assign  out_reg_wr_en = pass_din_to_out_reg | bram_out_is_valid;
        assign  out_reg_wr_en = pass_din_to_out_reg | bram_out_is_valid;
        assign  bram_out_is_valid_next = (bram_rd_en )? (rd_en &  ~bram_empty): 1'b0;
        assign  bram_out_is_valid_next = (bram_rd_en )? (rd_en &  ~bram_empty): 1'b0;
        always @(*) begin
        always @(*) begin
                valid_next = valid;
                valid_next = valid;
                if(out_reg_wr_en) valid_next =1'b1;
                if(depth_next == {DEPTH_DATA_WIDTH{1'b0}}) valid_next =1'b0;
 
                else if(out_reg_wr_en) valid_next =1'b1;
                else if( bram_empty & rd_en) valid_next =1'b0;
                else if( bram_empty & rd_en) valid_next =1'b0;
        end
        end
        bram_based_fifo  #(
        bram_based_fifo  #(
                        .Dw(DATA_WIDTH),//data_width
                        .Dw(DATA_WIDTH),//data_width
                        .B(MAX_DEPTH)// buffer num
                        .B(MAX_DEPTH)// buffer num
                )bram_fifo(
                )bram_fifo(
                        .din(din),
                        .din(din),
                        .wr_en(bram_wr_en),
                        .wr_en(bram_wr_en),
                        .rd_en(bram_rd_en),
                        .rd_en(bram_rd_en),
                        .dout(bram_dout),
                        .dout(bram_dout),
                        .full(),
                        .full(),
                        .nearly_full(),
                        .nearly_full(),
                        .empty(bram_empty),
                        .empty(bram_empty),
                        .reset(reset),
                        .reset(reset),
                        .clk(clk)
                        .clk(clk)
                );
                );
 
 
        wire [DEPTH_DATA_WIDTH-1         :   0]  depth;
 
        reg  [DEPTH_DATA_WIDTH-1         :   0]  depth_next;
 
 
 
        pronoc_register #(.W(DATA_WIDTH)      ) reg1 (.in(out_reg_next           ), .out(out_reg), .reset(reset), .clk(clk));
        pronoc_register #(.W(DATA_WIDTH)      ) reg1 (.in(out_reg_next           ), .out(out_reg), .reset(reset), .clk(clk));
        pronoc_register #(.W(1)               ) reg2 (.in(valid_next             ), .out(valid), .reset(reset), .clk(clk));
        pronoc_register #(.W(1)               ) reg2 (.in(valid_next             ), .out(valid), .reset(reset), .clk(clk));
        pronoc_register #(.W(1)               ) reg3 (.in(bram_out_is_valid_next ), .out(bram_out_is_valid), .reset(reset), .clk(clk));
        pronoc_register #(.W(1)               ) reg3 (.in(bram_out_is_valid_next ), .out(bram_out_is_valid), .reset(reset), .clk(clk));
        pronoc_register #(.W(DEPTH_DATA_WIDTH)) reg4 (.in(depth_next             ), .out(depth), .reset(reset), .clk(clk));
        pronoc_register #(.W(DEPTH_DATA_WIDTH)) reg4 (.in(depth_next             ), .out(depth), .reset(reset), .clk(clk));
        always @(*) begin
        always @(*) begin
                out_reg_next = out_reg;
                out_reg_next = out_reg;
                depth_next   = depth;
                depth_next   = depth;
                if (wr_en & ~rd_en) depth_next =   depth + 1'h1;
                if (wr_en & ~rd_en) depth_next =   depth + 1'h1;
                else if (~wr_en & rd_en) depth_next  = depth - 1'h1;
                else if (~wr_en & rd_en) depth_next  = depth - 1'h1;
                if(pass_din_to_out_reg) out_reg_next = din;
                if(pass_din_to_out_reg) out_reg_next = din;
                if(bram_out_is_valid)   out_reg_next = bram_dout;
                else if(bram_out_is_valid)   out_reg_next = bram_dout;
        end
        end
        wire empty;
        wire empty;
        assign full                         = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0];
        assign full                         = depth == MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0];
        assign nearly_full              = depth >= MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0] -1'b1;
        assign nearly_full              = depth >= MAX_DEPTH [DEPTH_DATA_WIDTH-1            :   0] -1'b1;
        assign empty     = depth == {DEPTH_DATA_WIDTH{1'b0}};
        assign empty     = depth == {DEPTH_DATA_WIDTH{1'b0}};
        assign recieve_more_than_0  = ~ empty;
        assign recieve_more_than_0  = ~ empty;
        assign recieve_more_than_1  = ~( depth == {DEPTH_DATA_WIDTH{1'b0}} ||  depth== 1 );
        assign recieve_more_than_1  = ~( depth == {DEPTH_DATA_WIDTH{1'b0}} ||  depth== 1 );
        //synthesis translate_off
        //synthesis translate_off
        //synopsys  translate_off
        //synopsys  translate_off
        always @(posedge clk)
        always @(posedge clk)
        begin
        begin
                if (wr_en & ~rd_en & full) begin
                if (wr_en & ~rd_en & full) begin
                        $display("%t: ERROR: Attempt to write to full FIFO:FIFO size is %d. %m",$time,MAX_DEPTH);
                        $display("%t: ERROR: Attempt to write to full FIFO:FIFO size is %d. %m",$time,MAX_DEPTH);
                        $finish;
                        $finish;
                end
                end
                /* verilator lint_off WIDTH */
                /* verilator lint_off WIDTH */
                if (rd_en & !recieve_more_than_0 & IGNORE_SAME_LOC_RD_WR_WARNING == "NO") begin
                if (rd_en & !recieve_more_than_0 & IGNORE_SAME_LOC_RD_WR_WARNING == "NO") begin
                        $display("%t ERROR: Attempt to read an empty FIFO: %m", $time);
                        $display("%t ERROR: Attempt to read an empty FIFO: %m", $time);
                        $finish;
                        $finish;
                end
                end
                if (rd_en & ~wr_en & !recieve_more_than_0 & (IGNORE_SAME_LOC_RD_WR_WARNING == "YES")) begin
                if (rd_en & ~wr_en & !recieve_more_than_0 & (IGNORE_SAME_LOC_RD_WR_WARNING == "YES")) begin
                        $display("%t ERROR: Attempt to read an empty FIFO: %m", $time);
                        $display("%t ERROR: Attempt to read an empty FIFO: %m", $time);
                        $finish;
                        $finish;
                end
                end
                /* verilator lint_on WIDTH */
                /* verilator lint_on WIDTH */
        end // always @ (posedge clk)
        end // always @ (posedge clk)
        //synopsys  translate_on
        //synopsys  translate_on
        //synthesis translate_on
        //synthesis translate_on
endmodule
endmodule
/**********************************
/**********************************
            bram_based_fifo
            bram_based_fifo
 *********************************/
 *********************************/
module bram_based_fifo  #(
module bram_based_fifo  #(
                parameter Dw = 72,//data_width
                parameter Dw = 72,//data_width
                parameter B  = 10// buffer num
                parameter B  = 10// buffer num
                )(
                )(
                din,
                din,
                wr_en,
                wr_en,
                rd_en,
                rd_en,
                dout,
                dout,
                full,
                full,
                nearly_full,
                nearly_full,
                empty,
                empty,
                reset,
                reset,
                clk
                clk
                );
                );
        function integer log2;
        function integer log2;
                input integer number; begin
                input integer number; begin
                        log2=(number <=1) ? 1: 0;
                        log2=(number <=1) ? 1: 0;
                        while(2**log2
                        while(2**log2
                                log2=log2+1;
                                log2=log2+1;
                        end
                        end
                end
                end
        endfunction // log2
        endfunction // log2
        localparam  B_1 = B-1,
        localparam  B_1 = B-1,
                Bw = log2(B),
                Bw = log2(B),
                DEPTHw=log2(B+1);
                DEPTHw=log2(B+1);
        localparam  [Bw-1   :   0] Bint =   B_1[Bw-1    :   0];
        localparam  [Bw-1   :   0] Bint =   B_1[Bw-1    :   0];
        input [Dw-1:0] din;     // Data in
        input [Dw-1:0] din;     // Data in
        input          wr_en;   // Write enable
        input          wr_en;   // Write enable
        input          rd_en;   // Read the next word
        input          rd_en;   // Read the next word
        output reg [Dw-1:0]  dout;    // Data out
        output reg [Dw-1:0]  dout;    // Data out
        output         full;
        output         full;
        output         nearly_full;
        output         nearly_full;
        output         empty;
        output         empty;
        input          reset;
        input          reset;
        input          clk;
        input          clk;
        reg [Dw-1       :   0] queue [B-1 : 0] /* synthesis ramstyle = "no_rw_check" */;
        reg [Dw-1       :   0] queue [B-1 : 0] /* synthesis ramstyle = "no_rw_check" */;
        reg [Bw- 1      :   0] rd_ptr;
        reg [Bw- 1      :   0] rd_ptr;
        reg [Bw- 1      :   0] wr_ptr;
        reg [Bw- 1      :   0] wr_ptr;
        reg [DEPTHw-1   :   0] depth;
        reg [DEPTHw-1   :   0] depth;
        // Sample the data
        // Sample the data
        always @(posedge clk)
        always @(posedge clk)
        begin
        begin
                if (wr_en)
                if (wr_en)
                        queue[wr_ptr] <= din;
                        queue[wr_ptr] <= din;
                if (rd_en)
                if (rd_en)
                        dout <=   queue[rd_ptr];
                        dout <=   queue[rd_ptr];
        end
        end
        always @(posedge clk)
        always @(posedge clk)
        begin
        begin
                if (reset) begin
                if (`pronoc_reset) begin
                        rd_ptr <= {Bw{1'b0}};
                        rd_ptr <= {Bw{1'b0}};
                        wr_ptr <= {Bw{1'b0}};
                        wr_ptr <= {Bw{1'b0}};
                        depth  <= {DEPTHw{1'b0}};
                        depth  <= {DEPTHw{1'b0}};
                end
                end
                else begin
                else begin
                        if (wr_en) wr_ptr <= (wr_ptr==Bint)? {Bw{1'b0}} : wr_ptr + 1'b1;
                        if (wr_en) wr_ptr <= (wr_ptr==Bint)? {Bw{1'b0}} : wr_ptr + 1'b1;
                        if (rd_en) rd_ptr <= (rd_ptr==Bint)? {Bw{1'b0}} : rd_ptr + 1'b1;
                        if (rd_en) rd_ptr <= (rd_ptr==Bint)? {Bw{1'b0}} : rd_ptr + 1'b1;
                        if (wr_en & ~rd_en) depth <=  depth + 1'b1;
                        if (wr_en & ~rd_en) depth <=  depth + 1'b1;
                        else if (~wr_en & rd_en) depth <=  depth - 1'b1;
                        else if (~wr_en & rd_en) depth <=  depth - 1'b1;
                end
                end
        end
        end
        //assign dout = queue[rd_ptr];
        //assign dout = queue[rd_ptr];
        localparam  [DEPTHw-1   :   0] Bint2 =   B_1[DEPTHw-1   :   0];
        localparam  [DEPTHw-1   :   0] Bint2 =   B_1[DEPTHw-1   :   0];
        assign full = depth == B [DEPTHw-1   :   0];
        assign full = depth == B [DEPTHw-1   :   0];
        assign nearly_full = depth >=Bint2; //  B-1
        assign nearly_full = depth >=Bint2; //  B-1
        assign empty = depth == {DEPTHw{1'b0}};
        assign empty = depth == {DEPTHw{1'b0}};
        //synthesis translate_off
        //synthesis translate_off
        //synopsys  translate_off
        //synopsys  translate_off
        always @(posedge clk)
        always @(posedge clk)
        begin
        begin
                if(~reset)begin
                if(`pronoc_reset==1'b0)begin
                        if (wr_en && depth == B[DEPTHw-1   :   0] && !rd_en) begin
                        if (wr_en && depth == B[DEPTHw-1   :   0] && !rd_en) begin
                                $display(" %t: ERROR: Attempt to write to full FIFO: %m",$time);
                                $display(" %t: ERROR: Attempt to write to full FIFO: %m",$time);
                                $finish;
                                $finish;
                        end
                        end
                        if (rd_en && depth == {DEPTHw{1'b0}}) begin
                        if (rd_en && depth == {DEPTHw{1'b0}}) begin
                                $display("%t: ERROR: Attempt to read an empty FIFO: %m",$time);
                                $display("%t: ERROR: Attempt to read an empty FIFO: %m",$time);
                                $finish;
                                $finish;
                        end
                        end
                end//~reset
                end//~reset
        end
        end
        //synopsys  translate_on
        //synopsys  translate_on
        //synthesis translate_on
        //synthesis translate_on
endmodule // fifo
endmodule // fifo
 
 

powered by: WebSVN 2.1.0

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