⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dcbcu.vhd

📁 X8086的VHDL源码
💻 VHD
字号:
-----------------------------------
--   FILE NAME : DC_BCU.vhd
--   FUNCTION  : DATA Control Unit
--   AUTHOR    : Kazuma Mishima
--   DATE      : 6/2001
------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use WORK.UPAC.all;

entity DCBCU is
	generic( PADRW : integer;
	         OADRW : integer;
	         DATAW : integer;
			 BYTEW : integer
			 );
    port( I_CLK		  :  in std_logic;
		  I_RST       :  in std_logic;
		  I_EUCRST    :  in std_logic;                      --from EUC reset signal
	      I_RD        :  in std_logic;                      --read signal from EU
          I_WR        :  in std_logic;                      --write signal from EU
		  I_BW        :  in std_logic;                      --byte = '0', word = '1'
		  I_FE        :  in std_logic;                      --fetch signal from QUE
		  I_IPF       :  in std_logic;                      --address out flag from AD_ADD(FETCH)
		  I_IRF       :  in std_logic;                      --address out flag from AD_ADD
		  I_IO        :  in std_logic;                      --I/O device access => '1'(READ,WRITE)
		  I_ADROUT    :  in std_logic;
		  I_ENDBC     :  in std_logic;                      --end 1 bus cycle = '1' 
          I_DATA2EU   :  in std_logic_vector(DATAW-1 downto 0);  --data from BCU
		  I_OADR      :  in std_logic_vector(OADRW-1 downto 0);  --immediate address from EUC_CU 
		  I_DATA2MEM  :  in std_logic_vector(DATAW-1 downto 0);  --data from EU
          I_PADR      :  in std_logic_vector(PADRW-1 downto 0);  --address in from add 
          O_RD        : out std_logic;                     --read signal to BCU
          O_WR        : out std_logic;                     --write signal to BCU
		  O_FE        : out std_logic;                     --fetch signal to BCU
          O_ENDRC     : out std_logic;                     --if data out to EU,'1'
		  O_ENDWC     : out std_logic;                     --end write mem => '1'
          O_BHE       : out std_logic;                     --memory access control signal(&A0)
		  O_ODD       : out std_logic;                     --I_ADR(0)='1'(odd) => '1'
		  O_QUEF      : out std_logic;                     --out QUE_IN = '1'
		  O_IO        : out std_logic;                     --memory access => '0' I/O device => '1'
		  O_DCSTATE_V : out std_logic_vector( 3 downto 0);
          O_DATA2EU   : out std_logic_vector(DATAW-1 downto 0); --data out to EU
		  O_DATA2MEM  : out std_logic_vector(DATAW-1 downto 0); --data out to BCU
		  O_DATA2QUE  : out std_logic_vector(DATAW-1 downto 0); --OP code to QUE
          O_PADR      : out std_logic_vector(PADRW-1 downto 0)  --address out to BCU
		  );                     --address from ECU to BCU                           
end DCBCU;

architecture RTL of DCBCU is

type   STATE is (S0,Sr1,Srob,Sreb,Srew,Srow1,Srow2,Sw1,Swow,Sendw,Sf1,Sfeo,Sfee);
signal currentstate : STATE;
signal nextstate    : STATE;
signal adr          : std_logic_vector(PADRW-1 downto 0); --next address ratch signal
signal dt           : std_logic_vector(BYTEW-1 downto 0); --data ratch signal
signal eudt         : std_logic_vector(DATAW-1 downto 0); 
signal adr0         : std_logic; --address(1) ratch signal

begin
--NEXT STATE 

	O_DATA2EU  <= eudt;

	BCU_CURRENT_STATE : 
	process(I_CLK,I_RST,I_EUCRST,nextstate) 
	begin 
		if (I_RST = RST_ACT) then
			currentstate <= S0;
		elsif (I_CLK'event and I_CLK='0') then
			if (I_EUCRST = '1') then
				currentstate <= S0;
			else
				currentstate <= nextstate;
			end if;   
		end if;
	end process;      

	DATA2MEM_O : 
	process(currentstate,I_OADR,I_PADR,I_DATA2MEM)
	begin
		if    (currentstate = Sw1) then
			if(I_OADR(0)='1' or I_PADR(0)='1')then --odd word or odd byte
				O_DATA2MEM <= I_DATA2MEM(7 downto 0) & "00000000";
			else --even word or even byte
				O_DATA2MEM <= I_DATA2MEM(15 downto 0);
			end if;
		elsif (currentstate = Swow) then
			O_DATA2MEM <= "00000000"&I_DATA2MEM(15 downto 8);
		else
			O_DATA2MEM <= (others=>'0');
		end if;
	end process;

	DCIO : 
	process(currentstate,I_IO,I_ADROUT)
	begin
		if    (currentstate = Sr1) then
			if    (I_ADROUT = '0' and I_IO = '1') then --I/O device access
				O_IO  <= '1';
			else
				O_IO  <= '0';
			end if;
		elsif (currentstate = Sw1) then
			if (I_IO = '1') then --I/O device access
				O_IO <= '1';
			else
				O_IO <= '0';
			end if;
		else
			O_IO   <= '0'; --memory access
		end if;
	end process;

	ADR_OUT : 
	process(currentstate,I_IO,I_ADROUT,I_OADR,I_PADR,adr)
	begin
		if    (currentstate = Sr1) then
			if    (I_ADROUT = '0' and I_IO = '1') then --I/O device access
				O_PADR <= "0000"&I_OADR;
			elsif (I_ADROUT = '1' and I_IO = '0') then
				O_PADR <= "0000"&I_OADR;
			else
				O_PADR <= I_PADR;
			end if;
		elsif (currentstate = Srow1 or currentstate = Swow) then
			O_PADR  <= adr;
		elsif (currentstate = Sw1) then
			if (I_IO = '1') then --I/O device access
				O_PADR <= "0000"&I_OADR;
			else
				O_PADR <= I_PADR;
			end if;
		elsif ((currentstate = Sf1 or currentstate = Sfeo )or currentstate = Sfee) then
            O_PADR  <= I_PADR;
		else
			O_PADR  <= (others => '0');
		end if;
	end process;

	process(currentstate,I_DATA2EU)
	begin
		if (currentstate = Sfeo) then
			O_DATA2QUE <= "00000000"&I_DATA2EU(15 downto 8);
		else
			O_DATA2QUE <= I_DATA2EU(15 downto 0);
		end if;
	end process;

--SEQUENCE PART
	process(currentstate)
	begin
		if (currentstate = Srow1 or currentstate = Swow) then 
  			O_BHE <= '1';
		else
  			O_BHE <= '0';
		end if;
	end process;

	process(currentstate)
	begin
		if (currentstate = Sfeo or currentstate = Sfee) then 
  			O_QUEF <= '1';
		else
  			O_QUEF <= '0';
		end if;
	end process;

	process(currentstate)
	begin
		if (currentstate = Sfeo) then 
  			O_ODD <= '1';
		else
  			O_ODD <= '0';
		end if;
	end process;

	process(currentstate)
	begin
		if (currentstate = Sendw) then 
  			O_ENDWC <= '1';
		else
  			O_ENDWC <= '0';
		end if;
	end process;

	process(currentstate)
	begin
		if ((currentstate = Srob or currentstate = Sreb ) or
			(currentstate = Srew or currentstate = Srow2))then
            O_ENDRC <= '1';
		else
            O_ENDRC <= '0';
		end if;
	end process;

	process(currentstate)
	begin
		if (currentstate = Sf1) then 
  			O_FE <= '1';
		else
  			O_FE <= '0';
		end if;
	end process;

	process(currentstate)
	begin
		if (currentstate = Sw1 or currentstate = Swow) then 
  			O_WR <= '1';
		else
  			O_WR <= '0';
		end if;
	end process;

	process(currentstate)
	begin
		if (currentstate = Sr1 or currentstate = Srow1) then 
  			O_RD <= '1';
		else
  			O_RD <= '0';
		end if;
	end process;
		
--FSM

	ADR_ZERObit_REG : 
	process(I_CLK,I_RST,currentstate,I_IO,I_OADR,I_PADR)
	begin
		if (I_RST = RST_ACT) then
			adr0 <= '0';
		elsif (I_CLK'event and I_CLK='0') then
			if    (currentstate = Sr1) then
				if(I_IO = '1')then
			  		adr0 <= I_OADR(0);	
			 	else
					adr0 <= I_PADR(0);
				end if;
			elsif (currentstate = Sf1) then
				adr0 <= I_PADR(0);
			elsif (currentstate = Sw1) then
				adr0 <= I_PADR(0);
			end if;
		end if;
	end process;

	ADR20_REG : 
	process(I_RST,I_CLK,currentstate,I_IO,I_OADR,I_PADR)
	begin
		if (I_RST = RST_ACT) then
			adr <= (others => '0');
		elsif (I_CLK'event and I_CLK='0') then
			if    (currentstate = Sr1) then
				if(I_IO = '1')then
					adr <= ("0000"&I_OADR) + '1'; --address+1 ratch	
		 		else
					adr <= I_PADR + '1'; --address+1 ratch
				end if;
			elsif (currentstate = Sf1 or currentstate = Sw1) then	
				adr <= I_PADR + '1'; --address+1 ratch
			end if;
		end if;
	end process;

	dt_REG : 
	process(I_CLK,I_RST,currentstate,I_ENDBC,I_BW,I_DATA2EU,adr0)
	begin
		if (I_RST = RST_ACT) then
			dt <= (others => '0');
		elsif (I_CLK'event and I_CLK='0') then
			if    (currentstate = Sr1) then
				if(I_ENDBC = '1')then --end read 1 bus cycle
					if   (adr0 = '1' and I_BW = '1')then --odd,word
						dt <= I_DATA2EU(15 downto 8); --15~8bit ratch 
					else --even,word
						dt <= (others => '0');
					end if;
				end if;
			end if;
		end if;
	end process;

	eudt_REG : 
	process(I_RST,I_CLK,currentstate,I_DATA2EU)
	begin
		if    (I_RST = RST_ACT) then
			eudt <= (others => '0');
		elsif (I_CLK'event and I_CLK = '0') then
			case currentstate is
			when Sr1 => --out adress
				eudt <= I_DATA2EU;
			when Srob => --read,odd,byte,end bus cycle 1
				eudt <= "00000000" & I_DATA2EU(15 downto 8);
			when Sreb => --read,even,byte,end bus cycle 1
				eudt <= "00000000" & I_DATA2EU( 7 downto 0);
			when Srew => --read,even,word,end bus cycle 1
				eudt <= I_DATA2EU;
			when Srow1 => --read,odd,word,end bus cycle 1
				eudt <= I_DATA2EU;
			when Srow2 => --read,odd,word,end bus cycle 2
				eudt <= I_DATA2EU( 7 downto 0)&dt; --reshuffule and data out
			when Sw1 => --out adress
				eudt <= I_DATA2EU;
			when Swow => --write,odd,word,end bus cycle 1
				eudt <= I_DATA2EU;
			when Sendw => --end write cycle state
				eudt <= I_DATA2EU;
			when Sf1  => --out adress
				eudt <= I_DATA2EU;
			when Sfeo => --fetch,odd
				eudt <= I_DATA2EU;
			when Sfee => --fetch,even
				eudt <= I_DATA2EU;
			when others => 
				null;
			end case;
		end if;
	end process;

	BCU_NEXTSTATE_OUT : 
	process(currentstate,I_ENDBC,I_IPF,I_IRF,I_RD,I_WR,I_FE,
			I_BW,adr0)
	begin
		case currentstate is
		when S0  => 
			if    (I_RD = '1' and I_WR = '0' and I_IRF = '1' and I_IPF = '0')then --read
				nextstate <= Sr1;
			elsif (I_RD = '0' and I_WR = '1' and I_IRF = '1' and I_IPF = '0')then --write
				nextstate <= Sw1;
			elsif (I_FE = '1'                and I_IRF = '0' and I_IPF = '1')then --fetch
				nextstate <= Sf1;
			else
				nextstate <= S0;
			end if;
		when Sr1  => 
			if(I_ENDBC='1')then --end read 1 bus cycle
				if   (adr0='1' and I_BW='1')then --odd,word
					nextstate <= Srow1;
				elsif(adr0='1' and I_BW='0')then --odd,byte
					nextstate <= Srob;
				elsif(adr0='0' and I_BW='0')then --even,byte
					nextstate <= Sreb;
				else --even,word
					nextstate <= Srew;
				end if;
			else
				nextstate <= Sr1;
			end if;
		when Sf1 => 
			if(I_ENDBC='1')then --end fetch 1 bus cycle
				if(adr0='1')then --odd
					nextstate <= Sfeo;
				else --even
					nextstate <= Sfee;
				end if;
			else
				nextstate <= Sf1;
			end if;
		when Srow1 => 
			if(I_ENDBC='1')then --end read 2 bus cycle
				nextstate <= Srow2;
			else 
				nextstate <= Srow1;
			end if;
		when Sw1 => 
			if(I_ENDBC='1')then --end write 1 bus cycle
				if(adr0='1' and I_BW='1')then --odd,word
					nextstate <= Swow;
				else --odd byte,even byte,even word
					nextstate <= Sendw;
				end if;
			else
				nextstate <= Sw1;
			end if;
		when Swow => 
			if(I_ENDBC='1')then --end write 2 cycle(odd,word)
				nextstate <= Sendw;
			else 
				nextstate <= Swow;
			end if;
		when Srob|Sreb|Srew|Srow2|Sendw|Sfeo|Sfee => 
			nextstate <= S0;                      
		when others => 
			nextstate <= S0;
		end case;
	end process;

	DCSTATE_V : 
	process(currentstate)
	begin
		case currentstate is
		when S0     => O_DCSTATE_V <= "0000";
		when Sr1    => O_DCSTATE_V <= "0001";
		when Srob   => O_DCSTATE_V <= "0010";
		when Sreb   => O_DCSTATE_V <= "0011";
		when Srow1  => O_DCSTATE_V <= "0100";
		when Srow2  => O_DCSTATE_V <= "0101";
		when Srew   => O_DCSTATE_V <= "0110";
		when Sw1    => O_DCSTATE_V <= "0111";
		when Swow   => O_DCSTATE_V <= "1000";
		when Sendw  => O_DCSTATE_V <= "1001";
		when Sf1    => O_DCSTATE_V <= "1010";
		when Sfee   => O_DCSTATE_V <= "1011";
		when Sfeo   => O_DCSTATE_V <= "1100";
		when others => O_DCSTATE_V <= "1111";
		end case;
	end process;

end RTL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -