任务错误:赋值语句l-value中的语法错误

时间:2018-01-21 04:39:36

标签: verilog

我已经为包含任务的同步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

1 个答案:

答案 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或特殊情况模拟行为模型,您应该只对组合逻辑的灵敏度列表进行硬编码。