1

I have written code for a synchronous FIFO that contains tasks. I am getting an error in task t_write that says

syntax error in assignment statement l-value

However, I do not understand the cause of the error.
Any help would be appreciated.

Source code:

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 Answer 1

1

Verilog is likely interoperating FIFO(WRITE_PTR) as a function (which cannot be a l-value) because you used parentheses. For array indexing you must use square brackets [ ].

You have the same problem in your read task. Either your compiler errors out before detecting it or it is lower in the log file.

FYI, your codes may simulate but it definitely will not synthesize. Your pointer, counters, and FIFO are being assigned in multiple always blocks which is not legal for synthesis. You need to combined them into one always block. Use else-if or case statements. Example:

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

Also you should assign synchronous logic with non-blocking (<=). This will prevent race conditions in the simulator’s scheduler with other always blocks that sample the output values. It will not impacted synthesis.

I will also recommended you change @(COUNT) to @*. It will not change your logic. @* is auto sensitivity and is the preferred way of doing combination logic since it was added in 2001. You should only hard code the sensitivity list of combination logic if required to use Verilog-1995 or special case analog behavioral models.

Sign up to request clarification or add additional context in comments.

1 Comment

thank you so much. that solved my problem. As for you suggestion on using multiple always blocks, I will try merging it into one as you suggested and give a try

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.