📄 cpu_control.vhd
字号:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity cpu_control is
port
(
clk :in std_logic;
reset :in std_logic;
databus_out :out std_logic_vector(15 downto 0)
);
end entity cpu_control;
architecture behave of cpu_control is
component rom is
port
(
addr :in std_logic_vector(7 downto 0);
ce :in std_logic;
dataout :out std_logic_vector(15 downto 0)
);
end component rom;
component ram is
port
(
datain :in std_logic_vector(15 downto 0);
address :in std_logic_vector(7 downto 0);
clk :in std_logic;
we :in std_logic;
dataout :out std_logic_vector(15 downto 0)
);
end component ram;
type states is
(
s0, s1, s2, s3, --取指,译码状态
load1, load2, load3, --LOAD语句的执行状态
store1, store2, store3, --STORE语句的执行状态
calc1, calc2, calc3, --ADD/SUB/AND/OR/NOT等算术逻辑指令的执行状态
jmp1, jmp2, --跳转语句JMPGEZ的执行状态
shift1, shift2 --移位语句SHIFTR/SHIFTL/ROTR/ROTL的执行状态
);
signal current_state,next_state :states;
signal flag,flag1 :std_logic;
signal pc :std_logic_vector(7 downto 0);
signal addrbus :std_logic_vector(7 downto 0);
signal databus :std_logic_vector(15 downto 0);
signal addrram :std_logic_vector(7 downto 0);
signal dataramin :std_logic_vector(15 downto 0);
signal dataramout :std_logic_vector(15 downto 0);
signal acc :std_logic_vector(15 downto 0);
signal cs :std_logic;
signal we :std_logic;
signal isrunning :std_logic;
signal mar :std_logic_vector(7 downto 0);
signal mbr :std_logic_vector(15 downto 0);
signal ir :std_logic_vector(15 downto 0);
signal br :std_logic_vector(15 downto 0);
begin
process
variable temp :std_logic_vector(7 downto 0);
begin
if (reset='1') then
pc <= X"00";
acc <= X"0000";
br <= X"0000";
isrunning <= '1';
flag <= '1';
flag1 <= '1';
current_state <= s0;
elsif (rising_edge(clk)) then
if (isrunning='1') then
case current_state is
when s0 =>
next_state <= s1;
mar <= pc;
when s1 =>
next_state <= s2;
mbr <= databus;
if (flag = '1') then
pc <= pc + 1;
flag <= '0';
end if;
when s2 =>
next_state <= s3;
flag <= '1';
ir <= mbr;
when s3 =>
temp := ir(15 downto 8);
if (temp = X"02") then
next_state <= load1;
elsif (temp = X"01") then
next_state <= store1;
elsif (temp = X"03" or temp = X"04" or temp = X"0A" or temp = X"0B" or temp = X"0C") then
next_state <= calc1;
elsif (temp = X"05") then
next_state <= jmp1;
elsif (temp = X"0D" or temp = X"0E" or temp = X"1D" or temp = X"1E") then
next_state <= shift1;
elsif (temp = X"07") then
isrunning <= '0';
else
next_state <= s0;
end if;
when load1 =>
next_state <= load2;
mar <= ir(7 downto 0);
when load2 =>
next_state <= load3;
mbr <= dataramout;
when load3 =>
next_state <= s0;
acc <= mbr;
when store1 =>
next_state <= store2;
mar <= ir(7 downto 0);
when store2 =>
next_state <= store3;
mbr <= acc;
when store3 =>
next_state <= s0;
dataramin <= mbr;
when calc1 =>
next_state <= calc2;
mar <= ir(7 downto 0);
when calc2 =>
next_state <= calc3;
mbr <= dataramout;
flag1 <= '1';
when calc3 =>
next_state <= s0;
if (temp = X"03" and flag1 = '1') then -- ADD
acc <= acc + mbr after 5 ns;
flag1 <= '0';
elsif (temp = X"04" and flag1 = '1') then -- SUB
acc <= acc - mbr after 5 ns;
flag1 <= '0';
elsif (temp = X"0A" and flag1 = '1') then -- AND
acc <= acc and mbr after 5 ns;
flag1 <= '0';
elsif (temp = X"0B" and flag1 = '1') then -- OR
acc <= acc or mbr after 5 ns;
flag1 <= '0';
elsif (temp = X"0C" and flag1 = '1') then -- NOT
acc <= not(mbr) after 5 ns;
flag1 <= '0';
end if;
when jmp1 =>
next_state <= jmp2;
mar <= ir(7 downto 0);
when jmp2 =>
next_state <= s0;
if (acc(15) = '0') then --当ACC>=0的时候直接调整PC的值
pc <= mar;
end if;
when shift1 =>
next_state <= shift2;
flag1 <= '1';
when shift2 =>
next_state <= s0;
if (temp = X"0D" and flag1 = '1') then
acc <= '0' & acc(15 downto 1) after 5 ns; --SHIFTR, Here we do logic shift right, acc(0) & acc(15 downto 1) for rotate right
flag1 <= '0';
elsif (temp = X"0E" and flag1 = '1') then --SHIFTL, Here we do logic shift left, acc(14 downto 0) & acc(15) for rotate left
acc <= acc(14 downto 0) & '0' after 5 ns;
flag1 <= '0';
elsif (temp = X"1D" and flag1 = '1') then
acc <= acc(0) & acc(15 downto 1) after 5 ns; --ROTR
flag1 <= '0';
elsif (temp = X"1E" and flag1 = '1') then
acc <= acc(14 downto 0) & acc(15) after 5 ns;--ROTL
flag1 <= '0';
end if;
end case;
current_state <= next_state; --每个状态为两个时钟周期
end if;
end if;
end process;
u1:rom port map(addrbus,cs,databus);
v1:ram port map(dataramin,addrram,clk,we,dataramout);
addrbus <= mar when (current_state = s1) else X"00";
addrram <= mar when (current_state = load2) or (current_state = store3) or (current_state = calc2) else X"00";
cs <= '0' when (current_state = s1) else '1'; --读ROM的片选信号
we <= '1' when (current_state = store3) else '0'; --写RAM的片选信号
databus_out <= databus;
end behave;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -