控制器,看名字就可以大概知道这个部件的作用了--根据指令产生各个部件的控制信号。也就是我们所有的部件控制信号都是通过这个控制器发出来的,而这些信号的产生是根据具体的指令来控制的,这个过程都由控制器完成。
实现这个部件有两个基本的思路:
- 对于每一条指令(共16条):根据判断给来输出对应的信号。这样有什么好处呢,显然,通过每一条指令我们很容易给出所有控制信号应该被赋予的值,那么我们也很容易给出所有情况下的赋值。但是缺点就是这样写必然比较繁琐,控制信号这么多,每一条指令都要赋一次值虽然写起来比较直观但是比较繁琐。
- 先对16条指令设计一个指令译码器,再将译码器的输出设计一个组合电路,输出为各个部件的控制信号,举个栗子:比如现在给F(移位逻辑的直传控制信号)赋值,当指令对应的操作为MOV或者ALU运算或者对操作数取非运算时F应该为1,故F=MOVA+MOVB+MOVC+ALU+NOT0,其它的信号跟这个差不多的原理可以得到逻辑表达式。这个看似要设计两个部分,但是实际操作起来却比较简洁,因为每个控制信号只需要赋一次值,而译码器相当于重用了部分逻辑组合,也简化了整体的电路。
这里的设计采用的是第二种方法:
一、译码器的设计:
判断一下当前输入的指令是那种操作,然后使该输出为高电平,其他为低电平即可。
(1)VHDL代码:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity ZLYMQ is
port(A :in std_logic_vector(3 downto 0);
B :in std_logic_vector(3 downto 0);
MOVA,MOVB,MOVC,ALU,NOT0,SH,JMP,
JZ,JC,IN0,OUT0,NOP,HEAL:
out std_logic);
end entity ZLYMQ;
architecture A_YMQ of ZLYMQ is
signal output:std_logic_vector(12 downto 0):="0000000000000";
begin
process (A,B)
begin
if A="1111" then
if(B(3 downto 2)="11") then output<="0000000000010";
elsif(B(1 downto 0)="11")then output<="0000000000100";
else output<="0000000000001";
end if;
elsif(A="1001"or A="0110"or A="1110")then output<="0000000001000";
elsif(A="0101")then output<="0000000010000";
elsif(A="1010")then output<="0000000100000";
elsif(A="0001")then
if(B(1 downto 0)="00")then output<="0000001000000";
elsif(B(1 downto 0)="01")then output<="0000010000000";
else output<="0000100000000";
end if;
elsif(A="0010")then output<="0001000000000";
elsif(A="0100")then output<="0010000000000";
elsif(A="0111")then output<="0100000000000";
elsif(A="1000")then output<="1000000000000";
else output<="0000000000000";
end if;
end process;
MOVA<=output(0);MOVB<=output(1);MOVC<=output(2);ALU<=output(3);
NOT0<=output(4);SH<=output(5);JMP<=output(6);JZ<=output(7);
JC<=output(8);IN0<=output(9);OUT0<=output(10);NOP<=output(11);HEAL<=output(12);
end architecture A_YMQ;
(2)
引脚说明:
A,B:数据输入端,分别是指令的前四位和后四位;
数据输出端及含义如下表所示:
(3)波形仿真:
当前四位A值为0000时为无效指令。其余情况下,任意时刻,输出端口中只有一个端口的值为高电平,端口的选择由A和B共同控制,控制规则如上表指令系统表所示。
二、组合电路的设计:
(1)VHDL代码:
library ieee;
use ieee.std_logic_1164.all;
entity KZQ is
port(A,B:in std_logic_vector(3 downto 0);
MOVA,MOVB,MOVC,ALU,NOT0,SH,JMP,JZ,
JC,IN0,OUT0,NOP,HEAL,C,Z,SM:in std_logic;
F,FL,FR,M,RAA1,RAA0,RWBA1,RWBA0,WE:out std_logic;
DXEN,CS,LDPC,INPC,LDIR:out std_logic;
MADD:out std_logic_vector(1 downto 0);
S:out std_logic_vector(3 downto 0));
end KZQ;
architecture ST of KZQ is
begin
process(A,B,MOVA,MOVB,MOVC,ALU,NOT0,SH,JMP,JZ,JC,IN0,OUT0,NOP,HEAL,C,Z,SM)
begin
F<=MOVA or MOVB or MOVC or ALU or NOT0;
if(SH='1')then
if(B(1 downto 0)="00")then FR<='1';FL<='0';
else FR<='0';FL<='1';
end if;
else FR<='0';FL<='0';
end if;
M<=ALU or NOT0;
RAA1<=B(1);RAA0<=B(0);RWBA1<=B(3);RWBA0<=B(2);
WE<=not(MOVA or MOVC or ALU or NOT0 or SH);
S<=A;
if(SM='0')then DXEN<='1';CS<='X';
elsif(MOVB='1')then DXEN<='0';CS<='1';
elsif(MOVC='1' or JMP='1' or JC='1' or JZ='1')then DXEN<='1';CS<='X';
else DXEN<='0';CS<='0';
end if;
LDPC<=((not SM) or (JMP or JZ or JC )or NOP)and (not HEAL) ;
INPC<=(not SM) or (not (JMP or (JZ and Z) or (JC and C))) or NOP;
LDIR<=not SM;
if(SM='0')then MADD<="00";
elsif(MOVB='1')then MADD<="10";
elsif(MOVC='1')then MADD<="01";
else MADD<="00";
end if;
end process;
end ST;
(2)
引脚说明:
输入输出端口分别为:
输入端口为指令译码器的输出端口以及A(指令的前四为),B(指令的后四位),C(ALU的进位判断),Z(ALU的运算结果是否为0),SM(控制取指令周期和执行周期);
输出端口对应为各个部件的输入端口。
(3)波形仿真:
未进行波形仿真(逃~)。
将这译码器的输入作为组合电路的输入,输出便是各个部件的控制信号。