给定指令系统的处理器设计---【最终版本】
时钟控制模块
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
library UNISIM;
--use UNISIM.VComponents.all;
entity timer is
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
en : out STD_LOGIC_VECTOR (3 downto 0));
end timer;
architecture Behavioral of timer is
signal temp: std_logic_vector(3 downto 0):="0000";
begin
process(clk,rst)
begin
if(rst = '1') then
temp <= "0000";
elsif(clk'event and clk='1') then
case temp is
when "0000" => temp <= "0001";
when "0001" => temp <= "0010";
when "0010" => temp <= "0100";
when "0100" => temp <= "1000";
when "1000" => temp <= "0001";
when others => null;
end case;
end if;
end process;
en <= temp;
end Behavioral;
取指模块
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity fetch is
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
PcUpdate : in STD_LOGIC;
t0,t2 : in STD_LOGIC;
IR_value : in STD_LOGIC_VECTOR (15 downto 0);
PcNew : in STD_LOGIC_VECTOR (15 downto 0);
PC : out STD_LOGIC_VECTOR (15 downto 0);
IR_out : out STD_LOGIC_VECTOR (15 downto 0));
end fetch;
architecture Behavioral of fetch is
---signal PC : std_logic_vector(15 downto 0):="0000000100000010";
signal IR : std_logic_vector(15 downto 0);
signal PC_temp : std_logic_vector(15 downto 0) := "0000000000000000";
begin
process(rst,t0,t2,clk,PcUpdate,IR_value,PcNew)
begin
---初始化信号---
---PcUpdate <= '0';
-------------
if(rst = '1') then
PC_temp <= "0000000000000000";
elsif(t0 = '1') then
IR <= IR_value;
elsif(PcUpdate = '1') then
PC_temp <= PcNew;
elsif(t2 = '1' and clk'event and clk = '1') then
PC_temp <= PC_temp+1;
end if;
end process;
IR_out <= IR;
PC <= PC_temp;
end Behavioral;
运算模块
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
library UNISIM;
use UNISIM.VComponents.all;
entity alu is
Port (
clk : in STD_LOGIC;
t1,t2,t3 : in STD_LOGIC;
rst : in STD_LOGIC;
IR_out : in STD_LOGIC_VECTOR (15 downto 0);
RegUpdate : in STD_LOGIC;
Rdata : in STD_LOGIC_VECTOR (7 downto 0);
Addr : out STD_LOGIC_VECTOR (15 downto 0);
alu_out : out STD_LOGIC_VECTOR (7 downto 0);
Zf_out : out STD_LOGIC;
Cy_out : out STD_LOGIC;
PC : in STD_LOGIC_VECTOR(15 downto 0));
end alu;
architecture Behavioral of alu is
signal Reg_A,Reg_B,temp_aluout : std_logic_vector(7 downto 0);
signal addrTemp: std_logic_vector(15 downto 0);
signal Cy : std_logic ;
signal Zf : std_logic ;
---signal isChange: std_logic;
signal cal : std_logic_vector(8 downto 0);
TYPE reg_arr is ARRAY(0 to 7) of std_logic_vector(7 downto 0);
signal Reg : reg_arr;
begin
Reg_A <= Reg(conv_integer(IR_out(10 downto 8)));
Reg_B <= Reg(conv_integer(IR_out(2 downto 0)));
process(clk,t1,t3,RegUpdate,IR_out)
begin
if(rst = '1') then
Zf <= '0';
--Cy <= '0'; 此处不知为何会错
---isChange <= '0';
Reg(1) <= "00000010";
Reg(2) <= "00000100";
Reg(3) <= "00001000";
Reg(5) <= "10100000";
Reg(6) <= "00000001";
Reg(7) <= "00000000";
cal <= "000000000";
--temp_aluout <= "ZZZZZZZZ";
--addrTemp <= "ZZZZZZZZZZZZZZZZ";
elsif(t1 = '1') then
case IR_out(15 downto 11) is
when "00001" =>
temp_aluout <= Reg_B;
when "00010" =>
temp_aluout <= IR_out(7 downto 0);
when "00011" =>
addrTemp <= Reg(7)&IR_out(7 downto 0);
when "00100" =>
addrTemp <= Reg(7)&IR_out(10 downto 3);
temp_aluout <= Reg_B;
when "11100" =>
addrTemp <= ("00000000"&Reg(6))+IR_out(7 downto 0);
when "01001" =>
addrTemp <= Reg(7)&Reg_B;
when "00110" =>
cal <= ('0' & Reg_A) + ('0' & Reg_B) + ("00000000"&Cy);
temp_aluout <= cal(7 downto 0);
if(temp_aluout = "00000000") then
Zf <= '1';
else
Zf <= '0';
end if;
when "01000" =>
cal <= ('0' & Reg_A) + ('0' & IR_out(7 downto 0)) + Cy;
temp_aluout <= cal(7 downto 0);
if(temp_aluout = "00000000") then
Zf <= '1';
else
Zf <= '0';
end if;
when "01010" =>
cal <= ('0' & Reg_A) - ('0' & Reg_B) - ("00000000"&Cy);
temp_aluout <= cal(7 downto 0);
if(temp_aluout = "00000000") then
Zf <= '1';
else
Zf <= '0';
end if;
when "01100" =>
cal <= ('0' & Reg_A) - ('0' & IR_out(7 downto 0))- ("00000000"&Cy);
temp_aluout <= cal(7 downto 0);
if(temp_aluout = "00000000") then
Zf <= '1';
else
Zf <= '0';
end if;
when "01110" =>
temp_aluout <= Reg_A AND Reg_B;
if(temp_aluout = "00000000") then
Zf <= '1';
else
Zf <= '0';
end if;
when "10000" =>
temp_aluout <= Reg_A AND IR_out(7 downto 0);
if(temp_aluout = "00000000") then
Zf <= '1';
else
Zf <= '0';
end if;
when "10110" =>
addrTemp <= Reg(7)&IR_out(7 downto 0);
when "11000" =>
addrTemp <= "00000000" & (PC(7 downto 0) + IR_out(7 downto 0) +1);
when "10010" =>
temp_aluout <= Reg_A OR Reg_B;
if(temp_aluout = "00000000") then
Zf <= '1';
else
Zf <= '0';
end if;
when "10100" =>
temp_aluout <= Reg_A OR IR_out(7 downto 0);
if(temp_aluout = "00000000") then
Zf <= '1';
else
Zf <= '0';
end if;
when "11010" =>
addrTemp <= "00000000" & (PC(7 downto 0) + IR_out(7 downto 0) +1);
when "11110" =>
Cy <= '0';
when "11111" =>
Cy <= '1';
when others => temp_aluout <= Reg_A;
end case;
elsif (t3 = '1') then
if(IR_out(15 downto 11) = "00110" or IR_out(15 downto 11)="01000" or IR_out(15 downto 11)="01010" or IR_out(15 downto 11)="01100") then
Cy <= cal(8);
end if;
if(RegUpdate = '1' and clk'event and clk = '0') then
if(IR_out(15 downto 11) = "00100") then
Reg(conv_integer(IR_out(2 downto 0))) <= Rdata;
else
Reg(conv_integer(IR_out(10 downto 8))) <= Rdata;
end if;
end if;
end if;
end process;
alu_out <= temp_aluout;
Addr <= addrTemp;
---Cy_out <= Cy;
Zf_out <= Zf;
process(Cy)
begin
Cy_out <= Cy;
end process;
end Behavioral;
存储管理模块library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity mem is
Port ( WR : out STD_LOGIC;
RD : out STD_LOGIC;
t2 : in STD_LOGIC;
rst : in STD_LOGIC;
mDBUS : in std_logic_vector(7 downto 0); ---内存中取得的数据
IR_out : in STD_LOGIC_VECTOR (15 downto 0);
Rtemp : out STD_LOGIC_VECTOR (7 downto 0));
end mem;
architecture Behavioral of mem is
signal temp: std_logic_vector(7 downto 0);
begin
process(rst,t2,IR_out)
begin
---初始化访存信号---
WR <= '0';
RD <= '0';
----------------
if(rst = '1') then
temp <= "ZZZZZZZZ";
else
if(t2 = '1') then
case IR_out(15 downto 11) is
when "00011" => ---mov Ri,X(addr)
RD <= '1';
temp <= mDBUS;
when "00100" => ---mov X(addr),Ri;
WR <= '1';
when "11100" => ---mov Ri,X变址
RD <= '1';
temp <= mDBUS;
when "01001" => ---mov Ri,[Rj]
RD <= '1';
temp <= mDBUS;
when others => null;
end case;
end if;
end if;
end process;
Rtemp <= temp;
end Behavioral;
回写模块
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity back is
Port ( t3 : in STD_LOGIC;
rst : in STD_LOGIC;
Rtemp : in STD_LOGIC_VECTOR (7 downto 0);
IR_out : in STD_LOGIC_VECTOR (15 downto 0);
alu_out : in STD_LOGIC_VECTOR (7 downto 0);
Addr : in STD_LOGIC_VECTOR (15 downto 0);
RegUpdate : out STD_LOGIC;
Rdata : out STD_LOGIC_VECTOR (7 downto 0);
PcNew : out STD_LOGIC_VECTOR(15 downto 0);
PcUpdate : out STD_LOGIC;
Zf_out : in STD_LOGIC;
Cy_out : in STD_LOGIC);
end back;
architecture Behavioral of back is
begin
process(rst,t3,IR_out,Rtemp,Addr)
begin
---初始化更新信号---
Rdata <= "ZZZZZZZZ";
RegUpdate <= '0';
PcUpdate <= '0';
PcNew <= "0000000000000000";
----------------
if(rst = '1') then
Rdata <= "ZZZZZZZZ";
RegUpdate <= '0';
PcNew <= "0000000000000000";
PcUpdate <= '0';
else
if(t3 = '1') then
case IR_out(15 downto 11) is
when "00010" => --立即数
RegUpdate <= '1';
Rdata <= alu_out;
when "00001" =>
RegUpdate <= '1';
Rdata <= alu_out;
when "00011" => ---mov Ri,X直接寻址
RegUpdate <= '1';
Rdata <= Rtemp;
when "11100" => ---mov Ri,X变址寻址
RegUpdate <= '1';
Rdata <= Rtemp;
when "01001" => ---mov Ri,[Rj]
RegUpdate <= '1';
Rdata <= Rtemp;
when "00110" =>
RegUpdate <= '1';
Rdata <= alu_out;
when "01000" =>
RegUpdate <= '1';
Rdata <= alu_out;
when "01010" =>
RegUpdate <= '1';
Rdata <= alu_out;
when "01100" =>
RegUpdate <= '1';
Rdata <= alu_out;
when "01110" =>
RegUpdate <= '1';
Rdata <= alu_out;
when "10000" =>
RegUpdate <= '1';
Rdata <= alu_out;
when "10010" =>
RegUpdate <= '1';
Rdata <= alu_out;
when "10100" =>
RegUpdate <= '1';
Rdata <= alu_out;
when "11000" => ---JZ X
if(Zf_out = '1') then
PcUpdate <= '1';
PcNew <= Addr;
else
PcUpdate <= '0';
end if;
when "11010" => ---JC X
---if(Reg(5) = "00000001")
if(Cy_out = '1') then
PcUpdate <= '1';
PcNew <= Addr;
else
PcUpdate <= '0';
end if;
---end if;
when "10110" => ---JMP
PcUpdate <= '1';
PcNew <= Addr;
when others => null;
end case;
end if;
end if;
end process;
end Behavioral;
访存控制模块
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity ctrl is
Port ( t0,t1,t2,t3 : in STD_LOGIC;
PC : in STD_LOGIC_VECTOR(15 downto 0);
Addr : in STD_LOGIC_VECTOR (15 downto 0);
WR : in STD_LOGIC;
RD : in STD_LOGIC;
alu_out : in STD_LOGIC_VECTOR (7 downto 0);
IR_out : in STD_LOGIC_VECTOR (15 downto 0);
mDBUS : out STD_LOGIC_VECTOR (7 downto 0);
ABUS : out STD_LOGIC_VECTOR (15 downto 0);
DBUS : inout STD_LOGIC_VECTOR (15 downto 0);
nRD : out STD_LOGIC;
nWR : out STD_LOGIC;
nBHE : out STD_LOGIC;
nBLE : out STD_LOGIC;
IR_value : out STD_LOGIC_VECTOR(15 downto 0);
nMREQ : out STD_LOGIC);
end ctrl;
architecture Behavioral of ctrl is
begin
process(PC,t0,t1,t2,t3,WR,RD,DBUS)
begin
---初始化内存读取控制信号---
nRD <= '1';
nWR <= '1';
nBHE <= '1';
nBLE <= '1';
nMREQ <= '1';
DBUS <= "ZZZZZZZZZZZZZZZZ";
---
if(t0 = '1') then
nMREQ <= '0';
nBHE <= '0';
nBLE <= '0';
nRD <= '0'; ----取数
ABUS <= PC;
IR_value <= DBUS;
---ABUS <= "ZZZZZZZZZZZZZZZZ";
elsif (WR = '1') then ---mov X,Ri
ABUS <= Addr;
nMREQ <= '0';
nBLE <= '0';
nBHE <= '0';
nWR <= '0';
DBUS(15 downto 8) <= "00000000";
DBUS(7 downto 0) <= alu_out;
elsif(RD = '1') then--mov Ri,[X] || mov Ri,X || mov Ri,[Rj]
ABUS <= Addr;
nMREQ <= '0';
nBLE <= '0';
nRD <= '0';
mDBUS <= DBUS(7 downto 0);
DBUS(7 downto 0) <= "ZZZZZZZZ";
else
null;
end if;
end process;
end Behavioral;
总模块
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity cpu is
Port ( rst : in STD_LOGIC;
clk : in STD_LOGIC;
abus : out STD_LOGIC_VECTOR (15 downto 0);
dbus : inout STD_LOGIC_VECTOR (15 downto 0);
nmreq : out STD_LOGIC;
nrd : out STD_LOGIC;
nwr : out STD_LOGIC;
nble : out STD_LOGIC;
nbhe : out STD_LOGIC;
b : out STD_LOGIC_VECTOR (7 downto 0);
a : out STD_LOGIC_VECTOR (7 downto 0);
s0 : out STD_LOGIC_VECTOR (7 downto 0);
s1 : out STD_LOGIC_VECTOR (7 downto 0);
s2 : out STD_LOGIC_VECTOR (7 downto 0);
s3 : out STD_LOGIC_VECTOR (7 downto 0);
s4 : out STD_LOGIC_VECTOR (7 downto 0);
s5 : out STD_LOGIC_VECTOR (7 downto 0));
end cpu;
architecture Behavioral of cpu is
---全局时钟---
--component bufgp is
--port(i : in std_logic;
-- o : out std_logic);
--end component;
---时钟控制模块---
component timer is
port (clk : in std_logic;
rst : in std_logic;
en : out std_logic_vector(3 downto 0));
end component;
---取值模块---
component fetch is
port (clk : in STD_LOGIC;
rst : in STD_LOGIC;
PcUpdate : in STD_LOGIC;
t0,t2 : in STD_LOGIC;
IR_value : in STD_LOGIC_VECTOR (15 downto 0);
PcNew : in STD_LOGIC_VECTOR (15 downto 0);
PC : out STD_LOGIC_VECTOR (15 downto 0);
IR_out : out STD_LOGIC_VECTOR (15 downto 0));
end component;
---计算模块---
component alu is
port (
clk : in STD_LOGIC;
---Cy : in STD_LOGIC;---R(5)存放Cy
t1,t2,t3 : in STD_LOGIC;
rst : in STD_LOGIC;
IR_out : in STD_LOGIC_VECTOR (15 downto 0);
RegUpdate : in STD_LOGIC;
Rdata : in STD_LOGIC_VECTOR (7 downto 0);
---Raddr : in STD_LOGIC_VECTOR (2 downto 0);
Addr : out STD_LOGIC_VECTOR (15 downto 0);
---PC_out : out STD_LOGIC_VECTOR (15 downto 0);
alu_out : out STD_LOGIC_VECTOR (7 downto 0);
Zf_out : out STD_LOGIC;
Cy_out : out STD_LOGIC;
PC : in STD_LOGIC_VECTOR(15 downto 0));
end component;
---访存模块---
component mem is
port ( WR : out STD_LOGIC;
RD : out STD_LOGIC;
t2 : in STD_LOGIC;
rst : in STD_LOGIC;
mDBUS : in std_logic_vector(7 downto 0); ---内存中取得的数据
IR_out : in STD_LOGIC_VECTOR (15 downto 0);
Rtemp : out STD_LOGIC_VECTOR (7 downto 0));
end component;
---回写模块---
component back is
port (t3 : in STD_LOGIC;
rst : in STD_LOGIC;
Rtemp : in STD_LOGIC_VECTOR (7 downto 0);
IR_out : in STD_LOGIC_VECTOR (15 downto 0);
alu_out : in STD_LOGIC_VECTOR (7 downto 0);
Addr : in STD_LOGIC_VECTOR (15 downto 0);
RegUpdate : out STD_LOGIC;
Rdata : out STD_LOGIC_VECTOR (7 downto 0);
PcNew : out STD_LOGIC_VECTOR(15 downto 0);
PcUpdate : out STD_LOGIC;
Zf_out : in STD_LOGIC;
Cy_out : in STD_LOGIC);
end component;
---访存控制模块---
component ctrl is
port (t0,t1,t2,t3 : in STD_LOGIC;
PC : in STD_LOGIC_VECTOR(15 downto 0);
Addr : in STD_LOGIC_VECTOR (15 downto 0);
WR : in STD_LOGIC;
RD : in STD_LOGIC;
alu_out : in STD_LOGIC_VECTOR (7 downto 0);
IR_out : in STD_LOGIC_VECTOR (15 downto 0);
mDBUS : out STD_LOGIC_VECTOR (7 downto 0);
ABUS : out STD_LOGIC_VECTOR (15 downto 0);
DBUS : inout STD_LOGIC_VECTOR (15 downto 0);
nRD : out STD_LOGIC;
nWR : out STD_LOGIC;
nBHE : out STD_LOGIC;
nBLE : out STD_LOGIC;
IR_value : out STD_LOGIC_VECTOR(15 downto 0);
nMREQ : out STD_LOGIC);
end component;
----信号
signal m_abus : std_logic_vector(15 downto 0);
signal m_nmreq : std_logic;
signal m_nrd : std_logic;
signal m_nwr : std_logic;
signal m_nble : std_logic;
signal m_nbhe : std_logic;
---
--signal clkgp : std_logic;
signal beat : std_logic_vector(3 downto 0);
signal PcUpdate : std_logic;
signal PcNew : std_logic_vector(15 downto 0);
signal IR_value : std_logic_vector(15 downto 0);
signal PC : std_logic_vector(15 downto 0);
signal IR_out : std_logic_vector(15 downto 0);
signal alu_out : std_logic_vector(7 downto 0);
signal Addr : std_logic_vector(15 downto 0);
signal RegUpdate : std_logic;
signal Rdata : std_logic_vector(7 downto 0);
signal Rtemp : std_logic_vector(7 downto 0);
signal mDBUS : std_logic_vector(7 downto 0);
signal WR : std_logic;
signal RD : std_logic;
signal Zf_out : std_logic;
signal Cy_out : std_logic;
begin
--U0 : bufgp port map (
-- i => clk,
-- o => clkgp
--);
U1 : timer port map (clk,rst,beat);
U2 : fetch port map (clk,rst,PcUpdate,beat(0),beat(2),IR_value,PcNew,PC,IR_out);
U3 : alu port map (clk,beat(1),beat(2),beat(3),rst,IR_out,RegUpdate,Rdata,Addr,alu_out,Zf_out,Cy_out,PC);
U4 : mem port map (WR,RD,beat(2),rst,mDBUS,IR_out,Rtemp);
U5 : back port map (
t3 => beat(3),
rst =>rst,
Rtemp =>Rtemp,
IR_out =>IR_out,
alu_out =>alu_out,
Addr =>Addr,
RegUpdate =>RegUpdate,
Rdata =>Rdata,
PcNew => PcNew,
PcUpdate => PcUpdate,
Zf_out => Zf_out,
Cy_out => Cy_out
);
U6 : ctrl port map (beat(0),beat(1),beat(2),beat(3),PC,Addr,WR,RD,alu_out,IR_out,mDBUS,m_abus,DBUS,m_nrd,m_nwr,m_nbhe,m_nble,IR_value,m_nmreq);
---IR数据s1,s0---
s0 <= IR_out(7 downto 0); --IR低位
s1 <= IR_out(15 downto 8); --IR高位
--数据总线s3,s2--
s2 <= DBUS(7 downto 0); ---s2对应数据总线低位
s3 <= DBUS(15 downto 8);
--地址总线s5,s4---
ABUS <= m_abus;
s4 <= m_abus(7 downto 0);
s5 <= m_abus(15 downto 8);
---节拍显示信号---
b(7 downto 4) <= "0000";
b(3 downto 0) <= beat;
---访??控?菩?号---
nBLE <= m_nble;
nBHE <= m_nbhe;
nWR <= m_nwr;
nRD <= m_nrd;
nMREQ <= m_nmreq;
a(0) <= Cy_out;
a(1) <= Zf_out;
a(3) <= not m_nble;
a(4) <= not m_nbhe;
a(6) <= not m_nwr;
a(5) <= not m_nrd;
a(7) <= not m_nmreq;
---复位信号---
end Behavioral;