-- -- Dalton Project -- Rilesh Patel, Puneet Mehra, Roman Lysecky -- 1/4/99 -- Version 1.2 -- Notes: This file implements the Parallel Ports device. This is similar to -- 8255-Programmable Parallel Interface chip. -- -- The P_PORTS has one 8 bit control register and three input or/and -- output registers for three 8-bit ports. -- -- CONTROL_REG: -- -- --------------------------------------------------------------- -- | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | -- --------------------------------------------------------------- -- ^ ^ ^ ^ ^ ^ ^ ^ -- | | | | | | | | -- | |_______| | | __| | | -- | | | | | | | -- MODE SET | PORT A ---- PORT C | PORT B -- PORT C -- FLAG | 1=INPUT (Upper) | 1=INPUT (Lower) -- 1= ACTIVE | 0=OUTPUT 1=INPUT | 0=OUTPUT 1=INPUT -- | 0=OUTPUT | 0=OUTPUT -- | | -- MODE FOR GROUP A MODE FOR GROUP B -- 00 = MODE 0 0 = MODE 0 -- 01 = MODE 1 1 = MODE 1 -- -- --*************************************************************************-- library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; --*************************************************************************-- entity PPP_IN is port( clk : in STD_LOGIC; di : in UNSIGNED(7 downto 0); do : out UNSIGNED(7 downto 0); den : out STD_LOGIC; cs : in STD_LOGIC; a0 : in STD_LOGIC; a1 : in STD_LOGIC; ib_wr : in STD_LOGIC; ib_rd : in STD_LOGIC; ib_rst: in STD_LOGIC; paen : out STD_LOGIC; pben : out STD_LOGIC; pcen : out UNSIGNED(7 downto 0); pai : in UNSIGNED(7 downto 0); pbi : in UNSIGNED(7 downto 0); pci : in UNSIGNED(7 downto 0); pao : out UNSIGNED(7 downto 0); pbo : out UNSIGNED(7 downto 0); pco : out UNSIGNED(7 downto 0)); end PPP_IN; --*************************************************************************-- architecture BHV_PPP_IN of PPP_IN is -- -- type declarations -- type MODE_TYPE is (ZERO,A0B1,A1B0,A1B1); -- -- constant declarations -- constant Z_23 : UNSIGNED(22 downto 0) := "ZZZZZZZZZZZZZZZZZZZZZZZ"; constant Z_8 : UNSIGNED(7 downto 0) := "ZZZZZZZZ"; constant C0_8 : UNSIGNED(7 downto 0) := "00000000"; constant C1_8 : UNSIGNED(7 downto 0) := "11111111"; constant C1_4 : UNSIGNED(3 downto 0) := "1111"; constant C0_4 : UNSIGNED(3 downto 0) := "0000"; constant Z_4 : UNSIGNED(3 downto 0) := "ZZZZ"; constant C0_2 : UNSIGNED(1 downto 0) := "00"; constant C1_2 : UNSIGNED(1 downto 0) := "01"; constant C2_2 : UNSIGNED(1 downto 0) := "10"; constant C3_2 : UNSIGNED(1 downto 0) := "11"; -- -- signal declarations -- signal cont_reg: UNSIGNED(7 downto 0); signal mode : MODE_TYPE; begin process(clk, ib_rst) begin if( ib_rst = '1' ) then -- --steady state -- paen <= '1'; pben <= '1'; pcen <= C1_8; mode <= ZERO; elsif( clk'event and clk = '1' ) then -- --steady state -- paen <= '1'; pben <= '1'; pcen <= C1_8; if( cont_reg(2)='0' and cont_reg(6 downto 5) = C0_2 ) then mode <= ZERO; elsif( cont_reg(2)='1' and cont_reg(6 downto 5)= C0_2 ) then mode <= A0B1; elsif( cont_reg(2)='0' and cont_reg(6 downto 5)= C1_2 ) then mode <= A1B0; elsif( cont_reg(2)='1' and cont_reg(6 downto 5)= C1_2 ) then mode <= A1B1; end if; case( mode ) is when ZERO => if( cont_reg(0)='1' ) then pco(3 downto 0) <= Z_4; pcen(3 downto 0) <= C1_4; elsif( cont_reg(0)='0' ) then pcen(3 downto 0) <= C0_4; end if; if( cont_reg(1)='1' ) then pbo <= Z_8; pben <= '1'; elsif( cont_reg(1)='0' ) then pben <= '0'; end if; if( cont_reg(3)='1' ) then pco( 7 downto 4 ) <= Z_4; pcen(7 downto 4) <= C1_4; elsif( cont_reg(3)='0' ) then pcen(7 downto 4) <= C0_4; end if; if( cont_reg(4)='1' ) then pao <= Z_8; paen <= '1'; elsif( cont_reg(4)='0' ) then paen <= '0'; end if; when others => null; end case; end if; end process; -- -- port read/write process -- process(clk, ib_rst) begin if( ib_rst = '1' ) then -- -- steady state -- do <= Z_8; pao <= Z_8; pbo <= Z_8; pco <= Z_8; den <= '1'; cont_reg <= "00011011"; elsif( cs = '1' ) then -- -- steady state -- den <= '1'; elsif( cs ='0' ) then if( clk'event and clk = '1' ) then -- -- steady state -- do <= Z_8; den <= '1'; if( ib_wr = '0' ) then den <= '1'; if( a0='0' and a1='0' ) then pao <= di; elsif( a0='1' and a1='0' ) then pbo <= di; elsif( a0='0' and a1='1' ) then pco <= di; elsif( a0='1' and a1='1' ) then cont_reg <= di; end if; elsif( ib_rd = '0' ) then den <= '0'; if( a0='0' and a1='0' ) then do <= pai; elsif( a0='1' and a1='0' ) then do <= pbi; elsif( a0='0' and a1='1' ) then do <= pci; elsif( a0='1' and a1='1' ) then do <= cont_reg; end if; end if; end if; end if; end process; end BHV_PPP_IN; --*************************************************************************-- library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; --*************************************************************************-- entity PPP_IM is generic( A_PORT_ADDR : INTEGER:=1028; B_PORT_ADDR : INTEGER:=1029; C_PORT_ADDR : INTEGER:=1030; CONT_REG_ADDR : INTEGER:=1031); port( clk : in STD_LOGIC; rst : in STD_LOGIC; di : out UNSIGNED(7 downto 0); do : in UNSIGNED(7 downto 0); ib_rst: out STD_LOGIC; ib_wr : out STD_LOGIC; ib_rd : out STD_LOGIC; cs : out STD_LOGIC; a0 : out STD_LOGIC; a1 : out 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 ); end PPP_IM; --*************************************************************************-- architecture BHV_PPP_IM of PPP_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_8 : UNSIGNED(7 downto 0) := "ZZZZZZZZ"; constant C0_32 : UNSIGNED(31 downto 0) := "00000000000000000000000000000000"; constant C0_24 : UNSIGNED(23 downto 0) := "000000000000000000000000"; constant C0_23 : UNSIGNED(22 downto 0) := "00000000000000000000000"; -- -- 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; di <= Z_8; ib_rd <= '1'; ib_wr <= '1'; ib_rst <= '1'; isa_data_read <= C0_32; read_done <= '0'; write_done <= '0'; elsif( clk'event and clk = '1' ) then -- -- steady state -- di <= Z_8; ib_rd <= '1'; ib_wr <= '1'; ib_rst <= '0'; read_done <= '0'; write_done <= '0'; case ( state ) is when IDLE_S => if( isa_rd = '1' ) then ib_rd <= '0'; state <= READ_S; elsif( isa_wr = '1' ) then di <= isa_data(7 downto 0); ib_wr <= '0'; state <= WRITE_S; end if; when READ_S => state <= READ_WAIT_S; when READ_WAIT_S => isa_data_read <= C0_24 & do; read_done <= '1'; state <= IDLE_S; when WRITE_S => 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 ( paddr = conv_integer(A_PORT_ADDR) or paddr = conv_integer(B_PORT_ADDR) or paddr = conv_integer(C_PORT_ADDR) or paddr = conv_integer(CONT_REG_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 ( paddr = conv_integer(A_PORT_ADDR) or paddr = conv_integer(B_PORT_ADDR) or paddr = conv_integer(C_PORT_ADDR) or paddr = conv_integer(CONT_REG_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 ( paddr = conv_integer(A_PORT_ADDR) or paddr = conv_integer(B_PORT_ADDR) or paddr = conv_integer(C_PORT_ADDR) or paddr = conv_integer(CONT_REG_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 ( paddr = conv_integer(A_PORT_ADDR) or paddr = conv_integer(B_PORT_ADDR) or paddr = conv_integer(C_PORT_ADDR) or paddr = conv_integer(CONT_REG_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 ( paddr = conv_integer(A_PORT_ADDR) or paddr = conv_integer(B_PORT_ADDR) or paddr = conv_integer(C_PORT_ADDR) or paddr = conv_integer(CONT_REG_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 ( paddr = conv_integer(A_PORT_ADDR) or paddr = conv_integer(B_PORT_ADDR) or paddr = conv_integer(C_PORT_ADDR) or paddr = conv_integer(CONT_REG_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 ( paddr = conv_integer(A_PORT_ADDR) or paddr = conv_integer(B_PORT_ADDR) or paddr = conv_integer(C_PORT_ADDR) or paddr = conv_integer(CONT_REG_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; -- -- address translation process -- process(clk, rst) begin if( rst = '1' ) then -- -- steady state -- cs <= '1'; a1 <= '0'; a0 <= '0'; elsif( clk'event and clk = '1' ) then -- -- steady state -- cs <= '1'; a1 <= '0'; a0 <= '0'; if( paddr = conv_integer(CONT_REG_ADDR) ) then cs <= '0'; a1 <= '1'; a0 <= '1'; elsif( paddr = conv_integer(A_PORT_ADDR) ) then cs <= '0'; a1 <= '0'; a0 <= '0'; elsif( paddr = conv_integer(B_PORT_ADDR) ) then cs <= '0'; a1 <= '0'; a0 <= '1'; elsif( paddr = conv_integer(C_PORT_ADDR) ) then cs <= '0'; a1 <= '1'; a0 <= '0'; end if; end if; end process; end BHV_PPP_IM; --*************************************************************************-- library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; --*************************************************************************-- entity PPP is generic( A_PORT_ADDR : INTEGER:=1028; B_PORT_ADDR : INTEGER:=1029; C_PORT_ADDR : INTEGER:=1030; CONT_REG_ADDR : INTEGER:=1031); 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; paen : out STD_LOGIC; pben : out STD_LOGIC; pcen : out UNSIGNED(7 downto 0); pai : in UNSIGNED(7 downto 0); pbi : in UNSIGNED(7 downto 0); pci : in UNSIGNED(7 downto 0); pao : out UNSIGNED(7 downto 0); pbo : out UNSIGNED(7 downto 0); pco : out UNSIGNED(7 downto 0)); end PPP; --*************************************************************************-- architecture STR_PPP of PPP is -- -- component declarations -- component PPP_IN port( clk : in STD_LOGIC; di : in UNSIGNED(7 downto 0); do : out UNSIGNED(7 downto 0); den : out STD_LOGIC; cs : in STD_LOGIC; a0 : in STD_LOGIC; a1 : in STD_LOGIC; ib_wr : in STD_LOGIC; ib_rd : in STD_LOGIC; ib_rst: in STD_LOGIC; paen : out STD_LOGIC; pben : out STD_LOGIC; pcen : out UNSIGNED(7 downto 0); pai : in UNSIGNED(7 downto 0); pbi : in UNSIGNED(7 downto 0); pci : in UNSIGNED(7 downto 0); pao : out UNSIGNED(7 downto 0); pbo : out UNSIGNED(7 downto 0); pco : out UNSIGNED(7 downto 0)); end component; component PPP_IM generic( A_PORT_ADDR : INTEGER:=1028; B_PORT_ADDR : INTEGER:=1029; C_PORT_ADDR : INTEGER:=1030; CONT_REG_ADDR : INTEGER:=1031); port( clk : in STD_LOGIC; rst : in STD_LOGIC; di : out UNSIGNED(7 downto 0); do : in UNSIGNED(7 downto 0); ib_rst: out STD_LOGIC; ib_wr : out STD_LOGIC; ib_rd : out STD_LOGIC; cs : out STD_LOGIC; a0 : out STD_LOGIC; a1 : out 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 ); end component; -- -- component configurations -- for all : PPP_IN use entity WORK.PPP_IN(BHV_PPP_IN); for all : PPP_IM use entity WORK.PPP_IM(BHV_PPP_IM); -- -- signals -- signal di, do : UNSIGNED(7 downto 0); signal a1, a0, cs : STD_LOGIC; signal ib_wr, ib_rd, ib_rst, den: STD_LOGIC; begin -- -- component instantiations -- U1 : PPP_IN port map( clk, di, do, den, cs, a0, a1, ib_wr, ib_rd, ib_rst, paen, pben, pcen, pai, pbi, pci, pao, pbo, pco); U2 : PPP_IM generic map( A_PORT_ADDR, B_PORT_ADDR, C_PORT_ADDR, CONT_REG_ADDR) port map( clk, rst, di, do, ib_rst, ib_wr, ib_rd, cs, a0, a1, pdata, paddr, ior, iow, ale, iochrdy); end STR_PPP; --*************************************************************************-- configuration CFG_PPP of PPP is for STR_PPP end for; end CFG_PPP; -- end of file --