《单周期CPU的设计与实现》-实验指导书

更新时间:2024-04-18 08:12:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

电子科技大学计算机科学与工程学院

单周期CPU的设计与实现

实验指导书

[计算机组成原理实验]

张建 2013-12-13

计算机组成原理实验单周期CPU的设计与实验

目录

前言 ................................................................................................................................................................ 1

1.1 实验内容 ......................................................................................................................................... 2 1.2实验要求 .......................................................................................................................................... 2 2. 实验环境 ................................................................................................................................................... 3

2.1 硬件平台 ...................................................................................................................................... 3 2.2 软件平台 ...................................................................................................................................... 3 2.3 实验主要仪器设备连接框图 ....................................................................................................... 4 3. 实验原理 ................................................................................................................................................... 5

3.1 概述 .............................................................................................................................................. 5 3.2 单周期CPU的总体电路 ............................................................................................................. 5 3.3 MIPS指令格式 ............................................................................................................................. 6 3.4 数据路径设计 .............................................................................................................................. 7 3.4.1 下一条指令地址的选择 ......................................................................................................... 7 3.4.2 ALU的输入端......................................................................................................................... 8 3.4.3寄存器堆的输入端.................................................................................................................. 8 4. 基本功能部件的设计与实现 .................................................................................................................. 10

4.1 32位2选1选择器的设计与实现 ............................................................................................. 10 4.2 32位4选1选择器的设计与实现 ............................................................................................. 18 4.3 5位2选1选择器的设计与实现 ............................................................................................... 19 4.4 带有异步清零的32位D触发器的设计与实现 ...................................................................... 19 4.5 移位器的设计 ............................................................................................................................ 20 4.6 32位加/减法器的设计与实现.................................................................................................... 20 5.运算器(ALU)的设计与实现 ............................................................................................................ 21 6.寄存器堆(Register File)的设计与实现 ............................................................................................ 24 7.控制器(Control Unit)的设计与实现 ................................................................................................ 27 8. CPU的封装 .............................................................................................................................................. 30 9. 测试 ......................................................................................................................................................... 32

9.1 指令存储器及测试程序 ............................................................................................................. 32 9.2 数据存储器及测试数据 ............................................................................................................. 33 9.3 仿真测试 .................................................................................................................................... 33 9.4 下载到开发板验证..................................................................................................................... 35 附件: .......................................................................................................................................................... 39

BTN_Anti_Jitter模块 .......................................................................................................................... 39 Hex7seg_decode模块 .......................................................................................................................... 39

计算机组成原理实验单周期CPU的设计与实验

前 言

《计算机组成原理》是计算机科学专业的一门重要专业基础课。在该课程中的理论学习中系统地阐述了计算机各组成部件的工作原理、逻辑实现和设计方法及将各部件连接成整机的方法,计算机硬件与底层软件的接口,培养了学生对计算机硬件系统的分析、开发与设计的基本技能能力。

本实验开设的目的是让学生通过设计一个单周期的CPU,加深对计算机各组成部件功能的理解和掌握,更好地理解计算机的基本工作原理,培养和锻炼学生掌握计算机硬件设计的基本方法和技能。本实验是计算机硬件系列实验的重要实验,是后续计算机系统实验的基础。

本实验的先修课程:《数字逻辑》及《Verilog HDL硬件描述语言》。

对于未修先修课程的学生实验指导教师应对其进行相关知识的培训,培训建议4学时。

本实验所针对的教材:《计算机组成与设计-硬件/软件接口》第4版,(美)David A.

Patterson、John L. Hennessy著,机械工作出版社,2012.1

计算机科学与工程学院 1

计算机组成原理实验单周期CPU的设计与实验

1. 实验内容与要求

1.1 实验内容

1. 本实例所设计CPU的指令格式的拟定; 2. 基本功能部件的设计与实现; 3. CPU各主要功能部件的设计与实现; 4. CPU的封装;

5. 仿真测试及板级测试。

1.2实验要求

1. 设计的CPU能够执行20条整数指令,每条指令的编码长度均为32位; 2. 指令类型应有:计算类型、访问存储器类型、条件转移类型和无条件转移类型; 3. 操作数应有:寄存器操作数、立即数;

4. 测试程应不少于10条,将设计成果仿真测试并起先板级验证。

计算机科学与工程学院 2

计算机组成原理实验单周期CPU的设计与实验

2. 实验环境

2.1硬件平台

本实验所需的硬件主要有:PC计算机和FFPEG实验开发板,具体要要求如下:

1. IBM PC及兼容计算机:内存≥1GB,硬盘空间≥30GB 2. FPGA开发套件,本实验采用的是Anvyl Spartan6/XC6SLX45 3. USB连接线

Anvyl Spartan6/XC6SLX45的主要特点:

? 通用输入接口

14个LED:8个红色,2组“红绿灯”模式8个滑动开关 4个按键

6个7段数码管

2组拨码开关(一组4个) ? 音频接口:I2S Codec接口 ? 视频接口

HDMI输出接口

12比特VGA接口(800×600),使用无源电阻网路 ? USB接口

USB1:JTAG编程及UART

USB2/3:USB设备接口,可接HID设备或U盘 ? 片外存储器

DDR2:256MB SRAM:2MB QSPI Falsh:32MB ? OLED:128×32蓝色显示

? LCD液晶屏:480×272全彩色液晶触摸屏 ? Clock:100MHz单端CMOS晶振

2.2 软件平台

1. 操作系统:Windows XP、Win 7;

2. 开发平台:Xilinx ISE Design Suite 13.4集成开发系统; 3. 编程语言:VerilogHDL硬件描述语言。

计算机科学与工程学院 3

计算机组成原理实验单周期CPU的设计与实验

2.3 实验主要仪器设备连接框图

实验主要仪器设备的连接框图如图2-1所示。

图2-1 主要实验仪器设备连接图

通过USB连接线将实验开发板与PC计算机连接,USB线的一端接在计算机上任一USB接口上,另一端接在实验板的JTAG(Joint Test Action Group;联合测试行动小组)接口上。

计算机科学与工程学院 4

计算机组成原理实验单周期CPU的设计与实验

3. 实验原理

3.1 概述

单周期(Single Cycle)CPU是指CPU从取出1条指令到执行完该指令只需1个时钟周期。

1个时钟周期

Clock

指令0 指令1 指令2 指令4 指令5 图3-1 时钟周期和单周期CPU指令的执行

一条指令的执行过程包括:取指令→分析指令→执行指令→保存结果(如果有的话)。对于单周期CPU来说,这些执行步骤均在一个时钟周期内完成。

3.2 单周期CPU的总体电路

本实验所设计的单周期CPU的总体电路结构如图3-2所示。

Clock 图3-2 单周期CPU总体电路

sa imm addr S A PC Do 4 op func m2reg pcsource wmem aluc shift aluimm Wreg 0 regrt sext jal Write A_data A_addr B_addr S f W_addr B_data Data B S << S A Control Unit + rs rt rd + Zero ALU Result 1 2 3 Inst Mem We A Do Data Mem Di S e <<

计算机科学与工程学院 5

计算机组成原理实验单周期CPU的设计与实验

本实验所设计的CPU主要组成部分有:运算器(ALU)、控制器(Control Unit)、寄存器堆(Register Files)、取指电路及相关基础部件(如选择器)等构成。

3.3 MIPS指令格式

MIPS指令系统结构有MIPS-32和MIPS-64两种。本实验的MIPS指令选用MIPS-32。以下所说的MIPS指令均指MIPS-32。

MIPS的指令格式为32位。图3-3给出了MIPS指令的3种格式。

31

26 25

21 20

16 15

11 10

6 5

0

R型指令

31

op

26 25

rs

21 20

rt

16 15

rd sa func

0

I型指令

31

op

26 25

rs rt immediate

0

J型指令 op address

图3-3 MIPS指令格式

本实验只选取了20条典型的MIPS指令来描述CPU逻辑电路的设计方法。表3-1列出了本实验的所涉及到的20条MIPS指令。

表1本实验所涉及的20条MIPS指令

R型指令 指令 Add Sub And Or Xor Sll Srl Sra Jr Addi Andi Ori Xori Lw Sw Beq [31:26] [25:21] [20:16] [15:11] 000000 000000 000000 000000 000000 000000 000000 000000 000000 001000 001100 001101 001110 100011 101011 000100 rs rs rs rs rs 00000 00000 00000 rs rs rs rs rs rs rs rs rt rt rt rt rt rt rt rt rt rt rt rt rt rt rt rt rd rd rd rd rd rd rd rd rd I型指令 immediate immediate immediate immediate offset offset offset 立即数加 立即数与 立即数或 立即数异或 取数据 存数据 相等转移 [10: 6] [5:0] 功能 寄存器加 寄存器减 寄存器与 寄存器或 寄存器异或 左移 逻辑右移 算术右移 寄存器跳 000000 100000 000000 100010 000000 100100 000000 100101 000000 100110 sa sa sa 000000 000010 000011 000000 001000 计算机科学与工程学院 6

计算机组成原理实验单周期CPU的设计与实验

Bne Lui J Jal 000101 001111 000010 000011 rs 00000 rt rt J型指令 address address offset immediate 不等转移 设置高位 跳转 调用 R型指令的op均为0,具体操作由func指定。rs和rt是源寄存器号,rd是目的寄存器号。移位指令中使用sa指定移位位数。

I型指令的低16位是立即数,计算时需扩展到32位,依指令的不同需进行零扩展和符号扩展。

J型指令的低26位是地址,是用于产生跳转的目标地址。

3.4 数据路径设计

CPU的电路包括数据路径(Data path)和控制部件(Control Unit)两大部分。下面介绍路径的设计。

3.4.1 下一条指令地址的选择

下一条指令的地址有4种情况:

1. 程序不转移时下一条指令的地址为PC+4;

2. 执行beq和bne指令发生转移时,下一条指令的地址是PC加4,再加上符号扩

展的偏移量左移2位的和;

3. 执行jr指令时转移的目标地址就是rs寄存器中的内容;

4. 执行j和jal指令时转移的目标地址是指令中的低26位地址左移2位,再与PC+4

的高4位拼接在一起。

下一条指令地址的产生和选择电路如图3-3所示。

计算机科学与工程学院 7

计算机组成原理实验单周期CPU的设计与实验

op func 4 p4 rs PC A Do rt Control Unit pcsource aluc 0 + A_addr A_data B_addr << A ALU zero Result + 1 2 3 Inst Mem B_data Clock imm addr e << B 图3-3 下一条指令地址的选择 在图3-3中控制器(Control Unit)根据op、func和zero(对于beq和bne指令)信号产生相应的转移控制选择信号pcsource。

3.4.2 ALU的输入端

ALU的输入端有2个:A输入端和B输入端。A、B输入端分别有2种输入情况。对于A输入端,有寄存器堆的A_data和移位数sa输入。对于B输入端,有寄存器堆的B_data和符号扩展后的立即数imm输入。其输入数据路径如图3-4所示

op func Control Unit aluimm shift MUX A_data B_data sa imm e A ALU MUX B RegFile 图3-4 ALU的输入端选择

ALU的A、B端具体输入哪路数据由控制器(Control Unit)根据指令译码产生控制信号shift和aluimm来选择。

3.4.3寄存器堆的输入端

计算机科学与工程学院 8

计算机组成原理实验单周期CPU的设计与实验

寄存器堆的A_addr和B_addr的输入来自指令,分别只有一种输入,W_addr有2种,而Data有4种输入,具体输入见图3-5。

Write A_data A_addr B_addr MUX rs rt rd PC+4 A ALU B We Do A Data Mem Di f W_addr B_data MUX Data 图3-5 寄存器堆的输入

寄存器堆的W_addr和Data端的输入信号由控制器(Control Unit)根据指令译码产生的控制信号reget、jal和m2reg来选择。

在图3-5中模块f的输入为5位的寄存器号reg_dest和jal,输出为W_addr,其Verilog HDL语句为:

Assign W_addr = reg_dest | {5{jal}};

MUX m2reg reget jal 计算机科学与工程学院 9

计算机组成原理实验单周期CPU的设计与实验

4. 基本功能部件的设计与实现

一个CPU主要由ALU(运算器)、控制器、寄存器堆、取指部件及其它基本功能部件等构成。

在本实验中基本功能部件主要有:32位2选1多路选择器、32位4选1多路选择器、5位2选1多路选择器、D触发器、移位器及32位加/减法器。

4.1 32位2选1选择器的设计与实现

多路选择器是计算机逻辑电路设计中最重要的基本逻辑电路之一,也是基于数据选择通路CPU的重要部件。32位2选1选择器的逻辑框图如图4-1所示。

Sel

Function:

A[31:0] B[31:0] M U X O[31:0]

Sel = 0:O = A Sel = 1:O = B

图4-1 32位2选1逻辑框图

1. 设计步骤 ? Step 1:新建工程

启动ISE软件,然后选择菜单File→New Project,弹出New Project Wizard对话框,在对话框中输入工程名Single_Cycle_CPU,并指定工作路径D:\\Single_Cycle_CPU(注:工程名并不需要和工作路径同名),如图4-2所示。

图4-2 New Project Wizard对话框

计算机科学与工程学院 10

计算机组成原理实验单周期CPU的设计与实验

输入完工程名和工作路径后点击Next进入下一页:Project Settings,设置设备和工程属性,选用Spartan6 XC6SLX45芯片,采用CSG484封装,这是本实验开发板所用的芯片,如图4-3所示。

图4-3 Project Settings对话框

在图4-3中点击Next进入下一页:Project Summary,这里显示了新建工程的信息,确认无误后,点击Finish就可以建立一个新的工程了,如图4-4所示。

图4-4 Project Summary对话框

? Step 2:模块(Module)设计

在ISE集成开发环境中(如图4-5所示),在工程管理区任意位置单击鼠标右键,在弹出的菜单中选择New Source命令,会弹出如图4-6所示的New Source Wizard对话框:Select SourceType。

计算机科学与工程学院 11

计算机组成原理实验单周期CPU的设计与实验

工程管理区

源代码编辑区

过程管理区

信息显示区

图4-5ISE集成开发环境

图4-6Select Source Type对话框

在图4-6中选择Verilog Module,并输入Verilog文件名:MUX32_2_1,代码存放位置(Location)改为D:\\Single_Cycle_CPU\\Code。将代码放在D:\\Single_Cycle_CPU\\Code文件夹中主要是为了方便管理。然后点击Next按钮进入端口定义对话框:Define Module,如图4-7所示。

图4-7Define Module对话框

在图4-7中, Modulename栏用于输入模块名,这里是MUX32_2_1,下面的列表框用于端口的定义。Port Name表示端口名称,Direction表示端口方向(可选择为input、

计算机科学与工程学院

12

计算机组成原理实验单周期CPU的设计与实验

output或inout),MSB表示信号最高位,LSB表示信号最低位,对于单信号的MSB和LSB不用填写。端口定义这一步略过,在源程序中自行添加。定义完端口后,点击Next按钮进入下一步,然后点击Finish按钮完成模块创建。

输入模块代码:

module MUX32_2_1(

input [31:0] A, input [31:0] B, input Sel, output[31:0] O );

assign O = Sel? B : A; endmodule

代码输入完成后,首先检查Verilog HDL语法:在工程管理区选中要检查的模块,在过程管理区双击Synthesize – XST→Check Syntax。如果有语法错误,会在信息显示区给出指示,请检查调试。如果没有语法错误,在模拟仿真前要进行Verilog HDL代码综合。

? Step 3:综合(Synthesize)

所谓综合,就是将HDL语言、原理图等设计输入翻译成由与、或、非门和RAM、触发器等基本逻辑单元的逻辑连接(网表),并根据目标和要求(约束条件)优化生成的RTL(Real Time Logistics)层连接。

完成了设计输入及语法检查后就可以进行综合。在工程管理区的View中选择Implementation,并选中要综合的模块MUX32_2_1,然后在过程管理区双击Synthesize-XST,就开始综合过程,如图4-8所示。

图4-8Running: Synthesis

综合错误会在信息显示区给出指示,如果代码过于行为化而不能转换成电路,称为不可综合代码,表示ISE无法转换成对应的电路,需要修改你的设计代码。如果综合通过,表示你设计的代码可以转换成RTL层描述,称为可综合代码。你可以通过View RTL Schematic查看综合后的RTL层电路,如图4-9所示。

计算机科学与工程学院

13

计算机组成原理实验单周期CPU的设计与实验

图4-9模块MUX32_2_1综合结果

? Step 4:仿真(Simulation)

在工程管理区任意位置单击鼠标右键,在弹出的菜单中选择New Source命令,会弹出如图4-10所示的New Source Wizard对话框:Select SourceType。在图4-10选择Verilog Test Fixture,输入测试文件名:MUX32__2_1_tb,单击Next按钮,进入下一个对话框,如图4-11所示。

图4-10创建仿真模块(1)

图4-11创建仿真模块(2)

在图4-11中工程中所有的模块名都会显示出来(由于目前工程中只有一个模块,故只显示了一个模块名),选择要测试的模块MUX32_1,点击Next按钮,再点击Finish按钮,ISE会在源代码编辑区自动生成测试模块的代码,如图4-12所示。

计算机科学与工程学院

14

计算机组成原理实验单周期CPU的设计与实验

图4-12Verilog Test Fixture– MUX32_1

在图4-12中示了刚生成的MUX32_1_tb模块,在该模块中添加如下测试代码:

?

// Add stimulus here

A <= 32'haaaa0000;

B <= 32'hbbbb1111; Sel <= 1'b0;

#100;

Sel <= 1'b1; end

endmodule

完成测试文件编辑后,确认工程管理区中View选项设置为Simulation,并选中MUX32_2_1_tb模块。这时在过程管理区会显示与仿真有关的进程,如图4-13中Processes栏所示。

图4-13选择仿真行为

在图4-13中右键单击其中的Simulate Behavioral Model项,选择弹出菜单中的Process Properties项,会弹出如图4-14所示的属性设置对话框,其中Simulation Run Time就是仿真时间的设置,可将其修改为任意时长。

计算机科学与工程学院 15

计算机组成原理实验单周期CPU的设计与实验

图4-14Process Properties对话框

仿真参数设置完后,就可以进行仿真。首先在工程管理区选中测试代码,然后在过程管理区双击Simulate Behavioral Model,ISE将启动ISE Simulator,可以得到仿真结果,如图4-15所示。

图4-15模块MUX32_1仿真效果

? Step 5:约束(Constraints)与实现(Implementation)

要实现设计,还需要为模块中的输入/输出信号添加管脚约束,这就需要在工程中添加UCF(User Constraints File)文件。在工程管理区单击鼠标右键,点击New Source,弹出如图4-6所示对话框,在类型中选择Implementation Constraints File,输入文件名:MUX32_2_1_ucf,选择关联模块:MUX32_2_1。系统会生成一个空白的约束文件并打开。我们就可以为设计添加各种约束。

本实验中用Anvyl中的8个Switch对应2组4位二进制输入,用4个LED发光二极管对应输出,BTN0按钮对应选择信号Sel。因为是组合电路,不需要时钟。具体约束内容如下:

NET Sel LOC = E6;

#switches

NET A<0> LOC= V5;

计算机科学与工程学院

16

计算机组成原理实验单周期CPU的设计与实验

NET A<1> LOC= U4; NET A<2> LOC= V3; NET A<3> LOC= P4; NET B<0> LOC= R4; NET B<1> LOC= P6; NET B<2> LOC= P5; NET B<3> LOC= P8;

#Leds

NET O<0> LOC=W3; NET O<1> LOC=Y4; NET O<2> LOC=Y1; NET O<3> LOC=Y3;

约束完成后,下一个步骤就是实现(Implementation)。所谓实现,是指将综合输出的逻辑网表翻译成所选器件的底层模块和硬件原语,将设计映射到器件结构上,进行布局布线,达到在选定器件上实现设计的目的。

在ISE中,执行实现过程,会自动执行翻译、映射和布局布线过程:也可单独执行。在过程管理区双击Implementation Design选项,就可以自动完成实现的3个步骤,如图4-16所示。

图4-16Running Synthesis

完成Place & Route后,在图4-16中双击Generate Programming File项生成二进制比

特文件mux32_2_1.bit。

? Step 5:流代码生成与下载

完成Place & Route后,在图4-16中双击Generate Programming File项生成二进制比

特文件mux32_2_1.bit。

将Anyvl开发板与计算机通过USB线连接好,开发板加电,启动Digilent Adept软件,系统开始自动连接FPGA设备,成功检测到设备后,会显示出JTAG链上所用芯片,如图4-17所示。

计算机科学与工程学院 17

计算机组成原理实验单周期CPU的设计与实验

图4-17Digilent Adept软件

在图4-17中点击Browse按钮,找到刚才生成的二进制比特文件mux32_1.bit,然后点击Program按钮开始下载,下载成功后会在图4-17下面的状态栏中显示Programming Successful。同学们可在开发板上拨动开关SW0S~SW7和按钮BTN0,并观察LED0~LED3的显示,思考一下观察的结果与设计是否一致。

4.2 32位4选1选择器的设计与实现

32位4选1选择器的逻辑框图如图4-18所示。

Sel[1:0] Function:

A[31:0] B[31:0] C[31:0] D[31:0] M U X Sel[1:0]= 00:O = A

O[31:0]

Sel[1:0]= 01:O = B Sel[1:0]= 10:O = C Sel[1:0]= 11:O = D

图4-18 32位4选1逻辑框图

32位4选1选择器的模块设计步骤可参考32位2选1选择器的设计步骤,下面给出32位4选1选择器的模块代码。

module MUX32_4_1(

input [31:0] A, input [31:0] B, input [31:0] C, input [31:0] D, input [1:0] Sel, output[31:0] O

计算机科学与工程学院

18

计算机组成原理实验单周期CPU的设计与实验

);

assign O = (Sel == 2'b00)? A : (Sel == 2'b01)? B : (Sel == 2'b10)? C : D; Endmodule

4.3 5位2选1选择器的设计与实现

5位2选1选择器的逻辑框图如图4-19所示。

Sel

Function:

A[4:0] B[4:0]

M U X O[4:0]

Sel = 0:O = A Sel = 1:O = B

图4-19 5位2选1逻辑框图

5位2选1选择器的模块设计步骤可参考32位2选1选择器的设计步骤,下面给出5位2选1选择器的模块代码。

module MUX5_2_1(

input [4:0] A, input [4:0] B, input Sel, output[4:0] O );

assign O = Sel? B :A; Endmodule

4.4 带有异步清零的32位D触发器的设计与实现

异步是指清零与时钟无关,只要有效就清零。其设计步骤可参考32位2选1选择器的设计步骤,下面给出其模块Verilog实现代码:

module dff32(

input [31:0] D, input Clock, input Reset,

output reg [31:0] Q );

always @(posedge Clock or negedge Reset) begin if(Reset == 0) Q <= 0; else Q <= D; end endmodule

计算机科学与工程学院 19

计算机组成原理实验单周期CPU的设计与实验

4.5移位器的设计

移位器的功能是将一个数进行逻辑左移、逻辑右移或算术右移。其设计步骤可参考32位2选1选择器的设计步骤,下面给出其模块Verilog实现代码:

module Shifter(

input [31:0] D, input [4:0] Sa, input Right, input Arith, output reg [31:0] O );

always @(*) begin

if (!Right) O = D << Sa ; else if (!Arith) O = D >> Sa;

else O = $signed(D) >>> Sa; end

endmodule

4.6 32位加/减法器的设计与实现

32位加/减法器的功能是完成32位的加法/减法运算。由于:

A?B?A?(?B)?A?B?1

故可以用加法器实现减法操作。下面给出其模块Verilog实现代码:

module addsub32(

input [31:0] A, input [31:0] B, input sub, output[31:0] Result );

cla32 as32(A , B^{32{sub}} , sub , Result);

endmodule

module cla32(

input [31:0] a, input [31:0] b, input c, output[31:0] s );

assign s = a + b + c; endmodule

计算机科学与工程学院 20

计算机组成原理实验单周期CPU的设计与实验

5.运算器(ALU)的设计与实现

运算器ALU是CPU组成的核心部件之一,其实现方法主要有2种:一种是以加法器为核心,通过改变进位函数实现;另一种是运算部件并行多路选择实现。本实验采用运算部件并行多路选择实现。综合表3-1的指令,ALU只需完成9种运算即可,具体完成的功能如表5-1所示。

表5-1:ALU功能真值表

ALU_Operation x000 x100 x001 x101 x010 x110 0011 0111 1111 功能描述 Add(加) Sub(减) And(与) Or(或) Xor(异或) Lui(设置高位) Sll(左移) Srl(右移) Sra(算术右移) ALU的逻辑框图如图5-1所示。在图5-1中各信号的功能:

ALU_Operation[3:0]

? A:操作数,32位,输入; ? B:操作数,32位,输入; ? ALU_Operation:4位操作码,输

Zero

Result[31:0]

A[31:0] 入;

? Result:运算结果,32位,输出; ? Zero:零标志,1位;当运算结果为0时,该位为1,否则为0;

B[31:0] 图5-1 ALU电路符号

在工程管理区任意位置单击鼠标右键,在弹出的菜单中选择New Source命令,选择Verilog Module输入,并输入Verilog文件名:ALU,单击Next按钮进入端口定义对话框。其中Module Name栏输入模块名:ALU,单击Next进入下一步,点击Finish完成创建。ALU模块的Verilog程序参考代码:

module ALU(

input [31:0] A, input [31:0] B,

计算机科学与工程学院

21

计算机组成原理实验单周期CPU的设计与实验

input [3:0] ALU_Operation, output [31:0] Result, output Zero );

wire [31:0] d_and = A & B; wire [31:0] d_or = A | B; wire [31:0] d_xor = A ^ B;

wire [31:0] d_lui = {B[15:0],16'h0};

wire [31:0] d_and_or = ALU_Operation[2]? d_or:d_and; wire [31:0] d_xor_lui = ALU_Operation[2]? d_lui:d_xor; wire [31:0] d_as , d_sh;

addsub32 as32 (A , B , ALU_Operation[2] , d_as); Shifter shift_1 ( B , A[4:0] , ALU_Operation[2] ,

ALU_Operation[3] , d_sh);

MUX32_4_1 sel ( d_as , d_and_or , d_xor_lui , d_sh ,

ALU_Operation[1:0] , Result);

assign Zero = ~|Result; endmodule

对ALU进行仿真。在工程管理区将View设置为Simulation,在任意位置单击鼠标右键,并在弹出的菜单中选择New Source,在类型中选择Verilog Test Fixture,输入测试文件名:ALU_tb,单击Next按钮,这时所有工程中的模块名都会显示出来,选择要进行测试的模块:ALU。点击Next ,再单击Finish按钮,ISE会在源代码编辑区自动生成测试模块的代码。我们看到,ISE已经自动生成了基本的信号并对被测模块做了实例化。

对ALU_tb模块,我们可以添加如下所示的测试激励代码。

// Add stimulus here A <= 32'h1234; B <= 32'h5678; ALU_Operation <= 4'b0000; //add

#100

A <= 32'h1234abcd; B <= 32'hf0f0f0f0; ALU_Operation <= 4'b001; //and

#100

A <= 32'h12345678; B <= 32'h78; ALU_Operation <= 4'b0010; //xor

#100

A <= 32'h4; B <= 32'habcd;

ALU_Operation <= 4'b0011; //sll #100

A <= 32'h1234;

B <= 32'h5678;

22

计算机科学与工程学院

计算机组成原理实验单周期CPU的设计与实验

ALU_Operation <= 4'b0100; //sub

#100

A <= 32'h1234; B <= 32'h0ff; ALU_Operation <= 4'b0101; //or

#100

A <= 32'h1234; B <= 32'habcd; ALU_Operation <= 4'b0110; //lui

#100

A <= 32'h4; B <= 32'hf2345678; ALU_Operation <= 4'b0111; //SRL

#100

ALU_Operation <= 4'b1111; //SRA

完成测试文件编辑后,确认工程管理区中View选项设置为Simulation,这时在过程管理区会显示与仿真有关的进程。右键单击其中的Simulate Behavioral Model项,选择弹出菜单中的Process Properties项,会弹出属性设置对话框,将其中Simulation Run Time设置为1000ns。

仿真参数设置完后,就可以进行仿真。首先在工程管理区选中测试模块ALU_tb,然后在过程管理区双击Simulate Behavioral Model,ISE将启动ISE Simulator,可以得到仿真结果,如图5-2所示。

图5-2 ALU仿真结果

计算机科学与工程学院 23

计算机组成原理实验单周期CPU的设计与实验

6.寄存器堆(Register File)的设计与实现

寄存器堆(Register File)是CPU组成的重要存储部件,也是数据通路中的重要部件,其主要功能是对数据进行存储。在本实验中将为Register File构建32×32的寄存器组,即共有32个寄存器,每个寄存器的位宽都是32位。32×32的Register File逻辑结构如图6-1所示。

A_addr[4:0] B_addr[4:0] W_addr[4:0] Write Data Clock 图6-1 Register File逻辑结构

Register File A_data[31:0]

B_data[31:0]

图6-1中的寄存器组有1个数据输入端口,2个数据输出端口,因此可以从该寄存器组中同时输出2个数据。由于没有设置读信号,故在本实验中当A_addr(或B_addr)为0时,并不是选择输出Register0的内容,而是直接输出0。图6-1中各信号引脚的功能:

? A_addr:A输出端口地址,5位,输入; ? B_addr:B输出端口地址,5位,输入; ? W_addr:数据写入的寄存器号,5位,输入; ? Write:写信号,1位,输入; ? Data:数据,32位,输入;

? A_data:A端口的输出数据,32位,输出; ? B_data:B端口的输出数据,32位,输出; ? Clock:时钟信号,输入。

在工程管理区任意位置单击鼠标右键,在弹出的菜单中选择New Source命令,选择Verilog Module输入,并输入Verilog文件名:RegFile,单击Next按钮进入端口定义对话框。其中Module Name栏输入模块名:RegFile,单击Next进入下一步,点击Finish完成创建。实现RegisterFiles的Verilog程序参考代码:

module RegFile(

input Clock,

input Reset, input [ 4:0] A_addr, input [ 4:0] B_addr, input [ 4:0] W_addr,

计算机科学与工程学院

24

计算机组成原理实验单周期CPU的设计与实验

input [31:0] Data, input Write, output [31:0] A_data, output [31:0] B_data );

reg [31:0] Register[1:31];

//Read data

assign A_data = (A_addr == 0)? 0 : Register[A_addr]; assign B_data = (B_addr == 0)? 0 : Register[B_addr];

//Write data integer i;

always @ ( posedge Clock or negedge Reset) begin if (Reset == 0) begin

for (i=1 ; i <=31 ; i = i+1) Register[i] <= 0; end else if (( Write ) && ( W_addr != 0)) Register[W_addr] <= Data; endendmodule

对Register File进行仿真。在工程管理区将View设置为Simulation,在任意位置单

击鼠标右键,并在弹出的菜单中选择New Source,在类型中选择Verilog Test Fixture,输入测试文件名:RegFile_tb,单击Next按钮,这时所有工程中的模块名都会显示出来,选择要进行测试的模块:RegFile。点击Next ,再单击Finish按钮,ISE会在源代码编辑区自动生成测试模块的代码。加入如下仿真代码:

module RegFile_tb;

reg Clock; reg Reset;

reg [4:0] A_addr; reg [4:0] B_addr; reg [4:0] W_addr; reg [31:0] Data; reg Write;

wire [31:0] A_data; wire [31:0] B_data;

// Instantiate the Unit Under Test (UUT) RegFile uut (

.Clock(Clock), .Reset(Reset), .A_addr(A_addr), .B_addr(B_addr), .W_addr(W_addr), .Data(Data), .Write(Write), .A_data(A_data), .B_data(B_data) );

计算机科学与工程学院

25

计算机组成原理实验单周期CPU的设计与实验

initial begin

// Initialize Inputs Clock = 0; Reset = 0; A_addr = 0; B_addr = 0; W_addr = 0; Data = 0; Write = 0;

// Wait 100 ns for global reset to finish #100;

Reset <= 1;

A_addr <= 5'b00001; B_addr <= 5'b00010; W_addr <=5'b00011; Data <=32'h12345678; Write <=1; Clock <= 1; #100;

A_addr <= 5'b00011;

B_addr <= 5'b00100; Write <=0;

// Add stimulus here end endmodule

完成测试文件编辑后,确认工程管理区中View选项设置为Simulation,这时在过程管理区会显示与仿真有关的进程。右键单击其中的Simulate Behavioral Model项,选择弹出菜单中的Process Properties项,会弹出属性设置对话框,将其中Simulation Run Time设置为1000ns。

仿真参数设置完后,就可以进行仿真。首先在工程管理区选中测试模块RegFile_tb,然后在过程管理区双击Simulate Behavioral Model,ISE将启动ISE Simulator,可以得到仿真结果,如图6-2所示。

图6-2 Register file仿真

计算机科学与工程学院

26

计算机组成原理实验单周期CPU的设计与实验

7.控制器(Control Unit)的设计与实现

控制器对指令进行译码,根据指令的功能产生相应的控制信号。其逻辑结构如图7-1所示。

图5-1 控制器逻辑结构

在图7-1中各引脚的功能如下: ? z:运算结果为零,1位,输入; ? op[5:0]:指令操作码,6位,输入; ? func[5:0]:指令功能码,6位,输入;

? wmem:写储存器,1位,为1时写储存器,否则不写,输出; ? wreg:写寄存器,1位,为1时写寄存器,否则不写,输出;

? regrt:目的寄存器是rt,1位,为1时目的寄存器是rt,否则是rt,输出; ? m2reg:存储器数据写寄存器信号,1位,为1选择存储器数据,否则t选择

ALU的运算结果,输出;

? shift:ALU的A端口使用移位位数,1位,为1时使用移位位数,否则使用寄

存器数据,输出;

? aluimm:ALU的B端口使用立即数,1位,为1时使用立即数,否则使用寄存

器数据,输出;

? jal:子程序调用,1位,为1时表示是jal,否则不是,输出; ? sext:立即数符号扩展,1位,为1时符号扩展,否则零扩展,输出;

计算机科学与工程学院

27

计算机组成原理实验单周期CPU的设计与实验

? aluc[3:0]:ALU操作控制码,4位输出;

? pcsource[1:0]:下一条指令地址选择,2位,输出。

在工程管理区任意位置单击鼠标右键,在弹出的菜单中选择New Source命令,选择Verilog Module输入,并输入Verilog文件名:Control_Unit,单击Next按钮进入端口定义对话框。其中Module Name栏输入模块名Control_Unit,单击Next进入下一步,点击Finish完成创建。实现Control_Unit的Verilog程序参考代码:

module Control_Unit(

input [5:0] op, input [5:0] func, input z, output wmem, output wreg, output regrt, output m2reg, output [3:0] aluc, output shift, output aluimm, output [1:0] pcsource, output jal,

output sext );

// Register addressing

wire i_add = (op == 6'b000000 & func == 6'b100000)?1:0; wire i_sub = (op == 6'b000000 & func == 6'b100010)?1:0; wire i_and = (op == 6'b000000 & func == 6'b100100)?1:0; wire i_or = (op == 6'b000000 & func == 6'b100101)?1:0; wire i_xor = (op == 6'b000000 & func == 6'b100110)?1:0; wire i_sll = (op == 6'b000000 & func == 6'b000000)?1:0; wire i_srl = (op == 6'b000000 & func == 6'b000010)?1:0; wire i_sra = (op == 6'b000000 & func == 6'b000011)?1:0; wire i_jr = (op == 6'b000000 & func == 6'b001000)?1:0;

//immediate addressing

wire i_addi = (op == 6'b001000)?1:0; wire i_andi = (op == 6'b001100)?1:0; wire i_ori = (op == 6'b001101)?1:0; wire i_xori = (op == 6'b001110)?1:0; wire i_lw = (op == 6'b100011)?1:0; wire i_sw = (op == 6'b101011)?1:0; wire i_beq = (op == 6'b000100)?1:0; wire i_bne = (op == 6'b000101)?1:0; wire i_lui = (op == 6'b001111)?1:0;

wire i_j = (op == 6'b000010)?1:0; // j wire i_jal = (op == 6'b000011)?1:0; // jal

计算机科学与工程学院

28

计算机组成原理实验单周期CPU的设计与实验

//Create control signal

assign wreg = i_add | i_sub | i_and | i_or | i_xor |

i_sll | i_srl |i_sra | i_addi | i_andi |

i_ori | i_or | i_xori | i_lw | i_lui |i_jal;

assign regrt = i_addi | i_andi | i_ori | i_xori |i_lw |i_lui; assign jal = i_jal; assign m2reg = i_lw;

assign shift = i_sll | i_srl |i_sra;

assign aluimm = i_addi | i_andi | i_ori | i_xori | i_lw |

i_lui |i_sw;

assign sext = i_addi | i_lw | i_sw | i_beq | i_bne;

assign aluc[3] = i_sra;

assign aluc[2] = i_sub |i_or | i_srl | i_sra | i_ori |i_lui; assign aluc[1] = i_xor | i_sll | i_srl | i_sra | i_xori |

i_beq | i_bne | i_lui;

assign aluc[0] = i_and | i_or | i_sll | i_srl |i_sra |

i_andi | i_ori;

assign wmem = i_sw;

assign pcsource[1] = i_jr | i_j | i_jal;

assign pcsource[0] = i_beq & z | i_bne&~z | i_j | i_jal; endmodule

在控制器的Verilog实现代码中,首先对指令的功能进行译码,以“i_”开头的变量表示批令的功能,例如i_add为1表示该指令的功能是加法(add),其余的以此类指。然后根据指令的功能产生相应的控制信号,例如:

assign regrt = i_addi | i_andi | i_ori | i_xori | i_lw | i_lui;

表示当指令的功能是:i_addi(立即数加)、i_andi(立即数与)、i_ori(立即数或)、i_xori(立即数异或)、i_lw(取整数数据字)或i_lui(设置高位)功能时控制信号regrt为1。

aluc[3:0]的设计参见表5-1中各运算的编码。

计算机科学与工程学院 29

计算机组成原理实验单周期CPU的设计与实验

8. CPU的封装

当CPU的所有功能部件分别设计完成后,就要将其进行封装,以构成一个完整的CPU。本实验封装后CPU如图8-1所示。

Clock Reset Inst[31:0] mem[31:0] pc[31:0] 图8-1 CPU的封装

wmem

CPU Result[31:0] Data[31:0]

在图8-1中CPU各引脚的功能: ? Clock:输入,1位,时钟脉冲信号; ? Reset:输入,1位,复位信号;

? Inst[31:0]:输入,32位,CPU要执行的指令; ? Mem[31:0]:输入,32位,内存操作数;

? pc[31:0]:输入,32位,下一条要执行指令的地址; ? wmem:输出,1位,存储器写信号; ? Result[31:0]:输出,32位,运行结果;

? Data[31:0]:输出,32位,寄存器B;端口输出数据。

CPU封装的基本原理就是根据单单周期CPU的总体电路(图3-2)将各功能部件连接起来。CPU封装的Verilog代码如下:

module Data_flow(

input Clock, input Reset, input [31:0] inst, input [31:0] mem, output[31:0] pc, output wmem, output[31:0] Result, output[31:0] Data );

wire [31:0] p4 , adr , npc , res , ra , alu_mem , alua , alub; wire [4:0] reg_dest , wn; wire [3:0] aluc;

wire [1:0] pcsource;

计算机科学与工程学院

30

计算机组成原理实验单周期CPU的设计与实验

wire zero , wreg,regrt, m2reg,shift,aluimm,jal,sext;

wire [31:0] sa = {27'b0 , inst[10:6]};

wire [31:0] offset = {imm[13:0] , inst[15:0] , 2'b00};

dff32 ip (npc , Clock , Reset , pc); cla32 pcplus4 ( pc , 32'h4 , 1'b0 , p4); cla32 br_adr ( p4 , offset , 1'b0 ,adr);

wire [31:0] jpc = {p4[31:28] , inst[25:0],2'b00};

Control_Unit CU ( inst[31:26] , inst[5:0] , zero, wmem,wreg,regrt,m2reg,aluc, shift,aluimm,pcsource,jal,sext );

wire e =sext & inst[15]; wire [15:0] imm = {16{e}};

wire [31:0] immdiate = {imm , inst[15:0]}; //立即数

RegFile rf ( Clock, Reset, inst[25:21], inst[20:16], wn, res, wreg, ra, Data );

MUX32_2_1 alu_a ( ra , sa , shift , alua);

MUX32_2_1 alu_b ( Data , immdiate , aluimm , alub);

ALU alu( alua , alub , aluc , Result , zero);

MUX5_2_1 reg_wn ( inst[15:11] , inst[20:16] , regrt ,

reg_dest);

assign wn = reg_dest | {5{jal}};

MUX32_2_1 res_mem ( Result , mem , m2reg , alu_mem); MUX32_2_1 link ( alu_mem , p4 , jal , res);

MUX32_4_1 nextpc( p4 , adr , ra , jpc , pcsource , npc);

endmodule

计算机科学与工程学院 31

计算机组成原理实验单周期CPU的设计与实验

9. 测试

当CPU设计完成后,还需要对其进行测试,为此需要再设计一个指令存储器和一个数据存储器,同时再设计相应的测试程序。

9.1 指令存储器及测试程序

由于我们的主要目的是对所设计的CPU进行测试,故可以不使用IP核设计指令存储器,直接使用通用代码实现。

在工程管理区任意位置单击鼠标右键,在弹出的菜单中选择New Source命令,选择Verilog Module输入,并输入Verilog文件名:Inst_mem,单击Next按钮进入端口定义对话框。其中Module Name栏输入模块名Inst_mem,单击Next进入下一步,点击Finish完成创建。实现Inst_mem的Verilog程序参考代码:

module Inst_mem(

input [31:0] address, output [31:0] inst

);

wire [31:0] ram [0:31];

assign ram[5'h00] = 32'h3c011234; //lui R1,0x1234 assign ram[5'h01] = 32'h34215678; //ori R1,R1,0x5678 assign ram[5'h02] = 32'h3C02AAAA; //lui R2 ,0xaaaa assign ram[5'h03] = 32'h3442BBBB; //ori R2,R2,0xbbbb assign ram[5'h04] = 32'h00221820; //add R3 , R1 , R2 assign ram[5'h05] = 32'h00221822; //sub R3 , R1 , R2 assign ram[5'h06] = 32'h00221824; //and R3 , R1 , R2 assign ram[5'h07] = 32'h00221825; //orR3 , R1 , R2 assign ram[5'h08] = 32'h00221826; //xor R3 , R1 , R2 assign ram[5'h09] = 32'h00021900; //sll R3 , R2 , 4 assign ram[5'h0a] = 32'h00021902; //srl R3 , R2 , 4 assign ram[5'h0b] = 32'h00021903; //srl R3 , R2 , 4

assign ram[5'h0c] = 32'h20231234; //addi R3 , R1,0x1234 assign ram[5'h0d]= 32'h302300EF; //andi R3 , R1,0xef assign ram[5'h0e] = 32'h342300EF; //ori R3 , R1,0xef assign ram[5'h0f] = 32'h382300EF; //xori R3 , R1,0xef assign ram[5'h10] = 32'h00631826; //xor R3 , R3 , R3 assign ram[5'h11] = 32'hAC610001; //sw R1 , 1(R3) assign ram[5'h12] = 32'h90650001; //lw R5 , 1(R3) assign inst = ram[address[6:2]];

endmodule

计算机科学与工程学院 32

计算机组成原理实验单周期CPU的设计与实验

9.2 数据存储器及测试数据

由于我们的主要目的是对所设计的CPU进行测试,故可以不使用IP核设计数据存储器,直接使用通用代码实现。

在工程管理区任意位置单击鼠标右键,在弹出的菜单中选择New Source命令,选择Verilog Module输入,并输入Verilog文件名:Data_mem,单击Next按钮进入端口定义对话框。其中Module Name栏输入模块名Data _mem,单击Next进入下一步,点击Finish完成创建。实现Data _mem的Verilog程序参考代码:

module Data_mem(

input Clock, output[31:0] dataout, input [31:0] datain, input [31:0] addr, input we, input inclk, input outclk );

reg [31:0] ram [0:31];

assign dataout = ram[addr[6:2]];

always @ (posedge Clock) begin

if (we) ram[addr[6:2]] = datain; end

integer i;

initial begin

for ( i = 0 ; i <= 31 ; i = i + 1) ram [i] = i * i; end

endmodule

9.3 仿真测试

在测试之前需将所设计的CPU、指令存储器和数据存储器连接起来。

在工程管理区任意位置单击鼠标右键,在弹出的菜单中选择New Source命令,选择Verilog Module输入,并输入Verilog文件名:Mainboard,单击Next按钮进入端口定义对话框。其中Module Name栏输入模块名Main_board,单击Next进入下一步,点击Finish完成创建。实现Mainboard的Verilog程序参考代码: module Mainboard( input Clock,

计算机科学与工程学院

33

计算机组成原理实验单周期CPU的设计与实验

input Reset, input mem_clk,

output[31:0] inst, output[31:0] pc,

output[31:0] aluout, output[31:0] memout );

wire [31:0] data; wire wmem;

Data_flow CPU (Clock , Reset , inst , memout , pc , wmem , aluout ,data);

Inst_mem imem(pc , inst);

Data_mem dmem(Clock , memout , data , aluout , wmem , Clock , Clock);

Endmodule

其连接如图9-1所示。

图9-1 CPU、指令存储器和数据存储器连接

向工程中添加测试模块。综合通过后,在工程管理区将View设置为Simulation,在任意位置单击鼠标右键,并在弹出的菜单中选择New Source,在类型中选择Verilog Test Fixture,输入测试文件名:Mainboard_tb,单击下一步。

这时所有工程中的模块名都会显示出来,选择要进行测试的模块:Mainboard。点击Next ,再单击Finish按钮,ISE会在源代码编辑区自动生成测试模块的代码。我们看到,ISE已经自动生成了基本的信号并对被测模块做了例化。

在Mainboard_tb添加如下测试代码:

计算机科学与工程学院

34

计算机组成原理实验单周期CPU的设计与实验

initial begin

// Initialize Inputs Clock = 0; Reset = 0; mem_clk = 0;

// Wait 100 ns for global reset to finish #100;

// Add stimulus here Reset <= 1; end

always begin #50;

Clock = ~Clock; End

完成测试文件编辑后,确认工程管理区中View选项设置为Simulation,并且选中的测试模块是Mainboard_tb,这时在过程管理区会显示与仿真有关的进程。右键单击其中的Simulate Behavioral Model项,选择弹出菜单中的Process Properties项,会弹出属性设置对话框,将其中Simulation Run Time设置为1000ns。

在过程管理区双击Simulate Behavioral Model,ISE将启动ISE Simulator,可以得到仿真结果,如图9-2所示。

图9-1CPU仿真测试结果

9.4下载到开发板验证

仿真测试通过后,下一步要做的工作就是将所做设计下载到开发板进行验证。为了便于测试和观察,对开发板上的器件作如下约定:

? 按钮Button[0],作测试时钟脉冲输入;

? 开关Switch[1:0]:输出内容选择,00 – 显示执行指令,01 – 显示pc,10 – 显

计算机科学与工程学院

35

计算机组成原理实验单周期CPU的设计与实验

示ALU运算结果,11 –显示数据存储器输出

? 开关Switch[2]:0 – 显示输出内容的低24位,1 – 显示输出内容的高24位 对模块Mainboard作如下修改:

module Mainboard( input Clock, input Reset,

output[31:0] inst, output[31:0] pc,

output[31:0] aluout, output[31:0] memout,

input BTN_IN, //单步脉冲输入 input [5:0] SW, //开关

output [7:0] seg, //数码管7段 output [5:0] AN_SEL, output [7:0] LED );

wire [31:0] data; wire wmem;

Data_flow CPU (Clock , Reset , inst , memout , pc , wmem , aluout ,data);

Inst_mem imem(pc , inst);

Data_mem dmem(Clock , memout , data , aluout , wmem );

//单步执行时钟控制

reg [31:0] clockdiv = 0; wire BTN_Out; BTN_Anti_Jitter anti_jitter( clockdiv[12] , BTN_IN , BTN_Out ); //按钮去抖动

always @ (posedge Clock) clockdiv <= clockdiv + 1;

assign LED[0] = BTN_Out | Reset; assign LED[1] = SW[1]; assign LED[2] = SW[2];

//控制数码管显示

wire [31:0] display_content; wire [23:0] disp_num;

//显示内容选择

assign display_content = (SW[1:0] == 2'b00)? inst: (SW[1:0] == 2'b01)? pc:

(SW[1:0] == 2'b10)? aluout : memout;

计算机科学与工程学院

36

计算机组成原理实验单周期CPU的设计与实验

//高低24位选择

assign disp_num = (SW[2] == 1)? display_content[31:8]:

display_content[23:0];

//数码管输出显示 Hex7seg_decode hex7(disp_num , clockdiv[18:16] , seg , AN_SEL);

endmodule

上述模块中引用的BTN_Anti_Jitter模块和Hex7seg_decode模块的设计参见附件中的相关内容。

为模块中的输入/输出信号添加管脚约束,即向工程中添加UCF(User Constraints File)文件。在工程管理区单击鼠标右键,点击New Source,弹出如图4-6所示对话框,在类型中选择Implementation Constraints File,输入文件名:Mainboard_ucf,选择关联模块:Mainboard。系统会生成一个空白的约束文件并打开。我们就可以为设计添加各种约束。

NET Clock LOC = D11;

Net \

#Buttons

Net \NET BTN_IN LOC = E6; //btn(0)

NET Reset LOC = D5; //btn(1)

#switches

NET SW<0> LOC= V5; NET SW<1> LOC= U4; NET SW<2> LOC= V3;

#Leds

NET LED<0> LOC=W3; NET LED<1> LOC=Y4; NET LED<2> LOC=Y1;

##### 7-seg anode #####

NET AN_SEL(0) LOC = M17; # 7-seg AN1 NET AN_SEL(1) LOC = AA20; # 7-seg AN4 NET AN_SEL(2) LOC = AB21; # 7-seg AN5 NET AN_SEL(3) LOC = N16; # 7-seg AN2 NET AN_SEL(4) LOC = P19; # 7-seg AN3 NET AN_SEL(5) LOC = P16; # 7-seg AN0

##### 7-seg display #####

NET seg(0) LOC=AA21; # 7-seg CA

计算机科学与工程学院

37

计算机组成原理实验单周期CPU的设计与实验

NET seg(1) LOC=AA22; # 7-seg CB NET seg(2) LOC=Y22; # 7-seg CC NET seg(3) LOC=N15; # 7-seg CD NET seg(4) LOC=AB19; # 7-seg CE NET seg(5) LOC=P20; # 7-seg CF NET seg(6) LOC=Y21; # 7-seg CG NET seg(7) LOC=P15; # 7-seg DP

约束完成后,下一个步骤就是实现(Implementation)。所谓实现,是指将综合输出的逻辑网表翻译成所选器件的底层模块和硬件原语,将设计映射到器件结构上,进行布局布线,达到在选定器件上实现设计的目的。

在ISE中,执行实现过程,会自动执行翻译、映射和布局布线过程:也可单独执行。在过程管理区双击Implementation Design选项,就可以自动完成实现的3个步骤:Translate、Map、Place & Route,如果没有错,双击Generate Program File,生成Mainboard.bit文件。将生成的Mainboard.bit下载开发板上验证(下载方法参见4.1步骤5)。

计算机科学与工程学院 38

计算机组成原理实验单周期CPU的设计与实验

附件:

BTN_Anti_Jitter模块

module BTN_Anti_Jitter( input Clock, input BTN_IN,

output reg BTN_Out );

reg [3:0] cnt; reg BTN_Old;

always @ (posedge Clock) begin if(BTN_IN != BTN_Old) begin

cnt <= 4'b0000; BTN_Old <= BTN_IN; end else begin

if( cnt == 4'b1111) begin

cnt <= 4'b0000; BTN_Out <= BTN_IN; end else

cnt <= cnt + 1'b1; end end endmodule

Hex7seg_decode模块

module Hex7seg_decode(

input wire [23:0] disp_num, input wire[2:0] Scanning, output wire [7:0] SEGMENT, output reg [5:0] AN );

reg [3:0] digit;

reg [7:0] digit_seg;

assign SEGMENT = digit_seg;

always @ (*) begin AN = 6'b000000; case (Scanning)

39

计算机科学与工程学院

计算机组成原理实验单周期CPU的设计与实验

3'h0: begin digit[3:0] = disp_num[3:0]; AN = 6'b000001; end

3'h1: begin digit[3:0] = disp_num[7:4]; AN = 6'b100000; end

3'h2: begin digit[3:0] = disp_num[11:8]; AN = 6'b010000; end

3'h3: begin digit[3:0] = disp_num[15:12]; AN = 6'b001000; end

3'h4: begin digit[3:0] = disp_num[19:16]; AN = 6'b000100; end

3'h5: begin digit[3:0] = disp_num[23:20]; AN = 6'b000010; end

endcase end

always @ (*) begin case (digit)

4'h0: digit_seg = 8'b00111111; 4'h1: digit_seg = 8'b00000110; 4'h2: digit_seg = 8'b01011011; 4'h3: digit_seg = 8'b01001111; 4'h4: digit_seg = 8'b01100110; 4'h5: digit_seg = 8'b01101101; 4'h6: digit_seg = 8'b01111101; 4'h7: digit_seg = 8'b00000111; 4'h8: digit_seg = 8'b01111111; 4'h9: digit_seg = 8'b01101111; 4'hA: digit_seg = 8'b01110111; 4'hB: digit_seg = 8'b01111100; 4'hC: digit_seg = 8'b00111001; 4'hD: digit_seg = 8'b01011110; 4'hE: digit_seg = 8'b01111001; 4'hF: digit_seg = 8'b01110001; endcase end

endmodule

计算机科学与工程学院 40

本文来源:https://www.bwwdw.com/article/ujhp.html

Top