---------------------------------------------------------------------------------- -- 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;