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

Subversion Repositories potato

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

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

powered by: WebSVN 2.1.0

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