Skip to content

Commit

Permalink
add fifo and clock crossing fifo for simulation purposes
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Reese committed Oct 5, 2023
1 parent 895fa26 commit 7d06bdf
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 0 deletions.
53 changes: 53 additions & 0 deletions examples/fifo/clock_crossing_fifo.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// this is only for simulation
module clock_crossing_fifo(
rd_clk,
wr_clk,
din,
rd_en,
wr_en,
dout,
rst,
empty,
full,
prog_full
);

parameter SIZE = 64;

input rd_clk, wr_clk, rd_en, wr_en, rst;
output empty, full, prog_full;
input [63:0] din;
output reg [63:0] dout; // internal registers

reg [63:0] FIFO[0:SIZE-1];
integer readCounter = 0, writeCounter = 0;
assign empty = (readCounter==writeCounter)? 1'b1:1'b0;
assign full = ((writeCounter+1)%SIZE==readCounter)? 1'b1:1'b0;
assign prog_full = full;
always @ (posedge wr_clk)
begin
if (rst) begin
writeCounter = 0;
end
else begin
if (wr_en==1'b1 && full==1'b0) begin
FIFO[writeCounter] = din;
writeCounter = (writeCounter+1)%SIZE;
end
end;
end

always @ (posedge rd_clk)
begin
if (rst) begin
readCounter = 0;
end
else begin
if (rd_en==1'b1 && empty==1'b0) begin
dout = FIFO[readCounter];
readCounter = (readCounter+1)%SIZE;
end
end;
end

endmodule
43 changes: 43 additions & 0 deletions examples/fifo/fifo.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
module fifo(
clk,
din,
rd_en,
wr_en,
dout,
rst,
empty,
full,
prog_full
);

parameter SIZE = 64;

input clk, rd_en, wr_en, rst;
output empty, full, prog_full;
input [63:0] din;
output reg [63:0] dout; // internal registers

reg [63:0] FIFO[0:SIZE-1];
integer readCounter = 0, writeCounter = 0;
assign empty = (readCounter==writeCounter)? 1'b1:1'b0;
assign full = ((writeCounter+1)%SIZE==readCounter)? 1'b1:1'b0;
assign prog_full = full;
always @ (posedge clk)
begin
if (rst) begin
readCounter = 0;
writeCounter = 0;
end
else begin
if (rd_en==1'b1 && empty==1'b0) begin
dout = FIFO[readCounter];
readCounter = (readCounter+1)%SIZE;
end
if (wr_en==1'b1 && full==1'b0) begin
FIFO[writeCounter] = din;
writeCounter = (writeCounter+1)%SIZE;
end
end;
end

endmodule
26 changes: 26 additions & 0 deletions examples/fifo/makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
all: run

VERILATOR_VERSION=`verilator --version | cut -d' ' -f 2 `

gvi: ../../gvi.cpp
g++ -o gvi ../../gvi.cpp

.gvi/fifo/fifo_wrapper.vhd: gvi fifo.v
./gvi -vv $(VERILATOR_VERSION) -v fifo.v -t fifo -c clk

.gvi/clock_crossing_fifo/clock_crossing_fifo_wrapper.vhd: gvi clock_crossing_fifo.v
./gvi -vv $(VERILATOR_VERSION) -v clock_crossing_fifo.v -t clock_crossing_fifo

run: testbench
ghdl -r testbench --stop-time=100us --wave=simulation.ghw --ieee-asserts=disable

testbench: .gvi/clock_crossing_fifo/clock_crossing_fifo_wrapper.vhd \
testbench.vhd
ghdl -a $(GHDLFLAGS) $+
ghdl -m $(GHDLFLAGS) \
$(shell cat .gvi/clock_crossing_fifo/clock_crossing_fifo_wrapper.flags) \
$(shell cat .gvi/common.flags) \
testbench

clean:
rm -rf fifo gvi .gvi *.o *.vcd *.ghw work-obj93.cf testbench
64 changes: 64 additions & 0 deletions examples/fifo/testbench.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity testbench is
end entity;

architecture simulation of testbench is
signal rd_clk : std_logic := '0';
signal wr_clk : std_logic := '0';
signal rd_en : std_logic := '0';
signal wr_en : std_logic := '0';
signal rst : std_logic := '1';
signal empty : std_logic := '0';
signal full : std_logic := '0';
signal prog_full : std_logic := '0';
signal din : std_logic_vector(63 downto 0) := (others => '1');
signal dout : std_logic_vector(63 downto 0) := (others => '0');
begin

rd_clk <= not rd_clk after 2.1 ns;
wr_clk <= not wr_clk after 5.0 ns;
rst <= '0' after 20 ns;

write: process
variable cnt : integer := 0;
begin
wait until rising_edge(wr_clk);
cnt := cnt + 1;
din <= std_logic_vector(to_unsigned(cnt,64));
case cnt is
when 5 => wr_en <= '1';
when 170 => wr_en <= '0';
when others =>
end case;
end process;

read: process
variable cnt : integer := 0;
begin
wait until rising_edge(rd_clk);
cnt := cnt + 1;
case cnt is
when 255 => rd_en <= '1';
when 390 => rd_en <= '0';
when others =>
end case;
end process;


dut: entity work.clock_crossing_fifo
port map(
rd_clk => rd_clk,
wr_clk => wr_clk,
rd_en => rd_en,
wr_en => wr_en,
rst => rst,
empty => empty,
full => full,
prog_full => prog_full,
din => din,
dout => dout);

end architecture simulation;

0 comments on commit 7d06bdf

Please sign in to comment.