blob: a96d35d9ca37fa2179204260b7f07c7f69bb17bd (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
library ieee;
context ieee.ieee_std_context;
entity fifo is
generic (
data_width : positive := 8;
fifo_depth : positive := 8
);
port (
clkw : in std_logic;
clkr : in std_logic;
rst : in std_logic;
wr : in std_logic;
rd : in std_logic;
d : in std_logic_vector(data_width-1 downto 0);
e : out std_logic;
f : out std_logic;
q : out std_logic_vector(data_width-1 downto 0)
);
end fifo;
architecture arch of fifo is
type fifo_t is array (0 to 2**fifo_depth-1)
of std_logic_vector(data_width-1 downto 0);
signal mem : fifo_t;
signal rdp, wrp : unsigned(fifo_depth downto 0);
begin
-- Assertions
process(clkw, clkr)
constant dx : std_logic_vector(d'left downto 0) := (others => 'X');
constant du : std_logic_vector(d'left downto 0) := (others => 'U');
begin
if rising_edge(clkw) then
if ( wr and ( d?=dx or d?=du ) ) then
assert false report "wrote X|U to fIfO" severity failure;
end if;
if (f and wr) then
assert false report "wrote to fIfO while full" severity failure;
end if;
end if;
if rising_edge(clkr) then
if (e and rd) then
assert false report "Read from fIfO while empty" severity failure;
end if;
end if;
end process;
--
process(clkw) begin
if rising_edge(clkw) then
if wr then
mem(to_integer(wrp(fifo_depth-1 downto 0))) <= d;
end if;
end if;
end process;
process(clkw) begin
if rising_edge(clkw) then
if rst then
wrp <= (others => '0');
else
if wr then
wrp <= wrp+1;
end if;
end if;
end if;
end process;
f <= rdp(fifo_depth-1 downto 0)?=wrp(fifo_depth-1 downto 0)
and (rdp(fifo_depth) xor wrp(fifo_depth));
e <= rdp ?= wrp;
process(clkr) begin
if rising_edge(clkr) then
if rst then
q <= (others => '0');
elsif rd then
q <= mem(to_integer(rdp(fifo_depth-1 downto 0)));
end if;
end if;
end process;
process(clkr) begin
if rising_edge(clkr) then
if rst then
rdp <= (others => '0');
else
if rd then rdp <= rdp+1; end if;
end if;
end if;
end process;
end arch;
|