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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
library ieee;
use ieee.std_logic_1164.all;
entity mod5x is
generic (
NBITS: natural := 13
);
port (
clk: in std_logic;
dividend: in std_logic_vector (NBITS - 1 downto 0);
load: in std_logic;
remzero: out std_logic
);
end entity;
architecture foo of mod5x is
-- type remains is (r0, r1, r2, r3, r4); -- remainder values
-- type remain_array is array (NBITS downto 0) of remains;
-- signal remaindr: remain_array := (others => r0);
-- type branch is array (remains, bit) of remains;
-- -- Dave Tweeds state transition table:
-- constant br_table: branch := ( r0 => ('0' => r0, '1' => r1),
-- r1 => ('0' => r2, '1' => r3),
-- r2 => ('0' => r4, '1' => r0),
-- r3 => ('0' => r1, '1' => r2),
-- r4 => ('0' => r3, '1' => r4)
-- );
signal is_zero: std_logic;
begin
do_ig:
process (dividend)
type remains is (r0, r1, r2, r3, r4); -- remainder values
type remain_array is array (NBITS downto 0) of remains;
variable tbit: bit_vector(NBITS - 1 downto 0);
variable remaind: remain_array := (others => r0);
type branch is array (remains, bit) of remains;
-- Dave Tweeds state transition table:
constant br_table: branch := ( r0 => ('0' => r0, '1' => r1),
r1 => ('0' => r2, '1' => r3),
r2 => ('0' => r4, '1' => r0),
r3 => ('0' => r1, '1' => r2),
r4 => ('0' => r3, '1' => r4)
);
begin
do_mod:
for i in NBITS - 1 downto 0 loop
tbit := to_bitvector(dividend);
remaind(i) := br_table(remaind(i + 1),tbit(i));
end loop;
-- remaindr <= remaind; -- all values for waveform display
if remaind(0) = r0 then
is_zero <= '1';
else
is_zero <= '0';
end if;
end process;
remainders:
process (clk)
begin
if rising_edge(clk) then
remzero <= is_zero
;
end if;
end process;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity mod5x_tb is
end entity;
architecture foo of mod5x_tb is
constant NBITS: integer range 0 to 13 := 8;
signal clk: std_logic := '0';
signal dividend: std_logic_vector (NBITS - 1 downto 0);
signal load: std_logic := '0';
signal remzero: std_logic;
signal psample: std_ulogic;
signal sample: std_ulogic;
signal done: boolean;
begin
DUT:
entity work.mod5x
generic map (NBITS)
port map (
clk => clk,
dividend => dividend,
load => load,
remzero => remzero
);
CLOCK:
process
begin
wait for 5 ns;
clk <= not clk;
if done'delayed(30 ns) then
wait;
end if;
end process;
STIMULI:
process
begin
for i in 0 to 2 ** NBITS - 1 loop
wait for 10 ns;
dividend <= std_logic_vector(to_unsigned(i,NBITS));
wait for 10 ns;
load <= '1';
wait for 10 ns;
load <= '0';
end loop;
wait for 15 ns;
done <= true;
wait;
end process;
SAMPLER:
process (clk)
begin
if rising_edge(clk) then
psample <= load;
sample <= psample;
end if;
end process;
MONITOR:
process (sample)
variable i: integer;
variable rem5: integer;
begin
if rising_edge (sample) then
i := to_integer(unsigned(dividend));
rem5 := i mod 5;
if rem5 = 0 and remzero /= '1' then
assert rem5 = 0 and remzero = '1'
report LF & HT &
"i = " & integer'image(i) &
" rem 5 expected " & integer'image(rem5) &
" remzero = " & std_ulogic'image(remzero)
SEVERITY ERROR;
end if;
end if;
end process;
end architecture;
|