OpenCores
URL https://opencores.org/ocsvn/ic6821/ic6821/trunk

Subversion Repositories ic6821

[/] [ic6821/] [web_uploads/] [VHDL6821.vhd] - Rev 6

Compare with Previous | Blame | View Log

Library ieee;
use ieee.std_logic_1164.all;
 
 
ENTITY IC6821 IS
--	GENERIC	();
	PORT
	(
		r_w: in std_logic;
		e: in std_logic;
--		dbg: out std_logic_vector(7 downto 0);
 
		cs0: in std_logic;
		cs1: in std_logic;
		cs2: in std_logic;  -- active low
		reset: in std_logic;  -- active low
		RS0: in std_logic;
		RS1: in std_logic;
		CA1: in std_logic;
		CA2: inout std_logic;
		CB1: in std_logic;
		CB2: inout std_logic;
		DB: inout std_logic_vector(7 downto 0);
		PA: inout std_logic_vector(7 downto 0);		
		PB: inout std_logic_vector(7 downto 0);		
		irqa: out std_logic;  -- active low
		irqb: out std_logic   -- active low
	);
END IC6821;
 
-------------------------------------------------
-------------------------------------------------
 
ARCHITECTURE bhv1 OF IC6821 IS
------------------------
COMPONENT DFF
   PORT (d   : IN STD_LOGIC;
        clk  : IN STD_LOGIC;
        clrn : IN STD_LOGIC;
        prn  : IN STD_LOGIC;
        q    : OUT STD_LOGIC );
END COMPONENT;
COMPONENT LATCH
   PORT (d  : IN STD_LOGIC;
      ena: IN STD_LOGIC;
      q  : OUT STD_LOGIC);
END COMPONENT;
COMPONENT TFF
   PORT (t   : IN STD_LOGIC;
      clk : IN STD_LOGIC;
      clrn: IN STD_LOGIC;
      prn : IN STD_LOGIC;
      q   : OUT STD_LOGIC);
END COMPONENT;
 
 
-----------------------
	SIGNAL bufPA,DDRAbits,CRA : STD_LOGIC_VECTOR(7 downto 0);
	SIGNAL bufPB,DDRBbits,CRB : STD_LOGIC_VECTOR(7 downto 0);
	SIGNAL CRA2, CRB2, iCS: STD_LOGIC;
	SIGNAL irqaf1_1, irqaf1_2, irqaf2_1, irqaf2_2,
		   irqbf1_1, irqbf1_2, irqbf2_1, irqbf2_2,
		   prev_readA, mpu_readA,
		   prev_writeB, mpu_readB: STD_LOGIC;
	SIGNAL disbla1, disbla2: std_logic;
	SIGNAL disblb1, disblb2: std_logic;
 
	SIGNAL edly: std_logic_vector(7 downto 0);
 
	SIGNAL DB_PA,DB_DDRA,DB_CRA, DB_PB,DB_DDRB,DB_CRB: std_logic_vector(7 downto 0);
BEGIN
  iCS<= CS0 and CS1 and (not CS2);
---------  peripheral register A
bufPAprcs:
PROCESS (E, RS0, RS1, CRA2, CRB2, DDRAbits,reset,iCS, DB, PA,r_w)
BEGIN
	if reset='0' then bufPA<=(others=>'0');
	elsif RS0='0' and RS1='0' and CRA2='1' and r_w='0' and iCS='1' then
	FOR i IN 0 to 7 LOOP
     if DDRAbits(i)='1' then   --- the pin acts like an output
		if e'event and	e='0' then	bufPA(i)<=DB(i); end if;
     elsif DDRAbits(i)='0' then   --- the pin acts like an input
		if e'event and	e='0' then	bufPA(i)<=bufPA(i); end if;
	 end if;
	END LOOP;
 
	elsif RS0='0' and RS1='0' and CRA2='1' and r_w='1' and iCS='1' then
	FOR i IN 0 to 7 LOOP
     if DDRAbits(i)='1' then   --- the pin acts like an output
		if e'event and	e='1' then	DB_PA(i)<=bufPA(i);  end if;
     elsif DDRAbits(i)='0' then   --- the pin acts like an input
		if e'event and	e='1' then	bufPA(i)<=PA(i); DB_PA(i)<=PA(i); end if;
	 end if;
	END LOOP;
	end if;
END PROCESS;
 
PAprcs:
PROCESS (DDRAbits, bufPA)
BEGIN
	 FOR i IN 0 to 7 LOOP
      if DDRAbits(i)='1' then   --- the pin acts like an output
		PA(i)<=bufPA(i);
	  else	PA(i)<='Z';  end if;
	END LOOP;
END PROCESS;
 
DDRAprcs:
PROCESS (E, RS0, RS1, CRA2, reset,iCS,r_w)
BEGIN
	if reset='0' then DDRAbits<=(others=>'0');
	elsif RS0='0' and RS1='0' and CRA2='0' and r_w ='0' and iCS='1' then
		if e'event and	e='0' then	DDRAbits<=DB; end if;
	elsif RS0='0' and RS1='0' and CRA2='0' and r_w ='1' and iCS='1' then
		if e'event and	e='1' then	DB_DDRA<=DDRAbits; end if;
	end if;
END PROCESS;
 
CRAprcs:
PROCESS (E, RS0, RS1, reset,iCS,CRA,r_w)
BEGIN
	if reset='0' then CRA(5 downto 0)<=(others=>'0');
	elsif RS0='1' and RS1='0' and r_w='0' and iCS='1' then
		if e'event and	e='0' then	CRA(5 downto 0)<=DB(5 downto 0);	end if;
	elsif RS0='1' and RS1='0' and r_w='1' and iCS='1' then
		if e'event and	e='1' then	DB_CRA(5 downto 0)<=CRA(5 downto 0);	end if;
	end if;	
	CRA2<=CRA(2);
END PROCESS;
---------  peripheral register B
bufPBprcs:
PROCESS (E, RS0, RS1, CRA2, CRB2, DDRBbits,reset,iCS, DB, PB,r_w)
BEGIN
	if reset='0' then bufPB<=(others=>'0');
	elsif RS0='0' and RS1='1' and CRB2='1' and r_w='0' and iCS='1' then
	FOR i IN 0 to 7 LOOP
     if DDRBbits(i)='1' then   --- the pin acts like an output
		if e'event and	e='0' then	bufPB(i)<=DB(i); end if;
     elsif DDRBbits(i)='0' then   --- the pin acts like an input
		if e'event and	e='0' then	bufPB(i)<=bufPB(i); end if;
	 end if;
	END LOOP;
 
	elsif RS0='0' and RS1='1' and CRB2='1' and r_w='1' and iCS='1' then
	FOR i IN 0 to 7 LOOP
     if DDRBbits(i)='1' then   --- the pin acts like an output
		if e'event and	e='1' then	DB_PB(i)<=bufPB(i); end if;
     elsif DDRBbits(i)='0' then   --- the pin acts like an input
		if e'event and	e='1' then	bufPB(i)<=PB(i); DB_PB(i)<=PB(i); end if;
	 end if;
	END LOOP;
	end if;
END PROCESS;
 
PBprcs:
PROCESS (DDRBbits, bufPB)
BEGIN
	 FOR i IN 0 to 7 LOOP
      if DDRBbits(i)='1' then   --- the pin acts like an output
		PB(i)<=bufPB(i);
	  else	PB(i)<='Z';  end if;
	END LOOP;
END PROCESS;
 
DDRBprcs:
PROCESS (E, RS0, RS1, CRA2, CRB2,reset,iCS,r_w)
BEGIN
	if reset='0' then DDRBbits<=(others=>'0');
	elsif RS0='0' and RS1='1' and CRB2='0' and r_w ='0' and iCS='1' then
		if e'event and	e='0' then	DDRBbits<=DB; end if;
	elsif RS0='0' and RS1='1' and CRB2='0' and r_w ='1' and iCS='1' then
		if e'event and	e='1' then	DB_DDRB<=DDRBbits; end if;
	end if;
 
END PROCESS;
 
CRBprcs:
PROCESS (E, RS0, RS1, reset,iCS,CRB,r_w)
BEGIN
	if reset='0' then CRB(5 downto 0)<=(others=>'0');
	elsif RS0='1' and RS1='1' and r_w='0' and iCS='1' then
		if e'event and	e='0' then	CRB(5 downto 0)<=DB(5 downto 0);	end if;
	elsif RS0='1' and RS1='1' and r_w='1' and iCS='1' then
		if e'event and	e='1' then	DB_CRB(5 downto 0)<=CRB(5 downto 0);	end if;
	end if;	
	CRB2<=CRB(2);
END PROCESS;
 
-------------------------------------------------------
-------------  spooling with the data bus
dbspoller:
PROCESS (RS0, RS1, CRA2, CRB2, r_w, iCS, 
		 DB_PA, DB_DDRA, DB_CRA,
		 DB_PB, DB_DDRB, DB_CRB)
BEGIN
	if RS0='0' and RS1='0' and CRA2='1' and r_w='1' and iCS='1' then
		DB<=DB_PA;
	elsif RS0='0' and RS1='0' and CRA2='0' and r_w ='1' and iCS='1' then
		DB<=DB_DDRA;
	elsif RS0='1' and RS1='0' and r_w='1' and iCS='1' then
		DB<=DB_CRA;		
	elsif RS0='0' and RS1='1' and CRB2='1' and r_w='1' and iCS='1' then
		DB<=DB_PB;	
	elsif RS0='0' and RS1='1' and CRB2='0' and r_w ='1' and iCS='1' then
		DB<=DB_DDRB;
	elsif RS0='1' and RS1='1' and r_w='1' and iCS='1' then
		DB<=DB_CRB;
	ELSE
		DB<=(OTHERS=>'Z');
	END IF;
END PROCESS;
 
----------------------------------------------------
----------  captures interrupts
	  mpu_readA<=(not RS0) and (not RS1) and CRA2 and r_w and iCS;
	  mpu_readB<=(not RS0) and RS1 and CRB2 and r_w and iCS;
 
prvsread:  -- this is the last read
PROCESS (E, RS0, RS1, reset, r_w, iCS,CRA,CRB)
BEGIN
	if reset='0' then prev_readA<='0';
	elsif e'event and e='1' then
		if RS0='0' and RS1='0' and CRA2='1' and r_w='1' and iCS='1' then
			prev_readA<='1';
		else prev_readA<='0';
		end if;
	end if;
 
	if reset='0' then prev_writeB<='0';
	elsif e'event and e='0' then
		if RS0='0' and RS1='1' and CRB2='1' and r_w='0' and iCS='1' then
			prev_writeB<='1';
		else prev_writeB<='0';
		end if;
	end if;
END PROCESS;
 
 
intrptsA:
PROCESS (E, RS0, RS1, reset, r_w, CRA,CRB,mpu_readA,mpu_readB,
		 prev_readA, prev_writeB,CA1,CB1,CA2,CB2,
		 irqaf1_1,irqaf1_2,irqaf2_1,irqaf2_2,
		 irqbf1_1, irqbf1_2,irqbf2_1,irqbf2_2,
		 iCS,disbla1,disbla2,
		 disblb1,disblb2)
BEGIN
	disbla1<= (not CRA(0));
	disbla2<= (not CRA(5)) and (not CRA(3));
	------------------------------------------
	---- CA1 line
	if (reset='0') or (mpu_readA='1') then irqaf1_1<='0'; irqaf1_2<='0';
	elsif CRA(1)='0' then   -- the latch for the CA1 is from high to low
		if CA1'event and CA1='0' then irqaf1_1<='1'; end if;
	elsif CRA(1)='1' then   -- the latch for the CA1 is from low to high
		if CA1'event and CA1='1' then irqaf1_2<='1'; end if;
	end if;
	CRA(7)<=irqaf1_1 or irqaf1_2; -- flag bit
	if (disbla1='1') and CRA(7)='1' then irqa<='0';
	elsif (disbla2='1') and CRA(6)='1' then irqa<='0';
	else irqa<='Z'; end if;
	---- CA2 line
	if (reset='0') then 
 
	elsif CRA(5)='1' and CRA(4)='0' and CRA(3)='0' then  -- the CA2 is output
													-- read Strobe with CA1 restore
		if (irqaf1_1='1') or (irqaf1_2='1') then CA2<='1';
		elsif prev_readA='1' then 
			if e'event and e='0' then	CA2<='0';	end if;
		end if;
	elsif CRA(5)='1' and CRA(4)='0' and CRA(3)='1' then  -- the CA2 is output
													-- read Strobe with E restore
		if e'event and e='0' then	
			if prev_readA='1' then  CA2<='0';
			elsif  ics='0' then  CA2<='1'; end if;
		end if;
	elsif CRA(5)='1' and CRA(4)='1' then  -- the CA2 is output
		CA2<=CRA(3);
	else 
		CA2<='Z';	
	end if;
--------------------		
	if (reset='0') or (mpu_readA='1') then irqaf1_1<='0'; irqaf1_2<='0';
	elsif CRA(5)='0' and CRA(4)='0' then   -- the latch for the CA2 is from high to low
		if CA2'event and CA2='0' then irqaf2_1<='1'; end if;
	elsif CRA(5)='0' and CRA(4)='1' then   -- the latch for the CA2 is from low to high
		if CA2'event and CA2='1' then irqaf2_2<='1'; end if;
	end if;
	CRA(6)<=irqaf2_1 or irqaf2_2; -- flag bit
---------------------------------------
---------------------------------------
	disblb1<= (not CRB(0));
	disblb2<= (not CRB(5)) and (not CRB(3));
	---- CB1 line
	if (reset='0') or (mpu_readB='1') then irqbf1_1<='0'; irqbf1_2<='0';
	elsif CRB(1)='0' then   -- the latch for the CB1 is from high to low
		if CB1'event and CB1='0' then irqbf1_1<='1'; end if;
	elsif CRB(1)='1' then   -- the latch for the CB1 is from low to high
		if CB1'event and CB1='1' then irqbf1_2<='1'; end if;
	end if;
	CRB(7)<=irqbf1_1 or irqbf1_2; -- flag bit
	if (disblb1='1') and CRB(7)='1' then irqb<='0';
	elsif (disblb2='1') and CRB(6)='1' then irqb<='0';
	else irqb<='Z'; end if;
	---- CB2 line
	if (reset='0') then 
 
	elsif CRB(5)='1' and CRB(4)='0' and CRB(3)='0' then  -- the CB2 is output
													-- read Strobe with CA1 restore
		if (irqbf1_1='1') or (irqbf1_2='1') then CB2<='1';
		elsif prev_writeB='1' then 
			if e'event and e='1' then CB2<='0';	end if;
		end if;
	elsif CRB(5)='1' and CRB(4)='0' and CRB(3)='1' then  -- the CB2 is output
													-- read Strobe with E restore
		if e'event and e='1' then	
			if prev_writeB='1' then  CB2<='0';
			elsif  ics='0' then  CB2<='1'; end if;
		end if;
	elsif CRB(5)='1' and CRB(4)='1' then  -- the CB2 is output
		CB2<=CRB(3);
	else 
		CB2<='Z';	
	end if;
--------------------		
	if (reset='0') or (mpu_readB='1') then irqbf1_1<='0'; irqbf1_2<='0';
	elsif CRB(5)='0' and CRB(4)='0' then   -- the latch for the CB2 is from high to low
		if CB2'event and CB2='0' then irqbf2_1<='1'; end if;
	elsif CRB(5)='0' and CRB(4)='1' then   -- the latch for the CB2 is from low to high
		if CB2'event and CB2='1' then irqbf2_2<='1'; end if;
	end if;
	CRB(6)<=irqbf2_1 or irqbf2_2; -- flag bit
-------------------		
END PROCESS;
 
END bhv1;
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.