zynq-sandbox

old FPGA projects for ZYNQ
git clone http://frotz.net/git/zynq-sandbox.git
Log | Files | Refs | README

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