Revision 1096
Added by markw about 5 years ago
common/a8core/pia.vhdl | ||
---|---|---|
END pia;
|
||
|
||
ARCHITECTURE vhdl OF pia IS
|
||
component synchronizer IS
|
||
PORT
|
||
(
|
||
CLK : IN STD_LOGIC;
|
||
RAW : IN STD_LOGIC;
|
||
SYNC : OUT STD_LOGIC
|
||
);
|
||
END component;
|
||
|
||
COMPONENT complete_address_decoder IS
|
||
generic (width : natural := 1);
|
||
PORT
|
||
... | ... | |
signal cb2_edge_reg : std_logic;
|
||
|
||
begin
|
||
ca1_synchronizer : synchronizer
|
||
port map (clk=>clk, raw=>CA1, sync=>CA1_SYNC);
|
||
ca2_synchronizer : synchronizer
|
||
port map (clk=>clk, raw=>CA2_IN, sync=>CA2_IN_SYNC);
|
||
cb1_synchronizer : synchronizer
|
||
port map (clk=>clk, raw=>CB1, sync=>CB1_SYNC);
|
||
cb2_synchronizer : synchronizer
|
||
port map (clk=>clk, raw=>CB2_IN, sync=>CB2_IN_SYNC);
|
||
|
||
-- register
|
||
process(clk,reset_n)
|
||
begin
|
||
... | ... | |
irqa_reg <= irqa_next;
|
||
irqb_reg <= irqb_next;
|
||
|
||
CA1_reg <= CA1;
|
||
CA2_reg <= CA2_in;
|
||
CB1_reg <= CB1;
|
||
CB2_reg <= CB2_in;
|
||
CA1_reg <= CA1_SYNC;
|
||
CA2_reg <= CA2_in_SYNC;
|
||
CB1_reg <= CB1_SYNC;
|
||
CB2_reg <= CB2_in_SYNC;
|
||
|
||
CA2_output_reg <= CA2_output_next;
|
||
CB2_output_reg <= CB2_output_next;
|
||
... | ... | |
|
||
-- irq handing
|
||
-- TODO REVIEW, this stuff is complicated! I think Atari does not need it anyway...
|
||
process (irqa_reg, porta_control_next, porta_control_reg, read_ora, write_ora, ca2_output_reg, CA1, CA1_reg, ca2_in, ca2_reg, ca1_edge_reg, ca2_edge_reg)
|
||
process (irqa_reg, porta_control_next, porta_control_reg, read_ora, write_ora, ca2_output_reg, CA1_SYNC, CA1_reg, ca2_in_SYNC, ca2_reg, ca1_edge_reg, ca2_edge_reg)
|
||
begin
|
||
irqa_next(1) <= irqa_reg(1) and not(read_ora);
|
||
irqa_next(0) <= irqa_reg(0) and not(read_ora);
|
||
|
||
ca2_output_next <= ca2_output_reg;
|
||
|
||
if (CA1 = '1' and CA1_reg = '0') then
|
||
if (CA1_SYNC = '1' and CA1_reg = '0') then
|
||
irqa_next(1) <= ca1_edge_reg;
|
||
end if;
|
||
if (CA1 = '0' and CA1_reg = '1') then
|
||
if (CA1_SYNC = '0' and CA1_reg = '1') then
|
||
irqa_next(1) <= not(ca1_edge_reg);
|
||
end if;
|
||
|
||
if (CA2_in = '1' and CA2_reg = '0') then
|
||
if (CA2_in_SYNC = '1' and CA2_reg = '0') then
|
||
irqa_next(0) <= ca2_edge_reg;
|
||
end if;
|
||
|
||
if (CA2_in = '0' and CA2_reg = '1') then
|
||
if (CA2_in_SYNC = '0' and CA2_reg = '1') then
|
||
irqa_next(0) <= not(ca2_edge_reg);
|
||
end if;
|
||
|
||
... | ... | |
|
||
end process;
|
||
|
||
process (irqb_reg, portb_control_next, portb_control_reg, read_orb, write_orb, cb2_output_reg, CB1, CB1_reg, cb2_in, cb2_reg, cb1_edge_reg, cb2_edge_reg)
|
||
process (irqb_reg, portb_control_next, portb_control_reg, read_orb, write_orb, cb2_output_reg, CB1_SYNC, CB1_reg, cb2_in_SYNC, cb2_reg, cb1_edge_reg, cb2_edge_reg)
|
||
begin
|
||
irqb_next(1) <= irqb_reg(1) and not(read_orb);
|
||
irqb_next(0) <= irqb_reg(0) and not(read_orb);
|
||
|
||
cb2_output_next <= cb2_output_reg;
|
||
|
||
if (CB1 = '1' and CB1_reg = '0') then
|
||
if (CB1_SYNC = '1' and CB1_reg = '0') then
|
||
irqb_next(1) <= cb1_edge_reg;
|
||
end if;
|
||
if (CB1 = '0' and CB1_reg = '1') then
|
||
if (CB1_SYNC = '0' and CB1_reg = '1') then
|
||
irqb_next(1) <= not(cb1_edge_reg);
|
||
end if;
|
||
|
||
if (CB2_in = '1' and CB2_reg = '0') then
|
||
if (CB2_in_SYNC = '1' and CB2_reg = '0') then
|
||
irqb_next(0) <= cb2_edge_reg;
|
||
end if;
|
||
|
||
if (CB2_in = '0' and CB2_reg = '1') then
|
||
if (CB2_in_SYNC = '0' and CB2_reg = '1') then
|
||
irqb_next(0) <= not(cb2_edge_reg);
|
||
end if;
|
||
|
Also available in: Unified diff
Added sychronizer to pia