-- -- Dalton Project -- Tony Givargis, Roman Lysecky, Rilesh Patel, Puneet Mehra -- 1/4/99 -- Version 1.2 -- Notes: This file implements the Parallel Ports device. This is similar to -- 8255-Programmable Parallel Interface chip. -- -- Implementation of National PC16550 UART chip. -- --*********************************************************************************************************************-- -- -- Not Implemented: -- -- Interrupt Enable Register -- Interrupt Identification Register -- FIFO Control -- Bit 0-6 of Line Control Register -- Bit 0-3 of Modem Status Register (delta) -- Bit 4 of Modem Control Register (loop back) -- --*********************************************************************************************************************-- -- -- ---------- -- D0 -|1 40|- VDD -- D1 -|2 39|- RI -- D2 -|3 38|- DCD -- D3 -|4 37|- DSR -- D4 -|5 36|- CTS -- D5 -|6 35|- MR -- D6 -|7 34|- OUT1 -- D7 -|8 33|- DTR -- RCLK -|9 32|- RTS -- SIN -|10 31|- OUT2 -- SOUT -|11 30|- INTR -- CS0 -|12 29|- RXRDY -- CS1 -|13 28|- AO -- CS2 -|14 27|- A1 -- BAUDOUT -|15 26|- A2 -- XIN -|16 25|- ADS -- XOUT -|17 24|- TXRDY -- WR -|18 23|- DDIS -- /WR -|19 22|- RD -- VSS -|20 21|- /RD -- ---------- -- --*********************************************************************************************************************-- library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; --*********************************************************************************************************************-- entity PC16550_IN is port ( din : in UNSIGNED (7 downto 0); dout : out UNSIGNED (7 downto 0); rclk : in STD_LOGIC; sin : in STD_LOGIC; sout : out STD_LOGIC; cs0 : in STD_LOGIC; cs1 : in STD_LOGIC; cs2 : in STD_LOGIC; baudout : out STD_LOGIC; xin : in STD_LOGIC; xout : out STD_LOGIC; wr : in STD_LOGIC; nwr : in STD_LOGIC; rd : in STD_LOGIC; nrd : in STD_LOGIC; ddis : out STD_LOGIC; txrdy : out STD_LOGIC; ads : in STD_LOGIC; addr : in STD_LOGIC_VECTOR (2 downto 0); rxrdy : out STD_LOGIC; intr : out STD_LOGIC; out2 : out STD_LOGIC; rts : out STD_LOGIC; dtr : out STD_LOGIC; out1 : out STD_LOGIC; mr : in STD_LOGIC; cts : in STD_LOGIC; dsr : in STD_LOGIC; dcd : in STD_LOGIC; ri : in STD_LOGIC ); end PC16550_IN; --*********************************************************************************************************************-- architecture BHV_PC16550_IN of PC16550_IN is -- -- state variable type for "transmit process" -- type TX_STATE_TYPE is (TX_IDLE, TX_BIT7, TX_BIT6, TX_BIT5, TX_BIT4, TX_BIT3, TX_BIT2, TX_BIT1, TX_BIT0, TX_PARITY, TX_STOP); -- -- state variable type for "receive process" -- type RX_STATE_TYPE is (RX_IDLE, RX_BIT7, RX_BIT6, RX_BIT5, RX_BIT4, RX_BIT3, RX_BIT2, RX_BIT1, RX_BIT0, RX_PARITY, RX_STOP); -- -- 8-bit constants -- constant C0_8 : UNSIGNED (7 downto 0) := "00000000"; constant C1_8 : UNSIGNED (7 downto 0) := "00000001"; -- -- 16-bit constants -- constant C0_16 : UNSIGNED (15 downto 0) := "0000000000000000"; -- -- 3-bit constants -- constant C0_3 : STD_LOGIC_VECTOR (2 downto 0) := "000"; constant C1_3 : STD_LOGIC_VECTOR (2 downto 0) := "001"; constant C2_3 : STD_LOGIC_VECTOR (2 downto 0) := "010"; constant C3_3 : STD_LOGIC_VECTOR (2 downto 0) := "011"; constant C4_3 : STD_LOGIC_VECTOR (2 downto 0) := "100"; constant C5_3 : STD_LOGIC_VECTOR (2 downto 0) := "101"; constant C6_3 : STD_LOGIC_VECTOR (2 downto 0) := "110"; constant C7_3 : STD_LOGIC_VECTOR (2 downto 0) := "111"; -- -- these signals asserted by "baud generator process" -- signal tx_clk : STD_LOGIC; signal div_16_cntr : INTEGER range 0 to 15; signal divisor_cntr : INTEGER range 0 to 65535; -- -- these signals asserted by "rd resolve process" -- signal rd_sig : STD_LOGIC; -- -- these signals asserted by "tx enable process" -- signal tx_enable : STD_LOGIC; -- -- these signals asserted by "address strobe process" -- signal addr_reg : STD_LOGIC_VECTOR (2 downto 0); signal cs_reg : STD_LOGIC_VECTOR (2 downto 0); -- -- these signals asserted by "cpu write process" -- signal dtr_reg : STD_LOGIC; signal rts_reg : STD_LOGIC; signal out1_reg : STD_LOGIC; signal out2_reg : STD_LOGIC; signal loop_back_reg : STD_LOGIC; signal tx_reg : UNSIGNED (7 downto 0); signal intr_en_reg : UNSIGNED (7 downto 0); signal line_ctr_reg : UNSIGNED (7 downto 0); signal baud_div_reg : UNSIGNED (15 downto 0); signal scratch_reg : UNSIGNED (7 downto 0); -- -- these signals asserted by "transmit process" -- signal tx_done : STD_LOGIC; signal tx_state : TX_STATE_TYPE; -- -- these signals asserted by "receive process" -- signal rx_reg : UNSIGNED (7 downto 0); signal rx_done : STD_LOGIC; signal rx_state : RX_STATE_TYPE; begin -- -- xout not used (there is no internal osc.) -- xout <= '0'; -- -- modem/data-set control output -- dtr <= not dtr_reg; rts <= not rts_reg; out1 <= not out1_reg; out2 <= not out2_reg; -- -- baud generator process -- process(mr, xin) begin if( mr = '1' ) then -- -- reset -- baudout <= '0'; tx_clk <= '0'; div_16_cntr <= 0; divisor_cntr <= 0; else tx_clk <= xin; baudout <= xin; end if; -- elsif( xin'event and xin = '1' ) then -- -- -- -- -- positive edge -- -- -- div_16_cntr <= div_16_cntr + 1; -- if( div_16_cntr = 15 ) then -- -- div_16_cntr <= 0; -- divisor_cntr <= divisor_cntr + 1; -- if( divisor_cntr >= conv_integer(baud_div_reg) ) then -- -- divisor_cntr <= 0; -- tx_clk <= '1'; -- baudout <= '1'; -- else -- -- tx_clk <= '0'; -- baudout <= '0'; -- end if; -- else -- -- tx_clk <= '0'; -- baudout <= '0'; -- end if; -- end if; end process; -- -- rd resolve process -- process(rd, nrd) begin rd_sig <= rd or (not nrd); end process; -- -- tx enable process -- process(tx_clk, wr, mr) begin if( mr = '1' ) then tx_enable <= '0'; elsif( wr = '1' ) then -- -- enable on write -- tx_enable <= '1'; elsif( tx_clk'event and tx_clk = '1' ) then tx_enable <= '0'; end if; end process; -- -- address strobe process -- process(mr, ads) begin if( mr = '1' ) then -- -- reset -- addr_reg <= C0_3; cs_reg <= C0_3; elsif( ads'event and ads = '1' ) then -- -- positive edge -- addr_reg <= addr; cs_reg <= cs0 & cs1 & (not cs2); end if; end process; -- -- cpu write process -- process(mr, wr) begin if( mr = '1' ) then -- -- reset -- dtr_reg <= '0'; rts_reg <= '0'; out1_reg <= '0'; out2_reg <= '0'; loop_back_reg <= '0'; tx_reg <= C0_8; intr_en_reg <= C1_8; line_ctr_reg <= C0_8; baud_div_reg <= conv_unsigned(C0_16, 16); scratch_reg <= C0_8; elsif( wr'event and wr = '1' ) then -- -- positive edge -- if( ads = '0' ) then -- -- addr/cs direct -- if( cs0 = '1' and cs1 = '1' and cs2 = '0' ) then case addr is when C0_3 => if( line_ctr_reg(7) = '0' ) then tx_reg <= din; else baud_div_reg(7 downto 0) <= din; end if; when C1_3 => if( line_ctr_reg(7) = '0' ) then intr_en_reg <= din; else baud_div_reg(15 downto 8) <= din; end if; when C2_3 => -- read only when C3_3 => line_ctr_reg <= din; when C4_3 => dtr_reg <= din(0); rts_reg <= din(1); out1_reg <= din(2); out2_reg <= din(3); loop_back_reg <= din(4); when C5_3 => -- read only when C6_3 => -- read only when C7_3 => scratch_reg <= din; when others => -- nothing end case; end if; else -- -- addr/cs latched -- if( cs_reg = C6_3 ) then case addr_reg is when C0_3 => if( line_ctr_reg(7) = '0' ) then tx_reg <= din; else baud_div_reg(7 downto 0) <= din; end if; when C1_3 => if( line_ctr_reg(7) = '0' ) then intr_en_reg <= din; else baud_div_reg(15 downto 8) <= din; end if; when C2_3 => -- read only when C3_3 => line_ctr_reg <= din; when C4_3 => dtr_reg <= din(0); rts_reg <= din(1); out1_reg <= din(2); out2_reg <= din(3); loop_back_reg <= din(4); when C5_3 => -- read only when C6_3 => -- read only when C7_3 => scratch_reg <= din; when others => -- nothing end case; end if; end if; end if; end process; -- -- cpu read process -- process(rd_sig) begin if( rd_sig'event and rd_sig = '1' ) then -- -- positive edge -- if( ads = '0' ) then -- -- addr/cs direct -- if( cs0 = '1' and cs1 = '1' and cs2 = '0' ) then case addr is when C0_3 => if( line_ctr_reg(7) = '0' ) then dout <= rx_reg; else dout <= baud_div_reg(7 downto 0); end if; when C1_3 => if( line_ctr_reg(7) = '0' ) then dout <= intr_en_reg; else dout <= baud_div_reg(15 downto 8); end if; when C2_3 => when C3_3 => dout <= line_ctr_reg; when C4_3 => dout(0) <= dtr_reg; dout(1) <= rts_reg; dout(2) <= out1_reg; dout(3) <= out2_reg; dout(4) <= loop_back_reg; dout(5) <= '0'; dout(6) <= '0'; dout(7) <= '0'; when C5_3 => when C6_3 => dout(0) <= '0'; dout(1) <= '0'; dout(2) <= '0'; dout(3) <= '0'; dout(4) <= not cts; dout(5) <= not dsr; dout(6) <= not ri; dout(7) <= not dcd; when C7_3 => dout <= scratch_reg; when others => -- nothing end case; end if; else -- -- addr/cs latched -- if( cs_reg = C6_3 ) then case addr_reg is when C0_3 => if( line_ctr_reg(7) = '0' ) then dout <= rx_reg; else dout <= baud_div_reg(7 downto 0); end if; when C1_3 => if( line_ctr_reg(7) = '0' ) then dout <= intr_en_reg; else dout <= baud_div_reg(15 downto 8); end if; when C2_3 => when C3_3 => dout <= line_ctr_reg; when C4_3 => dout(0) <= dtr_reg; dout(1) <= rts_reg; dout(2) <= out1_reg; dout(3) <= out2_reg; dout(4) <= loop_back_reg; dout(5) <= '0'; dout(6) <= '0'; dout(7) <= '0'; when C5_3 => when C6_3 => dout(0) <= '0'; dout(1) <= '0'; dout(2) <= '0'; dout(3) <= '0'; dout(4) <= not cts; dout(5) <= not dsr; dout(6) <= not ri; dout(7) <= not dcd; when C7_3 => dout <= scratch_reg; when others => -- nothing end case; end if; end if; end if; end process; -- -- transmit process -- process(mr, tx_clk) begin if( mr = '1' ) then -- -- reset -- sout <= '1'; tx_done <= '0'; tx_state <= TX_IDLE; elsif( tx_clk'event and tx_clk = '1' ) then -- -- positive edge -- case tx_state is when TX_IDLE => if( tx_enable = '1' and ads = '0' ) then -- -- addr/cs direct -- if( cs0 = '1' and cs1 = '1' and cs2 = '0' and addr = C0_3 ) then tx_done <= '0'; sout <= '1'; tx_state <= TX_BIT7; end if; end if; when TX_BIT7 => tx_done <= '1'; sout <= tx_reg(7); tx_state <= TX_BIT6; when TX_BIT6 => tx_done <= '1'; sout <= tx_reg(6); tx_state <= TX_BIT5; when TX_BIT5 => tx_done <= '1'; sout <= tx_reg(5); tx_state <= TX_BIT4; when TX_BIT4 => tx_done <= '1'; sout <= tx_reg(4); tx_state <= TX_BIT3; when TX_BIT3 => tx_done <= '1'; sout <= tx_reg(3); tx_state <= TX_BIT2; when TX_BIT2 => tx_done <= '1'; sout <= tx_reg(2); tx_state <= TX_BIT1; when TX_BIT1 => tx_done <= '1'; sout <= tx_reg(1); tx_state <= TX_BIT0; when TX_BIT0 => tx_done <= '1'; sout <= tx_reg(0); tx_state <= TX_PARITY; when TX_PARITY => tx_done <= '1'; sout <= '0'; tx_state <= TX_STOP; when TX_STOP => tx_done <= '1'; sout <= '1'; tx_state <= TX_IDLE; end case; end if; end process; -- -- receive process -- process(mr, rclk) begin if( mr = '1' ) then -- -- reset -- rx_reg <= C0_8; rx_state <= RX_IDLE; elsif( rclk'event and rclk = '1' ) then -- -- positive edge -- case rx_state is when RX_IDLE => if( sin = '0' ) then rx_done <= '0'; rx_state <= RX_BIT7; end if; when RX_BIT7 => rx_reg(7) <= sin; rx_state <= RX_BIT6; when RX_BIT6 => rx_reg(6) <= sin; rx_state <= RX_BIT5; when RX_BIT5 => rx_reg(5) <= sin; rx_state <= RX_BIT4; when RX_BIT4 => rx_reg(4) <= sin; rx_state <= RX_BIT3; when RX_BIT3 => rx_reg(3) <= sin; rx_state <= RX_BIT2; when RX_BIT2 => rx_reg(2) <= sin; rx_state <= RX_BIT1; when RX_BIT1 => rx_reg(1) <= sin; rx_state <= RX_BIT0; when RX_BIT0 => rx_reg(0) <= sin; rx_state <= RX_PARITY; when RX_PARITY => rx_state <= RX_STOP; when RX_STOP => rx_state <= RX_IDLE; end case; end if; end process; end BHV_PC16550_IN; --*********************************************************************************************************************-- library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; --*********************************************************************************************************************-- entity PC16550_IM is generic(INPUT_ADDR : INTEGER := 3000); port(clk : in STD_LOGIC; rst : in STD_LOGIC; pdata : inout UNSIGNED (7 downto 0); paddr : in UNSIGNED (22 downto 0); ib_data : inout UNSIGNED (7 downto 0); ib_addr : out STD_LOGIC_VECTOR (2 downto 0); ib_rd : out STD_LOGIC; ib_wr : out STD_LOGIC; ior : in STD_LOGIC; iow : in STD_LOGIC; ale : in STD_LOGIC; iochrdy : out STD_LOGIC ); end PC16550_IM; --*********************************************************************************************************************-- architecture BHV_PC16550_IM of PC16550_IM is -- -- type declarations -- type STATE_TYPE is (IDLE_S, READ_S, READ_WAIT_S, WRITE_S ); type ISA_STATE_TYPE is (IDLE_ISA_S, READ_WRITE_S, READ1_S, READ1_WAIT_S, READ2_IDLE_S, READ2_CHK_S, READ2_S, READ2_WAIT_S, READ3_IDLE_S, READ3_CHK_S, READ3_S, READ3_WAIT_S, READ4_IDLE_S, READ4_CHK_S, READ4_S, READ4_WAIT_S, WRITE1_S, WRITE1_WAIT_S, WRITE2_IDLE_S, WRITE2_CHK_S, WRITE2_S, WRITE2_WAIT_S, WRITE3_IDLE_S, WRITE3_CHK_S, WRITE3_S, WRITE3_WAIT_S, WRITE4_IDLE_S, WRITE4_CHK_S, WRITE4_S, WRITE4_WAIT_S ); -- -- constant declarations -- constant Z_32 : UNSIGNED(31 downto 0) := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"; constant Z_23 : UNSIGNED(22 downto 0) := "ZZZZZZZZZZZZZZZZZZZZZZZ"; constant Z_8 : UNSIGNED(7 downto 0) := "ZZZZZZZZ"; constant C0_32 : UNSIGNED(31 downto 0) := "00000000000000000000000000000000"; constant C0_23 : UNSIGNED(22 downto 0) := "00000000000000000000000"; constant C0_24 : UNSIGNED(23 downto 0) := "000000000000000000000000"; constant C0_3 : STD_LOGIC_VECTOR (2 downto 0) := "000"; -- -- signal declarations -- signal isa_data, isa_data_read : UNSIGNED (31 downto 0); signal isa_addr : UNSIGNED(22 downto 0); signal isa_wr, isa_rd, read_done, write_done : STD_LOGIC; signal state : STATE_TYPE; signal isa_state : ISA_STATE_TYPE; begin process(clk, rst) begin if( rst = '1' ) then -- -- steady state -- state <= IDLE_S; ib_data <= Z_8; ib_addr <= C0_3; ib_rd <= '0'; ib_wr <= '0'; isa_data_read <= C0_32; read_done <= '0'; write_done <= '0'; elsif( clk'event and clk = '1' ) then -- -- steady state -- ib_rd <= '0'; ib_wr <= '0'; read_done <= '0'; write_done <= '0'; case ( state ) is when IDLE_S => if( isa_rd = '1' ) then ib_rd <= '1'; state <= READ_S; elsif( isa_wr = '1' ) then -- -- This is the "special" signal -- -- ib_wr <= '1'; ib_data <= isa_data(7 downto 0); state <= WRITE_S; end if; when READ_S => state <= READ_WAIT_S; when READ_WAIT_S => isa_data_read <= C0_24 & ib_data; read_done <= '1'; state <= IDLE_S; when WRITE_S => ib_wr <= '1'; write_done <= '1'; state <= IDLE_S; when others => state <= IDLE_S; end case; end if; end process; -- -- ISA mux process -- process(clk, rst) begin if( rst = '1') then -- -- steady state -- isa_state <= IDLE_ISA_S; isa_data <= C0_32; isa_addr <= C0_23; isa_wr <= '0'; isa_rd <= '0'; iochrdy <= 'Z'; pdata <= Z_8; elsif( clk'event and clk = '1') then -- -- steady state -- isa_wr <= '0'; isa_rd <= '0'; iochrdy <= 'Z'; pdata <= Z_8; case( isa_state ) is when IDLE_ISA_S => if( ale = '1' ) then if( conv_integer(paddr) = INPUT_ADDR ) then isa_addr <= paddr; isa_state <= READ_WRITE_S; else isa_state <= IDLE_ISA_S; end if; else isa_state <= IDLE_ISA_S; end if; when READ_WRITE_S => if( ior = '1' ) then iochrdy <= '0'; isa_rd <= '1'; isa_state <= READ1_S; elsif( iow = '1') then iochrdy <= '0'; isa_data(7 downto 0) <= pdata; isa_state <= WRITE1_S; else isa_state <= IDLE_ISA_S; end if; when READ1_S => iochrdy <= '0'; isa_state <= READ1_WAIT_S; when READ1_WAIT_S => if( read_done = '1' ) then iochrdy <= '1'; pdata <= isa_data_read(7 downto 0); isa_state <= READ2_IDLE_S; else iochrdy <= '0'; isa_state <= READ1_WAIT_S; end if; when READ2_IDLE_S => if( ale = '1' ) then if( paddr = isa_addr ) then isa_state <= READ2_CHK_S; elsif( conv_integer(paddr) = INPUT_ADDR ) then isa_state <= READ_WRITE_S; else isa_state <= IDLE_ISA_S; end if; else isa_state <= READ2_IDLE_S; end if; when READ2_CHK_S => if( ior = '1' ) then iochrdy <= '0'; isa_state <= READ2_S; elsif( iow = '1') then iochrdy <= '0'; isa_data(7 downto 0) <= pdata; isa_state <= WRITE1_S; else isa_state <= IDLE_ISA_S; end if; when READ2_S => iochrdy <= '0'; isa_state <= READ2_WAIT_S; when READ2_WAIT_S => iochrdy <= '1'; pdata <= isa_data_read(15 downto 8); isa_state <= READ3_IDLE_S; when READ3_IDLE_S => if( ale = '1' ) then if( paddr = isa_addr ) then isa_state <= READ3_CHK_S; elsif( conv_integer(paddr) = INPUT_ADDR ) then isa_state <= READ_WRITE_S; else isa_state <= IDLE_ISA_S; end if; else isa_state <= READ3_IDLE_S; end if; when READ3_CHK_S => if( ior = '1' ) then iochrdy <= '0'; isa_state <= READ3_S; elsif( iow = '1') then iochrdy <= '0'; isa_data(7 downto 0) <= pdata; isa_state <= WRITE1_S; else isa_state <= IDLE_ISA_S; end if; when READ3_S => iochrdy <= '0'; isa_state <= READ3_WAIT_S; when READ3_WAIT_S => iochrdy <= '1'; pdata <= isa_data_read(23 downto 16); isa_state <= READ4_IDLE_S; when READ4_IDLE_S => if( ale = '1' ) then if( paddr = isa_addr ) then isa_state <= READ4_CHK_S; elsif( conv_integer(paddr) = INPUT_ADDR ) then isa_state <= READ_WRITE_S; else isa_state <= IDLE_ISA_S; end if; else isa_state <= READ4_IDLE_S; end if; when READ4_CHK_S => if( ior = '1' ) then iochrdy <= '0'; isa_state <= READ4_S; elsif( iow = '1') then iochrdy <= '0'; isa_data(7 downto 0) <= pdata; isa_state <= WRITE1_S; else isa_state <= IDLE_ISA_S; end if; when READ4_S => iochrdy <= '0'; isa_state <= READ4_WAIT_S; when READ4_WAIT_S => iochrdy <= '1'; pdata <= isa_data_read(31 downto 24); isa_state <= IDLE_ISA_S; when WRITE1_S => if( iow = '1' ) then iochrdy <= '1'; isa_state <= WRITE1_S; else isa_state <= WRITE2_IDLE_S; end if; when WRITE2_IDLE_S => if( ale = '1' ) then if( paddr = isa_addr ) then isa_state <= WRITE2_CHK_S; elsif( conv_integer(paddr) = INPUT_ADDR ) then isa_state <= READ_WRITE_S; else isa_state <= IDLE_ISA_S; end if; else isa_state <= WRITE2_IDLE_S; end if; when WRITE2_CHK_S => if( ior = '1' ) then iochrdy <= '0'; isa_rd <= '1'; isa_state <= READ1_S; elsif( iow = '1') then iochrdy <= '0'; isa_data(15 downto 8) <= pdata; isa_state <= WRITE2_S; else isa_state <= IDLE_ISA_S; end if; when WRITE2_S => if( iow = '1' ) then iochrdy <= '1'; isa_state <= WRITE2_S; else isa_state <= WRITE3_IDLE_S; end if; when WRITE3_IDLE_S => if( ale = '1' ) then if( paddr = isa_addr ) then isa_state <= WRITE3_CHK_S; elsif( conv_integer(paddr) = INPUT_ADDR ) then isa_state <= READ_WRITE_S; else isa_state <= IDLE_ISA_S; end if; else isa_state <= WRITE3_IDLE_S; end if; when WRITE3_CHK_S => if( ior = '1' ) then iochrdy <= '0'; isa_rd <= '1'; isa_state <= READ1_S; elsif( iow = '1') then iochrdy <= '0'; isa_data(23 downto 16) <= pdata; isa_state <= WRITE3_S; else isa_state <= IDLE_ISA_S; end if; when WRITE3_S => if( iow = '1' ) then iochrdy <= '1'; isa_state <= WRITE3_S; else isa_state <= WRITE4_IDLE_S; end if; when WRITE4_IDLE_S => if( ale = '1' ) then if( paddr = isa_addr ) then isa_state <= WRITE4_CHK_S; elsif( conv_integer(paddr) = INPUT_ADDR ) then isa_state <= READ_WRITE_S; else isa_state <= IDLE_ISA_S; end if; else isa_state <= WRITE4_IDLE_S; end if; when WRITE4_CHK_S => if( ior = '1' ) then iochrdy <= '0'; isa_rd <= '1'; isa_state <= READ1_S; elsif( iow = '1') then iochrdy <= '0'; isa_data(31 downto 24) <= pdata; isa_wr <= '1'; isa_state <= WRITE4_S; else isa_state <= IDLE_ISA_S; end if; when WRITE4_S => iochrdy <= '0'; if( write_done = '1' ) then isa_state <= WRITE4_WAIT_S; else isa_state <= WRITE4_S; end if; when WRITE4_WAIT_S => if( iow = '1' ) then iochrdy <= '1'; isa_state <= WRITE4_WAIT_S; else isa_state <= IDLE_ISA_S; end if; when others => isa_state <= IDLE_ISA_S; end case; end if; end process; end BHV_PC16550_IM; --*********************************************************************************************************************-- library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; --*********************************************************************************************************************-- entity PC16550 is generic(INPUT_ADDR : INTEGER := 3000); port(clk : in STD_LOGIC; rst : in STD_LOGIC; pdata : inout UNSIGNED (7 downto 0); paddr : in UNSIGNED (22 downto 0); ior : in STD_LOGIC; iow : in STD_LOGIC; ale : in STD_LOGIC; iochrdy : out STD_LOGIC; sout : out STD_LOGIC ); end PC16550; --*********************************************************************************************************************-- architecture STR_PC16550 of PC16550 is -- -- constant declarations -- constant C0_8 : UNSIGNED(7 downto 0) := "00000000"; constant CZ_8 : UNSIGNED(7 downto 0) := "ZZZZZZZZ"; -- -- component declarations -- component PC16550_IN port ( din : in UNSIGNED (7 downto 0); dout : out UNSIGNED (7 downto 0); rclk : in STD_LOGIC; sin : in STD_LOGIC; sout : out STD_LOGIC; cs0 : in STD_LOGIC; cs1 : in STD_LOGIC; cs2 : in STD_LOGIC; baudout : out STD_LOGIC; xin : in STD_LOGIC; xout : out STD_LOGIC; wr : in STD_LOGIC; nwr : in STD_LOGIC; rd : in STD_LOGIC; nrd : in STD_LOGIC; ddis : out STD_LOGIC; txrdy : out STD_LOGIC; ads : in STD_LOGIC; addr : in STD_LOGIC_VECTOR (2 downto 0); rxrdy : out STD_LOGIC; intr : out STD_LOGIC; out2 : out STD_LOGIC; rts : out STD_LOGIC; dtr : out STD_LOGIC; out1 : out STD_LOGIC; mr : in STD_LOGIC; cts : in STD_LOGIC; dsr : in STD_LOGIC; dcd : in STD_LOGIC; ri : in STD_LOGIC); end component; -- -- component declarations -- component PC16550_IM generic(INPUT_ADDR : INTEGER := 3000); port( clk : in STD_LOGIC; rst : in STD_LOGIC; pdata : inout UNSIGNED (7 downto 0); paddr : in UNSIGNED (22 downto 0); ib_data : inout UNSIGNED (7 downto 0); ib_addr : out STD_LOGIC_VECTOR (2 downto 0); ib_rd : out STD_LOGIC; ib_wr : out STD_LOGIC; ior : in STD_LOGIC; iow : in STD_LOGIC; ale : in STD_LOGIC; iochrdy : out STD_LOGIC); end component; -- -- component configurations -- for all : PC16550_IN use entity WORK.PC16550_IN(BHV_PC16550_IN); for all : PC16550_IM use entity WORK.PC16550_IM(BHV_PC16550_IM); -- -- signals -- signal dout : UNSIGNED (7 downto 0); signal rclk : STD_LOGIC; signal sin : STD_LOGIC; -- signal sout : STD_LOGIC; signal cs0 : STD_LOGIC; signal cs1 : STD_LOGIC; signal cs2 : STD_LOGIC; signal baudout : STD_LOGIC; signal xin : STD_LOGIC; signal xout : STD_LOGIC; signal nwr : STD_LOGIC; signal nrd : STD_LOGIC; signal ddis : STD_LOGIC; signal txrdy : STD_LOGIC; signal ads : STD_LOGIC; signal uaddr : STD_LOGIC_VECTOR (2 downto 0); signal rxrdy : STD_LOGIC; signal intr : STD_LOGIC; signal out2 : STD_LOGIC; signal rts : STD_LOGIC; signal dtr : STD_LOGIC; signal out1 : STD_LOGIC; signal cts : STD_LOGIC; signal dsr : STD_LOGIC; signal dcd : STD_LOGIC; signal ri : STD_LOGIC; -- -- signals -- signal ib_data : UNSIGNED(7 downto 0); signal ib_addr : STD_LOGIC_VECTOR (2 downto 0); signal ib_rd : STD_LOGIC; signal ib_wr : STD_LOGIC; begin -- -- we use the internal baudrate for receive -- rclk <= baudout; -- -- this is the external serial input to the chip that is currently held high -- sin <= '1'; -- -- these signals will enable the UART, currently the chip is forced to be enabled -- cs0 <= '1'; cs1 <= '1'; cs2 <= '0'; -- -- we use the processor's clock signal for baudrate input to the UART -- xin <= clk; -- -- we only use the active hi write signal -- nwr <= '1'; nrd <= '1'; -- -- we assume that rd and wr are held low for the duration of write/read, thus ads should be low -- ads <= '0'; -- -- these signals are the external inputs that are currently held high -- cts <= '1'; dsr <= '1'; dcd <= '1'; ri <= '1'; -- -- component instantiations -- U1 : PC16550_IN port map(ib_data, dout, rclk, sin, sout, cs0, cs1, cs2, baudout, xin, xout, ib_wr, nwr, ib_rd, nrd, ddis, txrdy, ads, ib_addr, rxrdy, intr, out2, rts, dtr, out1, rst, cts, dsr, dcd, ri); U2 : PC16550_IM generic map(INPUT_ADDR) port map(clk, rst, pdata, paddr, ib_data, ib_addr, ib_rd, ib_wr, ior, iow, ale, iochrdy); end STR_PC16550; --*********************************************************************************************************************-- configuration CFG_PC16550 of PC16550 is for STR_PC16550 end for; end CFG_PC16550;