📄 dcbcu.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 + -