计算机设计与实践 CPU 代码含19条指令.docx
《计算机设计与实践 CPU 代码含19条指令.docx》由会员分享,可在线阅读,更多相关《计算机设计与实践 CPU 代码含19条指令.docx(25页珍藏版)》请在冰豆网上搜索。
计算机设计与实践CPU代码含19条指令
时钟管理模块
entityclk_ctrlis
port(
Clk:
instd_logic;
Rst:
instd_logic;
k:
outstd_logic_vector(3downto0)
);
endclk_ctrl;
architectureBehavioralofclk_ctrlis
signaltmp:
std_logic_vector(3downto0);
begin
process(Clk,Rst,tmp)
begin
ifRst='1'then--rst=1复位;
--k<="0000";
tmp<="0001";
elsifClk='1'andClk'eventthen
tmp(0)<=tmp(3);
tmp(3downto1)<=tmp(2downto0);
endif;
endprocess;k<=tmp;
endBehavioral;
取指模块
entityirgetis
Port(
Rst:
inSTD_LOGIC;--复位;
Pcback:
inSTD_LOGIC_VECTOR(15downto0);--PC回写;
Pcbacka:
inSTD_LOGIC;--PC回写允许;
k1:
inSTD_LOGIC;--时钟控制;
Order:
inSTD_LOGIC_VECTOR(15downto0);--指令
Pcout:
outSTD_LOGIC_VECTOR(15downto0);--PC输出;
Orderout:
outSTD_LOGIC_VECTOR(15downto0);--指令输出;
AddrFlag:
outSTD_LOGIC);--访址标志
endirget;
architectureBehavioralofirgetis
signaltmpPC:
std_logic_vector(15downto0);--指令地址;
signalIR:
std_logic_vector(15downto0);--指令寄存器;
begin
process(Rst,Pcback,Pcbacka,k1,order,tmpPc)
begin
ifRst='1'then
tmpPc<="0000000000000000";
elsifk1='1'then
Pcout<=tmpPc;
AddrFlag<='1';--第一个节拍高电平取指;
elsifPcbacka='1'then
tmpPc<=Pcback;--pc回写允许
---endif;
--AddrFlag<='0';
elseAddrFlag<='0';
endif;
Orderout<=Order;--指令存入指令寄存器;
endprocess;
--Orderout<=IR;--得到指令,准备送往后面的模块;
endBehavioral;
运算模块
entityCPU_operationis
Port(k2:
inSTD_LOGIC;--时钟控制;
k3:
inSTD_LOGIC;--时钟控制;第三个时钟高电平改变标志寄存器的值;
order:
inSTD_LOGIC_VECTOR(15downto0);--命令输入;
Pcin:
inSTD_LOGIC_VECTOR(15downto0);--pc输入;
Rst:
inSTD_LOGIC;--复?
?
;
Rwb:
inSTD_LOGIC_VECTOR(7downto0);--回写数据;
Rwba:
inSTD_LOGIC;--回?
丛市?
?
?
高电平有效
Aluout:
outSTD_LOGIC_VECTOR(15downto0);--计算结果输出;
addr:
outSTD_LOGIC_VECTOR(15downto0)--内存?
刂?
?
);
endCPU_operation;
architectureBehavioralofCPU_operationis
typeregisarray(0to7)ofstd_logic_vector(7downto0);
signalsreg:
reg;
signalF9:
std_logic_vector(8downto0);--判断结果是否进位、是否为零;
signalsregflag:
std_logic_vector(1downto0);--标志寄存器;
begin
process(Rwb,Rwba,k2,order,sreg,Pcin,sregflag,F9)
begin
ifRwba='1'then
sreg(conv_integer(order(10downto8)))<=Rwb;--回写
endif;
ifRst='1'then
sreg(7)<="00000000";
sreg(6)<="00000000";
F9(8)<='0';
endif;
ifk2='1'then
caseorder(15downto11)is
when"00000"=>--movRi,Im
Aluout(7downto0)<=order(7downto0);
Aluout(15downto8)<="11111111";
when"00001"=>--LDARi,X
addr(15downto8)<=sreg(7);
addr(7downto0)<=order(7downto0);
Aluout(15downto8)<="11111111";
when"00010"=>--STARi,X
Aluout(7downto0)<=sreg(conv_integer(order(10downto8)));
Aluout(15downto8)<="11111111";
addr(7downto0)<=order(7downto0);
addr(15downto8)<=sreg(7);
when"00011"=>--movRi,Rj
Aluout(7downto0)<=sreg(conv_integer(order(2downto0)));
Aluout(15downto8)<="11111111";
when"00100"=>--movRi,(Rj)
addr(7downto0)<=sreg(conv_integer(order(2downto0)));
addr(15downto8)<=sreg(7);
when"00101"=>--movRi,[R7//R6+x]
addr<=sreg(7)&sreg(6)+order(7downto0);
when"00110"=>--Adc,Ri,Im
Aluout(7downto0)<=sreg(conv_integer(order(10downto8)))+order(7downto0)+sregflag
(1);
F9<=('0'&sreg(conv_integer(order(10downto8))))+('0'&order(7downto0));
Aluout(15downto8)<="11111111";
when"00111"=>--Adc,Ri,Rj,Ri+Rj+Cy->Ri
Aluout(7downto0)<=sreg(conv_integer(order(10downto8)))+sreg(conv_integer(order(2downto0)))+sregflag
(1);
F9<=('0'&sreg(conv_integer(order(10downto8))))+('0'&order(7downto0));
Aluout(15downto8)<="11111111";
when"01000"=>--SBBRi,Im
Aluout(7downto0)<=sreg(conv_integer(order(10downto8)))-order(7downto0)-sregflag
(1);
F9<=('0'&sreg(conv_integer(order(10downto8))))-('0'&order(7downto0));
Aluout(15downto8)<="11111111";
when"01001"=>--SBBRi,Rj,Ri-Rj-Cy->Ri
Aluout(7downto0)<=sreg(conv_integer(order(10downto8)))-sreg(conv_integer(order(2downto0)))-sregflag
(1);
F9<=('0'&sreg(conv_integer(order(10downto8))))-('0'&order(7downto0));
Aluout(15downto8)<="11111111";
when"01010"=>--ANDRi,Im
Aluout(7downto0)<=sreg(conv_integer(order(10downto8)))andorder(7downto0);
F9(7downto0)<=(sreg(conv_integer(order(10downto8))))and(order(7downto0));
Aluout(15downto8)<="11111111";
when"01011"=>--ANDRi,Rj
Aluout(7downto0)<=sreg(conv_integer(order(10downto8)))andsreg(conv_integer(order(2downto0)));
F9(7downto0)<=sreg(conv_integer(order(10downto8)))andorder(7downto0);
Aluout(15downto8)<="11111111";
when"01100"=>--ORRi,Im
Aluout(7downto0)<=sreg(conv_integer(order(10downto8)))ororder(7downto0);
F9(7downto0)<=(sreg(conv_integer(order(10downto8))))or(order(7downto0));
Aluout(15downto8)<="11111111";
when"01101"=>--ORRi,Rj
Aluout(7downto0)<=sreg(conv_integer(order(10downto8)))orsreg(conv_integer(order(2downto0)));
F9(7downto0)<=(sreg(conv_integer(order(10downto8))))or(order(7downto0));
Aluout(15downto8)<="11111111";
when"10000"=>--JMPAddr
Aluout<=sreg(7)&order(7downto0);
when"10001"=>--JZsign
ifsregflag(0)='1'then
iforder(7)='0'thenAluout<=Pcin+("00000000"&order(7downto0));
elseAluout<=Pcin+("11111111"&order(7downto0));
endif;
else
Aluout<=Pcin;
endif;
when"10010"=>--JCsign
ifsregflag
(1)='1'then
iforder(7)='0'thenAluout<=Pcin+("00000000"&order(7downto0));
elseAluout<=Pcin+("11111111"&order(7downto0));
endif;
else
Aluout<=Pcin;
endif;
whenothers=>NULL;
endcase;
endif;
endprocess;
process(k3,F9,order)
begin
ifrst='1'then
sregflag(0)<='0';
sregflag
(1)<='0';
elsifk3='1'then
caseorder(15downto12)is
when"0011"|"0101"|"0100"|"0110"=>
sregflag
(1)<=F9(8);
ifF9(7downto0)="00000000"then
sregflag(0)<='1';
elsesregflag(0)<='0';
endif;
when"0111"=>
sregflag(0)<=order(11);
whenothers=>null;
endcase;
endif;
endprocess;
endBehavioral;
存储管理模块
entityCPU_Momeryis
Port(
k3:
inSTD_LOGIC;--时钟控制;
order:
inSTD_LOGIC_VECTOR(15downto0);--命令输入;
alu:
inSTD_LOGIC_VECTOR(15downto0);--计算结果输?
?
;
datain:
inSTD_LOGIC_VECTOR(7downto0);--从内存读入的?
?
;
dataout:
outSTD_LOGIC_VECTOR(7downto0);--存入内存的数;
Rtmp:
outSTD_LOGIC_VECTOR(15downto0);--数据输出;送向回写模块;
sta:
outSTD_LOGIC;--存数控制;高电平有效;
lda:
outSTD_LOGIC);--取数控制;高电平有效?
?
endCPU_Momery;
architectureBehavioralofCPU_Momeryis
begin
process(k3,alu,order,datain)
begin
ifk3='1'then--高电平操作;
caseorder(15downto11)is
when"00001"=>--取数;
lda<='1';
Rtmp(7downto0)<=datain;
when"00100"=>--取数;
lda<='1';
Rtmp(7downto0)<=datain;
when"00101"=>--取数;
lda<='1';
Rtmp(7downto0)<=datain;
when"00010"=>--存数;
sta<='1';
dataout<=alu(7downto0);
whenothers=>
Rtmp<=alu;--不访存;运算结果直接送下一个模块;
lda<='0';
sta<='0';
endcase;
else
lda<='0';
sta<='0';
endif;
endprocess;
endBehavioral;
访存模块
entityCPU_ToMomeryis
Port(
sta:
inSTD_LOGIC;--存数指令;
lda:
inSTD_LOGIC;--取数指令;
Addr:
inSTD_LOGIC_VECTOR(15downto0);--内存地址;
flag:
inSTD_LOGIC;--取指标志;
PCaddr:
inSTD_LOGIC_VECTOR(15downto0);--指令地址输入;
orderout:
outSTD_LOGIC_VECTOR(15downto0);--指令输出;
dataout:
outSTD_LOGIC_VECTOR(7downto0);--从内存中取出的数;
datain:
inSTD_LOGIC_VECTOR(7downto0);--需要存入内存的数;
ABUS:
outSTD_LOGIC_VECTOR(15downto0);--地址总线?
?
DBUS:
inoutSTD_LOGIC_VECTOR(15downto0);--数据总线;
CS:
outSTD_LOGIC;--片选信号;低电平有效;
RD:
outSTD_LOGIC;--读信号;低电平有效;
WR:
OUTSTD_LOGIC;--写信号;低电平有?
?
?
?
nBHE:
outstd_logic;
nBLE:
outstd_logic
);
endCPU_ToMomery;
architectureBehavioralofCPU_ToMomeryis
begin
process(sta,lda,datain,DBUS,flag)
begin
ifflag='1'then--取指令;
CS<='0';
RD<='0';
WR<='1';
nBHE<='0';
nBLE<='0';
ABUS<=PCaddr;
orderout<=DBUS;
DBUS<="ZZZZZZZZZZZZZZZZ";
elsifsta='1'then--存数访存;
CS<='0';
RD<='1';
WR<='0';
nBHE<='0';
nBLE<='0';
ABUS<=Addr;
DBUS(7downto0)<=datain;
DBUS(15downto8)<="11111111";
elsiflda='1'then--取数访存;
CS<='0';
RD<='0';
WR<='1';
nBHE<='0';
nBLE<='0';
ABUS<=Addr;
dataout<=DBUS(7downto0);
DBUS<="ZZZZZZZZZZZZZZZZ";
else
CS<='1';
RD<='1';
WR<='1';
nBHE<='1';
nBLE<='1';
DBUS<="ZZZZZZZZZZZZZZZZ";
endif;
endprocess;
endBehavioral;
回写模块
entityWriteBackis
port(
k4:
instd_logic;--时钟控制;
order:
instd_logic_vector(15downto0);--指令输入;
Pcin:
instd_logic_vector(15downto0);--pc输入;
datain:
instd_logic_vector(15downto0);--需要回写的数据,包括跳转指令的PC?
?
Pcback:
outstd_logic_vector(15downto0);--pc回写;
Pcbacka:
outstd_logic;--pc回写允许;
dataout:
outstd_logic_vector(7downto0);--回写数据输出;
dataA:
outstd_logic);--回写允许;
endWriteBack;
architectureBehavioralofWriteBackis
begin
process(k4,order,Pcin,datain)
begin
ifk4='1'then
caseorder(15downto11)is
when"00000"=>--movRi,Im
Pcbacka<='1';
Pcback<=Pcin+1;
dataA<='1';
dataout<=datain(7downto0);
when"00001"=>--LDA
Pcbacka<='1';
Pcback<=Pcin+1;
dataA<='1';
dataout<=datain(7downto0);
when"00010"=>--STA
Pcbacka<='1';
Pcback<=Pcin+1;
dataA<='0';
when"00011"=>--movRi,Rj
Pcbacka<='1';
Pcback<=Pcin+1;
dataA<='1';
dataout<=datain(7downto0);
when