------------------------------------------------------------------------- -- Project: JCPU, a portable 8-bit RISC CPU written in VHDL -- This file: system test using Xilinx ML-402 -- Copyright (C) 2007 J. Ahrensfeld -- This library is free software; you can redistribute it and/or -- modify it under the terms of the GNU Lesser General Public -- License as published by the Free Software Foundation; either -- version 2.1 of the License, or (at your option) any later version. -- This library 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 -- Lesser General Public License for more details. -- You should have received a copy of the GNU Lesser General Public -- License along with this library; if not, write to the Free Software -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -- 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; use std.textio.all; -- Imports the standard textio package. Library UNISIM; use UNISIM.vcomponents.all; library work; use work.mips_types.all; --use work.fifo_ctrl_pkg.all; use work.sdram_config.all; use work.sdram_types.all; use work.sys_types.all; ENTITY mips_sys IS GENERIC ( sys_freq : integer := 100E6; ddr_phaseshift : integer := 0; ddr_frequency_hz : integer := 100E6 ); PORT ( sys_rst_n_in : in std_logic; sys_clk_in : in std_logic; -- Buttons and LEDs sys_btn : in unsigned(4 downto 0); sys_dip : in unsigned(7 downto 0); sys_led : out unsigned(8 downto 0); -- UART sys_rx : in std_logic; sys_tx : out std_logic; -- LCD sys_lcd_d : inout unsigned(3 downto 0); sys_lcd_e : out std_logic; sys_lcd_rs : out std_logic; sys_lcd_rw : out std_logic; -- DDR SDRAM sys_sdr_clk_p : out std_logic; -- ddr_sdram_clock sys_sdr_clk_n : out std_logic; -- /ddr_sdram_clock sys_sdr_cke_q : out std_logic; -- clock enable sys_sdr_cs_qn : out std_logic; -- /chip select sys_sdr_ras_qn : out std_logic; -- /ras sys_sdr_cas_qn : out std_logic; -- /cas sys_sdr_we_qn : out std_logic; -- /write enable sys_sdr_dm_q : out unsigned(DDR_DM_WIDTH-1 downto 0); -- data mask bits, set to "00" sys_sdr_dqs_q : inout unsigned(DDR_DQS_WIDTH-1 downto 0); -- data strobe, only for write sys_sdr_ba_q : out unsigned(DDR_BANK_WIDTH-1 downto 0); -- bank select sys_sdr_a_q : out unsigned(DDR_ADDR_WIDTH-1 downto 0); -- address bus sys_sdr_data : inout unsigned(DDR_DATA_WIDTH-1 downto 0); -- bidir data bus sys_sdr_clk_fb : in std_logic; -- VGA -- sys_vga_red : out unsigned(7 downto 0); -- sys_vga_green : out unsigned(7 downto 0); -- sys_vga_blue : out unsigned(7 downto 0); -- sys_vga_blank_n : out std_logic; -- sys_vga_sync_n : out std_logic; -- sys_vga_hsync : out std_logic; -- sys_vga_vsync : out std_logic; -- sys_vga_clk : out std_logic; sys_usb_d : inout unsigned(15 downto 0); sys_usb_a : out unsigned(1 downto 0); sys_usb_csn : out std_logic; sys_usb_wrn : out std_logic; sys_usb_rdn : out std_logic; sys_usb_rstn : out std_logic; sys_usb_int : in std_logic; sys_flash_d : inout unsigned(31 downto 0); sys_flash_a : out unsigned(24 downto 0); sys_flash_ce : out std_logic; sys_flash_wrn : out std_logic; sys_flash_rdn : out std_logic; sys_flash_rstn : out std_logic; sys_flash_byten : out std_logic; sys_error : out unsigned(1 downto 0) -- indicates Errors ); -- attribute BUFFER_TYPE : string; -- attribute BUFFER_TYPE of sys_clk_in : signal is "BUFG"; -- attribute BUFFER_TYPE of sys_sdr_dcm_clk_fb : signal is "BUFG"; END mips_sys; ARCHITECTURE behavior OF mips_sys IS COMPONENT mips_top Port ( RST_I : in STD_LOGIC; CLK_I : in STD_LOGIC; ACK_I : in STD_LOGIC; SRDY_I : in STD_LOGIC; ADDR_O : out word_t; DAT_I : in word_t; DAT_O : out word_t; WE_O : out STD_LOGIC; SEL_O : out unsigned(3 downto 0); CYC_O : out STD_LOGIC; STB_O : out STD_LOGIC; MRDY_O : out STD_LOGIC; INT : in unsigned (5 downto 0) ); END COMPONENT; COMPONENT rom_wb PORT ( CLK_I : in STD_LOGIC; RST_I : in STD_LOGIC; CYC_I : in STD_LOGIC; STB_I : in STD_LOGIC; ACK_O : out STD_LOGIC; MRDY_I : in STD_LOGIC; SRDY_O : out STD_LOGIC; ADDR_I : in unsigned(31 downto 0); DAT_O : out unsigned(31 downto 0) ); END COMPONENT; COMPONENT ram_wb PORT ( CLK_I : in STD_LOGIC; RST_I : in STD_LOGIC; CYC_I : in STD_LOGIC; STB_I : in STD_LOGIC; SEL_I : in unsigned(3 downto 0); WE_I : in STD_LOGIC; ACK_O : out STD_LOGIC; SRDY_O : out STD_LOGIC; MRDY_I : in STD_LOGIC; ADDR_I : in unsigned(31 downto 0); DAT_I : in unsigned(31 downto 0); DAT_O : out unsigned(31 downto 0) ); END COMPONENT; COMPONENT lcd_port PORT ( rst : in std_logic; clk : in std_logic; we : in std_logic; din : in unsigned(7 downto 0); dout : out unsigned(7 downto 0); lcd_d : inout unsigned(3 downto 0); lcd_e : out std_logic; lcd_rs : out std_logic; lcd_rw : out std_logic ); END COMPONENT; COMPONENT async_port_wb GENERIC ( addr_width : natural := 32; data_width : natural := 32; async_timespec : async_timespec_t ); PORT ( CLK_I : in STD_LOGIC; RST_I : in STD_LOGIC; CYC_I : in STD_LOGIC; STB_I : in STD_LOGIC; WE_I : in STD_LOGIC; ACK_O : out STD_LOGIC; SRDY_O : out STD_LOGIC; MRDY_I : in STD_LOGIC; ADDR_I : in unsigned(31 downto 0); DAT_I : in unsigned(31 downto 0); DAT_O : out unsigned(31 downto 0); async_a : out unsigned(addr_width-1 downto 0); async_d : inout unsigned(data_width-1 downto 0); async_cs : out std_logic; async_wr : out std_logic; async_rd : out std_logic; async_rst : out std_logic ); END COMPONENT; COMPONENT uart_wb PORT ( CLK_I : in STD_LOGIC; RST_I : in STD_LOGIC; CYC_I : in STD_LOGIC; STB_I : in STD_LOGIC; SEL_I : in unsigned(3 downto 0); WE_I : in STD_LOGIC; ACK_O : out STD_LOGIC; SRDY_O : out STD_LOGIC; MRDY_I : in STD_LOGIC; ADDR_I : in unsigned(31 downto 0); DAT_I : in unsigned(31 downto 0); DAT_O : out unsigned(31 downto 0); INT_RX_O : out STD_LOGIC; INT_TX_O : out STD_LOGIC; ser_rx : in std_logic; ser_tx : out std_logic ); END COMPONENT; COMPONENT gpio_wb PORT ( CLK_I : in STD_LOGIC; RST_I : in STD_LOGIC; CYC_I : in STD_LOGIC; STB_I : in STD_LOGIC; SEL_I : in unsigned(3 downto 0); WE_I : in STD_LOGIC; ACK_O : out STD_LOGIC; SRDY_O : out STD_LOGIC; MRDY_I : in STD_LOGIC; ADDR_I : in unsigned(31 downto 0); DAT_I : in unsigned(31 downto 0); DAT_O : out unsigned(31 downto 0); sys_gpo0 : out unsigned(31 downto 0); sys_gpo1 : out unsigned(31 downto 0); sys_gpi0 : in unsigned(31 downto 0); sys_gpi1 : in unsigned(31 downto 0) ); END COMPONENT; signal rst : std_logic; signal clk : std_logic; signal clk270 : std_logic; signal clk270var : std_logic; signal rst_in : std_logic; signal int_uart_rx : std_logic; signal locked : std_logic; signal usb_addr : unsigned(31 downto 0); signal flash_addr : unsigned(31 downto 0); -- J-Bus signals signal INT : unsigned(5 downto 0); signal DAT_I : word_t; signal DAT_O : word_t; signal ADDR_O : word_t; signal SEL_O : unsigned(3 downto 0); signal WE_O : std_logic; signal CYC_O : std_logic; signal STB_O : std_logic; signal ACK_I : std_logic; signal SRDY_I : std_logic; signal MRDY_O : std_logic; signal CYC_O_flash : std_logic; signal ACK_I_flash : std_logic; signal SRDY_I_flash : std_logic; signal DAT_I_flash : unsigned(31 downto 0); signal CYC_O_usb : std_logic; signal ACK_I_usb : std_logic; signal SRDY_I_usb : std_logic; signal DAT_I_usb : unsigned(31 downto 0); signal CYC_O_sdram : std_logic; signal ACK_I_sdram : std_logic; signal SRDY_I_sdram : std_logic; signal DAT_I_sdram : unsigned(31 downto 0); signal CYC_O_ram : std_logic; signal ACK_I_ram : std_logic; signal SRDY_I_ram : std_logic; signal DAT_I_ram : unsigned(31 downto 0); signal CYC_O_rom : std_logic; signal ACK_I_rom : std_logic; signal SRDY_I_rom : std_logic; signal DAT_I_rom : unsigned(31 downto 0); signal CYC_O_gpio : std_logic; signal ACK_I_gpio : std_logic; signal SRDY_I_gpio : std_logic; signal DAT_I_gpio : unsigned(31 downto 0); signal CYC_O_urom : std_logic; signal ACK_I_urom : std_logic; signal SRDY_I_urom : std_logic; signal DAT_I_urom : unsigned(31 downto 0); signal CYC_O_uart : std_logic; signal ACK_I_uart : std_logic; signal SRDY_I_uart : std_logic; signal DAT_I_uart : unsigned(31 downto 0); signal gpo0 : unsigned(31 downto 0); signal gpo1 : unsigned(31 downto 0); signal gpi0 : unsigned(31 downto 0); signal gpi1 : unsigned(31 downto 0); -- DDR SDRAM constant BURST_LEN : natural := 2; -- attribute rom_style: string; -- attribute rom_style of cmd_fifo_dout: signal is "DISTRIBUTED"; -- attribute rom_style of cpu_cpu_write_fifo_dout: signal is "DISTRIBUTED"; -- attribute rom_style of cpu_read_fifo_dout: signal is "DISTRIBUTED"; type mem_area_t is (mem_dead, mem_urom, mem_flash, mem_usb, mem_rom, mem_ram, mem_gpio, mem_uart, mem_sdram); signal mem_area : mem_area_t; BEGIN gpi0(4 downto 0) <= sys_btn; gpi1(7 downto 0) <= sys_dip; sys_led <= gpo0(8 downto 0); sys_error <= gpo0(31 downto 30); int <= "000" & sys_usb_int & int_uart_rx & sys_btn(4); rst_in <= not sys_rst_n_in; rst <= not locked; sys_usb_rstn <= not gpo1(0); sys_flash_byten <= '1'; usb_addr <= X"0000000" & "00" & ADDR_O(3 downto 2); flash_addr <= "0000000" & ADDR_O(25 downto 2) & '0'; mem_mux: process(ADDR_O) begin mem_area <= mem_dead; if ADDR_O(31 downto 28) = X"0" then mem_area <= mem_urom; elsif ADDR_O(31 downto 28) = X"A" then if ADDR_O(26) = '1' then mem_area <= mem_flash; elsif ADDR_O(17 downto 16) = "00" then mem_area <= mem_gpio; elsif ADDR_O(17 downto 16) = "01" then mem_area <= mem_uart; elsif ADDR_O(17 downto 16) = "10" then mem_area <= mem_usb; 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"B" and ADDR_O(15) = '1') then mem_area <= mem_ram; elsif (ADDR_O(31 downto 28) = X"8" or ADDR_O(30) = '1') then mem_area <= mem_sdram; end if; end process; signal_mux: process(mem_area, CYC_O) begin CYC_O_urom <= '0'; CYC_O_uart <= '0'; CYC_O_gpio <= '0'; CYC_O_flash <= '0'; CYC_O_usb <= '0'; CYC_O_rom <= '0'; CYC_O_ram <= '0'; CYC_O_sdram <= '0'; case mem_area is when mem_urom => CYC_O_urom <= CYC_O; when mem_gpio => CYC_O_gpio <= CYC_O; when mem_uart => CYC_O_uart <= CYC_O; when mem_flash => CYC_O_flash <= CYC_O; when mem_usb => CYC_O_usb <= CYC_O; when mem_rom => CYC_O_rom <= CYC_O; when mem_ram => CYC_O_ram <= CYC_O; when mem_sdram => CYC_O_sdram <= CYC_O; when others => null; end case; end process; -- sys_user_rom_addr <= ADDR_O; -- sys_user_rom_clk <= clk; -- sys_user_rom_en <= CYC_O_urom and STB_O; -- DAT_I_urom <= sys_user_rom_din; SRDY_I_urom <= CYC_O_urom; urom_ack_register: process(clk) begin if rising_edge(clk) then ACK_I_urom <= CYC_O_urom and STB_O; end if; end process; ------------------------------------------------------------------ SRDY_I <= SRDY_I_flash or SRDY_I_usb or SRDY_I_sdram or SRDY_I_ram or SRDY_I_rom or SRDY_I_urom or SRDY_I_uart or SRDY_I_gpio; ACK_I <= ACK_I_flash or ACK_I_usb or ACK_I_sdram or ACK_I_ram or ACK_I_rom or ACK_I_urom or ACK_I_uart or ACK_I_gpio; DAT_I <= DAT_I_sdram when CYC_O_sdram = '1' else DAT_I_ram when CYC_O_ram = '1' else DAT_I_rom when CYC_O_rom = '1' else DAT_I_urom when CYC_O_urom = '1' else DAT_I_flash when CYC_O_flash = '1' else DAT_I_usb when CYC_O_usb = '1' else DAT_I_uart when CYC_O_uart = '1' else DAT_I_gpio when CYC_O_gpio = '1' else X"DEADBEEF"; ------------------------------------------------------------------ inst_mips_top: mips_top PORT MAP ( RST_I => rst, CLK_I => clk, ACK_I => ACK_I, SRDY_I => SRDY_I, MRDY_O => MRDY_O, CYC_O => CYC_O, STB_O => STB_O, WE_O => WE_O, SEL_O => SEL_O, DAT_I => DAT_I, DAT_O => DAT_O, ADDR_O => ADDR_O, INT => INT ); inst_ram_wb : ram_wb PORT MAP ( CLK_I => clk, RST_I => rst, CYC_I => CYC_O_ram, STB_I => STB_O, SEL_I => SEL_O, WE_I => WE_O, ACK_O => ACK_I_ram, SRDY_O => SRDY_I_ram, MRDY_I => MRDY_O, ADDR_I => ADDR_O, DAT_I => DAT_O, DAT_O => DAT_I_ram ); inst_rom_wb : rom_wb PORT MAP ( CLK_I => clk, RST_I => rst, CYC_I => CYC_O_rom, STB_I => STB_O, ACK_O => ACK_I_rom, MRDY_I => MRDY_O, SRDY_O => SRDY_I_rom, ADDR_I => ADDR_O, DAT_O => DAT_I_rom ); inst_lcd_port: lcd_port PORT MAP ( clk => clk, rst => rst, we => '0', din => X"00", dout => open, lcd_d => sys_lcd_d, lcd_e => sys_lcd_e, lcd_rs => sys_lcd_rs, lcd_rw => sys_lcd_rw ); inst_gpio_wb : gpio_wb PORT MAP ( CLK_I => clk, RST_I => rst, CYC_I => CYC_O_gpio, STB_I => STB_O, SEL_I => SEL_O, WE_I => WE_O, ACK_O => ACK_I_gpio, SRDY_O => SRDY_I_gpio, MRDY_I => MRDY_O, ADDR_I => ADDR_O, DAT_I => DAT_O, DAT_O => DAT_I_gpio, sys_gpo0 => gpo0, sys_gpo1 => gpo1, sys_gpi0 => gpi0, sys_gpi1 => gpi1 ); inst_flash_port : async_port_wb GENERIC MAP ( addr_width => 25, data_width => 32, async_timespec => ts_flash ) PORT MAP ( CLK_I => clk, RST_I => rst, CYC_I => CYC_O_flash, STB_I => STB_O, WE_I => WE_O, ACK_O => ACK_I_flash, SRDY_O => SRDY_I_flash, MRDY_I => MRDY_O, ADDR_I => flash_addr, DAT_I => DAT_O, DAT_O => DAT_I_flash, async_a => sys_flash_a, async_d => sys_flash_d, async_cs => sys_flash_ce, async_wr => sys_flash_wrn, async_rd => sys_flash_rdn, async_rst => sys_flash_rstn ); inst_usb_port : async_port_wb GENERIC MAP ( addr_width => 2, data_width => 16, async_timespec => ts_usb ) PORT MAP ( CLK_I => clk, RST_I => rst, CYC_I => CYC_O_usb, STB_I => STB_O, WE_I => WE_O, ACK_O => ACK_I_usb, SRDY_O => SRDY_I_usb, MRDY_I => MRDY_O, ADDR_I => usb_addr, DAT_I => DAT_O, DAT_O => DAT_I_usb, async_a => sys_usb_a, async_d => sys_usb_d, async_cs => sys_usb_csn, async_wr => sys_usb_wrn, async_rd => sys_usb_rdn, async_rst => open ); inst_uart_wb : uart_wb PORT MAP ( CLK_I => clk, RST_I => rst, CYC_I => CYC_O_uart, STB_I => STB_O, SEL_I => SEL_O, WE_I => WE_O, ACK_O => ACK_I_uart, SRDY_O => SRDY_I_uart, MRDY_I => MRDY_O, ADDR_I => ADDR_O, DAT_I => DAT_O, DAT_O => DAT_I_uart, INT_RX_O => int_uart_rx, INT_TX_O => open, ser_rx => sys_rx, ser_tx => sys_tx ); inst_sdram_ctrl_frontend_wb : entity work.sdram_ctrl_frontend_wb GENERIC MAP ( BL => BURST_LEN, f_sysclk => ddr_frequency_hz, fifo_depth => 4 ) PORT MAP ( RST_I => rst, CLK_I => clk, CLK270_I => clk270, CLK270VAR_I => clk270var, CYC_I => CYC_O_sdram, STB_I => STB_O, SEL_I => SEL_O, WE_I => WE_O, ACK_O => ACK_I_sdram, MRDY_I => MRDY_O, SRDY_O => SRDY_I_sdram, ADDR_I => ADDR_O, DAT_I => DAT_O, DAT_O => DAT_I_sdram, -- SDRAM signals sd_clk_p => sys_sdr_clk_p, sd_clk_n => sys_sdr_clk_n, sd_cke => sys_sdr_cke_q, sd_cs_n => sys_sdr_cs_qn, sd_cas_n => sys_sdr_cas_qn, sd_ras_n => sys_sdr_ras_qn, sd_we_n => sys_sdr_we_qn, sd_addr => sys_sdr_a_q, sd_ba => sys_sdr_ba_q, sd_dm => sys_sdr_dm_q, sd_dqs => sys_sdr_dqs_q, sd_data => sys_sdr_data ); inst_clockgen : entity work.clockgen GENERIC MAP ( sys1_phaseshift => 0, frequency_hz => 100E6 ) PORT MAP ( -- Clocks and Reset rst => rst_in, -- external async reset, low active clk_in => sys_clk_in, -- system clock (e.g. 100MHz), from board clk_fb_in => sys_sdr_clk_fb, -- feedback clock sys1_clk0_out => open, -- System clock #1 (e.g. clock for DDR-SDRAM data capture), dcm#1 output 0° sys1_clk270_out => clk270var, -- System clock #1 (e.g. clock for DDR-SDRAM data capture), dcm#1 output 270° sys0_clk0_out => clk, -- System clock #0, dcm#0 output 0° sys0_clk270_out => clk270, -- System clock #0, dcm#0 output 270° locked_out => locked, -- DCM locked status error_out => open ); ------------------------------------------------------------------ END;