微程序控制器实验报告

时间:2024.4.20

                            

一、实验目的

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 等不方便定义的类型,综合器自动实现枚举类型元素的编码,一般将第一个枚举量(最左边)编码为0

       CONSTANT word_w: NATURAL :=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

PORT( clock      : IN   STD_LOGIC;--时钟

             reset      : IN   STD_LOGIC;--复位

             mode       : 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    :  UNSIGNED(word_w-op_w-1 DOWNTO 0);

       SIGNAL op       :  STD_LOGIC_VECTOR(op_w-1 DOWNTO 0);          

       SIGNAL z_flag   :  STD_LOGIC;                         

       SIGNAL mdr_out  :  STD_LOGIC_VECTOR(word_w-1 DOWNTO 0);  

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

       SIGNAL IR_out   :  STD_LOGIC_VECTOR(word_w-1 DOWNTO 0);   

       SIGNAL acc_out  :  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       : UNSIGNED(word_w-1 DOWNTO 0);

       CONSTANT zero      : UNSIGNED(word_w-1 DOWNTO 0):=(OTHERS =>'0')

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

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

       VARIABLE sysbus    : 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   --load_MDR='1'

                     mdr := sysbus;

              ELSIF data_r(8)='1' THEN   --CS='1'

                     IF data_r(7)='1' THEN      --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

              --mode=4 -> MAR

              --mode=5 -> MDR

              --mode=6 -> mem                                                      

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

              CASE mode is                   

             

WHEN "000" => 

                     output<=sysbus_out;

              WHEN "001" =>                  

                     output(word_w-op_w-1 DOWNTO 0)<= STD_LOGIC_VECTOR(count);

              WHEN "010" =>

                     output <= STD_LOGIC_VECTOR(acc_out);

              WHEN "011" =>

                     output <= IR_out; 

              WHEN "100" =>

                     output(word_w-op_w-1 DOWNTO 0) <= STD_LOGIC_VECTOR(mar_out);

              WHEN "101" =>

                     output <= mdr_out;      

              WHEN "110" =>

                     output <= mem(TO_INTEGER(mem_addr));

              WHEN others =>

                     output <= (OTHERS =>'Z'); 

              END CASE;                     

       END PROCESS;                                      

END ARCHITECTURE;      

现象结果:

    

四、实验体会

原本对于控制器的设计还是一片空白,通过实验初步理解微程序控制器的组成结构。理解微程序控制器的控制原理,加深了理解微程序控制器的工作原理。

更多相关推荐:
微程序控制器实验报告

计算机组成原理实验报告计算机组成原理实验报告1计算机组成原理实验报告一实验目的1掌握微程序控制器的组成原理2掌握微程序的编制写入观察微程序的运行过程二实验设备PC机一台TDCMA实验系统一套三实验原理微程序控制...

微程序控制器实验

计算机科学与技术系实验报告专业名称计算机科学与技术课程名称计算机组成原理项目名称微程序控制器实验班级学号姓名同组人员实验日期一、实验目的与要求实验目的(1)掌握微程序控制器的组成原理(2)掌握微程序控制器的编制…

计算机组成原理实验报告三:微程序控制器实验

微程序控制器实验报告一实验目的1掌握微程序控制器的功能组成知识2掌握为程序的编制写入观察微程序的运行二实验设备PC机一台TDCM3实验系统一套三实验原理微程序控制器的基本任务是完成当前指令的翻译和执行即将当前指...

计算机组成原理实验报告3 微程序控制器实验

计算机组成原理实验报告实验三微程序控制器实验一实验目的与要求实验目的1理解时序产生器的原理了解时钟和时序信号的波形2掌握微程序控制器的功能组成知识3掌握微指令格式和各字段功能4掌握微程序的编制写入观察微程序的运...

组成原理实验报告3 微程序控制器

计算机组织与体系结构实验报告320xx15姓名学号班级课题微程序控制器1实验目的1掌握微程序控制器的组成原理2掌握微程序的编制写入观察微程序的运行过程2实验设备PC机一台TDCMA实验系统一套3实验步骤1按图3...

计算机组成原理微程序控制器实验报告

计算机组成原理实验报告三微程序控制器实验20xx0506010009分类实验报告标签实验微程序字段微指令信号字号大中小订阅实验三微程序控制器实验一实验目的与要求实验目的1掌握时序产生器的原理和具体操作2掌握微程...

微程序控制器的组成与微程序设计实验报告

信息学院实验报告注每学期至少有一次设计性实验每学期结束请任课老师按时按量统一交到教学秘书处

实验四 微程序控制器设计实验

实验四微程序控制器设计实验该实验的图表可参考计算机组成原理题解题库实验书的193页第六节常规型微程序控制器组成实验一实验目的1掌握时序产生器的组成原理2掌握微程序控制器的组成原理3加深理解微指令与机器指令的关系...

计算机组成原理—微程序控制器组成实验

34常规型微程序控制器组成实验一实验目的1掌握时序发生器的组成原理2掌握微程序控制器的组成原理二实验电路1时序发生器本实验所用的时序电路见图34电路由一个500KHz晶振2片GAL22V10一片74LS390组...

微程序控制器实验

计算机组成原理实验报告班级计算机二班姓名李小硕学号08143103微程序控制器实验报告将微命令的集合仿照机器指令一样用数字代码的形式表示这种表示称为微指令可以用一个微指令序列表示一条机器指令这种微指令序列称为微...

计算机组成原理微程序控制器组成实验课程实验报告书

学生课程实验报告书13级计算机与信息科学系软件工程专业1303班学号3138907308姓名王明渊20xx20xx学年第2学期另外它还产生节拍信号W1W3的控制时钟CLK1该芯片的逻辑功图34时序信号发生器本次...

实验四 微程序控制器原理实验

信息与管理科学学院计算机与科学技术系课程名称计算机组成原理与系统结构实验名称微程序控制器原理实验姓名学号1110101043班级计科112班实验室紫竹地下实验室指导教师日期20xx419实验报告实验四微程序控制...

微程序控制器实验报告(17篇)