青岛理工大学控制器设计.doc
【精品文档】如有侵权,请联系网站删除,仅供学习与交流青岛理工大学控制器设计.精品文档.青岛理工大学实 验 报 告 实验课程: 计算机组成原理I 实验日期: 2014 年 11月7日, 交报告日期:2014 年11月 日,成绩:实验地点:现代教育技术中心305(计算机实验室) 计算机工程 学院,计算机科学与技术 专业, 班级:计算122班 实验指导教师: 龚玉玺 批阅教师:龚玉玺同组学生姓名郝兴明徐鹏学号201207051201207065一、 实验课题按照题目要求设计计算机控制器的基本逻辑(不包括微操作信号产生电路),决定外部的端口(名称、有效电平)和内部各元件的连接,画出系统框图和逻辑图,设计仿真数据,用VHDL编程和仿真。实验内容:用层次结构设计的方法设计控制器的指令部件。下层元件的设计已经在实验3中完成。包括:程序计数器、指令寄存器、数据寄存器、地址寄存器、指令译码器等。本实验只需要做顶层设计。顶层设计功能要求:具有控制器的部分基本功能,能够控制取指令操作、控制访存取数据操作、控制访存存数据操作、指令译码,等。取指令机器周期:把程序计数器的内容送到地址总线,延迟一段时间后把从存储器中读出的指令(通过数据总线读入),送到指令寄存器;每取一个指令字程序计数器加1。取数据机器周期:把地址寄存器的内容送到地址总线,延迟一段时间后把从存储器中读出的数据(通过数据总线)送到数据寄存器。存数据机器周期:把地址寄存器的内容送到地址总线,把数据寄存器中的数据送到数据总线,延迟一段时间后结束。 指令译码:假设操作码在指令字的最高3位。提示1: 控制器内部数据通路,可以是总线结构,也可以是直接连接结构。提示2: 控制器与系统总线的连接方法,有两种结构可以考虑: 程序计数器、指令寄存器、数据寄存器、地址寄存器都与系统总线有直接连接。 只有数据寄存器和地址寄存器与系统总线连接。程序计数器和指令寄存器不与系统总线连接。程序计数器内容必须先送到地址寄存器,然后才能到地址总线。从存储器中读出的指令必须先送到数据寄存器,然后才能到指令寄存器。仿真 设计仿真波形数据,模拟取指令、访存取数据、访存存数据等操作。要考虑到所有可能的情况。在实验报告中必须清楚说明仿真波形数据是怎样设计的。二、 逻辑设计控制器系统框图zpc控制器LoadqetrldzaLoaddLoadaLoadid0d7ic0ic7qa7.qa0qd0qd7zqzdclkCot1Cot0端口说明:Loadq,loadd:数据寄存器的同步置数端口Loada:地址寄存器的同步置数端口Loadi:指令寄存器的同步置数端口zq,zd;数据寄存器的三态控制端口Clk:时钟信号Zpc:程序计数器的三态控制端口Za:地址寄存器的三态控制端口ld:程序计数器的同步置数端口r:程序计数器的同步清零端口et:程序计数器的加1控制端口cot:cot(0),cot(1)分别控制数据寄存器和程序计数器向地址寄存器和指令寄存器的数据传送qd:数据的双向输入输出端口(连接系统数据总线)数据从外部先送到系统总线才可以送到数据寄存器da:地址寄存器输出端口(连接系统地址总线)ic:经过译码器输出的控制信号d:程序计数器的置数端口。控制器逻辑图Y0Y7.3-8译码器A2A0A1q6q7.系统总线.q7cldet.d7d0q5.q0Loaddd0d7d7d0指令寄存器loadclkCot(0)d7d0d7d0clkLoadqzdzqq0q7Cot(1)数据寄存器q7q0d7d0q0zLoadclk地址寄存器rzclk程序计数器Cot(0)三、 VHDL源程序library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;-ContolUnitentity control_unit isport-loadd,loadq,loada,loadi同步置数端口高电平有效-zq,zd三态控制端口,低电平有效-zpc,za三态控制端口,高电平有效-clk时钟信号,上升沿有效-ld程序计数器的预置数端口,低电平有效-r程序计数器的清零端口,低电平有效-et控制程序计数器自动加1功能-qd数据从内存读出数据后送入系统总线的输入端,也是输出端口-ic译码器的输出端口,即:控制信号。-cot是控制数据在寄存器间传输的信号-cot(0)控制DR到IR的数据流通-cot(1)控制程序计数器到AR的数据流通-d程序计数器的输入端口loadd,loadq,loada,loadi,zq,zd,clk,ld,r,et,za,zpc : in std_logic;cot : in std_logic_vector(1 downto 0);qd : inout std_logic_vector(7 downto 0);d : in unsigned(7 downto 0);ic : out std_logic_vector(7 downto 0);qa : out std_logic_vector(7 downto 0)end control_unit;architecture behave of control_unit is-数据总线和地址总线-signal ABUS : std_logic_vector(7 downto 0);-signal DBUS : std_logic_vector(7 downto 0);-引用地址寄存器component address_register port -load同步并行置数-z三态输出 z=1 is valide signal-d输入-q输出load ,z ,clk : in std_logic;d : in std_logic_vector(7 downto 0);q : out std_logic_vector(7 downto 0)end component;-引用数据寄存器component data_register port-clk时钟信号-zq控制q端口的三态-zd控制d端口的三态-load1,load2同步并行置数.loadd控制d,loadq控制q-d输入输出双向端口-q输入输出端口clk,zd,zq,loadd,loadq : in std_logic;d : inout std_logic_vector(7 downto 0);q : inout std_logic_vector(7 downto 0)end component;-引用译码器component decodeportA : in std_logic_vector(2 downto 0);-输入Y : out std_logic_vector(7 downto 0)-输出end component;-引用程序计数器component eight_countport -et控制自动加1的端口-clk时钟信号-c进位输出-z三态们 z=1-ld预制数控制端 ld=0-r同步清零端 r=0有效et,clk,z,ld,r :in std_logic;c : out std_logic;d : in unsigned(7 downto 0);q : out unsigned(7 downto 0)end component;-引用指令寄存器component instruction_registerportclk ,load : in std_logic;d : in std_logic_vector(7 downto 0);q : out std_logic_vector(7 downto 0)end component;-在程序计数器和地址寄存器之间的内部信号signal pcdr : std_logic_vector(7 downto 0);signal USpcdr : unsigned(7 downto 0);-在数据寄存器到指令寄存器之间的内部信号signal drir : std_logic_vector(7 downto 0);signal deir : std_logic_vector(7 downto 0);-暂存信号signal t1 : std_logic_vector(7 downto 0);signal t2 : std_logic_vector(7 downto 0);signal t3 : std_logic_vector(7 downto 0);begin P1 : process(cot) begin if cot(1) = '0' then t1<=(others=>('Z'); else t1<=pcdr; end if; if cot(0)='0' thent2<=(others=>('Z'); else t2<=drir;end if; end process;-实例化程序计数器,PC : eight_count port map(clk=>clk,z=>zpc,et=>et,d=>d,ld=>ld,r=>r,q=>USpcdr);-convert unsigned data to std_logic_vector;pcdr<=conv_std_logic_vector(USpcdr,8);-t1 <= cot(1) and pcdr;-实例化地址寄存器AR : address_register port map(clk=>clk,z=>za,load=>loada,d=>t1,q=>qa);-实例化数据寄存器DR : data_register port map(clk=>clk,zq=>zq,zd=>zd,loadd=>loadd,loadq=>loadq,q=>qd,d=>drir);-实例化指令寄存器IR : instruction_register port map(clk=>clk,load=>loadi,d=>t2,q=>deir);-实例化译码器DE : decode port map(A=>deir(7 downto 5),Y=>ic);end behave;-address_registerlibrary ieee;use ieee.std_logic_1164.all;entity address_register isport -load同步并行置数-z三态输出 z=1 is valide signal-d输入-q输出load ,z ,clk : in std_logic;d : in std_logic_vector(7 downto 0);q : out std_logic_vector(7 downto 0)end address_register;architecture behave of address_register issignal iq : std_logic_vector(7 downto 0);beginprocess(clk,z,load)beginif rising_edge(clk) and load = '1' theniq<=d;end if;if z='1' thenq<=(others=>'Z');elseq<=iq;end if;end process;end behave;-data registerlibrary ieee;use ieee.std_logic_1164.all;entity data_register isport-clk时钟信号-zq控制q端口的三态-zd控制d端口的三态-load1,load2同步并行置数.loadd控制d,loadq控制q-d输入输出双向端口-q输入输出端口clk,zd,zq,loadd,loadq : in std_logic;d : inout std_logic_vector(7 downto 0);q : inout std_logic_vector(7 downto 0)end data_register;architecture behave of data_register issignal iq : std_logic_vector(7 downto 0);begin process(clk,zd,zq,loadd,loadq)beginif rising_edge(clk) thenif loadd = '1' and zd = '0' then-因为d是双向端口,当d作为输入端口时, -d作为输出端口时应该是高阻态,否则会产生线与 iq <=d; d<=(others=>'Z');end if;if loadq = '1' and zq = '0' theniq<=q;q<=(others=>'Z');end if;end if;if zd = '0' then -三态门关闭d<=(others=>'Z');else d<=iq;end if;if zq = '0' then-三态门关闭q<=(others=>'Z');else q<=iq;end if;end process;end behave ;-Decodelibrary ieee;use ieee.std_logic_1164.all;entity decode isportA : in std_logic_vector(2 downto 0);-输入Y : out std_logic_vector(7 downto 0)-输出end decode; architecture de_behave of decode is signal s: std_logic;beginprocess(A)begincase A iswhen "000"=> Y<="11111110"when "001"=> Y<="11111101"when "010"=> Y<="11111011"when "011"=> Y<="11110111"when "100"=> Y<="11101111"when "101"=> Y<="11011111"when "110"=> Y<="10111111"when "111"=> Y<="01111111"end case;end process;end de_behave;-eight_countlibrary ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;entity eight_count isport -et控制自动加1的端口-clk时钟信号-c进位输出-z三态们 z=1-ld预制数控制端 ld=0-r同步清零端 r=0有效et,clk,z,ld,r :in std_logic;c : out std_logic;d : in unsigned(7 downto 0);q : out unsigned(7 downto 0)end eight_count;architecture behave of eight_count issignal iq : unsigned(7 downto 0);beginprocess (clk,et,z,ld,r)beginif rising_edge(clk) thenif r = '0' then-同步清零iq<=(others=>'0');elsif ld = '0' then iq<=d;-预制数elsif et = '1' then iq<=iq+1;-计数end if;end if;if iq = 255 then c <='1'-计数到255,产生进位else c<='0'end if;q<=iq;if z = '1' then -三态们关闭 c<='Z' q<=(others=>'Z');end if;end process;end behave;library ieee;use ieee.std_logic_1164.all;entity instruction_register isportclk ,load : in std_logic;d : in std_logic_vector(7 downto 0);q : out std_logic_vector(7 downto 0)end instruction_register;architecture behave of instruction_register issignal save : std_logic_vector(7 downto 0);begin process(clk , load)beginif rising_edge(clk) and load='1' thensave<=d;end if;q<=save;end process;end behave;四、 仿真设计由于元器件的仿真在实验3中已经做过,所以此处不再进行元器件的仿真。首先令clk每隔10纳秒翻转一次。et=1(有效),ld=1(无效),r=1(无效)这是程序计数器处于工作状态。取指令:在第三个时钟上升沿时,zpc=0,(程序计数器三态门打开),loada=1(地址寄存器同步控制端有效),za=0(地址寄存器三态门打开),Cot(1)=1(让pc输出的数据传入地址寄存器),这是输出应该是00000010,因为程序计数器刚好计数三个。访存取指令:下一个时钟上升沿时.qd=11111111,zq=0,zd=1,loadq=1,loadd=0.za=1,zpc=1,loada=0,loadi=1,cot(0)=1下一个时钟上升沿时:zd=1(数据寄存器的三态门打开),loadi=1(指令寄存器的同步置数端口有效),cot=01(让数据寄存器里的数据传入指令寄存器)。结果ic输出的应该是qd的高三位对应的指令控制信号011111111.访存存数据:下一个时钟上升沿:Zq=1,其它信号都处于无效状态。这是数据寄存器的三态门打开,数据送到系统总线,然后存入存储器。输出的应该是先前存入的数据11111111验证cot的有效性:下二个时钟上升沿:za=0,zpc=0,loada=1,cot分别等于00和10以验证控制数据传入的信号的有效性。五、 结果分析讨论从图中可以看出,当没有置数之前,ic的值是111111110,,那是因为软件默认传入A端口的值是000,从qa的第一变化开始出也可以看出,za=0三态门打开的时候在时钟上升沿来到之前qa由ZZZZZZZZ变为00000000中也可以得到佐证。时钟上升沿来到的时候,za的三态门是打开的,于是就把其中的地址输出,00000010,,正好是第三次时钟上升沿应该有的数据。然后,从qd植入数据11111111,虽然数据寄存器到总线的三态门是关闭的qd输入却是置入的数据,这是正确的。因为输入输出端口是一个端口,在此时此刻就应该显示qd置入的数据。然后把数据寄存器中保存的指令,传入指令寄存器,得到输出结果01111111。这真是译码器中的111对应的输出。然后zq的三态门打开,数据寄存器中的数据送到系统总线,显示的是上一次置入的数据。此系统总线上的数据可以送到存储器中。然后验证cot的有效性,从图中的可以看出,两次时钟上升沿中,第一次由于cot处于无效状态qa的输出是高组态(虽然三态门已经打开),而后一次,由于cot处于有效状态,qa输出的是第九次时钟上升沿的数据00001000这一副图也是验证cot有效性的。但它是验证数据寄存器和指令寄存器之间的cot的有效性的。