📄 cpu.vhd
字号:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
PACKAGE c_define IS
CONSTANT idle : std_logic_vector(3 DOWNTO 0) := "0000";
CONSTANT load : std_logic_vector(3 DOWNTO 0) := "0001";
CONSTANT move : std_logic_vector(3 DOWNTO 0) := "0010";
CONSTANT addP : std_logic_vector(3 DOWNTO 0) := "0011";
CONSTANT subp : std_logic_vector(3 DOWNTO 0) := "0100";
CONSTANT andp : std_logic_vector(3 DOWNTO 0) := "0101";
CONSTANT orp : std_logic_vector(3 DOWNTO 0) := "0110";
CONSTANT xorp : std_logic_vector(3 DOWNTO 0) := "0111";
CONSTANT shrp : std_logic_vector(3 DOWNTO 0) := "1000";
CONSTANT shlp : std_logic_vector(3 DOWNTO 0) := "1001";
CONSTANT swap : std_logic_vector(3 DOWNTO 0) := "1010";
CONSTANT jmp : std_logic_vector(3 DOWNTO 0) := "1011";
CONSTANT jz : std_logic_vector(3 DOWNTO 0) := "1100";
CONSTANT read : std_logic_vector(3 DOWNTO 0) := "1101";
CONSTANT write : std_logic_vector(3 DOWNTO 0) := "1110";
CONSTANT stop : std_logic_vector(3 DOWNTO 0) := "1111";
END c_define;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use work.c_define.all;
entity cpu is
port( reset: in std_logic;
clock: in std_logic;
M_address: out std_logic_vector(11 downto 0);
M_data_in: in std_logic_vector(7 downto 0);
M_data_out: out std_logic_vector(7 downto 0);
Write_Read: out std_logic;
Overflow: out std_logic;
R0out,R1out,R2out,R3out:out std_logic_vector(7 downto 0);
PCout: out std_logic_vector(11 downto 0);
OPout: out std_logic_vector(3downto 0);
status: out integer range 0 to 6
);
end cpu;
architecture cpu_behavor of cpu is
signal op: std_logic_vector(3 DOWNTO 0);
signal R0,R1,R2,R3,A,MDR: std_logic_vector(7 downto 0);
signal IR: std_logic_vector(15 downto 0);
signal over0,over1: std_logic_vector(8 downto 0);
signal MAR,PC: std_logic_vector(11 downto 0);
signal present_state,next_state: integer range 0 to 6;
begin
process(reset,clock,present_state,IR(15 downto 12))
begin
op <= IR(15 downto 12);
if reset = '0' then
present_state <= 0;
next_state <= 0;
A <= "00000000";
R0 <= "00000000";
R1 <= "00000000";
R2 <= "00000000";
R3 <= "00000000";
IR <= "0000000000000000";
PC <= "000000000000";
MAR <= "000000000000";
MDR <= "00000000";
elsif clock'event and clock = '1' then
case present_state is
when 0 =>
IR(15 downto 8) <= M_data_in;
next_state <= 1;
PC <= PC + 1;
when 1 =>
MAR <= PC;
if op = stop then
next_state <= 1;
else
next_state <= 2;
end if;
if op = load then
R0 <= "0000" & IR(11 downto 8);
elsif op = move then
case IR(11 downto 8) is
when "0000" =>
NULL;
when "0001" =>
R0 <= R1;
when "0010" =>
R0 <= R2;
when "0011" =>
R0 <= R3;
when "0100" =>
R1 <= R0;
when "0101" =>
NULL;
when "0110" =>
R1 <= R2;
when "0111" =>
R1 <= R3;
when "1000" =>
R2 <= R0;
when "1001" =>
R2 <= R1;
when "1010" =>
NULL;
when "1011" =>
R2 <= R3;
when "1100" =>
R3 <= R0;
when "1101" =>
R3 <= R1;
when "1110" =>
R3 <= R2;
when "1111" =>
NULL;
end case;
elsif op = shrp then
case IR(11 downto 10) is
when "00" =>
R0<= ('0' & R0(7 downto 1));
when "01" =>
R1<= ('0' & R1(7 downto 1));
when "10" =>
R2<= ('0' & R2(7 downto 1));
when "11" =>
R3<= ('0' & R3(7 downto 1));
end case;
elsif op = shlp then
case IR(11 downto 10) is
when "00" =>
R0 <= (R0(6 downto 0) & '0');
when "01" =>
R1 <= (R1(6 downto 0) & '0');
when "10" =>
R2 <= (R2(6 downto 0) & '0');
when "11" =>
R3 <= (R3(6 downto 0) & '0');
end case;
elsif op = addp or op = subp or op = andp or op = orp or op = xorp or op = swap then
case IR( 9 downto 8 ) is
when "00" =>
A<= R0;
when "01" =>
A<= R1;
when "10" =>
A<= R2;
when "11" =>
A<= R3;
end case;
else
null;
end if;
when 2 =>
if op = swap or op = jmp or op = jz or op = write or op = read then
next_state <= 3;
else
next_state <= 0;
end if;
--if op = idle or op = load or op = move or op = shrp or op = shlp or op = stop then
--null;
if op = addp then
case IR(11 downto 10) is
when "00" =>
--over0(7 downto 0) <= A;
--over0(8) <= A(7);
--over1(7 downto 0) <= R0;
--over1(8) <= R0(7);
--over1 <= over0 + over1;
--R0 <= over1(7 downto 0);
--if over1(7) /= over1(8) then
--Overflow <= '1';
--else
--Overflow <= '0';
--end if;
R0 <= R0 + A;
when "01" =>
over0(7 downto 0) <= A;
over0(8) <= A(7);
over1(7 downto 0) <= R1;
over1(8) <= R1(7);
over1 <= over0 + over1;
R1 <= over1(7 downto 0);
if over1(7) /= over1(8) then
Overflow <= '1';
else
Overflow <= '0';
end if;
when "10" =>
over0(7 downto 0) <= A;
over0(8) <= A(7);
over1(7 downto 0) <= R2;
over1(8) <= R2(7);
over1 <= over0 + over1;
R2 <= over1(7 downto 0);
if over1(7) /= over1(8) then
Overflow <= '1';
else
Overflow <= '0';
end if;
when "11" =>
over0(7 downto 0) <= A;
over0(8) <= A(7);
over1(7 downto 0) <= R3;
over1(8) <= R3(7);
over1 <= over0 + over1;
R3 <= over1(7 downto 0);
if over1(7) /= over1(8) then
Overflow <= '1';
else
Overflow <= '0';
end if;
end case;
elsif op = subp then
case IR(11 downto 10) is
when "00" =>
--over0(7 downto 0) <= A;
--over0(8) <= A(7);
--over1(7 downto 0) <= R0;
--over1(8) <= R0(7);
--over1 <= over1 - over0;
--R0 <= over1(7 downto 0);
--if over1(7) /= over1(8) then
--Overflow <= '1';
--else
--Overflow <= '0';
--end if;
R0 <= R0 - A;
when "01" =>
over0(7 downto 0) <= A;
over0(8) <= A(7);
over1(7 downto 0) <= R1;
over1(8) <= R1(7);
over1 <= over1 - over0;
R1 <= over1(7 downto 0);
if over1(7) /= over1(8) then
Overflow <= '1';
else
Overflow <= '0';
end if;
when "10" =>
over0(7 downto 0) <= A;
over0(8) <= A(7);
over1(7 downto 0) <= R2;
over1(8) <= R2(7);
over1 <= over1 - over0;
R2 <= over1(7 downto 0);
if over1(7) /= over1(8) then
Overflow <= '1';
else
Overflow <= '0';
end if;
when "11" =>
over0(7 downto 0) <= A;
over0(8) <= A(7);
over1(7 downto 0) <= R3;
over1(8) <= R3(7);
over1 <= over1 - over0;
R3 <= over1(7 downto 0);
if over1(7) /= over1(8) then
Overflow <= '1';
else
Overflow <= '0';
end if;
end case;
elsif op = andp then
case IR(11 downto 10) is
when "00" =>
R0 <= (R0) and (A);
when "01" =>
R1 <= (R1) and (A);
when "10" =>
R2 <= (R2) and (A);
when "11" =>
R3 <= (R3) and (A);
end case;
elsif op = orp then
case IR(11 downto 10) is
when "00" =>
R0 <= (R0) or (A);
when "01" =>
R1 <= (R1) or (A);
when "10" =>
R2 <= (R2) or (A);
when "11" =>
R3 <= (R3) or (A);
end case;
elsif op = xorp then
case IR(11 downto 10) is
when "00" =>
R0 <= (R0) xor (A);
when "01" =>
R1 <= (R1) xor (A);
when "10" =>
R2 <= (R2) xor (A);
when "11" =>
R3 <= (R3) xor (A);
end case;
elsif op = swap then
case IR(11 downto 8) is
when "0000" =>
NULL;
when "0001" =>
R1 <= R0;
when "0010" =>
R2 <= R0;
when "0011" =>
R3 <= R0;
when "0100" =>
R0 <= R1;
when "0101" =>
NULL;
when "0110" =>
R2 <= R1;
when "0111" =>
R3 <= R1;
when "1000" =>
R0 <= R2;
when "1001" =>
R1 <= R2;
when "1010" =>
NULL;
when "1011" =>
R3 <= R2;
when "1100" =>
R0 <= R3;
when "1101" =>
R1 <= R3;
when "1110" =>
R2 <= R3;
when "1111" =>
NULL;
end case;
else --if op = read or op = jmp or op = jz or op = write then
null;
end if;
when 3 =>
if op = swap then
case IR( 11 downto 10 ) is
when "00" =>
R0<= A;
when "01" =>
R1<= A;
when "10" =>
R2<= A;
when "11" =>
R3<= A;
end case;
next_state <= 0;
elsif op = read or op = jmp or op = jz or op = write then
IR(7 downto 0) <= M_data_in;
PC <= PC + 1;
next_state <= 4;
end if;
when 4 =>
next_state <= 5;
if op = read then
MAR <= IR(11 downto 0);
elsif op = write then
MAR <= IR(11 downto 0);
MDR <= R0;
elsif op =jmp then
PC <= IR(11 downto 0);
MAR <= IR(11 downto 0);
elsif op = jz then
if R0 = "00000000" then
PC <= IR(11 downto 0);
MAR <= IR(11 downto 0);
else
MAR <= PC;
end if;
end if;
when 5 =>
MAR <= PC;
if op = jmp or op = jz then
next_state <= 0;
elsif op = read or op = write then
next_state <= 6;
end if;
when 6 =>
next_state <= 0;
if op = read then
R0 <= M_data_in;
end if;
end case;
elsif clock'event and clock = '0' then
present_state <= next_state;
end if;
end process;
status <= present_state;
PCout <= PC;
R0out <= R0;
R1out <= R1;
R2out <= R2;
R3out <= R3;
OPout <= op;
M_address <= MAR;
M_data_out <= MDR;
Write_Read <= '1'
when reset='1' and present_state = 5 and op = write else '0';
end cpu_behavor;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -