📄 cpu.vhd
字号:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use work.xue.all;
entity cpu is
port(
reset: in std_logic;
clock: in std_logic;
M_data_in: in std_logic_vector( 7 downto 0);
Write_Read : out std_logic;
M_data_out: out std_logic_vector( 7 downto 0);
M_address: out std_logic_vector( 11 downto 0);
overflow: out std_logic;
R0out: out std_logic_vector( 7 downto 0);
R1out: out std_logic_vector( 7 downto 0);
R2out: out std_logic_vector( 7 downto 0);
R3out: out std_logic_vector( 7 downto 0);
PCout: out std_logic_vector( 4 downto 0);
status2: out std_logic_vector( 2 downto 0)
);
end cpu;
architecture rtl of cpu is
signal IR: std_logic_vector( 15 downto 0);
signal MDR: std_logic_vector( 7 downto 0);
signal MAR: std_logic_vector( 11 downto 0);
signal R0: std_logic_vector(7 downto 0):="00000000";
signal R1: std_logic_vector(7 downto 0):="00000000";
signal R2: std_logic_vector(7 downto 0):="00000000";
signal R3: std_logic_vector(7 downto 0):="00000000";
signal A: std_logic_vector(7 downto 0):="00000000";
signal status: integer range 0 to 6;
signal PC: std_logic_vector(11 downto 0);
signal OP: std_logic_vector(3 downto 0);
begin
process(reset, clock)
variable Rx: std_logic_vector(7 downto 0);
variable Ry: std_logic_vector(7 downto 0);
variable temp: bit_vector(7 downto 0);
variable Rst:std_logic_vector(7 downto 0);
variable aRst:std_logic_vector(8 downto 0);
variable IR_in: std_logic_vector(1 downto 0); --寄存器选择信号
variable over_r1: std_logic_vector(8 downto 0);
variable over_r2:std_logic_vector(8 downto 0);
begin
if reset = '0' then
status <= 0;
R0 <= "00000000";
R1 <= "00000000";
R2 <= "00000000";
R3 <= "00000000";
A <= "00000000";
PC <= "000000000000";
MDR <= "00000000";
IR <= "0000000000000000";
elsif (clock'event and clock='1') then
case status is
when 0=>
overflow <= '0';
IR(15 downto 8) <= M_data_in;
OP <= M_data_in(7 downto 4); --get operation code
Write_Read <= '0';
status <= 1;
when 1=>
if IR(9 downto 8)="00" then --确定Ry
Ry:=R0;
elsif IR(9 downto 8)="01" then
Ry:=R1;
elsif IR(9 downto 8)="10" then
Ry:=R2;
else
Ry:=R3;
end if;
IR_in:=IR(11 downto 10);
if IR_in="00" then --确定Rx
Rx:=R0;
elsif IR_in="01" then
Rx:=R1;
elsif IR_in="10" then
Rx:=R2;
else
Rx:=R3;
end if;
if OP=load then --操作数为load
R0(7 downto 4)<="0000";
R0(3 downto 0)<=IR(11 downto 8); --R0 <= "0000" & IR(11 downto 8);
elsif OP = move then --传数据
Rx := Ry;
elsif OP = shrp then --逻辑右移
temp := to_bitvector(Rx); --转化成位矢量
temp := temp srl 1;
Rx := to_stdlogicvector(temp); --位矢量转化为vector
elsif OP=shlp then
temp := to_bitvector(Rx);
temp := temp sll 1;
Rx := to_stdlogicvector(temp);
elsif ( OP = andp or OP = orp or OP = xorp or OP = swap) then
A <= Ry;
status <= 2;
elsif OP = addp then
if Rx(7) = '0' then --求两数补码
over_r1 := '0' & Rx;
else
over_r1 := '1' & Rx;
end if;
if Ry(7) = '0' then
over_r2 := '0' & Ry;
else
over_r2 := '1' & Ry;
end if;
status <= 2;
elsif OP = subp then
if Rx(7) = '0' then --求两数补码
over_r1 := '0' & Rx;
else
over_r1 := "11" & (not Rx(6 downto 0) +1);
end if;
if Ry(7) = '0' then
over_r2 := "11" & (not Ry(6 downto 0) +1);
else
over_r2 := "00"& Ry (6 downto 0);
end if;
status <= 2;
else
NULL;
end if;
if OP /= load then
if IR_in = "00" then
R0 <= Rx;
elsif IR_in = "01" then
R1 <=Rx;
elsif IR_in = "10" then
R2<=Rx;
else
R3 <= Rx;
end if;
end if;
if OP/=stop then
PC <= PC+1;
MAR <= PC+1;
status <= 2;
else status <= 1;
end if;
when 2=>
if (OP=load or OP=move or OP=shrp or OP=shlp or OP=stop or OP=idle or OP=jmp or OP=jz or OP=read or OP=write) then
NULL;
elsif OP=addp then --几个逻辑运算和算术运算的第二步。
aRst:=over_r1+over_r2;
overflow <= aRst(8) xor aRst(7);
Rst:=aRst(7 downto 0);
elsif OP=subp then
aRst:=over_r1+over_r2;
overflow <= aRst(8) xor aRst(7);
Rst:=aRst(7 downto 0);
elsif OP=andp then
Rst:=(A and Rx);
elsif OP=orp then
Rst:=Rx or A;
elsif OP=xorp then
Rst:=Rx xor A;
elsif OP=swap then --交换运算中Ry<-Rx;
if IR(9 downto 8)="00" then
R0 <= Rx;
elsif IR(9 downto 8)="01" then
R1 <= Rx;
elsif IR(9 downto 8)="10" then
R2 <= Rx;
else
R3 <= Rx;
end if;
end if;
if (OP=addp or OP=subp or OP=xorp or OP=orp or OP=andp) then --几个运算后将结果送回(Rx)
if IR_in="00" then
R0 <= Rst;
elsif IR_in="01" then
R1 <= Rst;
elsif IR_in="10" then
R2 <= Rst;
else
R3 <= Rst;
end if;
end if;
if (OP=swap or OP=jmp or OP=jz or OP=read or OP=write) then
status <= 3;
MAR <= PC;
else
status <= 0;
MAR <= PC;
end if;
when 3=>
if OP=swap then
if IR_in="00" then
R0 <= A;
elsif IR_in="01" then
R1 <= A;
elsif IR_in="10" then
R2 <= A;
else
R3 <= A;
end if;
status <= 0;
elsif (OP=read or OP=write or OP=jmp or OP=jz) then
IR(7 downto 0)<=M_data_in;
status <= 4;
PC <= PC+1;
Write_Read <= '0';
end if;
when 4=>
if OP=read then
MAR <= IR(11 downto 0);
status <= 5;
elsif OP=write then
MDR <= R0;
MAR <= IR(11 downto 0);
status <= 5;
elsif OP=jmp then
PC <= IR(11 downto 0);
MAR <= IR(11 downto 0);
status <= 5;
elsif OP=jz then
if(R0="00000000") then
PC <= IR(11 downto 0);
MAR <= IR(11 downto 0);
status <= 5;
else
MAR <= PC;
status <= 5;
end if;
else
status <= 0;
end if;
when 5=>
if (OP=jmp or OP=jz) then
status <= 0;
elsif OP=read then
Write_Read <= '0';
status <= 6;
elsif OP=write then
status <= 6;
end if;
MAR <= PC;
when 6=>
if OP=Read then
R0 <= M_data_in;
end if;
status <= 0;
when others=>
status <= 0;
end case;
if status = 4 and OP = write then
Write_Read <= '1';
else
Write_Read <= '0';
end if;
end if;
end process;
M_address <= MAR;
M_data_out <= MDR;
PCout <= PC( 4 downto 0 );
R0out <= R0;
R1out <= R1;
R2out <= R2;
R3out <= R3;
with status select --把整数转换成信号
status2 <=
"000" when 0,
"001" when 1,
"010" when 2,
"011" when 3,
"100" when 4,
"101" when 5,
"110" when 6;
end rtl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -