一、实验题目
微程序控制器的设计与实现
二、实验目的
- 理解微程序控制器的控制原理。
- 进一步掌握指令流程和功能。
- 了解掌握微程序控制器的设计思路和方法。
三、实验要求
- 给出指令系统;
- 确定总体结构;
- 在第2步的基础上,画出微命令序列图;
- 设计一个微程序控制器,控制器能够根据指令操作码及PSW,在每个时钟读出一条微指令,发出对应的微命令。
四、实验步骤
1.指令系统
指令格式:
寻址方式:直接寻址
指令类型:Load(000) M→AC
Add(010) AC+M→AC
Sub(011) AC-M→AC
Jnz(100) M→PC
Store(001) AC→M
Inc(101) M+1 → AC
And(111) M && AC → AC
2.总体结构
- 数据寄存器:AC
- 控制寄存器:PC、IR、Z_flag
- 桥梁寄存器:MAR、MDR
- 运算器:ALU(+ -)
3.微命令序列图
4.控制器的实现
1)CM实现代码:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity register_set is
port(
clk:in std_logic;--时钟
reset:in std_logic;--复位端,低电平有效
read_signal:in std_logic;--读信号,高电平有效
PSW:in std_logic_vector(7 downto 0);--程序状态寄存器
IR:in std_logic_vector(7 downto 0);--指令寄存器(7 downto 5为OP)
address:in std_logic_vector(4 downto 0);--21个寄存器
transfer_code: out std_logic_vector(1 downto 0); --控制转移字段
next_address:out std_logic_vector(4 downto 0); --下址字段
microinstruction:out std_logic_vector(19 downto 0) --微指令字段
);
end register_set;
architecture register_set_body of register_set is
type microcode_array is array(18 downto 0) of std_logic_vector(26 downto 0);
signal reg : microcode_array;
signal ZF:std_logic;
signal OP:std_logic_vector(2 downto 0);
signal data:std_logic_vector(26 downto 0);
signal current_address:std_logic_vecter(4 downto 0);
constant code : microcode_array:=(
0 => "000010001010000000000000001",--0转1
1 => "000001000001000000010000010",--1转2
2 => "010000000100000000000000011",--2转3
3 => "000010010000000000001000000",--3转8
4 => "000000000000000000000000000",--4转0
5 => "000000000000100000000000000",--5转0
6 => "101000000100010000100000000",--6转0
7 => "101000000100000001100000000",--7转0
8 => "000001000001000000010000100",--3转8转4
9 => "000001100000000000000000101",--3转9转5
10 => "000001000001000000010000110",--ADD 3转10转6
11 => "000001000001000000010000111",--SUB 3转11转7
12 => "000001000001000000010001111",--JNZ 3转12转15/16
13 => "000001000001000000010010001",--INC 3转13转17
14 => "000001000001000000010010010",--AND 3转14转18
15 => "000100000100000000000000000",--Z_flag=0 15转0
16 => "000000000000000000000000000",--Z_flag=1 空 16转0
17 => "101000000100001010100000000",--17转0
18 => "101000000100000100100000000"--18转0
);
begin
ZF <= PSW(0);
OP(2) <= IR(7);
OP(1) <= IR(6);
OP(0) <= IR(5);
process (reset,clk,read_signal,address)
begin
if reset='0' then--复位端低电平有效
reg <= code;
else -- reset信号无效时控制器正常工作
if(clk'event and clk = '1') then --时钟为上升沿有效
data <= reg(conv_Integer(address));
end if;
end if;
microinstruction <= data(26 downto 7);--26到7位是微指令字段
transfer_code <= data(6 downto 5);--6到5位是控制转移字段
next_address <= data(4 downto 0);--4到0位是下址字段
end process;
end register_set_body;
2)微地址形成部件代码:
----------------------微地址形成部件-------------------
--当转移控制字段为“00”时,下址字段直接提供下条微指令的地址;
--当转移控制字段为“10”时,根据指令操作码形成下一条微指令地址;
--当转移控制字段为“01”时,根据ZF的值修改下址字段,实现分支。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity microaddress is
port(
clk:in std_logic;--时钟
reset:in std_logic;--复位端,低电平有效
PSW:in std_logic_vector(7 downto 0);--程序状态寄存器
IR:in std_logic_vector(7 downto 0);--指令寄存器(7 downto 5为OP)
transfer_of_control:in std_logic_vector(1 downto 0);--控制转移字段
next_address:in std_logic_vector(4 downto 0);--下址字段
follow_address:out std_logic_vector(4 downto 0)--下一个地址
);
end microaddress;
architecture be_microaddress of microaddress is
signal OP:std_logic_vector(2 downto 0);--操作码
signal ZF:std_logic;--零标志位
begin
--OP分别对应IR的高三位
OP(2) <= IR(7);
OP(1) <= IR(6);
OP(0) <= IR(5);
ZF <= PSW(0);--PSW的最低位是ZF
process(clk,reset,transfer_of_control,next_address,OP,ZF)
begin
if reset = '0' then --复位端,低电平有效
follow_address <= "00000";--清零
else
if transfer_of_control = "00" then
follow_address <= next_address;
elsif transfer_of_control = "10" then
follow_address(0) <= OP(0);
follow_address(1) <= OP(1);
follow_address(2) <= OP(2);
follow_address(3) <= '1';
follow_address(4) <= '0';
elsif transfer_of_control = "01" then
follow_address(0) <= ZF;
follow_address(1) <= '0';
follow_address(2) <= '0';
follow_address(3) <= '0';
follow_address(4) <= '1';
end if;
end if;
end process;
end be_microaddress;
5.微程序控制器的连接图
6.仿真图
首先说明一下我设计的这个微程序控制器的基本情况:
(1)微指令格式:LoadAC、LoadIR、LoadPSW、LoadPC、LoadMAR、LoadMDR、AC_bus、Addr_bus、PC_bus、MDR_bus、IncPC、MemR、MemW、ALUop(5位)、selA(2位)、selM(2位)、条件字段、下址字段
(2)微指令条数:19条
(3)下址字段:5位
(4)转移控制:OP + ZF 两位
(5)微指令:27位
(6)OP为IR指令寄存器的高三位
(7) OP:000、001、010、011、100、101、111分别对应于指令LOAD、STORE、ADD、SUB、JNZ、INC、AND
(8) OP转移地址:01000、01001、01010、01011、01100、01101、01110、01111分别对应于状态8、9、10、11、12、13、14、15
(9)当转移控制字段为“00”时,下址字段直接提供下条微指令的地址;当转移控制字段为“10”时,根据指令操作码形成下一条微指令地址;当转移控制字段为“01”时,根据ZF的值修改下址字段,实现分支。
接下来,对仿真图进行分析,如图5所示:图示所在时间段IR为“11100000”,即OP为“111”,按照设计要求,寄存器将执行AND指令。
首先输出状态S0的微指令(00001000101000000000),根据控制转移字段transfer_code为“00”,则下址字段next_address跳转到状态S1(00001);然后输出状态S1处的微指令(00000100000100000001),根据控制转移字段transfer_code为“00”,则下址字段跳转到状态S2(00010);接着输出状态S2处的微指令(01000000010000000000),根据控制转移字段transfer_code为“00”,则下址字段跳转到状态S3(00011);再接着,输出状态S3处的微指令(00001001000000000000),根据控制转移字段transfer_code为“10”,则下址字段next_address跳转到状态S14(01110);再然后,输出状态S14处的微指令(00010000010000000000),根据控制转移字段transfer_code为“00”,则下址字段跳转到状态S18(10010);然后,输出状态S18处的微指令(10100000010000010010),根据控制转移字段transfer_code为“00”,则下址字段跳转到状态S0(00000),AND指令的完整运算过程就是这样。分析完毕。
五、总结与思考
本次实验我设计的是微程序控制器,设计步骤如下:
1、拟定指令系统
- 指令格式:总共27位,其中20位微命令字段、2位控制转移字段、5位下址字段
- 寻址方式:直接寻址
- 指令类型:包括Load、Add、Sub、Jnz、Store、Inc、And,总共7种
2、确定总体结构
- 数据寄存器:AC
- 控制寄存器:PC、IR、Z-flag
- 桥梁寄存器:MAR、MDR
- ALU:+ -
- 总体结构示意图
3、写出微命令序列图
- 写出指令流程
- 写出微命令序列
- 画出状态转换表
- 画出ASM图
4、形成微程序逻辑
5、完成各部件的连接
至此微程序控制器的总体设计就大概完成了。
那么微程序控制器有什么优点吗?答案是肯定的。与之相对的硬布线控制器存在一些缺陷:逻辑设计比较繁杂,而且每当需要新增或删除指令时,都需要对整个系统进行变更。因此,人们发明了微程序控制器。硬布线控制器的一条指令中有多个时钟周期,每个时钟周期对应一个状态,而一个状态对应一组并发控制信号,而微程序的思想是将并发信号事先存储为微指令,而一条指令就对应多条微指令,那么每一个状态就相当于是并发信号所在的存储器地址。微程序是一种软硬结合的思想,可以避免复杂的逻辑设计。
通过本次实验,我理解了微程序控制器的控制原理;进一步掌握了指令流程和功能;了解掌握了微程序控制器的设计思路和方法。