请教一个可综合的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,如果我的理解有什么问题的话,求指教 是我的问题太2b还是太深奥了。。。没人知道么 这几个东西是不相关的,在写的时候 地址进行加一要在下一个时钟周期,而你的写数据又是以你现在的地址写进去 回复【2楼】Fourier00
-----------------------------------------------------------------------
我的意思是,上面2段代码都有相同的敏感量,也就是说两端代码都被触发的情况下,会有竞争么? verilog 在两个不同的always内不能操作同一个reg的 回复【4楼】h198848
-----------------------------------------------------------------------
非常感谢您的回答。
那么新的疑问来了,究竟哪个always内会先对wr_ptr操作呢?是跟always模块在代码中的先后顺序有关,还是说两个always比谁先执行到这一步呢? 回复【5楼】lizardno1
回复【4楼】h198848
-----------------------------------------------------------------------
非常感谢您的回答。
那么新的疑问来了,究竟哪个always内会先对wr_ptr操作呢?是跟always模块在代码中的先后顺序有关,还是说两个always比谁先执行到这一步呢?
-----------------------------------------------------------------------
编译不过去的 如果在两个always 操作同一个reg
会报错的
哪怕你是在不同的条件下操作 回复【6楼】h198848
-----------------------------------------------------------------------
实际上,上面的代码,2个always的模块,一个是使用了wr_ptr,另一个才对wr_ptr作出了修改。
因为这段代码是《Verilog HDL 数字设计与综合》 Samir Palniktar著 里面附带的一个FIFO代码,总不会这个有错吧。。。
所以我的疑惑还是没有解决
不过,还是非常感谢您的热心解答
页:
[1]