w11 - vhd 0.794
W11 CPU core and support modules
Loading...
Searching...
No Matches
fifo_simple_dram.vhd
Go to the documentation of this file.
1-- $Id: fifo_simple_dram.vhd 1181 2019-07-08 17:00:50Z mueller $
2-- SPDX-License-Identifier: GPL-3.0-or-later
3-- Copyright 2019- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4--
5------------------------------------------------------------------------------
6-- Module Name: fifo_simple_dram - syn
7-- Description: FIFO, CE/WE interface, distributed RAM based
8--
9-- Dependencies: ram_1swar_gen
10--
11-- Test bench: tb/tb_fifo_simple_dram
12-- Target Devices: generic Spartan, Artix
13-- Tool versions: ise 14.7; viv 2017.2-2018.3; ghdl 0.35
14--
15-- Revision History:
16-- Date Rev Version Comment
17-- 2019-02-09 1109 1.0 Initial version
18------------------------------------------------------------------------------
19
20library ieee;
21use ieee.std_logic_1164.all;
22use ieee.numeric_std.all;
23use ieee.std_logic_textio.all;
24use std.textio.all;
25
26use work.slvtypes.all;
27use work.memlib.all;
28
29entity fifo_simple_dram is -- fifo, CE/WE interface, dram based
30 generic (
31 AWIDTH : positive := 6; -- address width (sets size)
32 DWIDTH : positive := 16); -- data width
33 port (
34 CLK : in slbit; -- clock
35 RESET : in slbit; -- reset
36 CE : in slbit; -- clock enable
37 WE : in slbit; -- write enable
38 DI : in slv(DWIDTH-1 downto 0); -- input data
39 DO : out slv(DWIDTH-1 downto 0); -- output data
40 EMPTY : out slbit; -- fifo empty status
41 FULL : out slbit; -- fifo full status
42 SIZE : out slv(AWIDTH-1 downto 0) -- number of used slots
43 );
45
46
47architecture syn of fifo_simple_dram is
48
49 type regs_type is record
50 waddr : slv(AWIDTH-1 downto 0); -- write address
51 raddr : slv(AWIDTH-1 downto 0); -- read address
52 empty : slbit; -- empty flag
53 full : slbit; -- full flag
54 end record regs_type;
55
56 constant memsize : positive := 2**AWIDTH;
57 constant regs_init : regs_type := (
58 slv(to_unsigned(0,AWIDTH)), -- waddr
59 slv(to_unsigned(0,AWIDTH)), -- raddr
60 '1','0' -- empty,full
61 );
62
63 signal R_REGS : regs_type := regs_init; -- state registers
64 signal N_REGS : regs_type := regs_init; -- next value state regs
65
66 signal RAM_WE : slbit := '0';
67 signal RAM_ADDR : slv(AWIDTH-1 downto 0) := (others=>'0');
68
69begin
70
71 RAM : ram_1swar_gen
72 generic map (
73 AWIDTH => AWIDTH,
74 DWIDTH => DWIDTH)
75 port map (
76 CLK => CLK,
77 WE => RAM_WE,
78 ADDR => RAM_ADDR,
79 DI => DI,
80 DO => DO
81 );
82
83 proc_regs: process (CLK)
84 begin
85
86 if rising_edge(CLK) then
87 if RESET = '1' then
89 else
90 R_REGS <= N_REGS;
91 end if;
92 end if;
93
94 end process proc_regs;
95
96 proc_next: process (R_REGS, RESET, CE, WE)
97
98 variable r : regs_type := regs_init;
99 variable n : regs_type := regs_init;
100
101 variable iram_we : slbit := '0';
102 variable iram_addr : slv(AWIDTH-1 downto 0) := (others=>'0');
103 variable isize : slv(AWIDTH-1 downto 0) := (others=>'0');
104
105 begin
106
107 r := R_REGS;
108 n := R_REGS;
109
110 iram_we := '0';
111 if WE = '1' then -- select RAM address
112 iram_addr := r.waddr; -- for write
113 else
114 iram_addr := r.raddr; -- for read
115 end if;
116
117 isize := slv(unsigned(r.waddr) - unsigned(r.raddr));
118
119 if CE = '1' then -- do read or write
120 if WE = '1' then -- do write
121 if r.full = '0' then -- only if not full
122 iram_we := '1'; -- assert write enable
123 n.waddr := slv(unsigned(r.waddr) + 1); -- advance address
124 n.empty := '0'; -- can't be empty after write
125 if unsigned(isize) = memsize-2 then -- check for full
126 n.full := '1';
127 end if;
128 end if;
129
130 else -- do read
131 if r.empty = '0' then -- only if not empty
132 n.raddr := slv(unsigned(r.raddr) + 1); -- advance address
133 n.full := '0'; -- can't be full after read
134 if unsigned(isize) = 1 then -- check for empty
135 n.empty := '1';
136 end if;
137 end if;
138 end if;
139 end if;
140
141 N_REGS <= n;
142
143 RAM_ADDR <= iram_addr;
144 RAM_WE <= iram_we;
145
146 EMPTY <= r.empty;
147 FULL <= r.full;
148 SIZE <= isize;
149
150 end process proc_next;
151
152-- synthesis translate_off
153 proc_moni: process (CLK)
154 variable oline : line;
155 begin
156
157 if rising_edge(CLK) then
158 if RESET='0' and CE='1' then -- not in reset and active
159 if WE = '0' then
160 if R_REGS.empty='1' then -- read on empty fifo
161 write(oline, now, right, 12);
162 write(oline, string'(" read on empty fifo - FAIL in "));
163 write(oline, fifo_simple_dram'path_name);
164 writeline(output, oline);
165 end if;
166 else
167 if R_REGS.full='1' then -- write on full fifo
168 write(oline, now, right, 12);
169 write(oline, string'(" write on full fifo - FAIL in "));
170 write(oline, fifo_simple_dram'path_name);
171 writeline(output, oline);
172 end if;
173 end if;
174 end if;
175 end if;
176
177 end process proc_moni;
178-- synthesis translate_on
179
180end syn;
regs_type := regs_init N_REGS
slv( AWIDTH- 1 downto 0) :=( others => '0') RAM_ADDR
positive := 2** AWIDTH memsize
regs_type := regs_init R_REGS
regs_type :=( slv( to_unsigned( 0, AWIDTH) ), slv( to_unsigned( 0, AWIDTH) ), '1', '0') regs_init
out DO slv( DWIDTH- 1 downto 0)
in DI slv( DWIDTH- 1 downto 0)
AWIDTH positive := 6
out SIZE slv( AWIDTH- 1 downto 0)
DWIDTH positive := 16
in ADDR slv( AWIDTH- 1 downto 0)
out DO slv( DWIDTH- 1 downto 0)
AWIDTH positive := 4
in DI slv( DWIDTH- 1 downto 0)
in CLK slbit
in WE slbit
DWIDTH positive := 16
std_logic slbit
Definition: slvtypes.vhd:30
std_logic_vector slv
Definition: slvtypes.vhd:31