One fine day we might create our ModelSim project files on demand.
[bos2k9.git] / bos2k9_t.vhd
1 -----------------------------------------------------------------------
2 -- Copyright (c) 2009 Malte S. Stretz <http://msquadrat.de> 
3 --
4 -- Testing the top level entity.
5 -----------------------------------------------------------------------
6
7 use work.bos2k9_globals.all;
8
9 library fhw_tools;
10 use fhw_tools.types.all;
11
12 library ieee;
13 use ieee.std_logic_1164.all;
14 use ieee.numeric_std.all;
15
16 -----------------------------------------------------------------------
17
18 entity bos2k9_t is
19   generic(
20     clock_interval : time := clock_interval_c;
21     clock_divider  : positive := 6;
22     txd_pattern : std_logic_byte_t := "10010110";
23     rxd_pattern : std_logic_byte_t := "LHLHLHLH";
24     repeat : natural := 1);
25 end bos2k9_t;
26
27 -----------------------------------------------------------------------
28
29 architecture test of bos2k9_t is
30
31   component bos2k9 is
32     port(
33       clk : in  std_logic;
34       rst : in  std_logic;
35     
36       start_btn : in  std_logic;
37       busy_led  : out std_logic;
38     
39       byte_swc : in  std_logic_byte_t;
40       byte_led : out std_logic_byte_t;
41     
42       spi_miso : in  std_logic;
43       spi_mosi : out std_logic;
44       spi_sck  : out std_logic;
45       spi_cs   : out std_logic);
46   end component;
47
48   signal test_s : integer;
49   
50   signal clock_s  : std_logic;
51   signal reset_s  : std_logic;
52   
53   signal start_n : std_logic;
54   signal busy_s  : std_logic;
55   signal txd_s   : std_logic_byte_t;
56   signal rxd_s   : std_logic_byte_t;
57   signal miso_s  : std_logic;
58   signal mosi_s  : std_logic;
59   signal sck_s   : std_logic;
60   signal cs_s    : std_logic;
61   
62   signal ss_n    : std_logic;
63   
64   signal simo_s  : std_logic_byte_t;
65 begin
66   dut : bos2k9 port map(
67     clk => clock_s,
68     rst => reset_s,
69     start_btn => start_n,
70     busy_led => busy_s,
71     byte_swc => txd_s,
72     byte_led => rxd_s,
73     spi_miso => miso_s,
74     spi_mosi => mosi_s,
75     spi_sck  => sck_s,
76     spi_cs   => cs_s);
77   
78   stimulus : process
79     variable repeat_v : natural;
80   begin
81     wait for clock_interval / 4;
82   
83     repeat_v := repeat;
84     test_s <= -3;
85     start_n <= '1';
86     txd_s   <= (others => 'U');
87     wait until falling_edge(reset_s); test_s <= test_s + 1;
88     
89     wait until rising_edge(clock_s); test_s <= test_s + 1;
90     txd_s  <= txd_pattern;
91     
92     wait until rising_edge(clock_s); test_s <= test_s + 1;
93     start_n <= '0';
94     
95     wait until rising_edge(clock_s); test_s <= test_s + 1;
96     
97     wait until rising_edge(clock_s); test_s <= test_s + 1;
98     wait until rising_edge(clock_s); test_s <= test_s + 1;
99     txd_s  <= (others => 'U');
100     
101     while repeat_v > 0 loop
102       repeat_v := repeat_v - 1;
103     
104       wait until rising_edge(clock_s); test_s <= test_s + 1;
105       txd_s  <= (others => '1');
106     
107       wait until rising_edge(clock_s); test_s <= test_s + 1;
108       txd_s  <= txd_s xor txd_pattern;
109       
110       wait until falling_edge(busy_s); test_s <= test_s + 1;
111     
112       -- while busy_s = '1' loop
113         -- wait until rising_edge(clock_s);
114       -- end loop;
115       -- test_s <= test_s + 1;
116       -- start_n <= '0';
117     
118       wait until rising_edge(clock_s); test_s <= test_s + 1;
119       start_n <= '1';
120     
121       wait until rising_edge(clock_s); test_s <= test_s + 1;
122       txd_s  <= (others => 'U');
123     end loop;
124     
125     start_n <= '1';
126     wait;
127   end process;
128   
129   ss_n <= cs_s;
130   
131   slave : process
132     variable count_v : integer;
133     variable index_v : integer;
134     variable data_v  : std_logic_byte_t;
135   begin
136     wait for clock_interval / 4;
137   
138     simo_s  <= (others => 'U');
139     miso_s  <= 'Z';
140     index_v := 7;
141     count_v := 0;
142     wait until falling_edge(ss_n);
143     data_v := txd_s;
144     
145     miso_s  <= rxd_pattern(index_v);
146     
147     while ss_n = '0' loop
148       wait until sck_s'event or ss_n'event;
149       if not (index_v = -1) then
150         count_v := count_v + 1;
151         -- Latch on odd edges, shift on even
152         if (count_v mod 2) = 1 then
153           simo_s(0) <= mosi_s;
154           index_v := index_v - 1;
155         else
156           simo_s  <= simo_s(6 downto 0) & simo_s(7);
157           miso_s  <= rxd_pattern(index_v);
158         end if;
159       end if;
160     end loop;
161     
162     assert simo_s = data_v      report "neq:txd";
163     assert rxd_s  = rxd_pattern report "neq:rxd";
164     wait until falling_edge(clock_s);
165   end process;
166   
167   reset : process
168   begin
169     reset_s <= '1';
170     wait until rising_edge(clock_s);
171     reset_s <= '0';
172     wait;
173   end process;
174   
175   clock : process
176   begin
177     clock_s <= '0';
178     wait for clock_interval / 2;
179     clock_s <= '1';
180     wait for clock_interval / 2;
181   end process;
182   
183 end test;