计算机组成原理:VHDL设计组合逻辑控制器(代码思路清晰易懂)

一、实验题目

组合逻辑控制器的设计与实现

二、实验目的

  1. 理解组合逻辑控制器的控制原理;
  2. 进一步掌握指令流程和微命令序列的概念;
  3. 了解并掌握组合逻辑控制器的设计过程和方法。

三、实验要求

  1. 给出指令系统;
  2. 确定总体结构;
  3. 画出状态图;
  4. 用状态机实现组合逻辑控制器。

四、实验步骤

1.指令系统

指令格式:

 

寻址方式:直接寻址

指令类型:Load(000)      M→AC

                  Add(010)       AC+M→AC

                  Sub(011)       AC-M→AC

                  Jnz(100)       M→PC

                  Store(001)     AC→M

                  And(110)       AC and M → AC

                  Or(111)        AC or M → AC

2.总体结构

 3.状态图

4.控制器的实现           (给出实现代码、实现的仿真图,并进行分析)

实现代码:

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY me IS
  PORT(CP :IN STD_LOGIC;      --时钟
      RESET:IN STD_LOGIC;       --复位端
     PSW:IN STD_LOGIC_VECTOR(1 downto 0);--标志位寄存器:OF SF ZF CF
     IR:IN STD_LOGIC_VECTOR(7 downto 0);--IR包括OP和IO,OP为7 downto 5
     
     PC_bus:OUT STD_LOGIC;
     LoadMAR:OUT STD_LOGIC;
     IncPC:OUT STD_LOGIC;
     MemR:OUT STD_LOGIC;
     LoadMDR:OUT STD_LOGIC;
     selM:OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
     MDR_bus:OUT STD_LOGIC;
     LoadIR:OUT STD_LOGIC;
     Addr_bus:OUT STD_LOGIC;
     AC_bus:OUT STD_LOGIC;
     Memw:OUT STD_LOGIC;
     LoadAC:OUT STD_LOGIC;
     selA:OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
     LoadPC:OUT STD_LOGIC;
     LoadPSW:OUT STD_LOGIC;
     ALUop:OUT STD_LOGIC_VECTOR(4 DOWNTO 0)
     );
END me;

ARCHITECTURE A OF me IS 
  TYPE STATE IS (S0,S1,S2,S3,S4,S5,S6,S7,S8,S9,S10);  --State Type Declare(10个)
  SIGNAL  PRESENTSTATE  :STATE;  --PRESENT STATE(当前状态)
  SIGNAL  NEXTSTATE    :STATE;  --NEXT STATE(下一个状态)
  Signal OP : std_logic_vector(2 downto 0);  --操作码
   Signal Z_flag : std_logic;--零标志位
BEGIN
  OP <= IR(7 downto 5);
   Z_flag <= PSW(1);
SWITCHTONEXTSTATE:PROCESS(CP)    --PRESENTSTATE->NEXTSTATE
  BEGIN
    IF RESET='1'  THEN PRESENTSTATE <= S0;  --复位端有效(高电平)的时候,设置当前状态为S0状态
    ELSIF CP'EVENT AND CP='1' THEN     --时钟上升沿有效
      PRESENTSTATE<=NEXTSTATE;
    END IF;
END PROCESS SWITCHTONEXTSTATE;

CHANGESTATEMODE:PROCESS(PRESENTSTATE,PSW,IR)
  BEGIN
  CASE PRESENTSTATE IS
    WHEN S0=>          --STATE S0  
        --OUTPUT
        PC_bus <= '1';  
        LoadMAR <= '1';  
        IncPC <= '1';
        NEXTSTATE <= S1;
        
    WHEN S1=>          --STATE S1
        --OUTPUT
        MemR <= '1';    
        LoadMDR <= '1';  
        selM <= "10";
        NEXTSTATE <= S2;
        
    WHEN S2=>          --STATE S2  
        --OUTPUT
        MDR_bus <= '1';  
        LoadIR <= '1';
        NEXTSTATE <= S3;
        
    WHEN S3=>          --STATE S3
        --OUTPUT
        Addr_bus <= '1'; 
        LoadMAR <= '1';
        IF (OP = "001") THEN 
          NEXTSTATE <= S4; 
        ELSE 
          NEXTSTATE <= S6; 
        End IF;
        
    WHEN S4=>              --STATE S4(STORE)
        --OUTPUT
        AC_bus <= '1'; 
        LoadMDR <= '1'; 
        selM <= "01"; 
        NEXTSTATE <= S5; 
      
    WHEN S5 =>            --STATE S5
        --OUTPUT
         Memw <= '1'; 
        NEXTSTATE <= S0; 
      
    WHEN S6 =>            --STATE S6(LOAD)
          --OUTPUT
         MemR <= '1'; 
        LoadMDR <= '1'; 
        selM <= "10"; 
        IF OP = "000" THEN 
          NEXTSTATE <= S7;
         ELSIF OP = "010" THEN 
          NEXTSTATE <= S8;
         ELSIF OP = "011" THEN 
          NEXTSTATE <= S8;
         ELSIF OP = "100" THEN 
          IF Z_flag = '1' 
            THEN NEXTSTATE <= S9;--JNZ
          ELSE NEXTSTATE <= S10;
          END IF;
        END IF;
      
    WHEN S7 =>         --STATE S7
        --OUTPUT
         MDR_bus <= '1'; 
         LoadAC <= '1'; 
         selA <= "01"; 
         NEXTSTATE <= S0; 
      
    WHEN S8 =>         --STATE S8
        --OUTPUT
         MDR_bus <= '1'; 
        LoadAC <= '1'; 
        selA <="10"; 
        LoadPSW <= '1'; 
        IF OP = "010" THEN 
          ALUop <= "00000";    selA <= "10"; --ADD
        ELSIF OP = "011" THEN 
          ALUop <= "00001";    selA <= "10"; --SUB
        ELSIF OP = "111" THEN 
          ALUop <= "00101";    selA <= "10"; --或
        ELSIF OP = "110" THEN 
          ALUop <= "01001";    selA <= "10"; --与
        END IF;
        NEXTSTATE <= S0;
    WHEN S9 =>        --STATE S9
        --OUTPUT
         MDR_bus <= '1'; 
        LoadPC <= '1'; 
        NEXTSTATE <= S0; 
    WHEN S10 =>
        NEXTSTATE <= S0; 
        
    END CASE;
  END PROCESS CHANGESTATEMODE;
END A;

仿真图:

         根据以上仿真图,首先从初始状态S0开始,没有转移条件,输出为PC_bus = '1',LoadMAR = '1',IncPC = '1',下一个状态为S1。到达状态S1之后,没有转移条件,输出MemR = '1',LoadMDR = '1',selM = "10",下一个状态为S2。到达状态S2之后,没有转移条件,输出MDR_bus = '1',LoadIR = '1',下一个状态为S3。到达状态S3之后,输出Addr_bus = '1',LoadMAR = '1',以OP(即仿真图里面IR的高三位)的取值作为状态转移条件来进行状态转移:当OP为"001"时,根据预先的设计要求,进入下一个状态S4实现STORE操作再输出AC_bus = '1',LoadMDR = '1',selM = "01"接着直接转移到下一个状态S5,输出Menw = '1'最后再回到初始状态S0,这样就完成了一条完整的STORE指令操作。当OP为其他值时,进入下一个状态S6,输出MemR = '1',LoadMDR = '1',selM = "10",然后继续根据OP的取值进行选择,当OP为‘000’时,进入状态S7,此时实现的就是LOAD操作,输出MDR_bus = '1',LoadAC = '1',selA = "01",最后再回到初始状态S0,这样就完成了一条完整的LOAD指令操作;当OP为‘010’和‘011’时,进入到状态S8,输出MDR_bus = '1',LoadAC = '1',selM = "10",LoadPSW = '1';当OP为‘100’并且零标志位Z_flag为1时,进入下一个状态S9,输出MDR_ bus = '1',LoadPC = '1',最后再回到初始状态S0,这样就完成了一条完整的JNZ指令操作。当进入到状态S8时,再根据ALUop的取值进行选择哪种运算:当ALUop 为"00000"时,执行ADD运算;当ALUop 为"00001"时,执行SUB运算;当ALUop 为"00101"时,执行OR运算;当ALUop 为"01001"时,执行AND运算,不管进行哪种运算,最终都会返回到初始状态S0。这样,我这个组合逻辑控制器完整的运行过程就分析完毕了。

五、总结与思考

本次实验我设计的是一台八位机,能实现多个数的累加和。设计步骤如下:

1、拟定指令系统

  • 指令格式:总共8位,包括3位的操作码,5位的地址码
  • 寻址方式:直接寻址
  • 指令类型:包括Load、Add、Sub、Jnz、Store、And、Or,总共7种

2、确定总体结构

  • 数据寄存器:AC
  • 控制寄存器:PC、IR、Z-flag
  • 桥梁寄存器:MAR、MDR
  • ALU:+  -  and  or
  • 最终的数据通路

3、设计状态图

    1)写出指令流程

    2)写出微命令序列

    3)画出状态转换表

    4)画出ASM图

4、形成控制逻辑

5、完成各部件的连接

至此组合逻辑控制器的总体设计就大概完成了。

        在实验过程中,各个寄存器之间的通路得理清,画状态转换表的时候,可以将那些输出完全相同的当成同一个状态,对程序进行简化。写代码时,不能缺少任何一个输出,确保所有输出端口都写上,否则整个组合逻辑控制器将无法正常工作。

        通过这次实验,我理解了组合逻辑控制器的控制原理;进一步掌握了指令流程和微命令序列概念;了解并掌握了组合逻辑控制器的设计过程和方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寥若晨星666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值