------------------------------------------------------------------------- -- 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.sdram_types.all; use work.sdram_config.all; ENTITY mips_sys IS GENERIC ( ICACHE_SIZE : natural := 4096; -- words DCACHE_SIZE : natural := 4096; -- words F_CLK_BRD : real := 50.0; F_CLK_SYS : real := 64.0 ); PORT ( sys_nmi_n : in std_logic; rst_brd_n : in std_logic; clk_brd : in std_logic; -- SDRAM signals sys_sdram_clk : out STD_LOGIC; sys_sdram_cke : out STD_LOGIC; sys_sdram_cs_n : out STD_LOGIC; sys_sdram_cas_n : out STD_LOGIC; sys_sdram_ras_n : out STD_LOGIC; sys_sdram_we_n : out STD_LOGIC; sys_sdram_addr : out sdr_addr_t; sys_sdram_ba : out sdr_ba_t; sys_sdram_dqm : out unsigned(PART_DM_WIDTH-1 downto 0); sys_sdram_data : inout unsigned(PART_DATA_WIDTH-1 downto 0); spi_ss_n : out std_logic; spi_clk : out std_logic; spi_miso : in std_logic; spi_mosi : out std_logic; uart_rx : in unsigned(1 downto 0); uart_tx : out unsigned(1 downto 0); dip_sw : in unsigned(3 downto 0); sys_leds : out unsigned(7 downto 0) ); END mips_sys; ARCHITECTURE behavior OF mips_sys IS signal cpu_debug : unsigned(1 downto 0); signal INT : unsigned (5 downto 0) := (others => '0'); -- J-BUS Master signal ACK_I : STD_LOGIC; signal SRDY_I : STD_LOGIC; signal ADDR_O : unsigned(31 downto 0); signal DAT_I : unsigned(31 downto 0); signal DAT_O : unsigned(31 downto 0); signal WE_O : STD_LOGIC; signal SEL_O : unsigned(3 downto 0); signal CYC_O : STD_LOGIC; signal STB_O : STD_LOGIC; signal MRDY_O : STD_LOGIC; -- J-BUS Slaves signal CYC_I_rom : std_logic; signal ACK_O_rom : std_logic; signal SRDY_O_rom : std_logic; signal DAT_O_rom : unsigned(31 downto 0); signal CYC_I_ram : std_logic; signal ACK_O_ram : std_logic; signal SRDY_O_ram : std_logic; signal DAT_O_ram : unsigned(31 downto 0); signal CYC_I_gpio : std_logic; signal ACK_O_gpio : std_logic; signal SRDY_O_gpio : std_logic; signal DAT_O_gpio : unsigned(31 downto 0); signal CYC_I_uart0 : std_logic; signal ACK_O_uart0 : std_logic; signal SRDY_O_uart0 : std_logic; signal DAT_O_uart0 : unsigned(31 downto 0); signal CYC_I_uart1 : std_logic; signal ACK_O_uart1 : std_logic; signal SRDY_O_uart1 : std_logic; signal DAT_O_uart1 : unsigned(31 downto 0); signal CYC_I_flash : std_logic; signal ACK_O_flash : std_logic; signal SRDY_O_flash : std_logic; signal DAT_O_flash : unsigned(31 downto 0); signal spi_ss : std_LOGIC; signal cpu_tx_data : unsigned(7 downto 0); signal cpu_tx_data_vld : std_logic; signal int_timer : std_logic; signal int_uart0 : std_logic; signal int_uart1 : std_logic; signal int_flash : std_logic; type mem_area_t is (mem_dead, mem_flash, mem_ram, mem_rom, mem_gpio, mem_uart0, mem_uart1); signal mem_area : mem_area_t; signal gpo0 : unsigned(31 downto 0); signal gpi0 : unsigned(31 downto 0) := (others => '0'); signal sys_nmi : STD_LOGIC; signal sys_rst : STD_LOGIC; signal sys_clk : STD_LOGIC; signal rst_brd : STD_LOGIC; signal cpu_rst : STD_LOGIC := '1'; -- pre-init for POR signal cpu_rst_count : unsigned(24 downto 0) := (others => '1'); -- pre-init for POR BEGIN rst_brd <= not rst_brd_n; sys_nmi <= not sys_nmi_n; sys_leds <= cpu_debug & gpo0(5 downto 0); spi_ss_n <= not spi_ss; gpi0(11 downto 8) <= dip_sw; inst_sys_clk : entity work.sdram_clk GENERIC MAP ( F_SDRCLK_IN => F_CLK_BRD, F_SDRCLK_OUT => F_CLK_SYS, clk0_out_phaseshift_ps => 0, clk1_out_phaseshift_ps => 3000 ) PORT MAP ( -- Clocks and Reset rst => rst_brd, -- external async reset, low active clk_in => clk_brd, -- system clock (e.g. 100MHz), from board clk_fb_in => clk_brd, -- feedback clock clk0_0_out => sys_clk, -- System clock #0, dcm#0 output 0° clk1_0_out => open, -- System clock #1 (e.g. clock for DDR-SDRAM data capture), dcm#1 output 0° rst0_0_out => sys_rst -- Reset out ); cpu_reset: process(sys_clk) begin if rising_edge(sys_clk) then if sys_rst = '1' then cpu_rst <= '1'; cpu_rst_count <= (others => '1'); elsif (cpu_rst_count /= 0) then cpu_rst_count <= cpu_rst_count - 1; else cpu_rst <= '0'; end if; end if; end process; ------------------------------------------------------------------ -- Memory mux ------------------------------------------------------------------ mem_mux: process(ADDR_O) begin mem_area <= mem_dead; if ADDR_O(31 downto 28) = X"0" then mem_area <= mem_flash; elsif ADDR_O(31 downto 28) = X"A" then if ADDR_O(27 downto 26) = "00" then if ADDR_O(18 downto 16) = "000" then mem_area <= mem_gpio; elsif ADDR_O(18 downto 16) = "001" then mem_area <= mem_uart0; elsif ADDR_O(18 downto 16) = "011" then mem_area <= mem_uart1; end if; elsif ADDR_O(27 downto 26) = "01" then mem_area <= mem_flash; end if; elsif (ADDR_O(31 downto 28) = X"B" and ADDR_O(15) = '0') then mem_area <= mem_rom; elsif (ADDR_O(31 downto 28) = X"8" or ADDR_O(30) = '1') then mem_area <= mem_ram; end if; end process; signal_mux: process(mem_area, CYC_O) begin CYC_I_gpio <= '0'; CYC_I_uart0 <= '0'; CYC_I_uart1 <= '0'; CYC_I_flash <= '0'; CYC_I_rom <= '0'; CYC_I_ram <= '0'; case mem_area is when mem_gpio => CYC_I_gpio <= CYC_O; when mem_uart0 => CYC_I_uart0 <= CYC_O; when mem_uart1 => CYC_I_uart1 <= CYC_O; when mem_flash => CYC_I_flash <= CYC_O; when mem_rom => CYC_I_rom <= CYC_O; when mem_ram => CYC_I_ram <= CYC_O; when others => null; end case; end process; SRDY_I <= SRDY_O_ram or SRDY_O_rom or SRDY_O_uart0 or SRDY_O_uart1 or SRDY_O_flash or SRDY_O_gpio; ACK_I <= ACK_O_ram or ACK_O_rom or ACK_O_uart0 or ACK_O_uart1 or ACK_O_flash or ACK_O_gpio; DAT_I <= DAT_O_ram when CYC_I_ram = '1' else DAT_O_rom when CYC_I_rom = '1' else DAT_O_uart0 when CYC_I_uart0 = '1' else DAT_O_uart1 when CYC_I_uart1 = '1' else DAT_O_flash when CYC_I_flash = '1' else DAT_O_gpio when CYC_I_gpio = '1' else X"DEADBEEF"; ------------------------------------------------------------------ inst_mips_top: entity work.mips_top GENERIC MAP ( icache_size => ICACHE_SIZE, -- words dcache_size => DCACHE_SIZE -- words ) PORT MAP ( debug => cpu_debug, nmi => sys_nmi, eb => '1', cpu_clk => sys_clk, RST_I => cpu_rst, CLK_I => sys_clk, ACK_I => ACK_I, SRDY_I => SRDY_I, ADDR_O => ADDR_O, DAT_I => DAT_I, DAT_O => DAT_O, WE_O => WE_O, SEL_O => SEL_O, CYC_O => CYC_O, STB_O => STB_O, MRDY_O => MRDY_O, INT => INT ); INT <= "00" & int_flash & int_uart1 & int_uart0 & int_timer; inst_rom : entity work.rom_wb PORT MAP ( CLK_I => sys_clk, RST_I => sys_rst, CYC_I => CYC_I_rom, STB_I => STB_O, WE_I => WE_O, ACK_O => ACK_O_rom, MRDY_I => MRDY_O, SRDY_O => SRDY_O_rom, ADDR_I => ADDR_O, DAT_O => DAT_O_rom ); inst_gpio : entity work.gpio_wb GENERIC MAP ( f_sysclk => F_CLK_SYS ) PORT MAP ( CLK_I => sys_clk, RST_I => sys_rst, CYC_I => CYC_I_gpio, STB_I => STB_O, SEL_I => SEL_O, WE_I => WE_O, ACK_O => ACK_O_gpio, SRDY_O => SRDY_O_gpio, MRDY_I => MRDY_O, ADDR_I => ADDR_O, DAT_I => DAT_O, DAT_O => DAT_O_gpio, INT_TIM_O => int_timer, sys_gpi_0 => gpi0, sys_gpo_0 => gpo0 ); inst_uart0 : entity work.uart_wb GENERIC MAP ( f_sysclk => F_CLK_SYS, baudrate_default => 460800.0, fifo_depth_bits => 4 ) PORT MAP ( CLK_I => sys_clk, RST_I => sys_rst, CYC_I => CYC_I_uart0, STB_I => STB_O, SEL_I => SEL_O, WE_I => WE_O, ACK_O => ACK_O_uart0, SRDY_O => SRDY_O_uart0, MRDY_I => MRDY_O, ADDR_I => ADDR_O, DAT_I => DAT_O, DAT_O => DAT_O_uart0, INT_O => int_uart0, ser_rx => uart_rx(0), ser_tx => uart_tx(0) ); inst_uart1 : entity work.uart_wb GENERIC MAP ( f_sysclk => F_CLK_SYS, baudrate_default => 460800.0, fifo_depth_bits => 4 ) PORT MAP ( CLK_I => sys_clk, RST_I => sys_rst, CYC_I => CYC_I_uart1, STB_I => STB_O, SEL_I => SEL_O, WE_I => WE_O, ACK_O => ACK_O_uart1, SRDY_O => SRDY_O_uart1, MRDY_I => MRDY_O, ADDR_I => ADDR_O, DAT_I => DAT_O, DAT_O => DAT_O_uart1, INT_O => int_uart1, ser_rx => uart_rx(1), ser_tx => uart_tx(1) ); inst_spi_flash : entity work.spi_flash_wb GENERIC MAP ( FLASH_ADDR_BITS => 24, CACHE_ADDR_BITS => 8 ) PORT MAP ( CLK_I => sys_clk, RST_I => sys_rst, CYC_I => CYC_I_flash, STB_I => STB_O, SEL_I => SEL_O, WE_I => WE_O, ACK_O => ACK_O_flash, SRDY_O => SRDY_O_flash, MRDY_I => MRDY_O, ADDR_I => ADDR_O, DAT_I => DAT_O, DAT_O => DAT_O_flash, INT_O => int_flash, spi_hold => '0', spi_ss => spi_ss, spi_clk => spi_clk, spi_miso => spi_miso, spi_mosi => spi_mosi ); -- DDR SDRAM Controller Core inst_ctrl_sdr_wb32 : entity work.ctrl_sdr_wb32 GENERIC MAP ( F_SYSCLK => F_CLK_SYS, F_SDRCLK_IN => F_CLK_BRD, F_SDRCLK => 100.000, FIFO_DEPTH => 4, TPD_BOARD_SIM => 3100 ps ) PORT MAP ( RST_I => sys_rst, CLK_I => sys_clk, SDRAM_CLK_I => clk_brd, SDRAM_CLK_FB_I => clk_brd, CYC_I => CYC_I_ram, STB_I => STB_O, SEL_I => SEL_O, WE_I => WE_O, ACK_O => ACK_O_ram, SRDY_O => SRDY_O_ram, MRDY_I => MRDY_O, ADDR_I => ADDR_O, DAT_I => DAT_O, DAT_O => DAT_O_ram, -- SDRAM signals sd_clk => sys_sdram_clk, sd_cke => sys_sdram_cke, sd_cs_n => sys_sdram_cs_n, sd_cas_n => sys_sdram_cas_n, sd_ras_n => sys_sdram_ras_n, sd_we_n => sys_sdram_we_n, sd_addr => sys_sdram_addr, sd_ba => sys_sdram_ba, sd_dqm => sys_sdram_dqm, sd_data => sys_sdram_data ); END;