跪求一个用VHDL设计一个CPU,请各位大侠帮帮忙!!
发布网友
发布时间:2024-10-06 08:54
我来回答
共1个回答
热心网友
时间:2024-10-28 20:10
CPU具有的功能:能完成一些简单的指令
MOV AX,ADDRESS4 --将address4中的内容赋给AX寄存器(在8086/8088汇编语言中称这种寻址方式为直接寻址方式)
ADD AX,ADDRESS4 -- 将address4中的内容加到AX寄存器中
SUB AX,ADDRESS4 -- 用address4中的内容减去AX寄存器中的内容
OUT -- 输出AX寄存器中的内容
HLT -- CPU停止运行
S0状态:程序计数器(PC)将值赋给MAR
S1状态:PC<=PC+1 注意:因为在设计状态机时引入了复位键(RST),为了避免一个信号有多个源,因而将时序进程(REG:PROCESS)和组合进程(COM:PROCESS)合二为一。但是产生了一个比较麻烦的事情--------------即一个状态占用了两个时钟周期。所以在设计PC<=PC+1时,引入了标志寄存器(FLAG),以确保在S1状态PC只加一次
S2状态:从只读存储器(ROM)中读取汇编指令,并且将赋给指令寄存器(IR)IR<=DATABUS
------------------------------------------------------------------------------------------------------------------------------------------------
从S0-S2状态每条指令的执行都是相同的
S3状态:取出指令寄存器的高4位(汇编的指令代码)进行译码
if (temp="0000") or (temp="0001")or (temp="0010") then
mar<=ir(3 downto 0); --将数据存储的地址赋给MAR
elsif temp="1110" then
output_data<=ax; -- out over
elsif temp="1111" then
run<='0'; --Hlt over
end if;
有上面的程序可以看出,当指令是MOV、ADD、SUB中的一个时,取出地址
当指令是OUT时将累加器中的值输出,该条指令做完
当指令是HLT(1111)时,程序停止运行,该条指令做完
S4状态:
if temp="0000" then - -MOV AX,data over
ax<=dataBus;
elsif temp="0001" then --ADD ax,data
bx<=databus;
f1<='1';
elsif temp="0010" then --SUB ax,bx
bx<=databus;
f1<='1';
end if;
读出RAM 中的内容(在此设计中,用ROM代替了RAM)在此状态MOV指令结束
S5状态:为计算状态
if temp="0001" and f1='1' then
ax<=ax+bx;
f1<='0';
elsif temp="0010" and f1='1' then
ax<=ax-bx;
f1<='0';
end if;
当指令是ADD(0001)时,AX<=AX+BX
当指令是SUB(0010)时, AX<=AX-BX
源程序:
ROM16_4.VHD
--//////////////////////////////////////////////////////////
--16*8ROM
--CE=0时允许读
--huyugui
--2005,1,28
--//////////////////////////////////////////////////////////
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity rom16_8 is
port( addr:in std_logic_vector(3 downto 0);
ce:in std_logic;
dataout:out std_logic_vector(7 downto 0)
);
end entity rom16_8;
architecture behave of rom16_8 is
begin
--10+20+60-10=80h
dataout<="00001001" when addr="0000" and ce='0' else --mov ax,9h
"00011010" when addr="0001" and ce='0' else --add ax,ah
"00011011" when addr="0010" and ce='0' else --add ax,bh
"00101100" when addr="0011" and ce='0' else --sub ax,ch
"11100000" when addr="0100" and ce='0' else --out
"11110000" when addr="0101" and ce='0' else --hlt
"00000000" when addr="0110" and ce='0' else
"00000000" when addr="0111" and ce='0' else
"00000000" when addr="1000" and ce='0' else
"00010000" when addr="1001" and ce='0' else --10h
"00100000" when addr="1010" and ce='0' else --20h
"01100000" when addr="1011" and ce='0' else --60h
"00010000" when addr="1100" and ce='0' else --10h
"00000000" when addr="1101" and ce='0' else
"00000000" when addr="1110" and ce='0' else
"00000000" when addr="1111" and ce='0' else
"11111111";
end architecture behave;
CPU_CONTROL.VHD
--/////////////////////////////////////////////////////////////////////////////
--8_CPU
--mov ax,address /add ax,address/sub ax,address/out /hlt
--说明:address为4位的地址(9H-fH)
--完善:每个状态为一个时钟周期,这样的话PC<=PC+1在S1状态将只做一次,时钟将
--得到很大的改善
--设计者:胡玉贵
--时间:2005,1,29A
--/////////////////////////////////////////////////////////////////////////////
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;
rst:in std_logic;
output_data,databus_out:out std_logic_vector(7 downto 0)
);
end entity cpu_control;
architecture behave of cpu_control is
component rom16_8 is
port( addr:in std_logic_vector(3 downto 0);
ce:in std_logic;
dataout:out std_logic_vector(7 downto 0)
);
end component rom16_8;
type states is (s0,s1,s2,s3,s4,s5);
signal current_state,next_state:states;
signal flag:std_logic;
signal pc,addrbus:std_logic_vector(3 downto 0);
signal ax,bx:std_logic_vector(7 downto 0);--Ax,Bx
signal cs:std_logic;
signal databus:std_logic_vector(7 downto 0);
signal run:std_logic;
signal mar:std_logic_vector(3 downto 0);
signal ir:std_logic_vector(7 downto 0);
signal f1:std_logic;
begin
reg:process
variable temp:std_logic_vector(3 downto 0);
begin
if rst='1' then --系统复位
pc<="0000";
ax<="00000000";
bx<="00000000";
run<='1';
flag<='1'; --PC可以加1
f1<='1';
current_state<=s0;
--databus<="00000000";
elsif rising_edge(clk) then
if run='1' then
case current_state is
when s0=>next_state<=s1; --Address State&Fetch
mar<=pc; --将PC的值赋给MAR,在S2状态时从ROM中读出指令(IR<=databus)
when s1=>next_state<=s2;
if flag='1' then
pc<=pc+1; --地址加1
flag<='0';
end if;
when s2=>next_state<=s3;
flag<='1' ;
ir<=databus; --将ROM中的指令赋给IR(指令寄存器)
when s3=>next_state<=s4;
temp:=ir(7 downto 4); --取指令寄存器的高4位(指令代码 MOV 0000,ADD 0001,SUB 0010)
-- Mov Add Sub
if (temp="0000") or (temp="0001")or (temp="0010") then
mar<=ir(3 downto 0); --将数据存储的地址赋给MAR
elsif temp="1110" then
output_data<=ax; -- out over
elsif temp="1111" then
run<='0'; --Hlt over
end if;
when s4=>next_state<=s5; --在S4状态,将从数据总线上读取数据
if temp="0000" then --MOV AX,data over
ax<=dataBus;
elsif temp="0001" then --ADD ax,data
bx<=databus;
f1<='1';
elsif temp="0010" then --SUB ax,bx
bx<=databus;
f1<='1';
end if;
when s5=>next_state<=s0;
if temp="0001" and f1='1' then
ax<=ax+bx;
f1<='0';
elsif temp="0010" and f1='1' then
ax<=ax-bx;
f1<='0';
end if;
end case;
current_state<=next_state; --此设计使每个状态为两个时钟周期�(Attention!!!!)
end if;
end if;
end process reg;
u1:rom16_8 port map(addrbus,cs,databus);
addrbus<=mar when (current_state=s2) or (current_state=s4) else
"0000";
cs<='0' when (current_state=s2) or (current_state=s4) else
'1';
databus_out<=databus;
end architecture behave;
参考资料:微机原理及应用第3章:清华大学出版社;VHDL和数字电路设计:科学出版社;VHDL实用教程:电子科技大出版社