simple_fifo.sv (2408B)
1 // Copyright 2014 Brian Swetland <swetland@frotz.net> 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 `timescale 1ns / 1ps 16 17 // rvalid: indicates rd was successful and rdata contains the read data 18 // not_full: indicates that wr will be successful if attempted 19 // not_empty: indicates that rd will be successful if attempted 20 21 module simple_fifo( 22 input clk, 23 24 input wr, 25 input [WIDTH-1:0]wdata, 26 27 input rd, 28 output [WIDTH-1:0]rdata, 29 output reg rvalid = 0, 30 31 output not_empty, 32 output not_full 33 ); 34 35 parameter WIDTH = 8; // bit width of fifo entries 36 parameter DEPTH = 8; // fifo contains 2^DEPTH entries 37 38 reg memrd = 0; 39 reg memwr = 0; 40 41 reg [DEPTH:0]rdptr = 0; 42 reg [DEPTH:0]wrptr = 0; 43 44 reg [DEPTH:0]next_rdptr; 45 reg [DEPTH:0]next_wrptr; 46 reg next_rvalid; 47 48 wire [DEPTH:0]count = (wrptr - rdptr); 49 wire full = count[DEPTH]; 50 wire empty = (count == 0); 51 52 wire [DEPTH-1:0]memraddr; 53 wire [WIDTH-1:0]memrdata; 54 wire [DEPTH-1:0]memwaddr; 55 56 assign not_full = ~full; 57 assign not_empty = ~empty; 58 59 wire do_rd = rd & not_empty; 60 wire do_wr = wr & not_full; 61 62 always_comb begin 63 next_rdptr = rdptr; 64 next_wrptr = wrptr; 65 next_rvalid = rvalid; 66 if (do_rd) 67 next_rdptr = rdptr + 1; 68 if (rd) 69 next_rvalid = not_empty; 70 if (do_wr) 71 next_wrptr = wrptr + 1; 72 end 73 74 always_ff @(posedge clk) begin 75 rdptr <= next_rdptr; 76 wrptr <= next_wrptr; 77 rvalid <= next_rvalid; 78 end 79 80 fifo_memory #( 81 .WIDTH(WIDTH), 82 .DEPTH(DEPTH) 83 ) memory( 84 .clk(clk), 85 .rd(do_rd), 86 .raddr(rdptr[DEPTH-1:0]), 87 .rdata(rdata), 88 .wr(do_wr), 89 .waddr(wrptr[DEPTH-1:0]), 90 .wdata(wdata) 91 ); 92 93 endmodule 94 95 module fifo_memory( 96 input clk, 97 input rd, 98 input [DEPTH-1:0]raddr, 99 output reg [WIDTH-1:0]rdata, 100 input wr, 101 input [DEPTH-1:0]waddr, 102 input [WIDTH-1:0]wdata 103 ); 104 105 parameter WIDTH = 8; 106 parameter DEPTH = 8; 107 108 reg [WIDTH-1:0]memory[0:(1<<DEPTH)-1]; 109 110 always_ff @(posedge clk) begin 111 if (rd) 112 rdata <= memory[raddr]; 113 if (wr) 114 memory[waddr] <= wdata; 115 end 116 117 endmodule