Files
vhdl/projects/cpu/src/systest/systest.orig.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

409 lines
11 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;
ENTITY systest IS
PORT
(
sys_rst_n_in : in std_logic;
sys_clk_in : in std_logic;
sys_btn : in std_logic_vector(4 downto 0);
sys_dip : in std_logic_vector(7 downto 0);
sys_led : out std_logic_vector(8 downto 0);
sys_rx : in std_logic;
sys_tx : out std_logic;
sys_lcd_d : inout std_logic_vector(3 downto 0);
sys_lcd_e : out std_logic;
sys_lcd_rs : out std_logic;
sys_lcd_rw : out std_logic
);
END systest;
ARCHITECTURE behavior OF systest IS
COMPONENT embedded_cpu
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_WIDTH-1 downto 0);
xmem_dout : out unsigned (DMEM_WIDTH-1 downto 0);
xmem_addr : out unsigned (DMEM_WIDTH-1 downto 0)
);
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 clk, clk0 : std_logic;
signal ce : std_logic;
signal int_req, int_in, int_ack, int_en : std_logic;
signal cpu_din : data_t;
signal cpu_dout : data_t;
signal cpu_addr : unsigned (DMEM_WIDTH-1 downto 0);
signal cpu_we, reg_sel : std_logic;
signal cpu_re : std_logic;
signal led_reg_we, lcd_reg_we, ctrl_reg_we : std_logic;
signal rom_dout, reg_dout, ctrl_reg : data_t;
signal led_reg : data_t;
signal lcd_reg_out, lcd_reg_in: data_t;
--
-- Signals for connection of peripherals
--
signal uart_status_port : data_t;
--
-- Signals to form an timer generating an interrupt every microsecond
--
constant timer_reload : integer := 99999;
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;
signal rom_addr : unsigned(5 downto 0);
signal reg_addr : unsigned(5 downto 0);
constant rom_data : string(1 to 64) :=
(
"J-CPU V1.0 " &
' ' & ' ' & ' ' & ' ' & ' ' & ' ' & ' ' & ' ' & ' ' & ' ' & ' ' & ' ' &
' ' & ' ' & ' ' & ' ' & ' ' & ' ' & ' ' & ' ' & ' ' & ' ' & ' ' & ' ' &
' ' & ' ' & ' ' & ' ' & ' ' & ' ' & ' ' & ' ' & ' ' & ' ' & ' ' & ' ' &
' ' & ' ' & ' ' & ' ' & ' ' & ' ' & ' ' & ' ' & ' ' & ' ' & ' ' & ' '
);
constant lcd_e : integer := 7;
constant lcd_rs : integer := 6;
constant lcd_rw : integer := 5;
BEGIN
int_in <= sys_btn(4) or sys_dip(7) or timer_pulse or ctrl_reg(7) or rx_data_present;
clk0 <= sys_clk_in;
ce <= not rst;
int_en <= ctrl_reg(0);
timer_en <= ctrl_reg(1);
sys_led(8) <= int_in;
sys_led (7 downto 0) <= std_logic_vector(led_reg(7 downto 0));
uart_status_port <= "000" & rx_data_present & rx_full & rx_half_full & tx_full & tx_half_full ;
sys_lcd_d <= std_logic_vector(lcd_reg_out(3 downto 0)) when lcd_reg_out(lcd_rw) = '0' else (others => 'Z');
sys_lcd_e <= lcd_reg_out(lcd_e);
sys_lcd_rw <= lcd_reg_out(lcd_rw);
sys_lcd_rs <= lcd_reg_out(lcd_rs);
rom_addr <= cpu_addr(5 downto 0);
reg_addr <= cpu_addr(5 downto 0);
BUFG_inst : BUFG
port map (
O => clk, -- Clock buffer output
I => clk0 -- Clock buffer input
);
clock_halbe:
process(sys_rst_n_in, sys_clk_in)
variable reset_latency : integer range 0 to 999 := 999;
begin
if sys_rst_n_in = '0' then
-- clk0 <= '0';
rst <= '1';
reset_latency := 999;
elsif rising_edge(sys_clk_in) then
rst <= '1';
-- clk0 <= not clk0;
if reset_latency /= 0 then
reset_latency := reset_latency - 1;
else
rst <= '0';
end if;
end if;
end process;
timer:
process(rst, clk, timer_count, timer_en)
begin
if rst = '1' then
timer_count <= timer_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 <= timer_reload;
end if;
end if;
end process;
reg_mux:
process(clk, reg_addr, reg_sel, cpu_we, cpu_re, sys_btn, sys_dip, lcd_reg_in, led_reg, uart_status_port)
variable data : data_t;
begin
led_reg_we <= '0';
lcd_reg_we <= '0';
ctrl_reg_we <= '0';
write_to_uart <= '0';
read_from_uart <= '0';
data := (others => '-');
if reg_sel = '1' then
case reg_addr(2 downto 0) is
when "000" => -- C0
data := "0000" & unsigned(sys_btn(3 downto 0));
when "001" => -- C1
data := led_reg;
led_reg_we <= cpu_we;
when "010" => -- C2
data := unsigned(rx_data);
write_to_uart <= cpu_we;
read_from_uart <= cpu_re;
when "011" => -- C3
data := lcd_reg_in;
lcd_reg_we <= cpu_we;
when "100" => -- C4
data := ctrl_reg;
ctrl_reg_we <= cpu_we;
when "101" => -- C5
data := unsigned(sys_dip);
when "110" => -- C6
data := uart_status_port;
when others => null;
end case;
end if;
if rising_edge(clk) then
reg_dout <= data;
end if;
end process;
din_mux:
process(clk, cpu_addr, cpu_we, rom_dout, reg_dout)
variable data : data_t;
begin
reg_sel <= '0';
case cpu_addr(7 downto 6) is
when "00" | "01" => -- 00 .. 7F
data := X"AA";
when "10" => -- 80 .. BF
data := rom_dout;
when "11" => -- C0 .. FF
data := reg_dout;
reg_sel <= '1';
when others =>
data := (others => '-');
end case;
cpu_din <= data;
end process;
ctrl_reg_write:
process(rst, clk, ctrl_reg_we, cpu_dout)
begin
if (rst = '1') then
ctrl_reg <= (others => '0');
elsif rising_edge(clk) then
if ctrl_reg_we = '1' then
ctrl_reg <= cpu_dout;
end if;
end if;
end process;
led_reg_write:
process(rst, clk, led_reg_we, cpu_dout)
begin
if (rst = '1') then
led_reg <= (others => '0');
elsif rising_edge(clk) then
if led_reg_we = '1' then
led_reg <= cpu_dout;
end if;
end if;
end process;
proc_lcd_reg_write:
process(rst, clk, lcd_reg_we, cpu_dout)
begin
if (rst = '1') then
lcd_reg_out <= (others => '0');
elsif rising_edge(clk) then
if lcd_reg_we = '1' then
lcd_reg_out <= cpu_dout;
end if;
end if;
end process;
proc_lcd_reg_sample:
process(rst, clk, sys_lcd_d, lcd_reg_out)
begin
if (rst = '1') then
lcd_reg_in <= (others => '0');
elsif rising_edge(clk) then
if lcd_reg_out(lcd_rw) = '1' then
lcd_reg_in <= unsigned("0000" & sys_lcd_d);
end if;
end if;
end process;
int_register:
process(rst, clk, int_in, int_ack)
begin
if (rst = '1') then
int_req <= '0';
elsif rising_edge(clk) then
if int_ack = '1' then
int_req <= '0';
elsif int_en = '1' and int_in = '1' then
int_req <= '1';
end if;
end if;
end process;
the_embedded_cpu: embedded_cpu
PORT MAP(
rst => rst,
clk => clk,
ce => ce,
int_in => int_req,
int_ack => int_ack,
xmem_we => cpu_we,
xmem_re => cpu_re,
xmem_din => cpu_din,
xmem_dout => cpu_dout,
xmem_addr => cpu_addr
);
transmit: uart_tx
port map ( data_in => std_logic_vector(cpu_dout),
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 );
--
-- 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.
--
baud_timer: process(clk)
begin
if clk'event and clk='1' then
if baud_count=162 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;
ROM_RD:
process(rst, clk, rom_addr)
begin
if rising_edge(clk) then
rom_dout <= to_unsigned(character'pos(rom_data(to_integer(rom_addr)+1)), data_t'length);
end if;
end process;
END;