我已经为包含任务的同步FIFO编写了代码。我在任务t_write
中收到错误消息
赋值语句l-value
中的语法错误
但是,我不明白错误的原因 任何帮助将不胜感激。
源代码:
module sync_fifo #(parameter Dwidth = 16, Ddepth = 2) (output reg [Dwidth-1:0] RD_DATA,
output reg FULL, EMPTY,
input [Dwidth-1:0] WR_DATA,
input WRITE, READ, CLK, RSTB);
reg COUNT = 0;
reg READ_PTR = 0;
reg WRITE_PTR = 0;
reg [Dwidth-1:0] FIFO[Ddepth-1:0];
task automatic t_read;
begin
RD_DATA = FIFO(READ_PTR);
COUNT = COUNT - 1;
READ_PTR = READ_PTR + 1;
end
endtask
task automatic t_write;
begin
FIFO(WRITE_PTR) = WR_DATA;
WRITE_PTR = WRITE_PTR + 1;
COUNT = COUNT + 1;
end
endtask
always @(COUNT) begin
FULL = (COUNT == Ddepth);
EMPTY = (COUNT == 0);
end
always @(posedge CLK) begin
if(RSTB) begin
COUNT = 0;
READ_PTR = 0;
WRITE_PTR = 0;
end
end
always @(posedge CLK) begin
if(!RSTB) begin
if(READ & !WRITE) begin
if(!EMPTY)
t_read;
else
$display("FIFO is empty");
end
end
end
always @(posedge CLK) begin
if(!RSTB) begin
if(!READ & WRITE) begin
if(!FULL)
t_write;
else
$display("FIFO is full");
end
end
end
always @(posedge CLK) begin
if(!RSTB) begin
if(READ & WRITE) begin
if(!EMPTY && !FULL) begin
t_read;
t_write;
end
else if(FULL) begin
t_read;
$display("FIFO is full");
end
else if(EMPTY) begin
t_write;
$display("FIFO is empty");
end
end
end
end
endmodule
答案 0 :(得分:0)
Verilog可能会将FIFO(WRITE_PTR)
作为一个函数进行互操作(它不能是l值),因为您使用了括号。对于数组索引,您必须使用方括号[ ]
。
您在阅读任务中遇到同样的问题。您的编译器在检测到之前会出错,或者在日志文件中出错。
仅供参考,您的代码可能会模拟,但绝对不能合成。您的指针,计数器和FIFO分配在多个始终块中,这对于合成来说是不合法的。你需要将它们组合成一个总是块。使用else-if或case语句。例如:
always @(posedge CLK)
begin
if(!RSTB) begin
// reset logic
end
else begin
case({READ,WRITE})
2’b10 : begin
// read logic
end
// other conditions
endcase
end
end
此外,您应该使用非阻塞(<=
)分配同步逻辑。这将防止模拟器调度程序中的竞争条件与其他总是采样输出值的块。它不会影响合成。
我还建议您将@(COUNT)
更改为@*
。它不会改变你的逻辑。 @*
是自动灵敏度,是自2001年添加组合逻辑以来的首选组合逻辑。如果需要使用Verilog-1995或特殊情况模拟行为模型,您应该只对组合逻辑的灵敏度列表进行硬编码。