112
现代计算机组成原理
第 4 章 CPU 功能模块设计
CPU 硬件主要由控制器、运算器、存储器、输入设备和输出设备五部分组成。本章
及下一章拟将传统计算机组成原理实验中涉及的 CPU 功能模块和 CPU 完全使用 VHDL
和 EDA 技术来表述与构建,介绍构建此 CPU 中的各模块的功能、结构、工作原理和设
计方法,最终完成一个片上计算机系统的构建。
4.1 8 位 CPU 功能与结构
CPU 由基本的功能模块和与之相连接的数据通路所组成。设计时须首先了解 CPU
的功能及其基本模块的功能。然后进行基本模块的设计、综合、调试、仿真和硬件实现,
即硬件设计,然后进行指令系统的设计和程序调试,即软件设计。
1. CPU 的功能
欲使计算机系统完成具体的任务,就要使各部件协调工作。CPU 的功能就是通过软
件指令的执行,控制各部件协调工作,具体可归结为以下四个方面。
(1)指令控制。若要计算机解决某个问题,程序员就要编制程序,而程序是指令
的有序集合。按照“存储程序控制”的概念,程序被装入主存后,计算机应能按其预先
设定的要求有序地执行指令,才能完成具体的任务。因此,严格控制程序的执行顺序,
是 CPU 的首要任务。
(2)操作控制。一条指令的执行,要涉及计算机中的若干个部件。控制这些部件
协同工作,则要靠各操作信号的有机配合。因此 CPU 产生操作信号,传送给被控部
件,并能检测各个部件发送的信号,从而协调各个工作部件,按指令要求完成规定的
任务。
(3)时序控制。欲使计算机正常地工作,对各种操作信号的产生时间、稳定时间、
撤销时间及相互之间的关系都应有严格的要求。对操作信号施加时间上的控制,称为
时序控制。只有严格的时序控制,才能保证各功能部件组合,构成协调工作的计算机
系统。
(4)数据加工。对涉及数值数据的算术运算、逻辑变量的逻辑运算以及其他非数
值数据(如字符、字符串)的处理,称为数据加工。数据加工处理是完成程序功能的基
础,因此它是 CPU 的基本任务。
2. CPU 的组成结构
CPU 由运算器和控制器两大部分组成。这两部分功能各异,但工作配合密切。
图 4-1 是 8 位 CPU 主要组成部件逻辑结构示意图。其中,运算器主要由算术逻辑单元
(ALU)、数据寄存器、缓冲寄存器、状态寄存器组成,是数据的加工处理部件,由它
第 4 章 CPU 功能模块设计
113
执行算术运算和逻辑运算。运算器接受控制器的命令而发出执行动作,它进行的全部操
作都由控制器发出的控制信号来控制。
图 4-1 CPU 组成部件逻辑结构图
从图 4-1 可以看到,控制器由程序计数器、指令寄存器、指令译码器、时序产生器
和操作控制器五部分组成。控制器是协调和指挥整个计算机系统工作的“决策机构”。
控制器的主要任务有以下三个方面:
(1)取指。即从主存中取出一条指令,存放到指令寄存器中。指令的操作码部分
送给指令译码器,并修改程序计数器,指出下一条指令在主存中的存放地址。
(2)译码。对译码器中指令操作码进行识别和解释,产生相应的操作控制信号,
启动相应的部件,完成指令规定的动作。
(3)数据流控制。指挥和控制 CPU、主存及输入输出部件之间的数据流动方向。
4.2 CPU 中的基本部件
CPU 由运算器和控制器等基本部件组成,是数据加工处理部件。运算器接受控制器
的命令完成具体的数据加工任务。运算器对累加器和数据缓冲寄存器的内容进行算术运
算或逻辑运算,运算的结果保存到累加器中,同时建立相应的状态标志,并存放到状态
寄存器中。
4.2.1 算术逻辑单元
算术逻辑单元(ALU)是计算机的核心部件之一,它能执行加法和减法等算术运算,
也能执行“与”、“或”、“非”等逻辑运算。
算术逻辑单元的基本功能可以根据 74LS181 的功能用 VHDL 编辑而成。
如表 4-1 所示,M 引脚是算术运算/逻辑运算的方式选择位。当 M=H(高电平)时,
ALU 进行逻辑运算;当 M=L(低电平)时,ALU 进行算术运算。Cn 是低位的进位,
当 Cn 为低电平时,做无进位运算;而当 Cn 为高电平时,做有进位运算。S3、S2、S1、
S0 分别是 4 位运算操作方式的选择控制端,从 0000~1111 共有 16 种不同的选择。在算
114
现代计算机组成原理
术运算方式下或逻辑运算方式下都分别具有各自不同的 16 种运算操作。
在例 4-1 程序中,各端口信号的作用分别是:S 是 ALU 的操作选择信号;A 和 B
分别是参加算术运算或逻辑运算的两个 8 位输入操作数;F 是 ALU 运算后的 8 位数据
输出结果;CN 是进入 ALU 进行算术运算的低位进位位,或进行逻辑运算的进位标志;
M 是进行算术运算或逻辑运算的控制位,M=0 时进行算术运算,M=1 时进行逻辑运算;
CO 是运算结果产生进位/借位的输出标志位;FZ 是运算结果为零的输出标志位;COUT
是输出标志位。
表 4-1 ALU181 的运算功能
选择端
S3 S2 S1 S0
M = H 逻辑操作
高电平作用数据
M = L 算术操作
Cn = L(无进位)
Cn = H(有进位)
0 0 0 0
0 0 0 1
0 0 1 0
0 0 1 1
0 1 0 0
0 1 0 1
0 1 1 0
0 1 1 1
1 0 0 0
1 0 0 1
1 0 1 0
1 0 1 1
1 1 0 0
1 1 0 1
1 1 1 0
1 1 1 1
F
F A=
+
=
F
A B
F AB=
0F =
AB=
F
F B=
= ⊕
F A B
F AB=
+
=
F A B
=
⊕
B
A
F B=
F AB=
1F =
= +
F A B
= +
F A B
F A=
F A=
= +
F A B
F A B
= +
F = 减 1(2 的补码)
F = A 加 AB
F = (A+B)加 AB
F = A 减 B
F = A+ B
F = A 加 AB
F = A 加 B
F = (A+ B )加 AB
F
F = AB
F = A 加 A *
F = A 加 1
F = (A+B) 加 1
+1
= +
F A B
0F =
F = A 加 AB 加 1
F = (A+B)加 AB +1
F = A 减 B 减 1
F = (A+ )B 减 1
F = A 加 AB 加 1
AB
加)
F = A 加 B 加 1
( +
=
BA
F = AB 减 1
F = A 加 A 加 1
加 1
F = (
F = (A+B)加 A
A B+ 加 A
F = A
)
F = (
F = (
)
A B+ 加 A 加 1
A B+ 加 A 加 1
)
F = A 减 1
注:① * 表示每一位都移至下一更高有效位,“+”是逻辑或,“加”是算术加。
② 在借位减法表达上,表 4-1 与 TTL 器件 74LS181 的真值表略有不同。
例 4-1 是算术逻辑单元的 VHDL 程序。图 4-2 是 ALU 逻辑
结构图。
【例 4-1】
图 4-2 ALU 逻辑
结构图
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY ALU181 IS
PORT(S : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
第 4 章 CPU 功能模块设计
115
A,B : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
F : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
COUT : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
M,CN : IN STD_LOGIC;
CO,FZ : OUT STD_LOGIC );
END ALU181;
ARCHITECTURE behav OF ALU181 IS
SIGNAL A9,B9,F9 : STD_LOGIC_VECTOR(8 DOWNTO 0);
BEGIN
A9 <= '0' & A ; B9 <= '0' & B ;
PROCESS(M,CN,A9,B9)
BEGIN
CASE S IS
WHEN "0000"=>IF M='0' THEN F9<=A9 + CN ; ELSE F9<=NOT A9; END IF;
WHEN "0001"=>IF M='0' THEN F9<=(A9 OR B9)+CN; ELSE F9<=NOT(A9 OR B9);
END IF;
WHEN "0010"=>IF M='0' THEN F9<=(A9 OR(NOT B9))+CN;
ELSE F9<=(NOT A9)AND B9; END IF;
WHEN "0011"=>IF M='0' THEN F9<= "000000000"-CN ; ELSE F9<="000000000";
END IF;
WHEN "0100"=>IF M='0' THEN F9<=A9+(A9 AND NOT B9)+CN ;
ELSE F9<=NOT(A9 AND B9); END IF;
WHEN "0101"=>IF M='0' THEN F9<=(A9 OR B9)+(A9 AND NOT B9)+CN ;
ELSE F9<=NOT B9; END IF;
WHEN "0110"=>IF M='0' THEN F9<=A9 -B9 - CN;ELSE F9<=A9 XOR B9; END IF;
WHEN "0111"=>IF M='0' THEN F9<=(A9 AND(NOT B9))-CN ;
ELSE F9<=A9 AND(NOT B9); END IF;
WHEN "1000" =>IF M='0' THEN F9<=A9 +(A9 AND B9)+CN;
ELSE F9<=(NOT A9)OR B9;END IF;
WHEN "1001" =>IF M='0' THEN F9<=A9 + B9 + CN; ELSE F9<=NOT(A9 XOR B9);
END IF;
WHEN "1010" =>IF M='0' THEN F9<=(A9 OR(NOT B9))+(A9 AND B9)+CN ;
ELSE F9<=B9; END IF;
WHEN "1011" =>IF M='0' THEN F9<=(A9 AND B9)- CN ; ELSE F9<=A9 AND
B9; END IF;
WHEN "1100" =>IF M='0' THEN F9<=A9 + A9 + CN; ELSE F9<= "000000001";
END IF;
WHEN "1101" =>IF M='0' THEN F9<=(A9 OR B9)+A9 + CN ;
ELSE F9<=A9 OR(NOT B9); END IF;
WHEN "1110" =>IF M='0' THEN F9<=(A9 OR(NOT B9))+A9+CN; ELSE F9<=A9
OR B9;END IF;
WHEN "1111" =>IF M='0' THEN F9<=A9-CN; ELSE F9<=A9 ; END IF;
WHEN OTHERS =>F9<= "000000000" ;
116
现代计算机组成原理
END CASE;
IF(A9= B9)THEN FZ <= '0';END IF;
END PROCESS;
F<= F9(7 DOWNTO 0); CO <= F9(8);
COUT <= "0000" WHEN F9(8)= '0' ELSE "0001" ;
END behav;
4.2.2 数据缓冲寄存器
数据缓冲寄存器(DR)用来存放 CPU 从主存读出的一个指令字或一个数据字,简
称暂存寄存器。缓冲寄存器的作用如下:
(1)作为 CPU 与主存、外围设备之间的信息中转站,对数据起暂存作用。
(2)为算术逻辑部件 ALU 提供一个或两个参加运算的操作数。
数据缓冲寄存器采用锁存器结构。例 4-2 是数据缓冲寄存器的 VHDL 描述。数据宽
度为 8 位,DIN[7..0]是数据输入端;DOUT[7..0]是数据输出端;gate 是数据锁存控制端,
当 gate 为高电平时,数据进入锁存器;而当 gate 为低电平时,锁存器保持已输入的数据。
【例 4-2】
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY LATCH8 IS
PORT( GATE : IN STD_LOGIC;
DIN : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
DOUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END LATCH8;
ARCHITECTURE behav OF LATCH8 IS
BEGIN
PROCESS(GATE, DIN)
BEGIN
IF GATE = '1' THEN DOUT <= DIN ; END IF;
END PROCESS;
END behav;
状态寄存器用来保存执行算术运算指令、逻辑运算指令及各类测试指令时,自动产
生的状态结果,为后续指令的执行提供判断条件。这些状态结果主要包括运算结果进位
标志和运算结果为零标志等。状态寄存器也采用锁存器结构。
寄存器也可以直接调用 LPM 模块来实现。LPM 模块的应用将在 4.2.4 节中详细
介绍。
4.2.3 移位运算器
移位运算器主要完成移位运算功能。移位运算器也使用 VHDL 编写。
移位运算器是时序电路,在时钟信号到来时状态产生变化,CLK 为其时钟脉冲。
由 S0、S1、M 分别控制移位运算的功能状态。移位运算器具有数据装入、数据保持、
循环右移、带进位循环右移,循环左移、带进位循环左移等功能,其具体功能如表 4-2
所示。
第 4 章 CPU 功能模块设计
117
移位运算器的 VHDL 描述如例 4-3 所示。
表 4-2 移位运算器的功能
S0
0
0
0
1
1
1
M
任意
0
1
0
1
任意
功 能
保持
循环右移
带进位循环右移
循环左移
带进位循环左移
加载待移位数
S1
0
1
1
0
0
1
G
0
0
0
0
0
任意
【例 4-3】
Library IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY SHIFTER IS
PORT(CLK, M, C0 : IN STD_LOGIC;
S : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
D : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
QB : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
CN : OUT STD_LOGIC);
END ENTITY;
ARCHITECTURE BEHAV OF SHIFTER IS
SIGNAL ABC : STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL REG : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL CY : STD_LOGIC ;
BEGIN
PROCESS(CLK,ABC,C0)
BEGIN
IF CLK'EVENT AND CLK = '1' THEN
CASE ABC IS
WHEN "011" =>REG(0)<= C0; REG(7 DOWNTO 1)<= REG(6 DOWNTO 0);
CY <= REG(7);--带进位循环左移
WHEN "010"=>REG(0)<=REG(7);REG(7 DOWNTO 1)<=REG(6 DOWNTO 0);--循环左移
WHEN "100"=>REG(7)<=REG(0); REG(6 DOWNTO 0)<=REG(7 DOWNTO 1);--循环右移
WHEN "101" =>REG(7)<= C0 ; REG(6 DOWNTO 0)<= REG(7 DOWNTO 1);
CY <= REG(0);--带进位循环右移
WHEN "110" =>REG(7 DOWNTO 0)<= D(7 DOWNTO 0); --加载待移位数
WHEN "111" =>REG(7 DOWNTO 0)<= D(7 DOWNTO 0); --加载待移位数
WHEN OTHERS => REG <= REG ; CY <= CY ; --保持
END CASE;
END IF;
118
现代计算机组成原理
END PROCESS;
ABC <= S & M; QB(7 DOWNTO 0)<= REG(7 DOWNTO 0); CN <= CY;
END BEHAV;
例 4-3 中,CLK 是时钟脉冲,S[1..0]和 M 控制移位运算的功能状态;D[7..0]是装入
数据的输入端;C0 是进位位的输入端;CN 是进位位移位后的输出端;QB[7..0]是移位
器的数据输出端。
4.2.4 程序存储器与数据存储器
程序存储器是用来存放用户程序的,通常采用只读存储器 ROM 来存储程序。数据
存储器存放运算数据及中间结果,一般采用随机存储器 RAM 来实现其功能。这里主要
介绍利用 LPM 模块构建程序存储器和数据存储器的方法。
CPU 中的一些重要部件,如 RAM、ROM 等,可直接调用 LPM 模块构成。因此在
FPGA 中利用嵌入式阵列块可以构成各种结构的存储器。以下将通过一个正弦信号发生
器的设计流程,详细介绍利用 MegaWizard Plug-In Manager 进行 LPM 模块调用和测试
的一般方法。
1. 工作原理
图 4-3 所示的正弦信号发生器的结构由四个部分组成:计数器或地址发生器(这里
选择 6 位)正弦信号数据 ROM(6 位地址线,8 位数据线,含有 64 个 8 位数据/周期),
VHDL 顶层设计,8 位 D/A(实验中用 DAC0832 代替)。
图 4-3 正弦信号发生器结构框图
图 4-3 所示的信号发生器结构图中,顶层文件 singt.vhd 在 FPGA 中实现,包含两个部分:
ROM 的地址信号发生器,由 6 位计数器担任;一个正弦数据 ROM,由 LPM_ROM 模块构
成。LPM_ROM 是由嵌入式模块 EAB 或 M4K 等构成。地址发生器时钟 CLK 的输入频率 f0
与每周期的波形数据点数(在此选择 64 点),以及 D/A 输出的频率 f 的关系是
2. 定制初始化数据文件
f = f0 /64
在此首先确定图 4-3 中 ROM 内的波形数据文件。QuartusII 能接受的 LPM_ROM 模
块 中 的 初 始 化 数 据 文 件 的 格 式 有 两 种 :Memory Initialization File (.mif ) 格 式 和
Hexadecimal(Intel-Format)File(.hex)格式。以下以 64 点正弦波形数据为例分别说明。
实际应用中只要使用其中一种格式的文件即可。
第 4 章 CPU 功能模块设计
119
(1)建立.mif 格式文件。首先在 QuartusII 中选择 ROM 数据文件编辑窗口,即在
File 菜单中选择 New,并在 New 窗口中选择 Other files 页,再选择 Memory Initialization
File 项,单击 OK 按钮后产生 ROM 数据文件大小选择窗口。根据 64 点 8 位正弦数据的
情况,可选 ROM 的数据数 Number 为 64,数据宽 Word size 取 8 位。单击 OK 按钮,
将出现如图 4-4 所示的空的 MIF 数据表格。表格中的数据格式可通过鼠标右键单击窗口
边缘的地址数据弹出的窗口选择。此表中任一数据(如第三行的 99)对应的地址为左
列与顶行数之和(如 16+2=18。十六进制为 12H,即 00010010)。然后将波形数据填入此
表中。完成后,在 File 菜单中单击 Save as 按钮,保存此数据文件,在这里不妨取名为
romd.mif。
也可以使用 QuartusII 以外的编辑器设计 MIF 文件,其格式如例 4-4 所示。其中地
址和数据都为十六进制,冒号左边是地址值,右边是对应的数据,并以分号结尾。
【例 4-4】
WIDTH = 8;
DEPTH = 64;
ADDRESS_RADIX = HEX;
DATA_RADIX = HEX;
CONTENT BEGIN
0 : FF;
1 : FE;
2 : FC;
3 : F9;
4 : F5;
…(数据略去)
3E : FE;
3F : FF;
END;
(2)建立.hex 格式文件。
建立.hex 格式文件有两种方法。第一种方法与以上介绍的方法相同,只是在 New
窗口中选择 Other files 项后,选择 Hexadecimal(Intel-Format)File 项,最后存盘.hex 格
式文件。第二种方法是用普通 8051 单片机编译器来产生。方法是利用汇编程序编辑器
将此 64 个数据编辑于如图 4-5 所示的编辑窗口中,然后用单片机 ASM 编译器产生.hex
格式文件。在此不妨取名为 sdata.asm,编译后得到 sdata.hex 文件。以下的示例拟使用
sdata.hex 文件。
注意,sdata.asm 和生成的目标文件 sdata.hex 都在本项工程文件夹内的 dataHEX 文
件夹中以备调用(d:\sin_gnt\dataHEX\),详细路径见图 4-6。
不难发现,这里提到的.hex 格式文件生成的第二种方法很容易应用到 51 单片机
/CPU 设计中,或程序 ROM 调用应用程序的设计技术中。
请注意图 4-6 中文件的路径结构,信号发生器工程的主文件存放路径是 d:\sin_gnt\,
而 d:\sin_gnt\dataHEX\ 中仅存放波形数据文件 sdata.hex!推荐以这种方式使用 ROM 数
据文件,但不要用“data”等容易与其他名称相混淆的名称作为文件夹名。