Initial import

git-svn-id: http://moon:8086/svn/vhdl/trunk@8 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
2008-08-23 08:34:09 +00:00
parent d3bd08bb52
commit a87b40a4be
27 changed files with 10441 additions and 0 deletions
+681
View File
@@ -0,0 +1,681 @@
-------------------------------------------------------------------------
-- 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;
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_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 : in STD_LOGIC;
clk : in STD_LOGIC;
int : in unsigned(5 downto 0);
mem_valid : in STD_LOGIC;
mem_rdy : in STD_LOGIC;
mem_re : out STD_LOGIC;
mem_en : out STD_LOGIC;
mem_we : out unsigned(3 downto 0);
mem_din : in word_t;
mem_dout : out word_t;
mem_addr : out word_t
);
END COMPONENT;
signal int : unsigned(5 downto 0);
signal mem_din : word_t;
signal mem_dout : word_t;
signal mem_addr : word_t;
signal mem_re : std_logic;
signal mem_en : std_logic;
signal mem_we : unsigned(3 downto 0);
signal mem_valid : std_logic;
signal mem_rdy : std_logic;
COMPONENT rom
Port
(
clk : in STD_LOGIC;
ce : in STD_LOGIC;
addr : in word_t;
dout : out word_t
);
END COMPONENT;
signal rom_data : word_t;
COMPONENT ram
PORT
(
clk : in STD_LOGIC;
ce : in STD_LOGIC;
we : in unsigned(3 downto 0);
addr : in unsigned(31 downto 0);
din : in unsigned(31 downto 0);
dout : out unsigned(31 downto 0)
);
END COMPONENT;
signal ram_data : word_t;
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 uart_tx
Port
(
data_in : in std_logic_vector(7 downto 0);
write_buffer : in std_logic;
reset_buffer : in std_logic;
en_16_x_baud : in std_logic;
serial_out : out std_logic;
buffer_full : out std_logic;
buffer_half_full : out std_logic;
clk : in std_logic
);
END COMPONENT;
COMPONENT uart_rx
Port
(
serial_in : in std_logic;
data_out : out std_logic_vector(7 downto 0);
read_buffer : in std_logic;
reset_buffer : in std_logic;
en_16_x_baud : in std_logic;
buffer_data_present : out std_logic;
buffer_full : out std_logic;
buffer_half_full : out std_logic;
clk : in std_logic
);
END COMPONENT;
signal rst : std_logic;
signal rst_in : std_logic;
signal started_up : std_logic := '1';
signal clk : std_logic;
signal led_reg : unsigned(7 downto 0);
signal cpu_lcd_out_reg, cpu_lcd_in_reg, reg_uart_tx: unsigned(7 downto 0);
signal cpu_lcd_we : std_logic;
signal err_led_reg : unsigned(1 downto 0);
signal btn_ps2_reg : unsigned(7 downto 0);
-- Signals to form an timer generating an interrupt every microsecond
subtype tick_usec_t is natural range 0 to 99;
signal tick_usec : tick_usec_t;
signal cnt_usec : word_t;
signal cnt_sec : word_t;
signal cnt_usec_preset : word_t;
signal cnt_sec_preset : word_t;
signal cnt_usec_en : std_logic;
signal cnt_usec_we : std_logic;
signal cnt_sec_en : std_logic;
signal cnt_sec_we : std_logic;
-- Signals for UART connections
signal baud_count : unsigned(7 downto 0);
signal en_16_x_baud : std_logic;
signal reg_we_uart_tx : std_logic;
signal tx_full : std_logic;
signal tx_half_full : std_logic;
signal reg_re_uart_rx : std_logic;
signal reg_uart_rx : std_logic_vector(7 downto 0);
signal rx_data_present : std_logic;
signal rx_full : std_logic;
signal rx_half_full : std_logic;
signal uart_status_port : unsigned(7 downto 0);
signal reg_uart_ctrl : unsigned(7 downto 0);
signal reg_uart_baud : unsigned(7 downto 0);
-- DDR SDRAM
constant BURST_LEN : natural := 2;
signal sdr_addr : user_addr_t;
signal sdr_busy_q : std_logic;
signal sdr_udata_in : unsigned(SDR_DATA_WIDTH-1 downto 0);
signal sdr_udata_out_q : unsigned(SDR_DATA_WIDTH-1 downto 0);
signal sdr_udata_vld_q : std_logic;
signal sdr_be : unsigned(SDR_DM_WIDTH-1 downto 0) := "00000000";
signal sdr_read : std_logic;
signal sdr_en : std_logic;
signal reg_data : word_t;
signal reg_data_vld : std_logic;
signal reg_en : std_logic;
signal rom_en : std_logic;
signal rom_data_vld : std_logic;
signal ram_en : std_logic;
signal ram_data_vld : std_logic;
signal sdram_en : std_logic;
signal sd_counter : word_t;
signal mem_re_r : std_logic;
signal mem_we_r : unsigned(3 downto 0);
signal mem_dout_r : word_t;
signal mem_addr_r : word_t;
-- 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";
BEGIN
int <= "0000" & rx_data_present & btn_ps2_reg(4);
rst_in <= not (started_up and sys_rst_n_in);
en_mux:
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
sdram_en <= '0';
else
reg_en <= '0';
rom_en <= '0';
ram_en <= '0';
-- sdram_en <= '0';
if mem_en = '1' then
mem_re_r <= mem_re;
mem_we_r <= mem_we;
mem_dout_r <= mem_dout;
mem_addr_r <= mem_addr;
if mem_addr(31 downto 28) = X"A" then
reg_en <= '1';
elsif (mem_addr(31 downto 28) = X"B" and mem_addr(15) = '0') then
rom_en <= '1';
elsif (mem_addr(31 downto 28) = X"B" and mem_addr(15) = '1') then
ram_en <= '1';
elsif (mem_addr(31 downto 28) = X"8" or mem_addr(30) = '1') then
sdram_en <= '1';
end if;
elsif sdr_busy_q = '0' then
sdram_en <= '0';
end if;
end if;
end if;
end process;
sdr_addr <= mem_addr_r(24 downto 2) & "0";
sdr_udata_in <= mem_dout_r & mem_dout_r;
sdr_be <= mem_we_r & mem_we_r;
sdr_read <= '1';
sdr_en <= sdram_en and not sdr_busy_q;
------------------------------------------------------------------
led_out:
process(rst, clk)
begin
if rst = '1' then
sys_led <= (others => '0');
sys_error <= (others => '0');
elsif rising_edge(clk) then
sys_led <= not mem_rdy & led_reg;
sys_error <= err_led_reg;
end if;
end process;
------------------------------------------------------------------
btn_ps2_register:
process(clk)
begin
if rising_edge(clk) then
btn_ps2_reg <= "000" & unsigned(sys_btn);
end if;
end process;
proc_sd_counter:
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
sd_counter <= (others => '0');
elsif sdr_udata_vld_q = '1' then
sd_counter <= sd_counter + 1;
end if;
end if;
end process;
mem_valid <= sdr_udata_vld_q or reg_data_vld or rom_data_vld or ram_data_vld;
mem_din <= reg_data when reg_data_vld = '1' else
rom_data when rom_data_vld = '1' else
ram_data when ram_data_vld = '1' else
sdr_udata_out_q(mem_din'left downto mem_din'right);
------------------------------------------------------------------
inst_rom: rom
PORT MAP
(
clk => clk,
ce => rom_en,
addr => mem_addr_r,
dout => rom_data
);
inst_ram: ram
PORT MAP
(
clk => clk,
ce => ram_en,
we => mem_we_r,
addr => mem_addr_r,
din => mem_dout_r,
dout => ram_data
);
ram_read:
process(clk)
begin
if rising_edge(clk) then
ram_data_vld <= '0';
if ram_en = '1' and mem_re_r = '1' then
ram_data_vld <= '1';
end if;
end if;
end process;
rom_read:
process(clk)
begin
if rising_edge(clk) then
rom_data_vld <= '0';
if rom_en = '1' and mem_re_r = '1' then
rom_data_vld <= '1';
end if;
end if;
end process;
registers_read:
process(clk)
begin
if rising_edge(clk) then
reg_data_vld <= '0';
reg_re_uart_rx <= '0';
if reg_en = '1' and mem_re_r = '1' then
reg_data_vld <= '1';
reg_data <= (others => '0');
case mem_addr_r(5 downto 2) is
when "0000" => null;
when "0001" =>
reg_re_uart_rx <= mem_re_r;
reg_data(7 downto 0) <= unsigned(reg_uart_rx);
when "0010" =>
reg_data(7 downto 0) <= uart_status_port;
reg_data(15 downto 8) <= reg_uart_baud;
reg_data(23 downto 16) <= btn_ps2_reg;
reg_data(31 downto 24) <= cpu_lcd_in_reg;
when "0100" =>
reg_data <= cnt_usec;
when "0101" =>
reg_data <= cnt_sec;
when others => null;
end case;
end if;
end if;
end process;
------------------------------------------------------------------
registers_write:
process(clk)
begin
if rising_edge(clk) then
cpu_lcd_we <= '0';
reg_we_uart_tx <= '0';
cnt_usec_we <= '0';
cnt_sec_we <= '0';
if rst = '1' then
led_reg <= (others => '0');
err_led_reg <= (others => '0');
cpu_lcd_out_reg <= (others => '0');
reg_uart_baud <= to_unsigned(53, 8);
reg_uart_ctrl <= to_unsigned(0, 8);
elsif reg_en = '1' then
case mem_addr_r(5 downto 2) is
when "0000" =>
if mem_we_r(0) = '1' then
led_reg(7 downto 0) <= mem_dout_r(7 downto 0);
end if;
if mem_we_r(3) = '1' then
err_led_reg <= mem_dout_r(31 downto 30);
end if;
when "0001" =>
if mem_we_r(0) = '1' then
reg_we_uart_tx <= '1';
reg_uart_tx <= mem_dout_r(7 downto 0);
end if;
when "0010" =>
if mem_we_r(0) = '1' then
reg_uart_ctrl <= mem_dout_r(7 downto 0);
end if;
if mem_we_r(1) = '1' then
reg_uart_baud <= mem_dout_r(15 downto 8);
end if;
if mem_we_r(3) = '1' then
cpu_lcd_we <= '1';
cpu_lcd_out_reg <= mem_dout_r(31 downto 24);
end if;
when "0100" =>
if mem_we_r(3) = '1' then
cnt_usec_we <= '1';
cnt_usec_preset <= mem_dout_r;
end if;
when "0101" =>
if mem_we_r(3) = '1' then
cnt_sec_we <= '1';
cnt_sec_preset <= mem_dout_r;
end if;
when others => null;
end case;
end if;
end if;
end process;
------------------------------------------------------------------
mem_rdy <= not sdr_busy_q;
------------------------------------------------------------------
inst_mips_top: mips_top
PORT MAP
(
rst => rst,
clk => clk,
int => int,
mem_valid => mem_valid,
mem_rdy => mem_rdy,
mem_en => mem_en,
mem_re => mem_re,
mem_we => mem_we,
mem_din => mem_din,
mem_dout => mem_dout,
mem_addr => mem_addr
);
inst_lcd_port: lcd_port
PORT MAP
(
rst => rst,
clk => clk,
we => cpu_lcd_we,
din => cpu_lcd_out_reg,
dout => cpu_lcd_in_reg,
lcd_d => sys_lcd_d,
lcd_e => sys_lcd_e,
lcd_rs => sys_lcd_rs,
lcd_rw => sys_lcd_rw
);
inst_uart_tx: uart_tx
port map
(
data_in => std_logic_vector(reg_uart_tx),
write_buffer => reg_we_uart_tx,
reset_buffer => rst,
en_16_x_baud => en_16_x_baud,
serial_out => sys_tx,
buffer_full => tx_full,
buffer_half_full => tx_half_full,
clk => clk
);
inst_uart_rx: uart_rx
port map
(
serial_in => sys_rx,
data_out => reg_uart_rx,
read_buffer => reg_re_uart_rx,
reset_buffer => rst,
en_16_x_baud => en_16_x_baud,
buffer_data_present => rx_data_present,
buffer_full => rx_full,
buffer_half_full => rx_half_full,
clk => clk
);
uart_status_port <= (7 downto 5 => '0') & rx_data_present & rx_full & rx_half_full & tx_full & tx_half_full;
tick_usec_timer:
process(clk)
begin
if clk'event and clk='1' then
cnt_usec_en <= '0';
if rst = '1' then
tick_usec <= 0;
cnt_usec_en <= '0';
elsif tick_usec = tick_usec_t'high then
tick_usec <= 0;
cnt_usec_en <= '1';
else
tick_usec <= tick_usec + 1;
end if;
end if;
end process;
cnt_usec_timer:
process(clk)
begin
if clk'event and clk='1' then
cnt_sec_en <= '0';
if rst = '1' then
cnt_usec <= (others => '0');
cnt_sec_en <= '0';
elsif cnt_usec_we = '1' then
cnt_usec <= cnt_usec_preset;
elsif cnt_usec_en = '1' then
if cnt_usec = to_unsigned(1E6 - 1, word_t'length) then
cnt_usec <= (others => '0');
cnt_sec_en <= '1';
else
cnt_usec <= cnt_usec + 1;
end if;
end if;
end if;
end process;
cnt_sec_timer:
process(clk)
begin
if clk'event and clk='1' then
if rst = '1' then
cnt_sec <= (others => '0');
elsif cnt_sec_we = '1' then
cnt_sec <= cnt_sec_preset;
elsif cnt_sec_en = '1' then
cnt_sec <= cnt_sec + 1;
end if;
end if;
end process;
baud_timer:
process(clk)
begin
if clk'event and clk='1' then
if rst = '1' then
baud_count <= (others => '0');
elsif baud_count = reg_uart_baud then
baud_count <= (others => '0');
en_16_x_baud <= '1';
else
baud_count <= baud_count + 1;
en_16_x_baud <= '0';
end if;
end if;
end process;
-- DDR SDRAM Controller Core
inst_sdram_ctrl_frontend : entity work.sdram_ctrl_frontend
Generic map
(
BL => BURST_LEN,
read_phaseshift => ddr_phaseshift,
f_sysclk => ddr_frequency_hz,
fifo_depth => 4
)
Port map
(
sys_rst_in => rst_in,
sys_clk_in => sys_clk_in,
sys_rst_out => rst,
sys_clk_out => clk,
sys_clk_fb => sys_sdr_clk_fb,
busy => sdr_busy_q,
en => sdr_en,
r_wn => mem_re_r,
be => sdr_be,
addr => sdr_addr,
din => sdr_udata_in,
dout => sdr_udata_out_q,
dout_re => sdr_read,
dout_vld => sdr_udata_vld_q,
-- 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
);
STARTUP_VIRTEX4_inst : STARTUP_VIRTEX4
port map (
EOS => started_up, -- End of Startup 1-bit output
CLK => open, -- Clock input for start-up sequence
GSR => '0', -- Global Set/Reset input (GSR cannot be used for the port name)
GTS => '0', -- Global 3-state input (GTS cannot be used for the port name)
USRCCLKO => '0', -- USRCCLKO 1-bit input
USRCCLKTS => '0', -- USRCCLKTS 1-bit input
USRDONEO => '0', -- USRDONEO 1-bit input
USRDONETS => '0' -- USRDONETS 1-bit input
);
------------------------------------------------------------------
END;