You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同步FIFO任务t_write报赋值语句左值语法错误,请求排查

Fixing the "syntax error in assignment statement l-value" in Your Sync FIFO

Hey there, let's break down the error you're seeing in your t_write task—it's a straightforward fix once you spot it, plus I'll point out a few other tweaks to make your FIFO more robust.

The Root Cause of the Syntax Error

In Verilog, when you access elements of a memory array (like your FIFO register array), you must use square brackets [] instead of parentheses (). Your code uses parentheses for array indexing in both the t_read and t_write tasks, which is invalid syntax—this is exactly what's triggering the "l-value" error.

Here's where you went wrong:

// Wrong in t_read:
RD_DATA = FIFO(READ_PTR);
// Wrong in t_write:
FIFO(WRITE_PTR) = WR_DATA;

Fixing the Array Indexing

Replace the parentheses with square brackets in both tasks. The corrected tasks look like this:

task automatic t_read;
begin
  RD_DATA = FIFO[READ_PTR];  // Use [] instead of ()
  COUNT = COUNT - 1;
  READ_PTR = READ_PTR + 1;
end
endtask

task automatic t_write;
begin
  FIFO[WRITE_PTR] = WR_DATA;  // Use [] instead of ()
  WRITE_PTR = WRITE_PTR + 1;
  COUNT = COUNT + 1;
end
endtask

Bonus: Additional Improvements for Your FIFO

While we're at it, here are a few other adjustments to make your code more flexible and correct:

  • Pointer/Count Bit Width: Your COUNT, READ_PTR, and WRITE_PTR are declared as 1-bit registers (reg COUNT = 0;). This will only work when Ddepth=2—for any larger depth, you'll get overflow issues. Change their declarations to use a width based on the depth parameter:
    reg [$clog2(Ddepth)-1:0] COUNT = 0;
    reg [$clog2(Ddepth)-1:0] READ_PTR = 0;
    reg [$clog2(Ddepth)-1:0] WRITE_PTR = 0;
    
    $clog2 calculates the minimum number of bits needed to represent the depth (e.g., 2 bits for Ddepth=4, 3 bits for Ddepth=8, etc.).
  • Reset Logic: Your reset block checks if(RSTB)—but since your port is named RSTB (typically meaning active-low reset), you probably want to trigger reset when RSTB is low. Adjust the always block to:
    always @(posedge CLK)
    begin
      if(!RSTB)  // Active-low reset
      begin
        COUNT = 0;
        READ_PTR = 0;
        WRITE_PTR = 0;
      end
    end
    
  • Combination Logic Sensitivity: Your always @(COUNT) block for FULL and EMPTY works here, but using always @* is safer—it automatically includes all inputs to the block, preventing accidental missing sensitivity list entries:
    always @*
    begin
      FULL = (COUNT == Ddepth);
      EMPTY = (COUNT == 0);
    end
    

Full Corrected Code

Here's the complete fixed version of your FIFO module with all the above changes:

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 [$clog2(Ddepth)-1:0] COUNT = 0;
reg [$clog2(Ddepth)-1:0] READ_PTR = 0;
reg [$clog2(Ddepth)-1:0] 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 @*
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

内容的提问来源于stack exchange,提问作者badri18

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:44:15