aboutsummaryrefslogtreecommitdiffstats
path: root/testsuite/gna/bug084/mod5x.vhdl
blob: 9a4d4a6cdf27dac91ded4d296e2607995f48e730 (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
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;