文档库

最新最全的文档下载
当前位置:文档库 > 微程序控制器实验报告

微程序控制器实验报告

、实验目的

1、通过实验,进一步理解微程序控制器的组成结构。理解微程序控制器的控制原理

2、加深理解微程序控制器的工作原理。掌握指令流程与功能

3、理解掌握微程序控制器的设计思路与方法

二、实验内容与步骤

1、微程序控制器的组成原理

控制存储器:实现整个指令系统的所有微程序,一般指令系统是规定的由高速半导体存储器构成,容量视机器指令系统而定,取决于微程序的个数,其长度就是微指令字的长度。

微指令寄存器:存放从控存读出的当前微指令。微操作控制字段将操作控制信号送到控制信号线上,

微地址字段指出下一条微地址的形成。

微地址寄存器:存放将要访问的下一条微指令地址

地址转移逻辑:形成将要执行的微指令地址,形成方式:

取指令公操作所对应的微程序一般从控存的0地址开始,所以微程序的人口地址0是由硬件控制

的。当出现分支时,通过判别测试字段、微地址字段、和执行部件的反馈信息形成后即微地址。

Cpu设计步骤:

1. 拟定指令系统

2. 确定总体结构(数据通路)

3. 安排时序

4. 拟定指令流程。根据指令系统,写出对应所有机器指令的全部微操作机器节拍安排,然后列出操作时间表

5. 确定微指令的控制方式、下地址形成方式、微指令格式及微指令字长,编写全部的微指令的代码,最后将编写的微指令

放入控制存储器中。

微程序控制器的设计步骤

(1)设计微程序确定微程序流程图,也就是控制算法流程图。

(2 )确定微指令格式

微指令格式中的操作控制字段取决于执行部件的子系统需要多少微指令。假定采用直接控制方式,执行

部件需要10个微命令,则操作控制字段需要10位。

测试判别字段取决于微程序流程图中有多少处分支转移。假定有3处分支,则测试判别字段需

要3位。

下址字段取决于微程序流程图的规模。假定微程序共用50条微指令,则下址字段至少需要6位。

这是因为ROM地址译码时,26=64,6位地址可容纳64条微指令。

(3)将微程序编译成二进制代码

(4 )微程序写入控制存储器

(5)设计硬件电路

三、实验现象

--CPU 头文件 cpu_defs

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

PACKAGE cpu_defs IS --定义程序包,包头,包体

TYPE opcode IS (load, store, add, sub, bne); --这个语句适合于定义一些用

std_logic 等不方

PORT( clock

: IN reset mode

--查看用

便定义的类型,综合器自动实现枚举类型元素的编码,一般将第一个枚举量(最左边)编码为 0

CONSTANT word_w: NA TURAL :=8; CONSTANT op_w: NATURAL :=3;

CONSTANT rfill: STD_LOGIC_VECTOR(op_w-1 downto 0):=(others =>'0'); --FUNCTIOn slv2op(slv:IN STD_LOGIC_VECTOR) RETURN opcode; FUNCTION op2slv(op:in opcode) RETURN STD_LOGIC_VECTOR; END PACKAGE cpu_defs; PACKAGE BODY cpu_defs IS

TYPE

optable IS ARRAY(opcode) OF STD_LOGIC_VECTOR(op_w-1 DOWNTO 0);--

数组有 5

个元素,其他均 0

CONSTANT trans_table:optable :=("000", "001", "010", "011", "100"); FUNCTION op2slv(op:IN opcode) RETURN STD_LOGIC_VECTOR IS BEGIN

RETURN trans_table(op);

END FUNCTION op2slv; END PACKAGE BODY cpu_defs; --实验 7-8 微程序控制器实验 LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL,IEEE.NUMERIC_STD.ALL; USE WORK.CPU_DEFS.ALL;-- 使用自己定义的程序包 ENTITY CPU IS

STD_LOGIC;-- 时钟 : IN STD_LOGIC;-- 复位

: IN STD_LOGIC_VECTOR(2 DOWNTO 0);

mem_addr : INUNSIGNED(word_w-op_w-1 DOWNTO 0);--

地址

output : OUT STD_LOGIC_VECTOR(word_w-1 DOWNTO 0);

data_r_out : OUT STD_LOGIC_VECTOR(19 DOWNTO 0);-- 微指令 R op_out : OUT STD_LOGIC_VECTOR(op_w-1 DOWNTO 0);-- 操作码

add_r_out : OUT UNSIGNED(4 DOWNTO 0) --微地址 R

); END ENTITY;

ARCHITECTURE rtl OF CPU IS

TYPE mem_array IS ARRAY (0 TO 2**(word_w-op_w)-1) OF STD_LOGIC_VECTOR(word_w-1 DOWNTO 0);-- 定义 RAM SIGNAL mem : mem_array; CONSTANT prog : mem_array:=(

0=>op2slv(load) &STD_LOGIC_VECTOR(TO_UNSIGNED(4,word_w-op_w)), 1=>op2slv(add) &STD_LOGIC_VECTOR(TO_UNSIGNED(5,word_w-op_w)), 2=>op2slv(store) &STD_LOGIC_VECTOR(TO_UNSIGNED(6,word_w-op_w)),

3=>op2slv(bne) &STD_LOGIC_VECTOR(TO_UNSIGNED(7,word_w-op_w)), --TO_UNSIGNED 转换函数将 4 转换为 5 位“ 00100 ” 4=>STD_LOGIC_VECTOR(TO_UNSIGNED(2,word_w)), 5=>STD_LOGIC_VECTOR(TO_UNSIGNED(3,word_w)), OTHERS =>(OTHERS =>'0'));

TYPE microcode_array IS ARRAY (0 TO 14) OF STD_LOGIC_VECTOR(19 DOWNTO 0); CONSTANT code : microcode_array:=(-- 控制存储器

0=>"00010100010000000001", 1=>"00000000000110000010", 2=>"00001010000000000011", 3=>"00000100001000001111", 4=>"00100010000000000000", 5=>"00000000000100000000", 6=>"00000010100001000000", 7=>"00000010100000100000", 8=>"00000000000110000100", 9=>"01000001000000000101", 10=>"00000000000110000110", 11=>"00000000000110000111", 12=>"00000000000110010000", 13=>"10000010000000000000",

14=>"00000000000000000000");

SIGNAL count SIGNAL op SIGNAL z_flag SIGNAL mdr_out SIGNAL mar_out SIGNAL IR_out SIGNAL acc_out : UNSIGNED(word_w-op_w-1 DOWNTO 0);

: STD_LOGIC_VECTOR(op_w-1 DOWNTO 0); : STD_LOGIC;

: STD_LOGIC_VECTOR(word_w-1 DOWNTO 0); : UNSIGNED(word_w-op_w-1 DOWNTO 0);

: STD_LOGIC_VECTOR(word_w-1 DOWNTO 0); : UNSIGNED(word_w-1 DOWNTO 0);

SIGNAL sysbus_out : STD_LOGIC_VECTOR(word_w-1 DOWNTO 0); EGIN PROCESS(reset,clock)

VARIABLE instr_reg : STD_LOGIC_VECTOR(word_w-1 DOWNTO 0);

VARIABLE acc CONSTANT zero VARIABLE mdr VARIABLE mar VARIABLE sysbus : UNSIGNED(word_w-1 DOWNTO 0);

: UNSIGNED(word_w-1 DOWNTO 0):=(OTHERS =>'0') : STD_LOGIC_VECTOR(word_w-1 DOWNTO 0);

: UNSIGNED(word_w-op_w-1 DOWNTO 0);

: STD_LOGIC_VECTOR(word_w-1 DOWNTO 0);

VARIABLE microcode : microcode_array;

VARIABLE add_r : UNSIGNED(4 DOWNTO 0);

VARIABLE data_r : STD_LOGIC_VECTOR(19 DOWNTO 0);

VARIABLE temp : STD_LOGIC_VECTOR(4 DOWNTO 0); BEGIN

IF reset='0' THEN add_r:=(OTHERS =>'0');

count <= (OTHERS =>'0');

instr_reg := (OTHERS =>'0'); acc := (OTHERS =>'0');

mdr := (OTHERS =>'0');

mar := (OTHERS =>'0');

z_flag <='0';

mem <= prog;

sysbus :=(OTHERS =>'0');

ELSIF RISING_EDGE(clock) THEN

--microprogram controller

data_r := code(TO_INTEGER(add_r));

IF data_r(4 DOWNTO 0)="01111"THEN -- 判断下地址 temp:="01"&op(2 DOWNTO 0);

add_r := UNSIGNED(temp);

ELSIF data_r(4 DOWNTO 0)="10000"THEN IF z_flag='1' THEN

add_r:="01110";

ELSE

add_r :="01101";

END IF;

ELSE

add_r := UNSIGNED(data_r(4 DOWNTO 0));

END IF;

data_r_out <=data_r; add_r_out <= add_r;

--PC

IF data_r(16)='1' THEN --PC_bus='1'

sysbus := rfill &STD_LOGIC_VECTOR(count);

END IF;

IF data_r(19)='1' THEN --load_PC='1'

count <= UNSIGNED(mdr(word_w-op_w-1 DOWNTO 0));

ELSIF data_r(10)='1' THEN --INC_PC='1'

count <= count+1;

ELSE

count <= count;

END IF;

--IR

IF data_r(15)='1' THEN --load_IR

instr_reg := mdr;

END IF;

IF data_r(9)='1' THEN --Addr_bus='1'

sysbus := rfill &instr_reg(word_w-op_w-1 DOWNTO 0);

END IF;

op <= instr_reg(word_w-1 DOWNTO word_w-op_w);

IR_out <= instr_reg;

op_out <=op;

--ALU

IF data_r(17)='1' THEN --load_ACC='1'acc:=UNSIGNED(mdr);

END IF;

IF data_r(11)='1' THEN --ALU_ACC='1'

IF data_r(6)='1' THEN --ALU_add='1'

acc := acc + UNSIGNED(mdr);

ELSIF data_r(5)='1' THEN --ALU_sub='1'

acc := acc - UNSIGNED(mdr);

END IF;

END IF;

IF data_r(18)='1' THEN --ACC_bus='1' sysbus := STD_LOGIC_VECTOR(acc);

END IF;

IF acc=zero THEN

z_flag <='1';

ELSE

z_flag <='0';

END IF;

acc_out<= acc;

--RAM

IF data_r(14)='1' THEN --load_MAR='1' mar := UNSIGNED(sysbus(word_w-op_w-1 DOWNTO 0));

ELSIF data_r(12)='1' THEN mdr := sysbus;

ELSIF data_r(8)='1' THEN IF data_r(7)='1' THEN

--load_MDR='1'

--CS='1'

--R_NW='1'

mdr := mem(TO_INTEGER(mar));

ELSE

mem(TO_INTEGER(mar))<=mdr;

END IF;

END IF;

IF data_r(13)='1' THEN --MDR_bus='1'

sysbus:=mdr;

END IF;

mdr_out <= mdr;

mar_out <= mar;

END IF;

sysbus_out <=sysbus;

END PROCESS;

PROCESS(mode,mem_addr)

BEGIN

--mode=0 ->sysbus

--mode=1 ->PC

--mode=2 ->result of ALU --mode=3 ->IR