Initial commit
This commit is contained in:
259
uart.vhd
Executable file
259
uart.vhd
Executable file
@@ -0,0 +1,259 @@
|
||||
----------------------------------------------------------------------------------
|
||||
-- Company:
|
||||
-- Engineer:
|
||||
--
|
||||
-- Create Date: 15:52:22 12/30/2008
|
||||
-- Design Name:
|
||||
-- Module Name: toplevel - Behavioral
|
||||
-- Project Name:
|
||||
-- Target Devices:
|
||||
-- Tool versions:
|
||||
-- Description:
|
||||
--
|
||||
-- Dependencies:
|
||||
--
|
||||
-- Revision:
|
||||
-- Revision 0.01 - File Created
|
||||
-- Additional Comments:
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
---- Uncomment the following library declaration if instantiating
|
||||
---- any Xilinx primitives in this code.
|
||||
library UNISIM;
|
||||
use UNISIM.VComponents.all;
|
||||
|
||||
entity uart is
|
||||
|
||||
port (
|
||||
CLK_16M : in std_logic;
|
||||
DATA_I : in std_logic_vector(7 downto 0);
|
||||
ADDR_I : in std_logic_vector(1 downto 0);
|
||||
IORQ_n, RD_n, WR_n : in std_logic;
|
||||
DATA_O : out std_logic_vector(7 downto 0);
|
||||
-- SPI for Atmel Dataflash
|
||||
SPI_MISO : in std_logic;
|
||||
SPI_MOSI : out std_logic;
|
||||
SPI_SCK : out std_logic;
|
||||
SPI_SS_B : out std_logic := '1';
|
||||
DATAFLASH_WP : out std_logic;
|
||||
DATAFLASH_RST : out std_logic;
|
||||
-- LCD interface
|
||||
LCD_DB : inout std_logic_vector(7 downto 0);
|
||||
LCD_E, LCD_RS, LCD_RW : out std_logic;
|
||||
-- Buttons
|
||||
BTN_NORTH : in STD_LOGIC;
|
||||
BTN_SOUTH : in STD_LOGIC;
|
||||
BTN_EAST : in STD_LOGIC;
|
||||
BTN_WEST : in STD_LOGIC;
|
||||
ROT_CENTER : in STD_LOGIC);
|
||||
|
||||
end uart;
|
||||
|
||||
architecture Behavioral of uart is
|
||||
|
||||
component kcpsm3
|
||||
port (
|
||||
address : out std_logic_vector(9 downto 0);
|
||||
instruction : in std_logic_vector(17 downto 0);
|
||||
port_id : out std_logic_vector(7 downto 0);
|
||||
write_strobe : out std_logic;
|
||||
out_port : out std_logic_vector(7 downto 0);
|
||||
read_strobe : out std_logic;
|
||||
in_port : in std_logic_vector(7 downto 0);
|
||||
interrupt : in std_logic;
|
||||
interrupt_ack : out std_logic;
|
||||
reset : in std_logic;
|
||||
clk : in std_logic);
|
||||
end component;
|
||||
|
||||
component uartprog
|
||||
port (
|
||||
address : in std_logic_vector(9 downto 0);
|
||||
instruction : out std_logic_vector(17 downto 0);
|
||||
clk : in std_logic);
|
||||
end component;
|
||||
|
||||
component fifo16x8
|
||||
port (
|
||||
DATAIN : in STD_LOGIC_VECTOR (7 downto 0);
|
||||
WRITESTB : in STD_LOGIC;
|
||||
DATAOUT : out STD_LOGIC_VECTOR (7 downto 0);
|
||||
READSTB : in STD_LOGIC;
|
||||
CLK : in STD_LOGIC;
|
||||
FULL : out STD_LOGIC;
|
||||
EMPTY : out STD_LOGIC);
|
||||
end component;
|
||||
|
||||
component spi
|
||||
port (
|
||||
MISO : in std_logic;
|
||||
MOSI, SCK : out std_logic;
|
||||
DATA_I : in std_logic_vector(7 downto 0);
|
||||
DATA_O : out std_logic_vector(7 downto 0);
|
||||
START : in std_logic;
|
||||
BUSY : out std_logic;
|
||||
CLK : in std_logic);
|
||||
end component;
|
||||
|
||||
signal receive_r, transmit_r : std_logic_vector(7 downto 0);
|
||||
signal drt_r, drr_r : std_logic := '0';
|
||||
|
||||
signal kcpsm3_addr : std_logic_vector(9 downto 0);
|
||||
signal kcpsm3_instr : std_logic_vector(17 downto 0);
|
||||
signal kcpsm3_portid, kcpsm3_outport, kcpsm3_inport : std_logic_vector(7 downto 0);
|
||||
signal kcpsm3_wrstb, kcpsm3_rdstb : std_logic;
|
||||
|
||||
attribute iob : string;
|
||||
signal lcdctrl_r : std_logic_vector(2 downto 0) := "000";
|
||||
signal lcdout_r : std_logic_vector(7 downto 0) := X"00";
|
||||
attribute iob of lcdout_r : signal is "true";
|
||||
attribute iob of lcdctrl_r : signal is "true";
|
||||
|
||||
signal spi_datao : std_logic_vector(7 downto 0);
|
||||
signal spi_start, spi_busy : std_logic;
|
||||
|
||||
signal iorq_old : std_logic := '0';
|
||||
|
||||
signal fifo_t_wrstb, fifo_t_rdstb, fifo_t_full, fifo_t_empty, fifo_r_wrstb, fifo_r_rdstb, fifo_r_full, fifo_r_empty : std_logic;
|
||||
signal fifo_r_din, fifo_r_dout, fifo_t_din, fifo_t_dout : std_logic_vector(7 downto 0);
|
||||
begin -- Behavioral
|
||||
|
||||
kcpsm3_inst : kcpsm3 port map (
|
||||
address => kcpsm3_addr,
|
||||
instruction => kcpsm3_instr,
|
||||
port_id => kcpsm3_portid,
|
||||
write_strobe => kcpsm3_wrstb,
|
||||
out_port => kcpsm3_outport,
|
||||
read_strobe => kcpsm3_rdstb,
|
||||
in_port => kcpsm3_inport,
|
||||
interrupt => '0',
|
||||
interrupt_ack => open,
|
||||
reset => '0',
|
||||
clk => CLK_16M);
|
||||
|
||||
prog_inst : uartprog port map (
|
||||
address => kcpsm3_addr,
|
||||
instruction => kcpsm3_instr,
|
||||
clk => CLK_16M);
|
||||
|
||||
spi_inst : spi port map (
|
||||
MISO => SPI_MISO,
|
||||
MOSI => SPI_MOSI,
|
||||
SCK => SPI_SCK,
|
||||
DATA_I => kcpsm3_outport,
|
||||
DATA_O => spi_datao,
|
||||
START => spi_start,
|
||||
BUSY => spi_busy,
|
||||
CLK => CLK_16M);
|
||||
|
||||
spi_start <= '1' when (kcpsm3_wrstb = '1') and (kcpsm3_portid = X"02") else
|
||||
'0';
|
||||
|
||||
spi_iface: process (CLK_16M)
|
||||
begin -- process spi_iface
|
||||
if rising_edge(CLK_16M) then
|
||||
if (kcpsm3_wrstb = '1') then
|
||||
if (kcpsm3_portid = X"03") then
|
||||
SPI_SS_B <= kcpsm3_outport(0);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
lcd_iface: process (CLK_16M)
|
||||
begin -- process lcd_iface
|
||||
if rising_edge(CLK_16M) then
|
||||
if (kcpsm3_wrstb = '1') then
|
||||
if (kcpsm3_portid = X"04") then
|
||||
lcdctrl_r <= kcpsm3_outport(2 downto 0);
|
||||
elsif kcpsm3_portid = X"05" then
|
||||
lcdout_r <= kcpsm3_outport;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process lcd_iface;
|
||||
|
||||
kcpsm3_inport <= fifo_t_dout when kcpsm3_portid = X"00" else
|
||||
"000000" & fifo_t_empty & fifo_r_full when kcpsm3_portid = X"01" else
|
||||
spi_datao when kcpsm3_portid = X"02" else
|
||||
"0000000" & spi_busy when kcpsm3_portid = X"03" else
|
||||
LCD_DB when kcpsm3_portid = X"05" else
|
||||
"00000" & lcdctrl_r when kcpsm3_portid = X"04" else
|
||||
"000" & ROT_CENTER & BTN_NORTH & BTN_EAST & BTN_SOUTH & BTN_WEST when kcpsm3_portid = X"06" else
|
||||
"XXXXXXXX";
|
||||
|
||||
process (CLK_16M)
|
||||
begin
|
||||
if rising_edge(CLK_16M) then
|
||||
fifo_r_wrstb <= '0';
|
||||
fifo_t_rdstb <= '0';
|
||||
if (kcpsm3_wrstb = '1') then
|
||||
if (kcpsm3_portid = X"00") then
|
||||
fifo_r_din <= kcpsm3_outport;
|
||||
fifo_r_wrstb <= '1';
|
||||
end if;
|
||||
elsif (kcpsm3_rdstb = '1') then
|
||||
if (kcpsm3_portid = X"00") then
|
||||
fifo_t_rdstb <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
fifo16x8_inst_transmit : fifo16x8 port map (
|
||||
DATAIN => fifo_t_din,
|
||||
WRITESTB => fifo_t_wrstb,
|
||||
DATAOUT => fifo_t_dout,
|
||||
READSTB => fifo_t_rdstb,
|
||||
CLK => CLK_16M,
|
||||
FULL => fifo_t_full,
|
||||
EMPTY => fifo_t_empty);
|
||||
|
||||
fifo16x8_inst_receive : fifo16x8 port map (
|
||||
DATAIN => fifo_r_din,
|
||||
WRITESTB => fifo_r_wrstb,
|
||||
DATAOUT => fifo_r_dout,
|
||||
READSTB => fifo_r_rdstb,
|
||||
CLK => CLK_16M,
|
||||
FULL => fifo_r_full,
|
||||
EMPTY => fifo_r_empty);
|
||||
|
||||
z80bus: process (CLK_16M)
|
||||
begin
|
||||
if rising_edge(CLK_16M) then
|
||||
fifo_r_rdstb <= '0';
|
||||
fifo_t_wrstb <= '0';
|
||||
if (iorq_old = '1') and (IORQ_n = '0') then
|
||||
if ADDR_I = "01" then
|
||||
if RD_n = '0' then -- read receiver register
|
||||
DATA_O <= fifo_r_dout;
|
||||
fifo_r_rdstb <= '1';
|
||||
elsif WR_n = '0' then -- transmitter buffer load
|
||||
fifo_t_din <= DATA_I;
|
||||
fifo_t_wrstb <= '1';
|
||||
end if;
|
||||
elsif ADDR_I = "10" then
|
||||
if RD_n = '0' then -- read status flags
|
||||
DATA_O <= not fifo_r_empty & not fifo_t_full & "XX000X"; -- DR, TBRE, x, x, FE, PE, OE, x
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
iorq_old <= IORQ_n;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
LCD_DB <= lcdout_r when lcdctrl_r(2) = '0' else
|
||||
"ZZZZZZZZ";
|
||||
LCD_E <= lcdctrl_r(0);
|
||||
LCD_RS <= lcdctrl_r(1);
|
||||
LCD_RW <= lcdctrl_r(2);
|
||||
|
||||
DATAFLASH_RST <= '1';
|
||||
DATAFLASH_WP <= '1';
|
||||
|
||||
end Behavioral;
|
||||
Reference in New Issue
Block a user