zynq-sandbox

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit cd483ab2e8cb26090e5c77c3ad418e46b93ed610
parent 56bfe21a860d7643b1cacd51e63dc968be720ac5
Author: Brian Swetland <swetland@frotz.net>
Date:   Sun, 20 Jul 2014 22:23:56 -0700

simple_fifo: a simple single clock synchronous fifo

Diffstat:
Ahdl/simple_fifo.sv | 117+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahdl/test/simple_fifo_test.sv | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 206 insertions(+), 0 deletions(-)

diff --git a/hdl/simple_fifo.sv b/hdl/simple_fifo.sv @@ -0,0 +1,117 @@ +// Copyright 2014 Brian Swetland <swetland@frotz.net> +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +`timescale 1ns / 1ps + +// rvalid: indicates rd was successful and rdata contains the read data +// not_full: indicates that wr will be successful if attempted +// not_empty: indicates that rd will be successful if attempted + +module simple_fifo( + input clk, + + input wr, + input [WIDTH-1:0]wdata, + + input rd, + output [WIDTH-1:0]rdata, + output reg rvalid = 0, + + output not_empty, + output not_full + ); + +parameter WIDTH = 8; // bit width of fifo entries +parameter DEPTH = 8; // fifo contains 2^DEPTH entries + +reg memrd = 0; +reg memwr = 0; + +reg [DEPTH:0]rdptr = 0; +reg [DEPTH:0]wrptr = 0; + +reg [DEPTH:0]next_rdptr; +reg [DEPTH:0]next_wrptr; +reg next_rvalid; + +wire [DEPTH:0]count = (wrptr - rdptr); +wire full = count[DEPTH]; +wire empty = (count == 0); + +wire [DEPTH-1:0]memraddr; +wire [WIDTH-1:0]memrdata; +wire [DEPTH-1:0]memwaddr; + +assign not_full = ~full; +assign not_empty = ~empty; + +wire do_rd = rd & not_empty; +wire do_wr = wr & not_full; + +always_comb begin + next_rdptr = rdptr; + next_wrptr = wrptr; + next_rvalid = rvalid; + if (do_rd) + next_rdptr = rdptr + 1; + if (rd) + next_rvalid = not_empty; + if (do_wr) + next_wrptr = wrptr + 1; +end + +always_ff @(posedge clk) begin + rdptr <= next_rdptr; + wrptr <= next_wrptr; + rvalid <= next_rvalid; +end + +fifo_memory #( + .WIDTH(WIDTH), + .DEPTH(DEPTH) + ) memory( + .clk(clk), + .rd(do_rd), + .raddr(rdptr[DEPTH-1:0]), + .rdata(rdata), + .wr(do_wr), + .waddr(wrptr[DEPTH-1:0]), + .wdata(wdata) + ); + +endmodule + +module fifo_memory( + input clk, + input rd, + input [DEPTH-1:0]raddr, + output reg [WIDTH-1:0]rdata, + input wr, + input [DEPTH-1:0]waddr, + input [WIDTH-1:0]wdata + ); + +parameter WIDTH = 8; +parameter DEPTH = 8; + +reg [WIDTH-1:0]memory[0:(1<<DEPTH)-1]; + +always_ff @(posedge clk) begin + if (rd) + rdata <= memory[raddr]; + if (wr) + memory[waddr] <= wdata; +end + +endmodule diff --git a/hdl/test/simple_fifo_test.sv b/hdl/test/simple_fifo_test.sv @@ -0,0 +1,89 @@ +// Copyright 2014 Brian Swetland <swetland@frotz.net> +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +`timescale 1ns / 1ps + +module testbench(input clk); + +parameter WIDTH = 8; +parameter DEPTH = 4; + +reg wr = 0; +reg rd = 0; +wire rvalid; +wire not_empty; +wire not_full; + +wire [WIDTH-1:0]rdata; +reg [WIDTH-1:0]wdata = 0; + +simple_fifo #( + .WIDTH(WIDTH), + .DEPTH(DEPTH) + ) fifo ( + .clk(clk), + .rd(rd), + .wr(wr), + .rdata(rdata), + .wdata(wdata), + .rvalid(rvalid), + .not_empty(not_empty), + .not_full(not_full) + ); + +integer count = 0; + +reg next_wr; +reg next_rd; +reg [WIDTH-1:0]next_wdata; + +always_comb begin + next_wr = 0; + next_rd = 0; + next_wdata = wdata; + + if (count == 10) begin + next_wr = 1; + next_wdata = 8'haa; + end + if (count == 11) begin + next_wr = 1; + next_wdata = 8'hbb; + end + if (count == 12) begin + next_wr = 1; + next_wdata = 8'hcc; + end + if (count == 20) begin + next_wr = 1; + next_wdata = 8'h42; + end + if (count > 30) begin + next_wr = 1; + next_wdata = 8'hee; + end + + if ((count > 15) && (count < 25)) next_rd = 1; + if (count == 50) next_rd = 1; + if (count == 100) $finish; +end + +always_ff @(posedge clk) begin + count <= count + 1; + rd <= next_rd; + wr <= next_wr; + wdata <= next_wdata; +end + +endmodule