Files
vhdl/projects/cpu/src/systest/systest.vhd
T
jens ea60299d26 - added
git-svn-id: http://moon:8086/svn/vhdl/trunk@1414 cc03376c-175c-47c8-b038-4cd826a8556b
2021-03-21 10:47:01 +00:00

1141 lines
33 KiB
VHDL

-------------------------------------------------------------------------
-- 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.cpu_pkg.all;
use work.vga_types.all;
use work.fifo_ctrl_pkg.all;
use work.sdram_config.all;
use work.sdram_types.all;
ENTITY systest IS
GENERIC
(
sys_freq : integer := 100E6;
ddr_phaseshift : integer := 0;
ddr_frequency_hz : integer := 100E6;
tsvga : vga_timespec_t := ts_vga_1280_1024_72
);
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;
-- Keybpard and mouse
sys_keyb_clk : in std_logic;
sys_keyb_data : in std_logic;
sys_mouse_clk : in std_logic;
sys_mouse_data : in 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 systest;
ARCHITECTURE behavior OF systest IS
COMPONENT cpu_embedded
Port (
rst : in STD_LOGIC;
clk : in STD_LOGIC;
ce : in STD_LOGIC;
int_in : in STD_LOGIC;
int_ack : out STD_LOGIC;
xmem_we : out STD_LOGIC;
xmem_re : out STD_LOGIC;
xmem_din : in unsigned (DMEM_DATA_WIDTH-1 downto 0);
xmem_dout : out unsigned (DMEM_DATA_WIDTH-1 downto 0);
xmem_addr : out unsigned (DMEM_ADDR_WIDTH-1 downto 0);
io_sel : out STD_LOGIC
);
END COMPONENT;
COMPONENT xrom
Port (
clk : in STD_LOGIC;
ce : in STD_LOGIC;
addr : in dmem_addr_t;
dout : out dmem_data_t
);
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;
--
-- declaration of UART transmitter with integral 16 byte FIFO buffer
--
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;
--
-- declaration of UART Receiver with integral 16 byte FIFO buffer
--
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 int_in, int_ack, int_en, io_sel, int_force : std_logic;
signal cpu_baudrate : dmem_data_t;
signal cpu_din : dmem_data_t;
signal cpu_dout : dmem_data_t;
signal cpu_addr : dmem_addr_t;
signal cpu_we : std_logic;
signal cpu_re : std_logic;
signal cpu_wait : std_logic;
signal ctrl_reg : dmem_data_t;
signal led_reg : dmem_data_t;
signal cpu_lcd_out_reg, cpu_lcd_in_reg, reg_uart_tx: dmem_data_t;
signal cpu_lcd_we : std_logic;
signal cpu_sdr_buf_we, cpu_sdr_valid : std_logic;
signal cpu_color : color_t;
signal cpu_vga_enable : std_logic;
signal cpu_error_leds : unsigned(1 downto 0);
signal btn_ps2_reg : dmem_data_t;
--
-- Signals for connection of peripherals
--
signal uart_status_port : dmem_data_t;
--
-- Signals to form an timer generating an interrupt every microsecond
--
signal cpu_tim_reload : unsigned(23 downto 0);
signal timer_count : integer range 0 to 99999 :=0;
signal timer_pulse, timer_en : std_logic;
--
-- Signals for UART connections
--
signal baud_count : integer range 0 to 255 :=0;
signal en_16_x_baud : std_logic;
signal write_to_uart : std_logic;
signal tx_full : std_logic;
signal tx_half_full : std_logic;
signal read_from_uart : std_logic;
signal rx_data : std_logic_vector(7 downto 0);
signal rx_data_present : std_logic;
signal rx_full : std_logic;
signal rx_half_full : std_logic;
-- X-ROM
signal xrom_data : dmem_data_t;
signal sdr_data : dmem_data_t;
-- DDR SDRAM
constant BURST_LEN : natural := 8;
subtype sdr_buf_t is unsigned(SDR_DATA_WIDTH-1 downto 0);
signal sdr_buf_in, sdr_vga_data : sdr_buf_t := (others => '0');
signal sdr_tag_in : user_tag_t;
signal sdr_tag_wr : user_tag_t;
signal sdr_tag_rd : user_tag_t;
signal sdr_ucmd : user_cmd_t;
signal cpu_sd_cmd : user_cmd_t;
signal cpu_sd_cmd_we : std_logic;
signal sdr_ucmd_vld : std_logic;
signal cpu_sdr_addr : user_addr_t;
signal cpu_vga_read_offset : user_addr_t;
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_req_wr : std_logic;
signal sdr_udata_out_q : unsigned(SDR_DATA_WIDTH-1 downto 0);
signal sdr_udata_vld_q : std_logic;
signal sdr_dm : unsigned(SDR_DM_WIDTH-1 downto 0) := "00000000";
signal cpu_cat_fifo_din : unsigned(29 downto 0);
signal cpu_cat_fifo_dout : unsigned(29 downto 0);
signal cpu_cat_fifo_re : std_logic;
signal cpu_cat_fifo_we : std_logic;
signal cpu_cat_fifo_full : std_logic;
signal cpu_cat_fifo_empty : std_logic;
signal cpu_write_fifo_din : unsigned(SDR_DATA_WIDTH-1 downto 0);
signal cpu_write_fifo_dout : unsigned(SDR_DATA_WIDTH-1 downto 0);
signal cpu_write_fifo_re : std_logic;
signal cpu_write_fifo_we : std_logic;
signal cpu_write_fifo_full : std_logic;
signal cpu_write_fifo_empty : std_logic;
signal cpu_read_fifo_din : unsigned(SDR_DATA_WIDTH-1 downto 0);
signal cpu_read_fifo_dout : unsigned(SDR_DATA_WIDTH-1 downto 0);
signal cpu_read_fifo_re : std_logic;
signal cpu_read_fifo_we : std_logic;
signal cpu_read_fifo_full : std_logic;
signal cpu_read_fifo_empty : std_logic;
alias cpu_tag_fifo_in is cpu_cat_fifo_din(29 downto 26);
alias cpu_cmd_fifo_in is cpu_cat_fifo_din(25 downto 24);
alias cpu_addr_fifo_in is cpu_cat_fifo_din(23 downto 0);
alias cpu_tag_fifo_out is cpu_cat_fifo_dout(29 downto 26);
alias cpu_cmd_fifo_out is cpu_cat_fifo_dout(25 downto 24);
alias cpu_addr_fifo_out is cpu_cat_fifo_dout(23 downto 0);
-- 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";
-- VGA
signal vga_clk : std_logic;
signal vga_ready : std_logic;
signal vga_color_w : color_t;
signal vga_color : color_t;
signal vga_color_we : std_logic;
signal vga_fifo_full : std_logic;
signal vga_fifo_almost_full : std_logic;
signal vga_hsync : std_logic;
signal vga_vsync : std_logic;
signal vga_pos_x : natural range 0 to tsvga.ts_h.ncyc_scan-1;
signal vga_pos_y : natural range 0 to tsvga.ts_v.ncyc_scan-1;
signal vga_scan_x : std_logic;
signal vga_scan_y : std_logic;
signal vga_scan_rdy : std_logic;
signal vga_scan_rdy_h : std_logic;
signal vga_scan_rdy_v : std_logic;
signal vga_active : std_logic;
type vga_cmd_state_t is (vga_cmd_s_init, vga_cmd_s_idle, vga_cmd_s_access);
signal vga_cmd_s, vga_cmd_sn : vga_cmd_state_t;
type vga_data_state_t is (vga_data_s_init, vga_data_s_idle, vga_data_s_read1, vga_data_s_read2);
signal vga_data_s, vga_data_sn : vga_data_state_t;
type sd_ctrl_state_t is (s_sd_idle, s_sd_vga_access, s_sd_cpu_access);
signal st, stn : sd_ctrl_state_t;
-- Character generator
signal cg_rst : std_logic;
signal cg_en : std_logic;
signal cg_ready : std_logic;
signal cg_clr_screen : std_logic;
signal cg_clr_line : std_logic;
signal cg_ascii_data : dmem_data_t;
signal cg_ascii_data_we : std_logic;
signal cg_ascii_posy_we : std_logic;
signal cg_ascii_posx_we : std_logic;
signal cg_draw_en : std_logic;
signal cg_color : color_t;
-- DDR to VGA
signal vga_pixel_cnt : natural range 0 to tsvga.ts_h.ncyc_scan*tsvga.ts_v.ncyc_scan-1;
signal vga_sd_addr : user_addr_t;
signal vga_sd_valid : std_logic;
signal vga_pixel_cnt_en : std_logic;
signal vga_sd_cmd : user_cmd_t;
signal vga_sd_cmd_we : std_logic;
signal vga_cat_fifo_din : unsigned(29 downto 0);
signal vga_cat_fifo_dout : unsigned(29 downto 0);
signal vga_cat_fifo_re : std_logic;
signal vga_cat_fifo_we : std_logic;
signal vga_cat_fifo_full : std_logic;
signal vga_cat_fifo_empty : std_logic;
signal vga_read_fifo_din : unsigned(SDR_DATA_WIDTH-1 downto 0);
signal vga_read_fifo_dout : unsigned(SDR_DATA_WIDTH-1 downto 0);
signal vga_read_fifo_re : std_logic;
signal vga_read_fifo_we : std_logic;
signal vga_read_fifo_full : std_logic;
signal vga_read_fifo_empty : std_logic;
signal vga_read_fifo_almost_full : std_logic;
signal vga_read_fifo_almost_empty : std_logic;
alias vga_tag_fifo_in is vga_cat_fifo_din(29 downto 26);
alias vga_cmd_fifo_in is vga_cat_fifo_din(25 downto 24);
alias vga_addr_fifo_in is vga_cat_fifo_din(23 downto 0);
alias vga_tag_fifo_out is vga_cat_fifo_dout(29 downto 26);
alias vga_cmd_fifo_out is vga_cat_fifo_dout(25 downto 24);
alias vga_addr_fifo_out is vga_cat_fifo_dout(23 downto 0);
BEGIN
int_in <= sys_btn(4) or sys_dip(7) or timer_pulse or int_force or rx_data_present;
rst_in <= not (started_up and sys_rst_n_in);
uart_status_port <= "000" & rx_data_present & rx_full & rx_half_full & tx_full & tx_half_full ;
-- VGA mapping
sys_vga_clk <= vga_clk;
sys_vga_red <= vga_color(r);
sys_vga_green <= vga_color(g);
sys_vga_blue <= vga_color(b);
vga_scan_rdy <= vga_scan_rdy_h and vga_scan_rdy_v;
cg_en <= vga_scan_x and vga_scan_y;
cg_rst <= rst;
------------------------------------------------------------------
cpu_sdr_buffer:
process(clk)
variable index, lo, hi : integer;
begin
if rising_edge(clk) then
index := to_integer(cpu_addr(2 downto 0));
hi := dmem_data_t'length*(index+1)-1;
lo := dmem_data_t'length*(index);
if cpu_sdr_buf_we = '1' then
sdr_buf_in(hi downto lo) <= cpu_dout;
end if;
sdr_data <= cpu_read_fifo_dout(hi downto lo);
end if;
end process;
------------------------------------------------------------------
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 <= int_in & led_reg;
sys_error <= cpu_error_leds;
end if;
end process;
------------------------------------------------------------------
btn_ps2_register:
process(clk)
begin
if rising_edge(clk) then
btn_ps2_reg <= sys_mouse_data & sys_mouse_clk & sys_keyb_data & sys_keyb_clk & unsigned(sys_btn(3 downto 0));
end if;
end process;
------------------------------------------------------------------
timer:
process(rst, clk)
begin
if rst = '1' then
timer_count <= to_integer(cpu_tim_reload);
timer_pulse <= '0';
elsif rising_edge(clk) then
timer_pulse <= '0';
if timer_count /= 0 then
if timer_en = '1' then
timer_count <= timer_count - 1;
end if;
else
timer_pulse <= '1';
timer_count <= to_integer(cpu_tim_reload);
end if;
end if;
end process;
------------------------------------------------------------------
reg_mux:
process(clk)
variable data : dmem_data_t;
variable addr : dmem_addr_t;
variable is_io : boolean;
variable cpu_read : std_logic;
begin
read_from_uart <= '0';
if rising_edge(clk) then
addr := cpu_addr;
is_io := (io_sel = '1');
cpu_read := cpu_re;
end if;
if is_io then
case addr is
when X"00" => -- 00
data := btn_ps2_reg;
when X"01" => -- 01
data := led_reg;
when X"02" => -- 02
data := unsigned(rx_data);
read_from_uart <= cpu_read;
when X"03" => -- 03
data := cpu_lcd_in_reg;
when X"04" => -- 04
data := int_force & '0' & cpu_error_leds & '0' & cpu_vga_enable & timer_en & int_en;
when X"05" => -- 05
data := unsigned(sys_dip);
when X"06" => -- 06
data := uart_status_port;
when X"07" => -- 07
data := '0' & '0' & cpu_read_fifo_empty & cpu_read_fifo_full & cpu_write_fifo_empty & cpu_write_fifo_full & cpu_cat_fifo_empty & cpu_cat_fifo_full;
when X"08" => -- 08
data := cpu_sdr_addr(7 downto 0);
when X"09" => -- 09
data := cpu_sdr_addr(15 downto 8);
when X"0A" => -- 10
data := cpu_sdr_addr(23 downto 16);
when X"0E" =>
data := (not rst) & "00000" & cg_ready & vga_ready;
when X"13" => -- 10
data := cpu_baudrate;
when others =>
data := X"00";
end case;
else
if cpu_addr(7) = '1' then
data := sdr_data;
else
data := xrom_data;
end if;
end if;
cpu_din <= data;
end process;
------------------------------------------------------------------
ctrl_reg_write:
process(rst, clk)
variable addr : unsigned(dmem_addr_t'length-1 downto 0);
begin
if (rst = '1') then
cpu_color <= (X"80", X"80", X"80");
cpu_error_leds <= (others => '0');
int_force <= '0';
int_en <= '0';
timer_en <= '0';
led_reg <= (others => '0');
cpu_lcd_out_reg <= (others => '0');
reg_uart_tx <= (others => '0');
cpu_sdr_addr <= (others => '0');
cg_ascii_data <= (others => '0');
cg_ascii_posy_we <= '0';
cg_ascii_posx_we <= '0';
cg_ascii_data_we <= '0';
cg_clr_line <= '0';
cg_clr_screen <= '0';
cpu_read_fifo_re <= '0';
cpu_write_fifo_we <= '0';
cpu_sd_cmd_we <= '0';
cpu_sd_cmd <= UCMD_NOP;
cpu_vga_enable <= '0';
cpu_baudrate <= to_unsigned(53, dmem_data_t'length);
cpu_vga_read_offset <= (others => '0');
cpu_tim_reload <= to_unsigned(99999, cpu_tim_reload'length);
elsif rising_edge(clk) then
int_force <= '0';
write_to_uart <= '0';
cpu_lcd_we <= '0';
cpu_sdr_buf_we <= '0';
cg_ascii_posy_we <= '0';
cg_ascii_posx_we <= '0';
cg_ascii_data_we <= '0';
cg_clr_line <= '0';
cg_clr_screen <= '0';
cpu_read_fifo_re <= '0';
cpu_write_fifo_we <= '0';
cpu_sd_cmd_we <= '0';
addr := cpu_addr;
if cpu_we = '1' then
if io_sel = '1' then
case addr is
when X"01" => -- 01
led_reg <= cpu_dout;
when X"02" => -- 02
reg_uart_tx <= cpu_dout;
write_to_uart <= '1';
when X"03" => -- 03
cpu_lcd_we <= '1';
cpu_lcd_out_reg <= cpu_dout;
when X"04" => -- 04
int_force <= cpu_dout(7);
cpu_error_leds <= cpu_dout(5 downto 4);
cpu_vga_enable <= cpu_dout(2);
timer_en <= cpu_dout(1);
int_en <= cpu_dout(0);
when X"07" => -- 07
cpu_read_fifo_re <= cpu_dout(5);
cpu_write_fifo_we <= cpu_dout(4);
cpu_sd_cmd_we <= cpu_dout(2);
cpu_sd_cmd <= cpu_dout(1 downto 0);
when X"08" => -- 08
cpu_sdr_addr(7 downto 0) <= cpu_dout;
when X"09" => -- 09
cpu_sdr_addr(15 downto 8) <= cpu_dout;
when X"0A" => -- 10
cpu_sdr_addr(23 downto 16) <= cpu_dout;
when X"0B" => -- 08
cg_ascii_data <= cpu_dout;
cg_ascii_posx_we <= '1';
when X"0C" => -- 09
cg_ascii_data <= cpu_dout;
cg_ascii_posy_we <= '1';
when X"0D" => -- 0A
cg_ascii_data <= cpu_dout;
cg_ascii_data_we <= '1';
when X"0E" => -- 0B
cg_clr_screen <= cpu_dout(0);
cg_clr_line <= cpu_dout(1);
when X"10" => -- 04
cpu_color(r) <= cpu_dout;
when X"11" => -- 04
cpu_color(g) <= cpu_dout;
when X"12" => -- 04
cpu_color(b) <= cpu_dout;
when X"13" => -- 04
cpu_baudrate <= cpu_dout;
when X"14" =>
cpu_vga_read_offset(7 downto 0) <= cpu_dout;
when X"15" =>
cpu_vga_read_offset(15 downto 8) <= cpu_dout;
when X"16" =>
cpu_vga_read_offset(23 downto 16) <= cpu_dout;
when X"17" => -- 04
cpu_tim_reload(7 downto 0) <= cpu_dout;
when X"18" => -- 04
cpu_tim_reload(15 downto 8) <= cpu_dout;
when X"19" => -- 04
cpu_tim_reload(23 downto 16) <= cpu_dout;
when others => null;
end case;
else
case addr is
when X"80"|X"81"|X"82"|X"83"|X"84"|X"85"|X"86"|X"87" =>
cpu_sdr_buf_we <= '1';
when others => null;
end case;
end if;
end if;
end if;
end process;
------------------------------------------------------------------
sdram_write_control:
process(st, sdr_busy_q, vga_cat_fifo_empty, cpu_cat_fifo_empty, vga_cmd_fifo_out, vga_addr_fifo_out, vga_tag_fifo_out, cpu_cmd_fifo_out, cpu_addr_fifo_out, cpu_tag_fifo_out)
begin
vga_cat_fifo_re <= '0';
cpu_cat_fifo_re <= '0';
sdr_ucmd_vld <= '0';
sdr_ucmd <= vga_cmd_fifo_out;
sdr_addr <= vga_addr_fifo_out;
sdr_tag_in <= vga_tag_fifo_out;
stn <= st;
case st is
when s_sd_idle =>
if vga_cat_fifo_empty = '0' then
stn <= s_sd_vga_access;
elsif cpu_cat_fifo_empty = '0' then
stn <= s_sd_cpu_access;
end if;
when s_sd_vga_access =>
sdr_ucmd <= vga_cmd_fifo_out;
sdr_addr <= vga_addr_fifo_out;
sdr_tag_in <= vga_tag_fifo_out;
if vga_cat_fifo_empty = '0' then
if sdr_busy_q = '0' then
sdr_ucmd_vld <= '1';
vga_cat_fifo_re <= '1';
end if;
else
stn <= s_sd_idle;
end if;
when s_sd_cpu_access =>
sdr_ucmd <= cpu_cmd_fifo_out;
sdr_addr <= cpu_addr_fifo_out;
sdr_tag_in <= cpu_tag_fifo_out;
if cpu_cat_fifo_empty = '0' then
if sdr_busy_q = '0' then
sdr_ucmd_vld <= '1';
cpu_cat_fifo_re <= '1';
end if;
else
stn <= s_sd_idle;
end if;
when others =>
stn <= s_sd_idle;
end case;
end process;
process(rst, clk)
begin
if rst = '1' then
st <= s_sd_idle;
elsif rising_edge(clk) then
st <= stn;
end if;
end process;
------------------------------------------------------------------
vga_to_sd_cmd: process (vga_cmd_s, cpu_vga_enable, vga_scan_rdy, vga_ready, vga_cat_fifo_full, vga_read_fifo_empty, vga_read_fifo_almost_empty)
begin
vga_sd_cmd <= UCMD_NOP;
vga_sd_cmd_we <= '0';
vga_pixel_cnt_en <= '0';
vga_cmd_sn <= vga_cmd_s;
case vga_cmd_s is
when vga_cmd_s_init =>
if vga_ready = '1' and vga_scan_rdy = '1' then
vga_cmd_sn <= vga_cmd_s_idle;
end if;
when vga_cmd_s_idle =>
if cpu_vga_enable = '1' and vga_read_fifo_almost_empty = '1' then
vga_cmd_sn <= vga_cmd_s_access;
end if;
when vga_cmd_s_access =>
if vga_cat_fifo_full = '0' then
vga_pixel_cnt_en <= '1';
vga_sd_cmd <= UCMD_READ;
vga_sd_cmd_we <= '1';
else
vga_cmd_sn <= vga_cmd_s_idle;
end if;
when others =>
vga_cmd_sn <= vga_cmd_s_idle;
end case;
end process;
vga_cmd_nxt: process (rst, clk)
begin
if (rst = '1') then
vga_cmd_s <= vga_cmd_s_init;
elsif rising_edge(clk) then
vga_cmd_s <= vga_cmd_sn;
end if;
end process;
------------------------------------------------------------------
pixel_counter: process (rst, clk)
begin
if rst = '1' then
vga_pixel_cnt <= 0;
vga_sd_addr <= (others => '0');
elsif rising_edge(clk) then
if vga_pixel_cnt_en = '1' then
if vga_pixel_cnt < tsvga.ts_h.ncyc_scan*tsvga.ts_v.ncyc_scan-BURST_LEN then
vga_pixel_cnt <= vga_pixel_cnt + BURST_LEN;
vga_sd_addr <= vga_sd_addr + BURST_LEN;
else
vga_pixel_cnt <= 0;
vga_sd_addr <= cpu_vga_read_offset;
end if;
end if;
end if;
end process;
------------------------------------------------------------------
vga_to_sd_data: process (vga_data_s, vga_fifo_full, vga_read_fifo_empty, vga_read_fifo_dout, vga_scan_rdy, vga_fifo_almost_full)
begin
vga_read_fifo_re <= '0';
vga_color_w <= (vga_read_fifo_dout(23 downto 16), vga_read_fifo_dout(15 downto 8), vga_read_fifo_dout(7 downto 0));
vga_color_we <= '0';
vga_data_sn <= vga_data_s;
case vga_data_s is
when vga_data_s_init =>
if vga_read_fifo_empty = '0' and vga_scan_rdy = '1' then
vga_data_sn <= vga_data_s_idle;
end if;
when vga_data_s_idle =>
if vga_fifo_almost_full = '0' then
vga_data_sn <= vga_data_s_read1;
end if;
when vga_data_s_read1 =>
vga_color_w <= (vga_read_fifo_dout(23 downto 16), vga_read_fifo_dout(15 downto 8), vga_read_fifo_dout(7 downto 0));
if vga_read_fifo_empty = '0' then
if vga_fifo_full = '0' then
vga_color_we <= '1';
vga_data_sn <= vga_data_s_read2;
else
vga_data_sn <= vga_data_s_idle;
end if;
end if;
when vga_data_s_read2 =>
vga_color_w <= (vga_read_fifo_dout(47 downto 40), vga_read_fifo_dout(39 downto 32), vga_read_fifo_dout(31 downto 24));
if vga_fifo_full = '0' then
vga_color_we <= '1';
vga_read_fifo_re <= '1';
vga_data_sn <= vga_data_s_read1;
end if;
when others =>
vga_data_sn <= vga_data_s_idle;
end case;
end process;
vga_data_nxt: process (rst, clk)
begin
if (rst = '1') then
vga_data_s <= vga_data_s_init;
elsif rising_edge(clk) then
vga_data_s <= vga_data_sn;
end if;
end process;
------------------------------------------------------------------
inst_cpu_embedded: cpu_embedded
PORT MAP(
rst => rst,
clk => clk,
ce => '1',
int_in => int_in,
int_ack => int_ack,
xmem_we => cpu_we,
xmem_re => cpu_re,
xmem_din => cpu_din,
xmem_dout => cpu_dout,
xmem_addr => cpu_addr,
io_sel => io_sel
);
inst_xrom: xrom
PORT MAP(
clk => clk,
ce => '1',
addr => cpu_addr,
dout => xrom_data
);
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
);
transmit: uart_tx
port map ( data_in => std_logic_vector(reg_uart_tx),
write_buffer => write_to_uart,
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 );
receive: uart_rx
port map ( serial_in => sys_rx,
data_out => rx_data,
read_buffer => read_from_uart,
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 );
-- Instantiate synchronous FIFO
inst_cpu_cat_fifo: entity work.fifo_sync
GENERIC MAP
(
addr_width => 6,
data_width => 4+2+24,
almost_full_thresh => 60,
almost_empty_thresh => 4
)
PORT MAP
(
rst => rst,
clk => clk,
we => cpu_cat_fifo_we,
re => cpu_cat_fifo_re,
fifo_full => cpu_cat_fifo_full,
fifo_empty => cpu_cat_fifo_empty,
fifo_afull => open,
fifo_aempty => open,
data_w => cpu_cat_fifo_din,
data_r => cpu_cat_fifo_dout
);
-- Instantiate synchronous FIFO
inst_cpu_write_fifo: entity work.fifo_sync
GENERIC MAP
(
addr_width => 8,
data_width => 2*DDR_DATA_WIDTH,
almost_full_thresh => 252,
almost_empty_thresh => 4
)
PORT MAP
(
rst => rst,
clk => clk,
we => cpu_write_fifo_we,
re => cpu_write_fifo_re,
fifo_full => cpu_write_fifo_full,
fifo_empty => cpu_write_fifo_empty,
fifo_afull => open,
fifo_aempty => open,
data_w => cpu_write_fifo_din,
data_r => cpu_write_fifo_dout
);
-- Instantiate synchronous FIFO
inst_cpu_read_fifo: entity work.fifo_sync
GENERIC MAP
(
addr_width => 8,
data_width => 2*DDR_DATA_WIDTH,
almost_full_thresh => 252,
almost_empty_thresh => 4
)
PORT MAP
(
rst => rst,
clk => clk,
we => cpu_read_fifo_we,
re => cpu_read_fifo_re,
fifo_full => cpu_read_fifo_full,
fifo_empty => cpu_read_fifo_empty,
fifo_afull => open,
fifo_aempty => open,
data_w => cpu_read_fifo_din,
data_r => cpu_read_fifo_dout
);
-- Instantiate synchronous FIFO
inst_vga_cat_fifo: entity work.fifo_sync
GENERIC MAP
(
addr_width => 6,
data_width => 4+2+24,
almost_full_thresh => 60,
almost_empty_thresh => 4
)
PORT MAP
(
rst => rst,
clk => clk,
we => vga_cat_fifo_we,
re => vga_cat_fifo_re,
fifo_full => vga_cat_fifo_full,
fifo_empty => vga_cat_fifo_empty,
fifo_afull => open,
fifo_aempty => open,
data_w => vga_cat_fifo_din,
data_r => vga_cat_fifo_dout
);
-- Instantiate synchronous FIFO
inst_vga_read_fifo: entity work.fifo_sync
GENERIC MAP
(
addr_width => 10,
data_width => 2*DDR_DATA_WIDTH,
almost_full_thresh => 960,
almost_empty_thresh => 128
)
PORT MAP
(
rst => rst,
clk => clk,
we => vga_read_fifo_we,
re => vga_read_fifo_re,
fifo_full => vga_read_fifo_full,
fifo_empty => vga_read_fifo_empty,
fifo_afull => vga_read_fifo_almost_full,
fifo_aempty => vga_read_fifo_almost_empty,
data_w => vga_read_fifo_din,
data_r => vga_read_fifo_dout
);
vga_tag_fifo_in <= "0010";
vga_addr_fifo_in <= vga_sd_addr;
vga_cmd_fifo_in <= vga_sd_cmd;
vga_cat_fifo_we <= vga_sd_cmd_we;
cpu_tag_fifo_in <= "0001";
cpu_addr_fifo_in <= cpu_sdr_addr;
cpu_cmd_fifo_in <= cpu_sd_cmd;
cpu_cat_fifo_we <= cpu_sd_cmd_we;
sdr_udata_in <= cpu_write_fifo_dout;
cpu_read_fifo_we <= sdr_udata_vld_q when sdr_tag_rd = "0001" else '0';
vga_read_fifo_we <= sdr_udata_vld_q when sdr_tag_rd = "0010" else '0';
cpu_read_fifo_din <= sdr_udata_out_q;
vga_read_fifo_din <= sdr_udata_out_q;
cpu_write_fifo_din <= sdr_buf_in;
cpu_write_fifo_re <= sdr_udata_req_wr and (not cpu_write_fifo_empty);
cpu_wait <= '0';
-- DDR SDRAM Controller Core
inst_sdram_ctrl : entity work.sdram_ctrl_top
Generic map
(
BL => BURST_LEN,
read_phaseshift => ddr_phaseshift,
f_sysclk => ddr_frequency_hz
)
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,
-- User interface
u_data_vld => sdr_udata_vld_q,
u_data_req_w => sdr_udata_req_wr,
u_data_req_r => open,
u_tag_in => sdr_tag_in,
u_tag_rd => sdr_tag_rd,
u_tag_wr => sdr_tag_wr,
u_busy => sdr_busy_q,
u_addr => sdr_addr,
u_cmd => sdr_ucmd,
u_cmd_we => sdr_ucmd_vld,
u_data_wr => sdr_udata_in,
u_data_rd => sdr_udata_out_q,
u_dm => sdr_dm,
-- 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_vga_backend: entity work.vga_backend
GENERIC MAP
(
sys_freq => sys_freq,
fifo_depth => 2048,
fifo_almost_full_thresh => 1920,
fifo_almost_empty_thresh => 128,
tsvga => tsvga
)
PORT MAP
(
sys_rst => rst,
sys_clk => clk,
vga_ready => vga_ready,
color_in => vga_color_w,
color_fifo_we => vga_color_we,
color_fifo_full => vga_fifo_full,
color_fifo_afull => vga_fifo_almost_full,
direct_color_in => cg_color,
direct_draw_en => cg_draw_en,
stat_hsync => vga_hsync,
stat_vsync => vga_vsync,
stat_hready => vga_scan_rdy_h,
stat_vready => vga_scan_rdy_v,
stat_hscan => vga_scan_x,
stat_vscan => vga_scan_y,
stat_hpos => vga_pos_x,
stat_vpos => vga_pos_y,
vga_clk_out => vga_clk,
vga_color_out => vga_color,
vga_blank_n => sys_vga_blank_n,
vga_sync_n => sys_vga_sync_n,
vga_hsync => sys_vga_hsync,
vga_vsync => sys_vga_vsync
);
inst_char_gen : entity work.char_gen
GENERIC MAP
(
tsvga => tsvga,
CHARACTER_SCALE => 1,
CHAR_ROM_SIZE_X => 8, -- Pixels
CHAR_ROM_SIZE_Y => 16, -- Pixels
CHAR_ROM_DEPTH => 256, -- Chars
MAX_CHAR_PER_LINE => 80, -- Chars
MAX_LINE_PER_FRAME => 32, -- Chars
CHAR_SPACING_X => 0, -- Pixels
CHAR_SPACING_Y => 0, -- Pixels
SCREEN_OFFSET_X => 16, -- Pixels
SCREEN_OFFSET_Y => 16 -- Pixels
)
PORT MAP
(
rst => rst,
sys_clk => clk,
vga_clk => vga_clk,
ce => cg_en,
frame_pulse => vga_scan_rdy,
clr_screen => cg_clr_screen,
clr_line => cg_clr_line,
ascii_data => cg_ascii_data,
ascii_data_we => cg_ascii_data_we,
ascii_posy_we => cg_ascii_posy_we,
ascii_posx_we => cg_ascii_posx_we,
ready => cg_ready,
pos_x => vga_pos_x,
pos_y => vga_pos_y,
char_draw_en => cg_draw_en
);
------------------------------------------------------------------
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
);
------------------------------------------------------------------
--
-- Set baud rate to 38400 for the UART communications
-- Requires en_16_x_baud to be 614400Hz which is a single cycle pulse every 163 cycles at 100MHz
--
-- NOTE : If the highest value for baud_count exceeds 127 you will need to adjust
-- the range of integers in the signal declaration for baud_count.
--
------------------------------------------------------------------
proc_cg_color_sample:
process (vga_clk)
variable p0, p1 : color_t;
begin
if rising_edge(vga_clk) then
cg_color <= p1;
p1 := p0;
p0 := cpu_color;
end if;
end process;
baud_timer: process(clk)
begin
if clk'event and clk='1' then
if baud_count=cpu_baudrate then
baud_count <= 0;
en_16_x_baud <= '1';
else
baud_count <= baud_count + 1;
en_16_x_baud <= '0';
end if;
end if;
end process baud_timer;
END;