您好,欢迎来到中国企业库   [请登陆]  [免费注册]
小程序  
APP  
微信公众号  
手机版  
 [ 免责声明 ]     [ 举报 ]
企业库免费B2B网站
搜产品 搜企业
客服电话:400-000-8722

实验八 16位CPU验证性设计

实验八 16位CPU验证性设计

一、实验目的

1. 理解16位CPU的结构和功能;

2.学习各类典型指令的执行流程;

3. 学习掌握部件单元电路的设计技术;

4. 掌握应用程序在用FPGA所设计的CPU上仿真和软硬件综合调试方法。

二、实验设备

1.装有quartus Ⅱ 9.0的pc一台;

2.Cyclone Ⅲ 实验箱一台。

三、实验原理

使用VHDL语言编写CPU所要具备的寄存器、存储器、ALU(运算器)、比较器、移位寄存器和控制器。最后将各模块连接起来,受控制器控制各模块的工作状态。

四、实验内容和步骤

1.编写移位器SFT4的VHDL代码

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_ARITH.ALL;

entity SFT4 is

port (a:in std_logic_vector (15 downto 0);

sel:in std_logic_vector (2 downto 0);

y:out std_logic_vector (15 downto 0));

end SFT4;

architecture rtl of SFT4 is

constant shftpass: std_logic_vector (2 downto 0):="000";

constant sftl: std_logic_vector (2 downto 0):="001";

constant sftr: std_logic_vector (2 downto 0):="010";

constant rotl: std_logic_vector (2 downto 0):="011";

constant rotr: std_logic_vector (2 downto 0):="100";

begin

process(a,sel)begin

case sel is

when shftpass => y <=a;

when sftl => y <=a(14 downto 0) & '0';

when sftr => y <='0' & a(15 downto 1);

when rotl => y <=a(14 downto 0) & a(15) ;

when rotr => y <=a(0) & a(15 downto 1);

when others => y <="0000000000000000";

end case;

end process;

end rtl;

2.编写缓冲寄存器REGT的VHDL代码

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

entity REGT is

port(a:in std_logic_vector (15 downto 0);

clk,RST,en :in std_logic;

q:out std_logic_vector (15 downto 0));

end REGT;

architecture bhv of REGT is

signal v1 : std_logic_vector (15 downto 0);

begin

process (clk,a,RST) begin

if RST='1'then v1<="0000000000000000";

elsif rising_edge(clk) then v1<=a;end if;

end process;

process(en,v1) begin

if en ='1'then q<=v1; else q<="ZZZZZZZZZZZZZZZZ";end if;

end process;

end bhv;

3.编写输出锁存器和指令寄存器REG16A的VHDL代码

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY REG16A IS

PORT(A:IN STD_LOGIC_VECTOR(15 DOWNTO 0);CLK:IN STD_LOGIC;

Q:OUT STD_LOGIC_VECTOR(15 DOWNTO 0));

END REG16A;

ARCHITECTURE BHV OF REG16A IS

BEGIN

PROCESS(CLK,A) BEGIN

IF RISING_EDGE(CLK) THEN Q<=A;END IF;

END PROCESS;

END BHV;

4.编写R7-R0寄存器阵列REG_AR8的VHDL代码

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY REG_AR8 IS

PORT(DATA:IN STD_LOGIC_VECTOR(15 DOWNTO 0);

SEL :IN STD_LOGIC_VECTOR(2 DOWNTO 0);

CLK: IN STD_LOGIC;Q: OUT STD_LOGIC_VECTOR(15 DOWNTO 0));

END REG_AR8;

ARCHITECTURE RTL OF REG_AR8 IS

TYPE T_RAM IS ARRAY (0 TO 7) OF STD_LOGIC_VECTOR(15 DOWNTO 0);

SIGNAL RAMDATA:T_RAM;

SIGNAL TEMP_DATA: STD_LOGIC_VECTOR(15 DOWNTO 0);

BEGIN

PROCESS (CLK,SEL) BEGIN

IF RISING_EDGE(CLK) THEN RAMDATA(CONV_INTEGER(SEL))<=DATA;END IF;

END PROCESS;

PROCESS(SEL) BEGIN

TEMP_DATA<=RAMDATA(CONV_INTEGER(SEL));END PROCESS;

Q<=TEMP_DATA;

END RTL;

5.编写地址寄存器REG_A的VHDL代码

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY REG_A IS

PORT(RST,CLK,LOAD:IN STD_LOGIC;

D:IN STD_LOGIC_VECTOR(15 DOWNTO 0);

Q:OUT STD_LOGIC_VECTOR(15 DOWNTO 0));

END REG_A;

ARCHITECTURE BEHAVIORAL OF REG_A IS

BEGIN

PROCESS (CLK,RST) BEGIN

IF RST='1' THEN Q<=(OTHERS=>'0');

ELSIF RISING_EDGE(CLK) THEN

IF LOAD='1' THEN Q<=D; END IF;

END IF ;

END PROCESS;

END BEHAVIORAL;

6.编写比较器comp的VHDL代码

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

use ieee.std_logic_unsigned.all;

entity comp is

port(a,b:in std_logic_vector(15 downto 0);

sel:in std_logic_vector(2 downto 0);

compout:out std_logic);

end comp;

architecture rtl of comp is

constant eq :std_logic_vector(2 downto 0):="000";

constant neq:std_logic_vector(2 downto 0):="001";

constant gt :std_logic_vector(2 downto 0):="010";

constant gte:std_logic_vector(2 downto 0):="011";

constant lt :std_logic_vector(2 downto 0):="100";

constant lte:std_logic_vector(2 downto 0):="101";

begin

process(a,b,sel) begin

case sel is

when eq=>if a=b then compout<='1';else compout<='0';end if;

when neq=>if a/=b then compout<='1';else compout<='0';end if;

when gt =>if a>b then compout<='1';else compout<='0';end if;

when gte =>if a>=b then compout<='1';else compout<='0';end if;

when lt =>if a<b then compout<='1';else compout<='0';end if;

when lte =>if a<=b then compout<='1';else compout<='0';end if;

when others => compout<='0';

end case;

end process;

end rtl;

7.编写运算器ALU的VHDL代码

library IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY ALU_V IS

PORT(a,b:in std_logic_vector(15 downto 0);

sel:in std_logic_vector(3 downto 0);

c:out std_logic_vector(15 downto 0));

end ALU_V;

architecture rtl of ALU_V IS

constant alupass:std_logic_vector(3 downto 0):="0000";

constant andOp:std_logic_vector(3 downto 0):="0001";

constant orOp:std_logic_vector(3 downto 0):="0010";

constant notOp:std_logic_vector(3 downto 0):="0011";

constant xorOp:std_logic_vector(3 downto 0):="0100";

constant plus:std_logic_vector(3 downto 0):="0101";

constant alusub:std_logic_vector(3 downto 0):="0110";

constant inc:std_logic_vector(3 downto 0):="0111";

constant dec:std_logic_vector(3 downto 0):="1000";

constant zero:std_logic_vector(3 downto 0):="1001";

begin

process(a,b,sel) begin

case sel is

when alupass=>c<=a;

when andOp=>c<=a and b;

when orOp=>c<=a and b;

when xorOp=>c<=a xor b;

when notOp=>c<=not a;

when plus =>c<=a+b;

when alusub=>c<=a-b;

when inc=>c<=a+"0000000000000001";

when dec=>c<=a-"0000000000000001";

when zero=>c<="0000000000000000";

when others=>c<="0000000000000000";

end case ;end process;

end rtl;

8.编写控制器CONTRAL的VHDL代码

library ieee;

use ieee.std_logic_1164.all;

entity contrla is

port(clock:in std_logic;reset:in std_logic;

instrreg:in std_logic_vector(15 downto 0);

compout:in std_logic;

progcntrwr:out std_logic;

progcntrrd:out std_logic;

addrregwr:out std_logic;

addrregrd:out std_logic;

outregwr:out std_logic;

outregrd:out std_logic;

shiftsel:out std_logic_vector(2 downto 0);

alusel:out std_logic_vector(3 downto 0);

compsel:out std_logic_vector(2 downto 0);

opregrd:out std_logic;

opregwr:out std_logic;

instrwr:out std_logic;

regsel:out std_logic_vector(2 downto 0);

regrd:out std_logic;

regwr:out std_logic;

rw:out std_logic;

vma:out std_logic);

end contrla;

architecture rtl of contrla is

constant shftpass:std_logic_vector(2 downto 0):="000";

constant alupass :std_logic_vector(3 downto 0):="0000";

constant zero :std_logic_vector(3 downto 0):="1001";

constant inc :std_logic_vector(3 downto 0):="0111";

constant plus :std_logic_vector(3 downto 0):="0101";

type state is (reset1,reset2,reset3,execute,nop,load,store,

load2,load3,load4,store2,store3,store4,incpc,incpc2,incpc3,loadi2,loadi3,loadi4,loadi5,loadi6,inc2,inc3,inc4,move1,move2,

add2,add3,add4);

signal current_state, next_state : state;

begin

com:process(current_state,instrreg,compout) begin

progcntrwr<='0';progcntrrd<='0';addrregwr<='0';addrregrd<='0';

outregwr<='0';outregrd<='0';shiftsel<=shftpass;alusel<=alupass;

opregrd<='0';opregwr<='0';instrwr<='0';regsel<="000";

regrd<='0';regwr<='0';rw<='0';vma<='0';

case current_state is

when reset1=>alusel<=zero;shiftsel<=shftpass;

outregwr<='1';next_state<=reset2;

when reset2=>outregrd<='1';progcntrwr<='1';

addrregwr<='1';next_state<=reset3;

when reset3=>vma<='1';rw<='0';instrwr<='1';next_state<=execute;

when execute=>

case instrreg(15 downto 11) is

when"00000"=>next_state<=incpc;

when"00001"=>next_state<=load2;

when"00010"=>next_state<=store2;

when"00100"=>progcntrrd<='1';alusel<=inc;

shiftsel<=shftpass;next_state<=loadi2;

when"00111"=>next_state<=inc2;

when"01101"=>next_state<=add2;

when"00011"=>next_state<=move1;

when others=>next_state<=incpc;

end case;

when load2=>regsel<=instrreg(5 downto 3);regrd<='1';

addrregwr<='1';next_state<=load3;

when load3=>vma<='1';rw<='0';regsel<=instrreg(2 downto 0);

regwr<='1';next_state<=incpc;

when add2=>regsel<=instrreg(5 downto 3);

regrd<='1';

next_state<=add3;opregwr<='1';

when add3=>regsel<=instrreg(2 downto 0);

regrd<='1';alusel<=plus;

shiftsel<=shftpass;outregwr<='1';

next_state<=add4;

when add4=>regsel<="011";

outregrd<='1';regwr<='1';

next_state<= incPc;

when move1=>regsel<=instrreg(5 downto 3);regrd<='1';alusel<=alupass;

shiftsel<=shftpass;outregwr<='1';next_state<=move2;

When move2 => regsel <=instrReg(2 downto 0); outregrd<='1';

Regwr <='1'; next_state<=incpc;

When store2 => regsel <=instrReg(2 downto 0); regrd<='1';

addrRegwr <= '1'; next_state<=store3;

When store3 => regsel <=instrReg(5 downto 3); regrd<='1';

rw<='1'; next_state<=incpc;

When loadi2 => progcntrrd<='1';alusel<=inc; shiftsel<=shftpass;

Outregwr <='1';next_state<=loadi3;

When loadi3 =>Outregrd <='1';next_state <= loadi4;

When loadi4 =>Outregrd <= '1';progcntrwr<='1'; addrregwr<='1';next_state <= loadi5;

When loadi5 => vma <= '1'; rw <= '0'; next_state <= loadi6;

When loadi6 => vma <= '1'; rw <= '0'; regsel<=instrreg (2 downto 0);

Regwr <= '1'; next_state <= incpc;

When inc2 =>regSel<=instrReg(2 downto 0) ; regrd<='1'; alusel<=inc;

shiftsel<=shftpass;Outregwr <= '1';next_state <=inc3;

When inc3 => Outregrd <= '1';next_state <= inc4;

When inc4 =>outregrd<='1';regsel <= instrreg (2 downto 0) ;

Regwr <='1'; next_state <= incpc;

When incpc => progcntrrd<='1';alusel<=inc; shiftsel<=shftpass;

Outregwr <= '1';next_state<=incpc2;

When incpc2 => outregrd<='1'; progcntrwr <= '1'; addrregwr<='1';

Next_state <= incpc3;

When incpc3 => outregrd<='0'; vma<='1'; rw<='0'; instrwr<='1';

next_state<=execute;

When others => next_state <= incpc;

End case;

End process;

reg: process (clock, reset) begin

If reset = '1' then current_state <= reset1 ;

Elsif rising_edge(clock) then current_state<=next_state ; end if;

End process;

End rtl;

9.使用原理图生成节拍脉冲发生器STEP

10.使用LPM调用生成RAMK和三态门lpm_bustri0

11.编写测试程序cx.mif并使用它初始化RAM


12.由以上模块画出总电路原理图如下所示


13.仿真调试

实现了将立即数0032H存放到R1,将立即数0011H存放到R2,并将R1和R2的数据之和0043H存放在R3的功能。

14.设计新指令

①新增指令及其功能表

②修改控制器contrla.vhd的代码


library ieee;

use ieee.std_logic_1164.all;

entity contrla is

port(clock:in std_logic;reset:in std_logic;

instrreg:in std_logic_vector(15 downto 0);

compout:in std_logic;

progcntrwr:out std_logic;

progcntrrd:out std_logic;

addrregwr:out std_logic;

addrregrd:out std_logic;

outregwr:out std_logic;

outregrd:out std_logic;

shiftsel:out std_logic_vector(2 downto 0);

alusel:out std_logic_vector(3 downto 0);

compsel:out std_logic_vector(2 downto 0);

opregrd:out std_logic;

opregwr:out std_logic;

instrwr:out std_logic;

regsel:out std_logic_vector(2 downto 0);

regrd:out std_logic;

regwr:out std_logic;

rw:out std_logic;

vma:out std_logic;

we1:out std_logic);

end contrla;

architecture rtl of contrla is

constant shftpass:std_logic_vector(2 downto 0):="000";

constant alupass :std_logic_vector(3 downto 0):="0000";

constant zero :std_logic_vector(3 downto 0):="1001";

constant inc :std_logic_vector(3 downto 0):="0111";

constant plus :std_logic_vector(3 downto 0):="0101";

constant notOp :std_logic_vector(3 downto 0):="0011";type state is (reset1,reset2,reset3,execute,nop,load,store,

load2,load3,load4,store2,store3,store4,incpc,incpc2,incpc3,

loadi2,loadi3,loadi4,loadi5,loadi6,inc2,inc3,inc4,move1,move2,

add2,add3,add4,in0,in1,in2,in3,in4,out0,out1,out2,out3);

signal current_state, next_state : state;

begin

com:process(current_state,instrreg,compout) begin

progcntrwr<='0';progcntrrd<='0';addrregwr<='0';addrregrd<='0';

outregwr<='0';outregrd<='0';shiftsel<=shftpass;alusel<=alupass;

opregrd<='0';opregwr<='0';instrwr<='0';regsel<="000";

regrd<='0';regwr<='0';rw<='0';vma<='0';we1<='0';

case current_state is

when reset1=>alusel<=zero;shiftsel<=shftpass;

outregwr<='1';next_state<=reset2;

when reset2=>outregrd<='1';progcntrwr<='1';

addrregwr<='1';next_state<=reset3;

when reset3=>vma<='1';rw<='0';instrwr<='1';next_state<=execute;

when execute=>

case instrreg(15 downto 11) is

when"00000" => next_state<=incpc;

when"00001" => next_state<=load2;

when"00010" => next_state<=store2;

when"00100" => progcntrrd<='1'; alusel<=inc;

shiftsel<=shftpass;next_state<=loadi2;

when"00111" => next_state<=inc2;

when"01101" => next_state<=add2;

when"00011" => next_state<=move1;

--新定义指令:IN 从输入端口读外设数据,OUT 从端口向外设输出数据

when"01111" => next_state<=in0;--IN,从端口读外设数据到寄存器Rn

when"10010" => next_state<=out0; --OUT 向端口输出数据

when others=>next_state<=incpc;

end case;

when load2=>regsel<=instrreg(5 downto 3);regrd<='1';

addrregwr<='1';next_state<=load3;

when load3=>vma<='1';rw<='0';

regsel<=instrreg(2 downto 0);regwr<='1';

next_state<=incpc;

when add2=>regsel<=instrreg(5 downto 3);

regrd<='1'; next_state<=add3;opregwr<='1';

when add3=>regsel<=instrreg(2 downto 0);

regrd<='1';alusel<=plus;shiftsel<=shftpass;

outregwr<='1'; next_state<=add4;

when add4=>regsel<="011"; outregrd<='1';regwr<='1';

next_state<= incPc;

when move1=>regsel<=instrreg(5 downto 3);regrd<='1';

alusel<=alupass;shiftsel<=shftpass;outregwr<='1';

next_state<=move2;

When move2 => regsel <=instrReg(2 downto 0);

outregrd<='1';Regwr <='1'; next_state<=incpc;

When store2 => regsel <=instrReg(2 downto 0);

regrd<='1';addrRegwr <= '1'; next_state<=store3;

When store3 => regsel <=instrReg(5 downto 3);

regrd<='1';rw<='1'; next_state<=incpc;

When loadi2 => progcntrrd<='1';alusel<=inc;

shiftsel<=shftpass;Outregwr <='1';next_state<=loadi3;

When loadi3 =>Outregrd <='1';next_state <= loadi4;

When loadi4 =>Outregrd <= '1';progcntrwr<='1';

addrregwr<='1';next_state <= loadi5;

When loadi5 => vma <= '1'; rw <= '0';

next_state <= loadi6;

When loadi6 => vma <= '1'; rw <= '0';

regsel<=instrreg (2 downto 0);Regwr <= '1';

next_state <= incpc;

When inc2 =>regSel<=instrReg(2 downto 0) ;

regrd<='1'; alusel<=inc; shiftsel<=shftpass;

Outregwr <= '1';next_state <=inc3;

When inc3 => Outregrd <= '1';next_state <= inc4;

When inc4 =>outregrd<='1';

regsel <= instrreg (2 downto 0) ;Regwr <='1';

next_state <= incpc;

When incpc => progcntrrd<='1';alusel<=inc;

shiftsel<=shftpass;Outregwr <= '1';next_state<=incpc2;

When incpc2 => outregrd<='1'; progcntrwr <= '1';

addrregwr<='1'; Next_state <= incpc3;

When incpc3 => outregrd<='0'; vma<='1'; rw<='0';

instrwr<='1';next_state<=execute;

--以下为新的指令状态

when in0 => progCntrRd <= '1' ; aluSel<= notOp;

shiftsel<=shftpass; Outregwr <= '1';next_state <=in1;

when in1 => outregrd<='1';addrRegwr <= '1';

next_state <=in2;

when in2 => opRegRd<='1';

regSel<=instrReg(2 downto 0) ; regWr <='1';

next_state <= incpc;

when out0 => progCntrRd <= '1' ; aluSel<= notOp;

shiftsel<=shftpass;we1<='0';Outregwr <= '1';

next_state <=out1;

when out1 => outregrd<='1';addrRegwr <= '1';we1<='0';

next_state <=out2;

when out2 => we1<='0';regSel<=instrReg(2 downto 0);

RegRd<='1'; next_state <= out3; --功能仿真代码

when out3 => we1<='1'; next_state <= incpc; --功能仿真代码

--时序仿真代码 when out2 => we1<='1'; regSel<=instrReg(2 downto 0);

RegRd<='1'; next_state <= incpc;

When others => next_state <= incpc;

End case;

End process;

reg: process (clock, reset) begin

If reset = '1' then current_state <= reset1 ;

Elsif rising_edge(clock) then current_state<=next_state ;

end if;

End process;

End rtl;

③编写存储器RAMK初始化文件,该程序执行的功能是:(7802H)从输入端口读数据并存放到寄存器R2;(2001H、0001H)将立即数0001H送寄存器R1;680AH将寄存器R1和R2的内容相加后送R3;9003H将寄存器R3的内容向输出端口输出到外设。

④仿真测试(基于ModelSim-Alera的功能仿真)

程序运行总体图

7802H、2001H和0001H程序运行图

680AH执行过程图


9003H执行过程图

郑重声明:以上文章来源于网络,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库www.qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
会员咨询QQ群:902340051 入群验证:企业库会员咨询.

新的文章
 

高尔夫杂志

微信号:Golf_magazine
功能介绍:这是一本顶级专业的高尔夫杂志,帮助读者不断提升球技,同时发现高尔夫的奥妙与乐趣.