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

Subversion Repositories ion

[/] [ion/] [trunk/] [src/] [mips_tb2_template.vhdl] - Blame information for rev 51

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

Line No. Rev Author Line
1 42 ja_rd
--##############################################################################
2
-- This file was generated automatically from '/src/mips_tb2_template.vhdl'.
3
-- 
4
--------------------------------------------------------------------------------
5
-- Simulation test bench TB2 -- not synthesizable.
6
--
7
-- Simulates the CPU core connected to a simulated external static RAM and an
8
-- internal BRAM block through a stub (i.e. empty).
9
-- BRAM is initialized with the program object code, and SRAM is initialized 
10
-- with data secions from program. 
11
-- The makefile for the source samples include targets to build simulation test 
12
-- benches using this template, use them as usage examples.
13
--
14
-- The memory setup is meant to test the basic 'dummy' cache. 
15
-- 
16
-- Console output (at addresses compatible to Plasma's) is logged to text file
17
-- "hw_sim_console_log.txt".
18
-- IMPORTANT: The code that echoes UART TX data to the simulation console does
19
-- line buffering; it will not print anything until it gets a CR (0x0d), and
20
-- will ifnore LFs (0x0a). Bear this in mind if you see no output when you 
21
-- expect it.
22
--
23
-- WARNING: Will only work on Modelsim; uses custom library SignalSpy.
24
--##############################################################################
25
 
26 51 ja_rd
library ieee;
27 42 ja_rd
use ieee.std_logic_1164.all;
28
use ieee.std_logic_arith.all;
29
use ieee.std_logic_unsigned.all;
30 51 ja_rd
use std.textio.all;
31 42 ja_rd
 
32
use work.mips_pkg.all;
33 51 ja_rd
use work.mips_tb_pkg.all;
34 42 ja_rd
use work.txt_util.all;
35
 
36
entity @entity_name@ is
37
end;
38
 
39
 
40
architecture @arch_name@ of @entity_name@ is
41
 
42
-------------------------------------------------------------------------------
43
-- Simulation parameters
44
 
45
-- Master clock period
46
constant T : time           := 20 ns;
47
-- Time the UART is unavailable after writing to the TX register
48
-- WARNING: slite does not simulate this. The logs may be different when > 0.0!
49
constant SIMULATED_UART_TX_TIME : time := 0.0 us;
50
 
51
-- Simulation length in clock cycles 
52
-- 2000 is enough for 'hello' sample, 22000 enough for 10 digits of pi
53
constant SIMULATION_LENGTH : integer := @sim_len@;
54
 
55
-- Simulated external SRAM size in 32-bit words 
56
constant SRAM_SIZE : integer := @xram_size@;
57
-- Ext. SRAM address length (memory is 16 bits wide so it needs an extra address bit)
58
constant SRAM_ADDR_SIZE : integer := log2(SRAM_SIZE)+1;
59
 
60
 
61
-- BRAM table and interface signals --------------------------------------------
62
constant BRAM_SIZE : integer := @code_table_size@;
63
constant BRAM_ADDR_SIZE : integer := @code_addr_size@;
64
subtype t_bram_address is std_logic_vector(BRAM_ADDR_SIZE-1 downto 0);
65
-- (this table holds one byte-slice; the RAM will have 4 of these)
66
type t_bram is array(0 to BRAM_SIZE-1) of std_logic_vector(7 downto 0);
67
 
68
signal bram_rd_addr :       t_bram_address;
69
signal bram_wr_addr :       t_bram_address;
70
signal bram_rd_data :       t_word;
71
signal bram_wr_data :       t_word;
72
signal bram_byte_we :       std_logic_vector(3 downto 0);
73 51 ja_rd
signal bram_data_rd_vma :   std_logic;
74 42 ja_rd
 
75
-- bram0 is LSB, bram3 is MSB
76
signal bram3 : t_bram := (@code3@);
77
signal bram2 : t_bram := (@code2@);
78
signal bram1 : t_bram := (@code1@);
79
signal bram0 : t_bram := (@code0@);
80
 
81
-- This is a 16-bit SRAM split in 2 byte slices; so each slice will have two
82
-- bytes for each word of SRAM_SIZE
83
type t_sram is array(0 to SRAM_SIZE*2-1) of std_logic_vector(7 downto 0);
84
signal sram1 : t_sram := (@data31@);
85
signal sram0 : t_sram := (@data20@);
86
 
87
 
88
signal data_uart :          std_logic_vector(31 downto 0);
89
signal data_uart_status :   std_logic_vector(31 downto 0);
90
signal uart_tx_rdy :        std_logic := '1';
91
signal uart_rx_rdy :        std_logic := '1';
92
 
93
--------------------------------------------------------------------------------
94
 
95
signal clk :                std_logic := '0';
96
signal reset :              std_logic := '1';
97
signal interrupt :          std_logic := '0';
98
signal done :               std_logic := '0';
99
 
100
-- interface to asynchronous 16-bit-wide external SRAM
101 51 ja_rd
signal sram_address :       std_logic_vector(SRAM_ADDR_SIZE downto 1);
102 42 ja_rd
signal sram_databus :       std_logic_vector(15 downto 0);
103
signal sram_byte_we_n :     std_logic_vector(1 downto 0);
104
signal sram_oe_n :          std_logic;
105
 
106
-- interface cpu-cache
107
signal cpu_data_rd_addr :   t_word;
108
signal cpu_data_rd_vma :    std_logic;
109
signal cpu_data_rd :        t_word;
110
signal cpu_code_rd_addr :   t_pc;
111
signal cpu_code_rd :        t_word;
112
signal cpu_code_rd_vma :    std_logic;
113
signal cpu_data_wr_addr :   t_pc;
114
signal cpu_data_wr :        t_word;
115
signal cpu_byte_we :        std_logic_vector(3 downto 0);
116
signal cpu_mem_wait :       std_logic;
117
 
118
-- interface to i/o
119
signal io_rd_data :         std_logic_vector(31 downto 0);
120
signal io_wr_data :         std_logic_vector(31 downto 0);
121
signal io_rd_addr :         std_logic_vector(31 downto 2);
122
signal io_wr_addr :         std_logic_vector(31 downto 2);
123
signal io_rd_vma :          std_logic;
124
signal io_byte_we :         std_logic_vector(3 downto 0);
125
 
126
 
127
--------------------------------------------------------------------------------
128
-- Logging signals
129
 
130
 
131
-- Log file
132 51 ja_rd
file log_file: TEXT open write_mode is "hw_sim_log.txt";
133 42 ja_rd
 
134
-- Console output log file
135
file con_file: TEXT open write_mode is "hw_sim_console_log.txt";
136
 
137
-- Maximum line size of for console output log. Lines longer than this will be
138
-- truncated.
139
constant CONSOLE_LOG_LINE_SIZE : integer := 1024*4;
140
 
141
-- Console log line buffer
142
signal con_line_buf :       string(1 to CONSOLE_LOG_LINE_SIZE);
143
signal con_line_ix :        integer := 1;
144
 
145 51 ja_rd
signal log_info :           t_log_info;
146
 
147 42 ja_rd
-- Debug signals ---------------------------------------------------------------
148
 
149
 
150
signal full_rd_addr :       std_logic_vector(31 downto 0);
151
signal full_wr_addr :       std_logic_vector(31 downto 0);
152
signal full_code_addr :     std_logic_vector(31 downto 0);
153
 
154
 
155
begin
156
 
157
    cpu: entity work.mips_cpu
158
    port map (
159
        interrupt   => '0',
160
 
161
        data_rd_addr=> cpu_data_rd_addr,
162
        data_rd_vma => cpu_data_rd_vma,
163
        data_rd     => cpu_data_rd,
164
 
165
        code_rd_addr=> cpu_code_rd_addr,
166
        code_rd     => cpu_code_rd,
167
        code_rd_vma => cpu_code_rd_vma,
168
 
169
        data_wr_addr=> cpu_data_wr_addr,
170
        data_wr     => cpu_data_wr,
171
        byte_we     => cpu_byte_we,
172
 
173
        mem_wait    => cpu_mem_wait,
174
 
175
        clk         => clk,
176
        reset       => reset
177
    );
178
 
179
    cache: entity work.mips_cache_stub
180
    generic map (
181
        BRAM_ADDR_SIZE => BRAM_ADDR_SIZE,
182
        SRAM_ADDR_SIZE => SRAM_ADDR_SIZE
183
    )
184
    port map (
185
        clk             => clk,
186
        reset           => reset,
187
 
188
        -- Interface to CPU core
189
        data_rd_addr    => cpu_data_rd_addr,
190
        data_rd         => cpu_data_rd,
191
        data_rd_vma     => cpu_data_rd_vma,
192
 
193
        code_rd_addr    => cpu_code_rd_addr,
194
        code_rd         => cpu_code_rd,
195
        code_rd_vma     => cpu_code_rd_vma,
196
 
197
        data_wr_addr    => cpu_data_wr_addr,
198
        byte_we         => cpu_byte_we,
199
        data_wr         => cpu_data_wr,
200
 
201
        mem_wait        => cpu_mem_wait,
202 51 ja_rd
        cache_enable    => '1',
203 42 ja_rd
 
204
        -- interface to FPGA i/o devices
205
        io_rd_data      => io_rd_data,
206
        io_wr_data      => io_wr_data,
207
        io_rd_addr      => io_rd_addr,
208
        io_wr_addr      => io_wr_addr,
209
        io_rd_vma       => io_rd_vma,
210
        io_byte_we      => io_byte_we,
211
 
212
        -- interface to synchronous 32-bit-wide FPGA BRAM
213
        bram_rd_data    => bram_rd_data,
214
        bram_wr_data    => bram_wr_data,
215
        bram_rd_addr    => bram_rd_addr,
216
        bram_wr_addr    => bram_wr_addr,
217
        bram_byte_we    => bram_byte_we,
218 51 ja_rd
        bram_data_rd_vma=> bram_data_rd_vma,
219 42 ja_rd
 
220
        -- interface to asynchronous 16-bit-wide external SRAM
221
        sram_address    => sram_address,
222
        sram_databus    => sram_databus,
223
        sram_byte_we_n  => sram_byte_we_n,
224
        sram_oe_n       => sram_oe_n
225
    );
226
 
227
    ---------------------------------------------------------------------------
228
    -- Master clock: free running clock used as main module clock
229
    run_master_clock:
230
    process(done, clk)
231
    begin
232
        if done = '0' then
233
            clk <= not clk after T/2;
234
        end if;
235
    end process run_master_clock;
236
 
237
    drive_uut:
238
    process
239
    variable l : line;
240
    begin
241
        wait for T*4;
242
        reset <= '0';
243
 
244
        wait for T*SIMULATION_LENGTH;
245
 
246
        -- Flush console output to log console file (in case the end of the
247
        -- simulation caugh an unterminated line in the buffer)
248
        if con_line_ix > 1 then
249
            write(l, con_line_buf(1 to con_line_ix));
250
            writeline(con_file, l);
251
        end if;
252
 
253
        print("TB0 finished");
254
        done <= '1';
255
        wait;
256
 
257
    end process drive_uut;
258
 
259
    full_rd_addr <= cpu_data_rd_addr;
260
    full_wr_addr <= cpu_data_wr_addr & "00";
261
    full_code_addr <= cpu_code_rd_addr & "00";
262
 
263
    data_ram_block:
264
    process(clk)
265
    begin
266
        if clk'event and clk='1' then
267
            if reset='0' then
268
                bram_rd_data <=
269
                    bram3(conv_integer(unsigned(bram_rd_addr))) &
270
                    bram2(conv_integer(unsigned(bram_rd_addr))) &
271
                    bram1(conv_integer(unsigned(bram_rd_addr))) &
272
                    bram0(conv_integer(unsigned(bram_rd_addr)));
273
 
274
                if bram_byte_we(3)='1' then
275
                    bram3(conv_integer(unsigned(bram_wr_addr))) <= cpu_data_wr(31 downto 24);
276
                end if;
277
                if bram_byte_we(2)='1' then
278
                    bram2(conv_integer(unsigned(bram_wr_addr))) <= cpu_data_wr(23 downto 16);
279
                end if;
280
                if bram_byte_we(1)='1' then
281
                    bram1(conv_integer(unsigned(bram_wr_addr))) <= cpu_data_wr(15 downto  8);
282
                end if;
283
                if bram_byte_we(0)='1' then
284
                    bram0(conv_integer(unsigned(bram_wr_addr))) <= cpu_data_wr( 7 downto  0);
285
                end if;
286
            end if;
287
        end if;
288
    end process data_ram_block;
289
 
290
    sram_databus <=
291
        sram1(conv_integer(unsigned(sram_address))) &
292
        sram0(conv_integer(unsigned(sram_address)))   when sram_oe_n='0'
293
        else (others => 'Z');
294
 
295
    -- Do a very basic simulation of an external SRAM
296
    simulated_sram:
297 51 ja_rd
    process(sram_byte_we_n, sram_address, sram_oe_n)
298 42 ja_rd
    begin
299 51 ja_rd
        -- Write cycle
300
        -- FIXME should add OE\ to write control logic
301 42 ja_rd
        if sram_byte_we_n'event or sram_address'event then
302
            if sram_byte_we_n(1)='0' then
303
                sram1(conv_integer(unsigned(sram_address))) <= sram_databus(15 downto  8);
304
            end if;
305
            if sram_byte_we_n(0)='0' then
306
                sram0(conv_integer(unsigned(sram_address))) <= sram_databus( 7 downto  0);
307 51 ja_rd
            end if;
308
        end if;
309
 
310
        -- Read cycle
311
        -- FIXME should add some verification of /WE 
312
        if sram_oe_n'event or sram_address'event then
313
            if sram_oe_n='0' then
314
                sram_databus <=
315
                    sram1(conv_integer(unsigned(sram_address))) &
316
                    sram0(conv_integer(unsigned(sram_address)));
317
            else
318
                sram_databus <= (others => 'Z');
319 42 ja_rd
            end if;
320
        end if;
321 51 ja_rd
 
322 42 ja_rd
    end process simulated_sram;
323
 
324
 
325
    simulated_io:
326
    process(clk)
327
    variable i : integer;
328
    variable uart_data : integer;
329
    begin
330
        if clk'event and clk='1' then
331
 
332
            if io_byte_we/="0000" then
333
                if io_wr_addr(31 downto 28)=X"2" then
334
                    -- Write to UART
335
 
336
                    -- If we're simulating the UART TX time, pulse RDY low
337
                    if SIMULATED_UART_TX_TIME > 0 us then
338
                        uart_tx_rdy <= '0', '1' after SIMULATED_UART_TX_TIME;
339
                    end if;
340
 
341
                    -- TX data may come from the high or low byte (opcodes.s
342
                    -- uses high byte, no_op.c uses low)
343
                    if io_byte_we(0)='1' then
344
                        uart_data := conv_integer(unsigned(io_wr_data(7 downto 0)));
345
                    else
346
                        uart_data := conv_integer(unsigned(io_wr_data(31 downto 24)));
347
                    end if;
348
 
349
                    -- UART TX data goes to output after a bit of line-buffering
350
                    -- and editing
351
                    if uart_data = 10 then
352
                        -- CR received: print output string and clear it
353
                        print(con_file, con_line_buf(1 to con_line_ix));
354
                        con_line_ix <= 1;
355
                        for i in 1 to con_line_buf'high loop
356
                           con_line_buf(i) <= ' ';
357
                        end loop;
358
                    elsif uart_data = 13 then
359
                        -- ignore LF
360
                    else
361
                        -- append char to output string
362
                        if con_line_ix < con_line_buf'high then
363
                            con_line_buf(con_line_ix) <= character'val(uart_data);
364
                            con_line_ix <= con_line_ix + 1;
365
                        end if;
366
                    end if;
367
                end if;
368
            end if;
369
        end if;
370
    end process simulated_io;
371
 
372
    -- UART read registers; only status, and hardwired, for the time being
373 51 ja_rd
    io_rd_data <= X"00000003";
374 42 ja_rd
    data_uart <= data_uart_status;
375
    data_uart_status <= X"0000000" & "00" & uart_tx_rdy & uart_rx_rdy;
376
 
377 51 ja_rd
    log_execution:
378 42 ja_rd
    process
379
    begin
380 51 ja_rd
        log_cpu_activity(clk, reset, done,
381
                         "@entity_name@/cpu", log_info, "log_info", log_file);
382 42 ja_rd
        wait;
383 51 ja_rd
    end process log_execution;
384 42 ja_rd
 
385
 
386
end architecture @arch_name@;

powered by: WebSVN 2.1.0

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