OpenCores
URL https://opencores.org/ocsvn/potato/potato/trunk

Subversion Repositories potato

[/] [potato/] [trunk/] [testbenches/] [tb_soc.vhd] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 skordal
-- The Potato Processor - A simple processor for FPGAs
2
-- (c) Kristian Klomsten Skordal 2014 <kristian.skordal@wafflemail.net>
3
-- Report bugs and issues on <https://github.com/skordal/potato/issues>
4
 
5
library ieee;
6
use ieee.std_logic_1164.all;
7
use ieee.numeric_std.all;
8
use ieee.std_logic_textio.all;
9
use std.textio.all;
10
 
11
use work.pp_constants.all;
12
use work.pp_utilities.all;
13
 
14
--! @brief Testbench providing a full SoC architecture connected with a Wishbone bus.
15
entity tb_soc is
16
        generic(
17
                IMEM_SIZE : natural := 2048; --! Size of the instruction memory in bytes.
18
                DMEM_SIZE : natural := 2048; --! Size of the data memory in bytes.
19
                IMEM_FILENAME : string := "imem_testfile.hex"; --! File containing the contents of instruction memory.
20
                DMEM_FILENAME : string := "dmem_testfile.hex"  --! File containing the contents of data memory.
21
        );
22
end entity tb_soc;
23
 
24
architecture testbench of tb_soc is
25
 
26
        -- Clock signals:
27
        signal clk : std_logic;
28
        constant clk_period : time := 10 ns;
29
 
30
        -- Reset:
31
        signal reset : std_logic := '1';
32
 
33
        -- Interrupts:
34
        signal irq : std_logic_vector(7 downto 0) := (others => '0');
35
 
36
        -- HTIF:
37
        signal fromhost_data, tohost_data : std_logic_vector(31 downto 0);
38
        signal fromhost_updated : std_logic := '0';
39
        signal tohost_updated : std_logic;
40
 
41
        -- Instruction memory signals:
42
        signal imem_adr_in : std_logic_vector(log2(IMEM_SIZE) - 1 downto 0);
43
        signal imem_dat_in : std_logic_vector(31 downto 0);
44
        signal imem_dat_out : std_logic_vector(31 downto 0);
45
        signal imem_cyc_in : std_logic;
46
        signal imem_stb_in : std_logic;
47
        signal imem_sel_in : std_logic_vector(3 downto 0);
48
        signal imem_we_in : std_logic;
49
        signal imem_ack_out : std_logic;
50
 
51
        -- Data memory signals:
52
        signal dmem_adr_in  : std_logic_vector(log2(DMEM_SIZE) - 1 downto 0);
53
        signal dmem_dat_in  : std_logic_vector(31 downto 0);
54
        signal dmem_dat_out : std_logic_vector(31 downto 0);
55
        signal dmem_cyc_in  : std_logic;
56
        signal dmem_stb_in  : std_logic;
57
        signal dmem_sel_in  : std_logic_vector(3 downto 0);
58
        signal dmem_we_in   : std_logic;
59
        signal dmem_ack_out : std_logic;
60
 
61
        -- Processor signals:
62
        signal p_adr_out : std_logic_vector(31 downto 0);
63
        signal p_dat_out : std_logic_vector(31 downto 0);
64
        signal p_dat_in  : std_logic_vector(31 downto 0);
65
        signal p_cyc_out : std_logic;
66
        signal p_stb_out : std_logic;
67
        signal p_sel_out : std_logic_vector(3 downto 0);
68
        signal p_we_out  : std_logic;
69
        signal p_ack_in  : std_logic;
70
 
71
        -- Arbitrated wishbone signals:
72
        signal wb_adr : std_logic_vector(31 downto 0);
73
        signal wb_dat : std_logic_vector(31 downto 0);
74
        signal wb_sel : std_logic_vector( 3 downto 0);
75
        signal wb_cyc : std_logic;
76
        signal wb_stb : std_logic;
77
        signal wb_we  : std_logic;
78
 
79
        -- Initialization "module" signals:
80
        signal init_adr_out : std_logic_vector(31 downto 0) := (others => '0');
81
        signal init_dat_out : std_logic_vector(31 downto 0) := (others => '0');
82
        signal init_cyc_out : std_logic := '0';
83
        signal init_stb_out : std_logic := '0';
84
        signal init_we_out  : std_logic := '1';
85
 
86
        -- Processor reset signals:
87
        signal processor_reset : std_logic := '1';
88
 
89
        -- Simulation control:
90
        signal initialized  : boolean := false;
91
        signal simulation_finished : boolean := false;
92
 
93
begin
94
 
95
        processor: entity work.pp_potato
96
                port map(
97
                        clk => clk,
98
                        reset => processor_reset,
99
                        irq => irq,
100
                        fromhost_data => fromhost_data,
101
                        fromhost_updated => fromhost_updated,
102
                        tohost_data => tohost_data,
103
                        tohost_updated => tohost_updated,
104
                        wb_adr_out => p_adr_out,
105
                        wb_sel_out => p_sel_out,
106
                        wb_cyc_out => p_cyc_out,
107
                        wb_stb_out => p_stb_out,
108
                        wb_we_out => p_we_out,
109
                        wb_dat_out => p_dat_out,
110
                        wb_dat_in => p_dat_in,
111
                        wb_ack_in => p_ack_in
112
                );
113
 
114
        imem: entity work.pp_soc_memory
115
                generic map(
116
                        MEMORY_SIZE => IMEM_SIZE
117
                ) port map(
118
                        clk => clk,
119
                        reset => reset,
120
                        wb_adr_in => imem_adr_in,
121
                        wb_dat_in => imem_dat_in,
122
                        wb_dat_out => imem_dat_out,
123
                        wb_cyc_in => imem_cyc_in,
124
                        wb_stb_in => imem_stb_in,
125
                        wb_sel_in => imem_sel_in,
126
                        wb_we_in => imem_we_in,
127
                        wb_ack_out => imem_ack_out
128
                );
129
 
130
        dmem: entity work.pp_soc_memory
131
                generic map(
132
                        MEMORY_SIZE => DMEM_SIZE
133
                ) port map(
134
                        clk => clk,
135
                        reset => reset,
136
                        wb_adr_in => dmem_adr_in,
137
                        wb_dat_in => dmem_dat_in,
138
                        wb_dat_out => dmem_dat_out,
139
                        wb_cyc_in => dmem_cyc_in,
140
                        wb_stb_in => dmem_stb_in,
141
                        wb_sel_in => dmem_sel_in,
142
                        wb_we_in => dmem_we_in,
143
                        wb_ack_out => dmem_ack_out
144
                );
145
 
146
        imem_adr_in <= wb_adr(imem_adr_in'range);
147
        imem_dat_in <= wb_dat;
148
        imem_we_in <= wb_we;
149
        imem_sel_in <= wb_sel;
150
        dmem_adr_in <= wb_adr(dmem_adr_in'range);
151
        dmem_dat_in <= wb_dat;
152
        dmem_we_in <= wb_we;
153
        dmem_sel_in <= wb_sel;
154
 
155
        address_decoder: process(wb_adr, imem_dat_out, imem_ack_out, dmem_dat_out, dmem_ack_out,
156
                wb_cyc, wb_stb)
157
        begin
158
                if to_integer(unsigned(wb_adr)) < IMEM_SIZE then
159
                        p_dat_in <= imem_dat_out;
160
                        p_ack_in <= imem_ack_out;
161
                        imem_cyc_in <= wb_cyc;
162
                        imem_stb_in <= wb_stb;
163
                        dmem_cyc_in <= '0';
164
                        dmem_stb_in <= '0';
165
                else
166
                        p_dat_in <= dmem_dat_out;
167
                        p_ack_in <= dmem_ack_out;
168
                        dmem_cyc_in <= wb_cyc;
169
                        dmem_stb_in <= wb_stb;
170
                        imem_cyc_in <= '0';
171
                        imem_stb_in <= '0';
172
                end if;
173
        end process address_decoder;
174
 
175
        arbiter: process(initialized, init_adr_out, init_dat_out, init_cyc_out, init_stb_out, init_we_out,
176
                p_adr_out, p_dat_out, p_cyc_out, p_stb_out, p_we_out, p_sel_out)
177
        begin
178
                if not initialized then
179
                        wb_adr <= init_adr_out;
180
                        wb_dat <= init_dat_out;
181
                        wb_cyc <= init_cyc_out;
182
                        wb_stb <= init_stb_out;
183
                        wb_we <= init_we_out;
184
                        wb_sel <= x"f";
185
                else
186
                        wb_adr <= p_adr_out;
187
                        wb_dat <= p_dat_out;
188
                        wb_cyc <= p_cyc_out;
189
                        wb_stb <= p_stb_out;
190
                        wb_we <= p_we_out;
191
                        wb_sel <= p_sel_out;
192
                end if;
193
        end process arbiter;
194
 
195
        initializer: process
196
                file imem_file : text open READ_MODE is IMEM_FILENAME;
197
                file dmem_file : text open READ_MODE is DMEM_FILENAME;
198
                variable input_line  : line;
199
                variable input_index : natural;
200
                variable input_value : std_logic_vector(31 downto 0);
201
                variable temp : std_logic_vector(31 downto 0);
202
 
203
                constant DMEM_START : natural := IMEM_SIZE;
204
        begin
205
                if not initialized then
206
                        -- Read the instruction memory file:
207
                        for i in 0 to IMEM_SIZE loop
208
                                exit when endfile(imem_file);
209
 
210
                                readline(imem_file, input_line);
211
                                hread(input_line, input_value);
212
 
213
                                init_adr_out <= std_logic_vector(to_unsigned(i * 4, init_adr_out'length));
214
                                init_dat_out <= input_value;
215
                                init_cyc_out <= '1';
216
                                init_stb_out <= '1';
217
                                wait until imem_ack_out = '1';
218
                                wait for clk_period;
219
                                init_stb_out <= '0';
220
                                wait until imem_ack_out = '0';
221
                                wait for clk_period;
222
                        end loop;
223
 
224
                        init_cyc_out <= '0';
225
                        init_stb_out <= '0';
226
                        wait for clk_period;
227
 
228
                        -- Read the data memory file:
229
                        for i in 0 to DMEM_SIZE loop
230
                                exit when endfile(dmem_file);
231
 
232
                                readline(dmem_file, input_line);
233
                                hread(input_line, input_value);
234
 
235
 
236
                                -- Swap endianness, TODO: prevent this, fix scripts/extract_hex.sh
237
                                temp(7 downto 0) := input_value(31 downto 24);
238
                                temp(15 downto 8) := input_value(23 downto 16);
239
                                temp(23 downto 16) := input_value(15 downto 8);
240
                                temp(31 downto 24) := input_value(7 downto 0);
241
 
242
                                input_value := temp;
243
 
244
                                init_adr_out <= std_logic_vector(to_unsigned(DMEM_START + (i * 4), init_adr_out'length));
245
                                init_dat_out <= input_value;
246
                                init_cyc_out <= '1';
247
                                init_stb_out <= '1';
248
                                wait until dmem_ack_out = '1';
249
                                wait for clk_period;
250
                                init_stb_out <= '0';
251
                                wait until dmem_ack_out = '0';
252
                                wait for clk_period;
253
                        end loop;
254
 
255
                        init_cyc_out <= '0';
256
                        init_stb_out <= '0';
257
                        wait for clk_period;
258
 
259
                        initialized <= true;
260
                        wait;
261
                end if;
262
        end process initializer;
263
 
264
        clock: process
265
        begin
266
                clk <= '1';
267
                wait for clk_period / 2;
268
                clk <= '0';
269
                wait for clk_period / 2;
270
 
271
                if simulation_finished then
272
                        wait;
273
                end if;
274
        end process clock;
275
 
276
        stimulus: process
277
        begin
278
                wait for clk_period * 2;
279
                reset <= '0';
280
 
281
                wait until initialized;
282
                processor_reset <= '0';
283
 
284
                wait until tohost_updated = '1';
285
                wait for clk_period; -- Let the signal "settle", because of stupid clock edges
286
                if tohost_data = x"00000001" then
287
                        report "Success!" severity NOTE;
288
                else
289
                        report "Failure in test " & integer'image(to_integer(shift_right(unsigned(tohost_data), 1))) & "!" severity NOTE;
290
                end if;
291
 
292
                simulation_finished <= true;
293
                wait;
294
        end process stimulus;
295
 
296
end architecture testbench;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.