硬布线控制器的基本原理,每个微操作控制信号S是一系列输入量的逻辑函数,即用组合逻辑来实现
S=f(Im, Mi, Tk, Bj)
其中 Im 是机器指令操作码译码器的输出信号,Mi 是节拍电位信号,Tk 是节拍脉冲信号,Bj 是状态条件信号。
在TEC-8实验系统中,节拍脉冲信号Tk(T1~T3)已经直接输送到数据通路,因为机器指令系统比较简单,省去操作码译码器,4位指令操作码IR4~IR7直接直接成为Im的一部分;由于TEC-8实验系统有控制台操作,控制台操作可以看做一些特殊的功能复杂的指令,因此SWC、SWB、SWA可以看做是Im的一部分。Mi是时序发生器产生的节拍信号W1~W3,我们将利用SHORT、LONG信号控制产生不同操作需要的节拍数;Bj包括ALU产生的进位信号C、结果为0信号Z。
设计硬布线控制器的控制流程,就是解决Im、Mi、Tk、Bj如何起作用的问题。我们设计硬布线控制器使用流程图,以节拍电位为时间单位,一个节拍电位的时间是从T1的上升沿到T3的下降沿的一段时间。在我们的流程图中,一个执行框代表了一个节拍电位时间。
在我们的硬布线控制器的设计中,是根据流程图来编写代码,即通过判断一系列输入量,来确定控制器处于哪一个执行框,然后发射出相应的微操作信号。这种方式相比于译码表,逻辑更加清晰易懂,更容易检错纠错,更利于功能扩展。对于一些控制台操作,需要4个节拍电位才能完成规定的功能。为了满足这种情况,我们将控制台操作化为两条机器指令的节拍。为了区分控制台操作的两个不同阶段,我们我们加了个ST0内部信号作为标志位,当ST0=0时,执行操作的第一阶段;当ST0=1时,执行操作的第二阶段。并且,只有当T3的下降沿的时候,我们的ST0才能发生翻转,所以我们又设了个SST0内部信号作为ST0的触发信号,当SST0=1,且T3的下降沿到来时,ST0发生翻转。
源代码:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY cpu IS
PORT(SW:IN std_logic_vector(2 Downto 0); --向量形式简洁易懂
IR:IN std_logic_vector(7 Downto 4);
W1,W2,W3:IN std_logic;
C,Z,CLR,T3:IN std_logic;
ARINC,CIN,DRW,LPC,LAR,LIR,LDZ,LDC,PCINC,PCADD,SELCTL,M,MEMW,STOP:OUT std_logic;
SHORT,LONG,ABUS,SBUS,MBUS:OUT std_logic;
S,SEL:OUT std_logic_vector(3 Downto 0));
END cpu;
ARCHITECTURE cont OF cpu IS
SIGNAL ST0:std_logic;
SIGNAL SST0:std_logic;
BEGIN
PROCESS(ST0,SST0,SW,IR CLR,T3,W1,W2,W3) --敏感信号表
BEGIN
IF (CLR='0') THEN --clear信号
ST0<='0';
SST0<='0';
CIN<='0'; --初始值
DRW<='0';
LPC<='0';
LAR<='0';
LIR<='0';
LDZ<='0';
LDC<='0';
PCINC<='0';
PCADD<='0';
SELCTL<='0';
M<='0';
S<="0000";
SEL<="0000";
MEMW<='0';
STOP<='0';
SHORT<='0';
LONG<='0';
ABUS<='0';
SBUS<='0';
MBUS<='0';
ARINC<='0';
ELSE
CIN<='0'; --初始值
DRW<='0';
LPC<='0';
LAR<='0';
LIR<='0';
LDZ<='0';
LDC<='0';
PCINC<='0';
PCADD<='0';
SELCTL<='0';
M<='0';
S<="0000";
SEL<="0000";
MEMW<='0';
STOP<='0';
SHORT<='0';
LONG<='0';
ABUS<='0';
SBUS<='0';
MBUS<='0';
ARINC<='0';
SST0<=(NOT ST0)AND ((SW(2)AND(NOT(SW(1)))AND(NOT SW(0))AND W2)OR((NOT SW(2))AND SW(1)AND(NOT SW(0))AND W1)OR((NOT SW(2))
AND (NOT SW(1)) AND SW(0) AND W1));
--用译码形式表示SST0
IF(SST0='1' ) THEN
IF (T3'EVENT AND (T3='0'))THEN --T3下降沿
ST0<='1';
END IF;
END IF;
CASE SW IS
--根据硬连线控制器参考流程图采用流程的形式
WHEN "100" => --写寄存器
IF (ST0='0') THEN
IF (W1='1') THEN
SBUS<='1';
SEL<="0011";
SELCTL<='1';
DRW<='1';
STOP<='1';
END IF;
IF (W2='1') THEN
SBUS<='1';
SEL<="0100";
SELCTL<='1';
DRW<='1';
STOP<='1';
SST0<='1';
END IF;
END IF;
IF (ST0='1') THEN
IF (W1='1') THEN
SBUS<='1';
SEL<="1001";
SELCTL<='1';
DRW<='1';
STOP<='1';
END IF;
IF (W2='1') THEN
SBUS<='1';
SEL<="1110";
SELCTL<='1';
DRW<='1';
STOP<='1';
END IF;
END IF;
WHEN "011" => --读寄存器
IF (W1='1') THEN
SEL<="0001";
SELCTL<='1';
STOP<='1';
END IF;
IF (W2='1') THEN
SEL<="1011";
SELCTL<='1';
STOP<='1';
END IF;
WHEN "010"=> --读存储器
IF (ST0='0') THEN
IF (W1='1') THEN
SBUS<='1';
LAR<='1';
STOP<='1';
SHORT<='1';
SELCTL<='1';
SST0<='1';
END IF;
END IF;
IF (ST0='1') THEN
IF (W1='1') THEN
MBUS<='1';
ARINC<='1';
STOP<='1';
SHORT<='1';
SELCTL<='1';
END IF;
END IF;
WHEN "001"=> --写存储器
IF (ST0='0') THEN
IF (W1='1') THEN
SBUS<='1';
LAR<='1';
STOP<='1';
SHORT<='1';
SELCTL<='1';
SST0<='1';
END IF;
END IF;
IF (ST0='1') THEN
IF (W1='1') THEN
SBUS<='1';
MEMW<='1';
ARINC<='1';
STOP<='1';
SHORT<='1';
SELCTL<='1';
END IF;
END IF;
WHEN "000"=> --取指
IF (W1='1') THEN
LIR<='1';
PCINC<='1';
END IF;
CASE IR IS
WHEN "0001"=> --ADD
IF (W2='1') THEN
S<="1001";
CIN<='1';
ABUS<='1';
DRW<='1';
LDZ<='1';
LDC<='1';
END IF;
WHEN "0010"=> --SUB
IF (W2='1') THEN
S<="0110";
ABUS<='1';
DRW<='1';
LDZ<='1';
LDC<='1';
END IF;
WHEN "0011"=> --AND
IF (W2='1') THEN
M<='1';
S<="1011";
ABUS<='1';
DRW<='1';
LDZ<='1';
END IF;
WHEN "0100"=> --INC
IF (W2='1') THEN
S<="0000";
ABUS<='1';
DRW<='1';
LDZ<='1';
LDC<='1';
END IF;
WHEN "0101"=> --LD
IF (W2='1') THEN
M<='1';
S<="1010";
ABUS<='1';
LAR<='1';
LONG<='1';
END IF;
IF (W3='1') THEN
DRW<='1';
MBUS<='1';
END IF;
WHEN "0110"=> --ST
IF (W2='1') THEN
M<='1';
S<="1111";
ABUS<='1';
LAR<='1';
LONG<='1';
END IF;
IF (W3='1') THEN
S<="1010";
M<='1';
ABUS<='1';
MEMW<='1';
END IF;
WHEN "0111"=> --JC
IF (W2='1') THEN
IF (C='1') THEN
PCADD<='1';
END IF;
END IF;
WHEN "1000"=> --JZ
IF (W2='1') THEN
IF (Z='1') THEN
PCADD<='1';
END IF;
END IF;
WHEN "1001"=> --JMP
IF (W2='1') THEN
M<='1';
S<="1111";
ABUS<='1';
LPC<='1';
END IF;
WHEN "1010"=> --OUT
IF (W2='1') THEN
M<='1';
S<="1010";
ABUS<='1';
END IF;
WHEN "1011"=> --OR
IF (W2='1') THEN
M<='1';
S<="1110";
ABUS<='1';
DRW<='1';
LDZ<='1';
END IF;
WHEN "1100"=> --XOR
IF (W2='1') THEN
M<='1';
S<="0110";
ABUS<='1';
DRW<='1';
LDZ<='1';
END IF;
WHEN "1101"=> --DOUBLE
IF (W2='1') THEN
S<="1100";
CIN<='1';
ABUS<='1';
DRW<='1';
LDZ<='1';
LDC<='1';
END IF;
WHEN "1110"=> --STP
IF (W2='1') THEN
STOP<='1';
END IF;
WHEN OTHERS=>SBUS<='0';
END CASE;
WHEN OTHERS=>SBUS<='0';
END CASE;
END IF;
END PROCESS;
END cont;