------------------------------------------------------------------------- -- Project: JIPS, a portable 32-bit RISC CPU written in VHDL -- This file: Testbench for JCPU -- also writes 'opc.lst' for JASM-assembler -- -- Copyright (C) 2007 J. Ahrensfeld -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation, either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . -- -- For questions and ideas, please contact the author at jens@jayfield.org -- -------------------------------------------------------------------------- LIBRARY ieee; use IEEE.STD_LOGIC_1164.ALL; USE ieee.numeric_std.ALL; library work; use work.mips_types.all; use work.mips_instr.all; use work.async_types.all; use work.async_defs.all; ENTITY tb_mips_sys IS END tb_mips_sys; ARCHITECTURE behavior OF tb_mips_sys IS constant CLK_PERIOD : time := 10 ns; constant ICACHE_SIZE : natural := 512; -- words constant DCACHE_SIZE : natural := 512; -- words constant SRAM_ADDR_WIDTH : integer := 17; -- bits constant FLASH_ADDR_WIDTH : integer := 17; -- bits signal debug : unsigned(1 downto 0); -- Master signal nmi : STD_LOGIC := '0'; signal rst : STD_LOGIC := '1'; signal clk : STD_LOGIC := '0'; signal eb : STD_LOGIC := '1'; signal flash_cs_n : std_logic; signal flash_we_n : std_logic; signal flash_oe_n : std_logic; signal flash_be_n : unsigned(3 downto 0); signal sram_cs_n : std_logic; signal sram_be_n : unsigned(3 downto 0); signal sram_wr_n : std_logic; signal sram_oe_n : std_logic; signal sram_a : unsigned(SRAM_ADDR_WIDTH-1 downto 0); signal sram_d : unsigned(31 downto 0); signal flash_a : unsigned(FLASH_ADDR_WIDTH-1 downto 0); signal flash_d : unsigned(31 downto 0); signal gpo0 : unsigned(31 downto 0); signal gpo1 : unsigned(31 downto 0); signal gpi0 : unsigned(31 downto 0) := (others => '0'); signal gpi1 : unsigned(31 downto 0) := (others => '0'); signal int_timer : std_logic; signal int_uart : std_logic; signal rx : std_logic := '1'; signal tx : std_logic; type word_array_t is array (natural range <>) of unsigned(31 downto 0); signal sram_data : word_array_t(0 to 2**SRAM_ADDR_WIDTH-1); signal flash_data : word_array_t(0 to 2**FLASH_ADDR_WIDTH-1); BEGIN ------------------------------------------------------------------ CLK_GEN: process begin wait for CLK_PERIOD/2; clk <= not clk; end process; ------------------------------------------------------------------ uut : entity work.mips_sys GENERIC MAP ( ICACHE_SIZE => ICACHE_SIZE, -- words DCACHE_SIZE => DCACHE_SIZE, -- words SRAM_ADDR_WIDTH => SRAM_ADDR_WIDTH, FLASH_ADDR_WIDTH => FLASH_ADDR_WIDTH ) PORT MAP ( eb => eb, nmi => nmi, rst => rst, clk => clk, flash_cs_n => flash_cs_n, flash_oe_n => flash_oe_n, flash_we_n => flash_we_n, flash_be_n => flash_be_n, sram_cs_n => sram_cs_n, sram_we_n => sram_wr_n, sram_oe_n => sram_oe_n, sram_be_n => sram_be_n, sram_a => sram_a, sram_d => sram_d, flash_a => flash_a, flash_d => flash_d, gpo0 => gpo0, gpo1 => gpo1, gpi0 => gpi0, gpi1 => gpi1, rx => rx, tx => tx, debug => debug ); ------------------------------------------------------------------ SRAM_READ: process(sram_a, sram_cs_n, sram_oe_n, sram_be_n) begin sram_d <= (others => 'Z') after 10 ns; if sram_oe_n = '0' then if sram_cs_n = '0' then if sram_be_n(0) = '0' then sram_d(7 downto 0) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(7 downto 0) after 10 ns; end if; if sram_be_n(1) = '0' then sram_d(15 downto 8) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(15 downto 8) after 10 ns; end if; if sram_be_n(2) = '0' then sram_d(23 downto 16) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(23 downto 16) after 10 ns; end if; if sram_be_n(3) = '0' then sram_d(31 downto 24) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(31 downto 24) after 10 ns; end if; end if; end if; end process; SRAM_WRITE: process(sram_wr_n) begin if rising_edge(sram_wr_n) then if sram_cs_n = '0' then if sram_be_n(0) = '0' then sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(7 downto 0) <= sram_d(7 downto 0); end if; if sram_be_n(1) = '0' then sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(15 downto 8) <= sram_d(15 downto 8); end if; if sram_be_n(2) = '0' then sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(23 downto 16) <= sram_d(23 downto 16); end if; if sram_be_n(3) = '0' then sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(31 downto 24) <= sram_d(31 downto 24); end if; end if; end if; end process; ------------------------------------------------------------------ FLASH_READ: process(rst, flash_cs_n, flash_oe_n, flash_a) type file_t is file of integer; file load_flash : file_t open read_mode is "hello.flash.bin"; variable instr : integer; variable index : natural; variable temp : signed(31 downto 0); constant tpd : time := 25 ns; begin if rst = '1' then index := 0; while not endfile(load_flash) loop read(load_flash, instr); temp := to_signed(instr, word_t'length); flash_data(index) <= unsigned(temp); index := index + 1; end loop; else flash_d <= (others => 'Z') after tpd; index := to_integer(flash_a(FLASH_ADDR_WIDTH-1 downto 2)); if flash_oe_n = '0' then if flash_cs_n = '0' then if flash_be_n(0) = '0' then flash_d(7 downto 0) <= flash_data(index)(7 downto 0) after tpd; end if; if flash_be_n(1) = '0' then flash_d(15 downto 8) <= flash_data(index)(15 downto 8) after tpd; end if; if flash_be_n(2) = '0' then flash_d(23 downto 16) <= flash_data(index)(23 downto 16) after tpd; end if; if flash_be_n(3) = '0' then flash_d(31 downto 24) <= flash_data(index)(31 downto 24) after tpd; end if; end if; end if; end if; end process; ------------------------------------------------------------------ STIMULUS: process begin wait for 3*CLK_PERIOD; wait until rising_edge(clk); rst <= '0'; wait for 778254*CLK_PERIOD; wait until rising_edge(clk); nmi <= '0'; wait for 3000*CLK_PERIOD; wait until rising_edge(clk); nmi <= '0'; wait; end process; END;