The SPI slave was broken.
[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 use std.textio.all;
17 use work.txt_util.all;
18
19 -----------------------------------------------------------------------
20
21 entity bos2k9_t is
22   generic(
23     clock_interval : time   := clock_interval_c;
24     spi_filename   : string := "bos2k9_t.dat");
25 end bos2k9_t;
26
27 -----------------------------------------------------------------------
28
29 architecture test of bos2k9_t is
30
31   component bos2k9 is
32     port(
33       CLOCK_50 : in std_logic;
34     
35       KEY  : in  std_logic_vector(3 downto 0);
36       SW   : in  std_logic_vector(17 downto 0);
37       LEDR : out std_logic_vector(17 downto 0);
38       LEDG : out std_logic_vector(8 downto 0);
39     
40       SD_DAT  : in  std_logic;
41       SD_DAT3 : out std_logic;
42       SD_CMD  : out std_logic;
43       SD_CLK  : out std_logic);
44   end component;
45
46   file   spi_file : text open read_mode is spi_filename;
47   signal test_s   : integer;
48   
49   signal clock_s  : std_logic;
50   signal reset_s  : std_logic;
51   
52   signal KEY_s      : std_logic_vector(3 downto 0);
53   signal SW_s       : std_logic_vector(17 downto 0);
54   signal LEDR_s     : std_logic_vector(17 downto 0);
55   signal LEDG_s     : std_logic_vector(8 downto 0);
56   signal SD_DAT_s   : std_logic;
57   signal SD_DAT3_s  : std_logic;
58   signal SD_CMD_s   : std_logic;
59   signal SD_CLK_s   : std_logic;
60   
61   signal start_s : std_logic;
62   signal txd_s   : std_logic_byte_t;
63   signal rxd_s   : std_logic_byte_t;
64   signal spi_s   : spi_bus_t;
65   
66   signal addr_sw_s : std_logic_byte_t;
67   signal byte_sw_s : std_logic_byte_t;
68   signal byte_dw_s : std_logic_byte_t;
69 begin
70   dut : bos2k9 port map(clock_s,
71     KEY_s,
72     SW_s,
73     LEDR_s,
74     LEDG_s,
75     SD_DAT_s,
76     SD_DAT3_s,
77     SD_CMD_s,
78     SD_CLK_s);
79   SD_DAT_s   <= spi_s.miso;
80   spi_s.mosi <= SD_CMD_s;
81   spi_s.sck  <= SD_CLK_s;
82   spi_s.cs   <= SD_DAT3_s;
83   
84   byte_dw_s         <= LEDR_s(7 downto 0);
85   SW_s(7 downto 0)  <= addr_sw_s;
86   SW_s(15 downto 8) <= byte_sw_s;
87   SW_s(16)          <= '0';
88   SW_s(17)          <= not reset_s;
89   KEY_s(0)          <= not start_s;
90   KEY_s(3 downto 1) <= (others => '1');
91   
92   addr_sw_s <= (others => '0');
93   byte_sw_s <= (others => '0');
94   
95   stimulus : process
96   begin
97     start_s <= '0';
98   
99     
100     wait;
101   end process;
102   
103   slave : process
104     procedure read_txd_and_rxd is
105       variable line_v  : line;
106       variable input_v : string(1 to 17);
107       variable byte_v  : std_logic_byte_t;
108     begin
109       readline(spi_file, line_v);
110       read(line_v, input_v);
111       txd_s <= to_std_logic_vector(input_v(1 to 8));
112       rxd_s <= to_std_logic_vector(input_v(10 to 17));
113     end read_txd_and_rxd;
114     variable count_v : integer;
115     variable index_v : integer;
116     variable txd_v   : std_logic_byte_t;
117   begin
118     rxd_s <= (others => 'Z');
119     txd_v := (others => 'U');
120     test_s <= 0;
121     
122     wait until falling_edge(spi_s.cs);
123     while spi_s.cs = '0' loop
124       index_v := 7;
125       count_v := 0;
126       read_txd_and_rxd;
127       spi_s.miso <= rxd_s(index_v);
128       while index_v > -1 loop
129         wait until spi_s.sck'event or spi_s.cs'event;
130         if not (index_v = -1) then
131           count_v := count_v + 1;
132           -- Latch on odd edges, shift on even
133           if (count_v mod 2) = 1 then
134             txd_v(0)   := spi_s.mosi;
135             index_v    := index_v - 1;
136           else
137             txd_v      := txd_v(6 downto 0) & 'U';
138             spi_s.miso <= rxd_s(index_v);
139           end if;
140         end if;
141       end loop;
142       assert txd_v = txd_s report "unexpected spi data. got: " & str(txd_v) & " expected: " & str(txd_s);
143     end loop;
144     wait until falling_edge(clock_s);
145   end process;
146   
147   reset : process
148   begin
149     reset_s <= '1';
150     wait until rising_edge(clock_s);
151     wait until rising_edge(clock_s);
152     reset_s <= '0';
153     wait;
154   end process;
155   
156   clock : process
157   begin
158     clock_s <= '0';
159     wait for clock_interval / 2;
160     clock_s <= '1';
161     wait for clock_interval / 2;
162   end process;
163   
164 end test;