lizardno1 发表于 2011-11-10 23:17:52

请教一个可综合的FIFO Verilog代码中一个变量是否会产生竞争的问题

All ports with a suffix "N" are low-asserted.

Clk— Clock signal

RstN— Reset signal

Data_In— 32-bit data into the FIFO

FInN— Write into FIFO signal

FClrN— Clear signal to FIFO

FOutN— Read from FIFO signal

Output ports

F_Data— 32-bit output data from FIFO

F_FullN— Signal indicating that FIFO is full

F_EmptyN— Signal indicating that FIFO is empty

F_LastN— Signal indicating that FIFO has space for one data value

F_SLastN— Signal indicating that FIFO has space for two data values

F_FirstN— Signal indicating that there is only one data value in FIFO

 

The Verilog HDL code for the FIFO implementation is shown in Example F-1.

Example F-1 Synthesizable FIFO Model

////////////////////////////////////////////////////////////////////
// FileName:"Fifo.v"
// Author:Venkata Ramana Kalapatapu
// Company :Sand Microelectronics Inc.
//         (now a part of Synopsys, Inc.),
// Profile :Sand develops Simulation Models, Synthesizable Cores and
//         Performance Analysis Tools for Processors, buses and
//         memory products.Sand's products include models for
//         industry-standard components and custom-developed models
//         for specific simulation environments.
//
////////////////////////////////////////////////////////////////////


`defineFWIDTH   32         // Width of the FIFO.
`defineFDEPTH   4            // Depth of the FIFO.
`defineFCWIDTH    2            // Counter Width of the FIFO 2 to power
                                 // FCWIDTH = FDEPTH.
module FIFO(Clk,
            RstN,
            Data_In,
            FClrN,
            FInN,
            FOutN,

            F_Data,
            F_FullN,
            F_LastN,
            F_SLastN,
            F_FirstN,
            F_EmptyN
         );



input                     Clk;      // CLK signal.
input                     RstN;   // Low Asserted Reset signal.
input [(`FWIDTH-1):0]       Data_In;// Data into FIFO.
input                     FInN;   // Write into FIFO Signal.
input                     FClrN;    // Clear signal to FIFO.
input                     FOutN;    // Read from FIFO signal.

output [(`FWIDTH-1):0]      F_Data;   // FIFO data out.
output                      F_FullN;// FIFO full indicating signal.
output                      F_EmptyN; // FIFO empty indicating signal.
output                      F_LastN;// FIFO Last but one signal.
output                      F_SLastN; // FIFO SLast but one signal.
output                      F_FirstN; // Signal indicating only one
                                    // word in FIFO.


reg                F_FullN;
reg                F_EmptyN;
reg                F_LastN;
reg                F_SLastN;
reg                F_FirstN;

reg    [`FCWIDTH:0]      fcounter; //counter indicates num of data in FIFO
reg    [(`FCWIDTH-1):0]   rd_ptr;      // Current read pointer.
reg    [(`FCWIDTH-1):0]   wr_ptr;      // Current write pointer.
wire   [(`FWIDTH-1):0]    FIFODataOut; // Data out from FIFO MemBlk
wire   [(`FWIDTH-1):0]    FIFODataIn;// Data into FIFO MemBlk

wire   ReadN= FOutN;
wire   WriteN = FInN;

assign F_Data   = FIFODataOut;
assign FIFODataIn = Data_In;


    FIFO_MEM_BLK memblk(.clk(Clk),
                        .writeN(WriteN),
                        .rd_addr(rd_ptr),
                        .wr_addr(wr_ptr),
                        .data_in(FIFODataIn),
                        .data_out(FIFODataOut)
                     );



    // Control circuitry for FIFO. If reset or clr signal is asserted,
    // all the counters are set to 0. If write only the write counter
    // is incremented else if read only read counter is incremented
    // else if both, read and write counters are incremented.
    // fcounter indicates the num of items in the FIFO. Write only
    // increments the fcounter, read only decrements the counter, and
    // read && write doesn't change the counter value.
    always @(posedge Clk or negedge RstN)
    begin

       if(!RstN) begin
         fcounter    <= 0;
         rd_ptr      <= 0;
         wr_ptr      <= 0;
       end
       else begin

         if(!FClrN ) begin
               fcounter    <= 0;
               rd_ptr      <= 0;
               wr_ptr      <= 0;
         end
         else begin

               if(!WriteN && F_FullN)
                   wr_ptr <= wr_ptr + 1;

               if(!ReadN && F_EmptyN)
                   rd_ptr <= rd_ptr + 1;

               if(!WriteN && ReadN && F_FullN)
                   fcounter <= fcounter + 1;

               else if(WriteN && !ReadN && F_EmptyN)
                   fcounter <= fcounter - 1;
          end
       end
    end



    // All the FIFO status signals depends on the value of fcounter.
    // If the fcounter is equal to fdepth, indicates FIFO is full.
    // If the fcounter is equal to zero, indicates the FIFO is empty.



    // F_EmptyN signal indicates FIFO Empty Status. By default it is
    // asserted, indicating the FIFO is empty. After the First Data is
    // put into the FIFO the signal is deasserted.
    always @(posedge Clk or negedge RstN)
    begin

       if(!RstN)
          F_EmptyN <= 1'b0;

       else begin
          if(FClrN==1'b1) begin

             if(F_EmptyN==1'b0 && WriteN==1'b0)

               F_EmptyN <= 1'b1;

             else if(F_FirstN==1'b0 && ReadN==1'b0 && WriteN==1'b1)

               F_EmptyN <= 1'b0;
          end
          else
             F_EmptyN <= 1'b0;
       end
    end

    // F_FirstN signal indicates that there is only one datum sitting
    // in the FIFO. When the FIFO is empty and a write to FIFO occurs,
    // this signal gets asserted.
    always @(posedge Clk or negedge RstN)
    begin

       if(!RstN)

          F_FirstN <= 1'b1;

       else begin
          if(FClrN==1'b1) begin

             if((F_EmptyN==1'b0 && WriteN==1'b0) ||
                (fcounter==2 && ReadN==1'b0 && WriteN==1'b1))

               F_FirstN <= 1'b0;

             else if (F_FirstN==1'b0 && (WriteN ^ ReadN))
               F_FirstN <= 1'b1;
          end
          else begin

             F_FirstN <= 1'b1;
          end
       end
    end


    // F_SLastN indicates that there is space for only two data words
    //in the FIFO.
    always @(posedge Clk or negedge RstN)
    begin

       if(!RstN)

          F_SLastN <= 1'b1;

       else begin

          if(FClrN==1'b1) begin

             if( (F_LastN==1'b0 && ReadN==1'b0 && WriteN==1'b1) ||
               (fcounter == (`FDEPTH-3) && WriteN==1'b0 && ReadN==1'b1))

               F_SLastN <= 1'b0;


             else if(F_SLastN==1'b0 && (ReadN ^ WriteN) )
               F_SLastN <= 1'b1;

          end
          else
             F_SLastN <= 1'b1;

       end
    end

    // F_LastN indicates that there is one space for only one data
    // word in the FIFO.
    always @(posedge Clk or negedge RstN)
    begin

       if(!RstN)

          F_LastN <= 1'b1;

       else begin
          if(FClrN==1'b1) begin

             if ((F_FullN==1'b0 && ReadN==1'b0)||
               (fcounter == (`FDEPTH-2) && WriteN==1'b0 && ReadN==1'b1))

               F_LastN <= 1'b0;

             else if(F_LastN==1'b0 && (ReadN ^ WriteN) )
               F_LastN <= 1'b1;
          end
          else
             F_LastN <= 1'b1;
       end
    end


    // F_FullN indicates that the FIFO is full.
    always @(posedge Clk or negedge RstN)
    begin

       if(!RstN)

         F_FullN <= 1'b1;

       else begin
         if(FClrN==1'b1)begin

               if (F_LastN==1'b0 && WriteN==1'b0 && ReadN==1'b1)

                  F_FullN <= 1'b0;

               else if(F_FullN==1'b0 && ReadN==1'b0)

                  F_FullN <= 1'b1;
         end
         else
               F_FullN <= 1'b1;

       end
    end

endmodule



///////////////////////////////////////////////////////////////////
//
//
//   Configurable memory block for fifo. The width of the mem
//   block is configured via FWIDTH. All the data into fifo is done
//   synchronous to block.
//
//   Author : Venkata Ramana Kalapatapu
//
///////////////////////////////////////////////////////////////////

module FIFO_MEM_BLK( clk,
                     writeN,
                     wr_addr,
                     rd_addr,
                     data_in,
                     data_out
                   );


input                  clk;       // input clk.
inputwriteN;// Write Signal to put data into fifo.
input[(`FCWIDTH-1):0]wr_addr;   // Write Address.
input[(`FCWIDTH-1):0]rd_addr;   // Read Address.
input[(`FWIDTH-1):0]   data_in;   // DataIn in to Memory Block

output [(`FWIDTH-1):0]   data_out;// Data Out from the Memory
                                    // Block(FIFO)

wire   [(`FWIDTH-1):0] data_out;

reg    [(`FWIDTH-1):0] FIFO;



assign data_out= FIFO;

always @(posedge clk)
begin

   if(writeN==1'b0)
      FIFO <= data_in;
end

endmodule


我的问题是:module FIFO_MEM_BLK中的这句

always @(posedge clk)
begin

   if(writeN==1'b0)
      FIFO <= data_in;
end

和第一个always 块中的下面这句
               if(!WriteN && F_FullN)
                   wr_ptr <= wr_ptr + 1;
会不会产生下面所述情形呢?
还有没进行写操作的时候,wr_ptr就+1了,或者说开始执行/执行完了FIFO <= data_in,再执行wr_ptr+1。
也就是说,这两个语句产生了竞争?

请高人解惑,才看了一天的Verilog HDL,如果我的理解有什么问题的话,求指教

lizardno1 发表于 2011-11-11 16:38:07

是我的问题太2b还是太深奥了。。。没人知道么

Fourier00 发表于 2011-11-11 21:25:51

这几个东西是不相关的,在写的时候 地址进行加一要在下一个时钟周期,而你的写数据又是以你现在的地址写进去

lizardno1 发表于 2011-11-11 21:47:48

回复【2楼】Fourier00
-----------------------------------------------------------------------

我的意思是,上面2段代码都有相同的敏感量,也就是说两端代码都被触发的情况下,会有竞争么?

h198848 发表于 2011-11-11 22:34:26

verilog 在两个不同的always内不能操作同一个reg的

lizardno1 发表于 2011-11-11 23:13:39

回复【4楼】h198848
-----------------------------------------------------------------------

非常感谢您的回答。
那么新的疑问来了,究竟哪个always内会先对wr_ptr操作呢?是跟always模块在代码中的先后顺序有关,还是说两个always比谁先执行到这一步呢?

h198848 发表于 2011-11-12 10:13:41

回复【5楼】lizardno1
回复【4楼】h198848
-----------------------------------------------------------------------
非常感谢您的回答。
那么新的疑问来了,究竟哪个always内会先对wr_ptr操作呢?是跟always模块在代码中的先后顺序有关,还是说两个always比谁先执行到这一步呢?
-----------------------------------------------------------------------

编译不过去的 如果在两个always 操作同一个reg
会报错的
哪怕你是在不同的条件下操作

lizardno1 发表于 2011-11-12 13:29:00

回复【6楼】h198848
-----------------------------------------------------------------------

实际上,上面的代码,2个always的模块,一个是使用了wr_ptr,另一个才对wr_ptr作出了修改。
因为这段代码是《Verilog HDL 数字设计与综合》 Samir Palniktar著 里面附带的一个FIFO代码,总不会这个有错吧。。。
所以我的疑惑还是没有解决

不过,还是非常感谢您的热心解答
页: [1]
查看完整版本: 请教一个可综合的FIFO Verilog代码中一个变量是否会产生竞争的问题