David
David

Reputation: 53

verilog code of FIFO (first in first out) is not showing the proper result?

I wanted to design a FIFO having a certain depth and width. The Verilog code of the FIFO is written in Vivado 2017.4. The code is able to to read the input data, but it is only showing XX as the output. The design sources and test bench of the FIFO is given below. Help me to find the problem.

module fifo #(parameter WIDTH=8, parameter DEPTH=8) (
    input wire [WIDTH-1:0] data_in,
    output reg [WIDTH-1:0] data_out,
        output reg data_valid,
        input wire reset,
    input wire clk
    );
        function integer clog2(input reg [32-1:0] value); 
        begin 
            value = value-1;
            for (clog2=0; value>0; clog2=clog2+1)
                value = value>>1;
        end 
    endfunction
        reg [WIDTH-1:0] data [DEPTH-1:0];
    reg [clog2(DEPTH)-1:0] write_pointer;
    reg [clog2(DEPTH)-1:0] read_pointer;
        always @(posedge clk) begin
        if (reset == 1'b0) begin
            write_pointer <= 0;
            read_pointer <= 1;
            data_valid <= 0;
        end else begin
            if (write_pointer == DEPTH-1) write_pointer <= 0;
            else write_pointer <= write_pointer + 1;
                if (read_pointer == DEPTH-1) read_pointer <= 0;
            else read_pointer <= read_pointer + 1;
                data[write_pointer] <= data_in;
            data_out <= data[read_pointer];
        end
            if (read_pointer == 0) data_valid <= 1'b1;
    end
    endmodule

test bench

`timescale 1ns / 1ps
module fifo_tb;
    parameter WIDTH = 16;
    parameter DEPTH = 8;
    reg reset;
    reg clk;
reg [(WIDTH-1):0] data_in;
    wire [(WIDTH-1):0] data_out;
    wire data_valid;    
   fifo #(WIDTH,DEPTH) U0(data_in,data_out,data_valid,reset,clk);
     initial begin
        clk = 0;
        reset = 1;
        #1 reset = 0;
        #1 reset = 1;

    end

    // Create clock
    always
    #5 clk = ~clk;

reg signed [15:0] rom_memory [4096-1:0];
integer i=0;
initial 
begin
    $readmemh("C:\\Users\\input_7_zz.txt",rom_memory);

end

always@(posedge clk )
begin
    if(~reset)
    begin
    data_in <= 0;
    end
    else
    begin
      data_in <= rom_memory[i];
     i <= i+ 1;
 end

end
endmodule

Upvotes: 0

Views: 1104

Answers (1)

Serge
Serge

Reputation: 12354

In your test bench code the clock is changed every 5 ticks:

// Create clock
always
    #5 clk = ~clk;

The reset in RTL uses posedge of this clock:

always @(posedge clk) begin
    if (reset == 1'b0) begin
        write_pointer <= 0;
        read_pointer <= 1;
        data_valid <= 0;

So, the reset action could happen only if the posedge clk could be detected during the reset period. In other words you have a synchronous reset.

Nevertheless, in your test bench code your reset lasts only a single tick:

initial begin
    clk = 0;
    reset = 1;
    #1 reset = 0;
    #1 reset = 1; // << one tick after the reset was asserted.
end

Potentially you have 2 possible solutions.

1) keep the synchronous reset, but make sure that the posedge of the clk could be detected during the reset. So, make it bigger than a clock cycle (or at least half clock cycle if you are sure when it comes). Something like 5 should work in your case. Make it 10 or more to be sure for arbitrary starting points.

initial begin
    clk = 0;
    reset = 1;
    #1 reset = 0;
    #5 reset = 1; // << 5 tick after the reset was asserted. 

The reset above will last from time 1 to time 6. The first posegde will happen at time 5. So, it should be sufficient in your case.

2) you can use an asynchronous reset in RTL which will look as the following:

always @(posedge clk or reset) begin
    if (reset == 1'b0) begin
        write_pointer <= 0;
        read_pointer <= 1;
        data_valid <= 0;

In the above case the always block will be executed whenever 'reset' changes. However you have to be careful about the timing of other assignment there. They could happen when you deassert reset with some offset from the posedge clk.

Upvotes: 2

Related Questions