Committed on the Free edition of March Hare Software CVSNT Server. Upgrade to CVS Suite for more features and support: http://march-hare.com/cvsnt/ git-svn-id: http://moon:8086/svn/vhdl/trunk@926 cc03376c-175c-47c8-b038-4cd826a8556b
234 lines
6.8 KiB
VHDL
234 lines
6.8 KiB
VHDL
-------------------------------------------------------------------------
|
|
-- 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 <http://www.gnu.org/licenses/>.
|
|
--
|
|
-- 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;
|