⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpu_control.vhd

📁 简单的cpu 设计 用hdl语句设计 能实现基本的功能
💻 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 + -