Synchronous FIFO
In Verilog, you can implement a FIFO data structure using a combination of registers and logic gates. Here’s an example of how you can implement a simple FIFO module in Verilog:
RTL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | module sync_fifo(clk,rst,wr_valid,rd_valid,wdata,rdata,full,empty,wr_error,rd_error); parameter WIDTH = 8 ; parameter DEPTH = 16 ; parameter PTR_WIDTH = $clog2(DEPTH) ; //-----------input------------------- input clk,rst,wr_valid,rd_valid; input [WIDTH-1:0] wdata ; //-----------output------------------ output reg [WIDTH-1:0] rdata ; output reg full,empty; output reg wr_error,rd_error ; //---------------register------------- reg [PTR_WIDTH:0] wr_ptr_reg,rd_ptr_reg ; //5 bit--> 0-3 bits i am using as toggle bit. reg [WIDTH-1:0] mem[DEPTH-1:0] ; integer i ; //---------------define--------------- `define wr_tgl_f wr_ptr_reg[PTR_WIDTH] //last bit use as toggle bit. `define wr_ptr wr_ptr_reg[PTR_WIDTH-1:0] //0-3-->4 bit use as ptr. `define rd_ptr rd_ptr_reg[PTR_WIDTH-1:0]//0-3-->4 bit use as ptr. `define rd_tgl_f rd_ptr_reg [PTR_WIDTH] //last bit use as toggle bit. //------read-write_error--------------- always@(*) begin wr_error= full & wr_valid; rd_error = empty & rd_valid; end //-------------write_block------------ always @(posedge clk) begin if(rst) begin full <= 0 ; wr_ptr_reg <= 0 ; for(i = 0 ; i < DEPTH ; i = i+1) mem[i] <= 0 ; end else if(wr_valid & !full) begin mem[`wr_ptr] <= wdata ; wr_ptr_reg <= wr_ptr_reg + 1 ; end else begin mem[`wr_ptr] <= mem[`wr_ptr] ; wr_ptr_reg <= wr_ptr_reg ; end end //-----------read_block------------- always @(posedge clk) begin if(rst) begin rdata <= 0 ; empty <= 1 ; rd_ptr_reg <= 0 ; for(i = 0 ; i < DEPTH ; i = i+1) mem[i] <= 0 ; end else if(rd_valid&!empty) begin rdata <= mem[`rd_ptr] ; rd_ptr_reg <= rd_ptr_reg + 1 ; end else begin rdata <= rdata; rd_ptr_reg <= rd_ptr_reg ; end end //-------full_&_empty_check--------- always @(*) begin full= (rd_ptr_reg=={~`wr_tgl_f,`wr_ptr}) ?1'b1:1'b0; empty=(rd_ptr_reg==wr_ptr_reg) ?1'b1:1'b0; end endmodule |
TESTBENCH
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | `include "sync_fifo.v" module tb ; parameter WIDTH = 8 ; parameter DEPTH = 16 ; parameter PTR_WIDTH = $clog2(DEPTH) ; reg clk,rst,wr_valid,rd_valid; reg [WIDTH-1:0] wdata ; wire [WIDTH-1:0] rdata ; wire full,empty,wr_error,rd_error ; integer i,j; reg [70*8:1]testname; //instantiation of design in tb with parameter overriding sync_fifo #(.DEPTH(DEPTH),.WIDTH(WIDTH),.PTR_WIDTH(PTR_WIDTH)) dut( clk,rst,wr_valid,rd_valid,wdata,rdata,full,empty,wr_error,rd_error ); //clk generation initial begin clk = 0 ; forever #5 clk = ~clk ; end //task for write task wr_fifo(input [PTR_WIDTH:0] num_loc); begin for(i = 0 ; i < num_loc ; i = i+1) begin @(posedge clk) ; wr_valid = 1 ; wdata = $random ; end @(posedge clk) ; wr_valid = 0 ; wdata = 0 ; end endtask //task for read task rd_fifo(input [PTR_WIDTH:0] num_loc); begin for(j = 0 ; j < num_loc ; j = j+1) begin @(posedge clk) ; rd_valid = 1 ; end @(posedge clk) ; rd_valid = 0 ; end endtask //task for reset all inputs task reset_inputs(); begin wr_valid = 0 ; rd_valid = 0 ; wdata = 0 ; end endtask initial begin $value$plusargs( "testname=%s" ,testname); rst= 1 ; i=0; j=0; reset_inputs(); @(posedge clk) ; rst= 0 ; case(testname) "test_fifo_full" : begin wr_fifo(DEPTH); end "test_fifo_empty" : begin wr_fifo(DEPTH); rd_fifo(DEPTH); end "test_fifo_full_error" : begin wr_fifo(DEPTH+5); rd_fifo(DEPTH+4); end "test_fifo_empty_error" : begin wr_fifo(DEPTH); rd_fifo(DEPTH+4); end "test_fifo_concurrent_wr_rd_no_delay" : begin fork wr_fifo(DEPTH); rd_fifo(DEPTH); join end endcase #50 $finish ; end //waveform generation /* initial begin $dumpfile( "dump.vcd" ); $dumpvars(1,tb); end*/ endmodule |
FIFO
Nice post. I learn something new and challenging on websites I stumbleupon every day. It will always be useful to read through articles from other writers and use a little something from other websites.
Thankyou for your feedback !!