Project4 VerilogHDL完成单周期处理器开发(2013.12.2)

合集下载

单周期CPU实验报告

单周期CPU实验报告

MIPS-CPU设计实验报告实验名称:32位单周期MIPS-CPU设计姓名学号:刘高斯11072205实验日期:2014年12月19日目录前言MIPS简介------------------------------------------------------------- 3 实验目的------------------------------------------------------------- 3第一部分VERILOG HDL 语言实现部分实验内容------------------------------------------------------------- 4 试验环境------------------------------------------------------------- 4 模块简介------------------------------------------------------------- 4 实验截图------------------------------------------------------------- 5 实验感想------------------------------------------------------------- 5 实验代码------------------------------------------------------------- 6第二部分LOGISIM 语言实现部分实验内容------------------------------------------------------------- 16 实验环境------------------------------------------------------------- 16模块设计------------------------------------------------------------- 16 试验感想------------------------------------------------------------- 23前言一、MIPS简介MIPS是世界上很流行的一种RISC处理器。

单周期CPU实验报告

单周期CPU实验报告

MIPS-CPU设计实验报告实验名称:32位单周期MIPS-CPU设计姓名学号:刘高斯11072205实验日期:2014年12月19日目录前言MIPS简介------------------------------------------------------------- 3 实验目的------------------------------------------------------------- 3第一部分VERILOG HDL 语言实现部分实验内容------------------------------------------------------------- 4 试验环境------------------------------------------------------------- 4 模块简介------------------------------------------------------------- 4 实验截图------------------------------------------------------------- 5 实验感想------------------------------------------------------------- 5 实验代码------------------------------------------------------------- 6第二部分LOGISIM 语言实现部分实验内容------------------------------------------------------------- 16 实验环境------------------------------------------------------------- 16模块设计------------------------------------------------------------- 16 试验感想------------------------------------------------------------- 23前言一、MIPS简介MIPS是世界上很流行的一种RISC处理器。

Project5 VerilogHDL开发多周期处理器(V1.3@2013.12.08)

Project5 VerilogHDL开发多周期处理器(V1.3@2013.12.08)

2. 3.4.Figure1 多周期数据通路(供参考)5.多周期数据通路应必须包括PC、NPC、IM、DM这4个独立模块。

其中:a)IM:容量为4KB(32bit×1024字)。

b)DM:容量为4KB(32bit×1024字)。

6.层次及模块实例化命名必须满足下列要求:a)本project的顶层设计文件命名:mips.v。

b)PC必须被实例化命名:U_PC。

下面代码为示例。

pc U_PC(…) ; // 实例化PC(程序计数器)c)指令存储器必须被实例化命名:U_IM。

d)数据存储器必须被实例化命名:U_DM。

e)寄存器文件必须被实例化命名:U_RF。

7.建议datapath中的每个module都由一个独立的V erilogHDL文件组成。

a)建议所有mux(包括不同位数、不同端口数等)都建模在一个mux.v中。

可以有多个module。

8.为使得代码更加清晰可读,建议多使用宏定义,并将宏定义组织在1个或多个头文件中。

9.PC复位后初值为0x0000_3000,目的是与MARS的Memory Configuration相配合。

a)现场测试用的测试程序将通过MARS产生,其配置模式如Figure2所示。

Figure2 MIPS存储配置模式(MARS memory configuration)10.建议你用工程化方法来构造数据通路和状态机。

具体内容请参见随project提供的PPT。

a)你初次接触工程化方法时可能不是非常理解其价值。

但一旦当你运用这个方法后(特别是在后续project中),你会发现设计将被分为2个环节:真正意义上的设计和实现。

b)设计:仅仅在表格中就可以完成,而无需在HDL这个层次进行。

这一方面避免了HDL的大量细节对设计的干扰,另一方面使得你的设计可以被追朔,从而更高效的开发和准确的发现错误。

c)实现:当设计都完成后,可以一次性的完成HDL编码。

这个编码仅仅是对表格的翻译,对你的要求仅仅是掌握基本的HDL和认真细心。

单周期CPU及其Verilog_HDL实现概要共94页文档

单周期CPU及其Verilog_HDL实现概要共94页文档

36、自己的鞋子,自己知道紧在哪里。——西班牙
37、我们唯一不会改正的缺点是软弱。——拉罗什福科
xiexie! 38、我这个人走得很慢,但是我从不后退。——亚伯拉罕·林肯
39、勿问成功的秘诀为何,且尽全力做你应该做的事吧。——美华纳

40、学而不思则罔,思而不学则殆。——孔子
单周期CPU及其Verilog_HDL实现概 要
1、纪律是管理关系的形式。——阿法 纳西耶 夫 2、改革如果不讲纪律,就难以成功。
3、道德行为训练,不是通过语言影响 ,而是 让儿童 练习良 好道德 行为, 克服懒 惰、轻 率、不 守纪律 、颓废 等不良 行为。 4、学校没有纪律便如磨房里没有水。 ——夸 美纽斯
5、教导儿童服从真理、服从集体,养 成儿童 自觉的 纪律性 ,这是 儿童道 德教育 最重要 的部分 。—— 陈鹤琴
谢谢!

第5章单周期CPU及其Verilog HDL设计

第5章单周期CPU及其Verilog HDL设计
26 25 21 20 16 15 11 10 6 5 0
op 6 bits
rs 5 bits
rt 5 bits
rd 5 bits
sa 5 bits
funct 6 bits
I Format
31
(rs, rt: Register Numbers, imm: Immediate)
26 25 21 20 16 15 0
时钟上升沿(0到 1的变化) 一个周期
Clock
下降沿
指令1
指令2
指令3
指令4
在时钟上升沿保存指令的结果和下一条指令的地址
c
5.1 执行指令所需的硬件电路
• 指令的执行过程
取指令 执行指令
—读取指令
程序计数器的值作为地址从存储器中 取指令 形 成 下 一 条 指 令 地 址
—分析指令 —按指令规定内容执行指令 —检查有无中断请求
c
取指部件(Instruction Fetch Unit)
• 每条指令都有的公共操作
– 取指令: M[PC] – 更新PC:PC ← PC + 4
转移(Branch and Jump)时,PC内容再次被更新为 “转移目标地址 ” 下地址 逻辑
Next Address Logic Address Instruction Word
rs rt P C a do Inst mem
we rna
rnb qa wn Regfile d clk qb b ALU
rd
a
aluc z r
clock
c
Sll指令 (Shift Left Logical)
sll rd, rt, sa ; rd <-- rt << sa

电子科技大学CPU设计:《单周期CPU的设计与实现》-实验指导书

电子科技大学CPU设计:《单周期CPU的设计与实现》-实验指导书

电子科技大学计算机科学与工程学院单周期CPU的设计与实现实验指导书[计算机组成原理实验]张建2013-12-13目录前言 (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,加深对计算机各组成部件功能的理解和掌握,更好地理解计算机的基本工作原理,培养和锻炼学生掌握计算机硬件设计的基本方法和技能。

verilog_hdl_fpga抢答器

verilog_hdl_fpga抢答器

FPGA期末结业论文基于FPGA&VerilogHDL的四路抢答器院系:物理与电子学院专业:电子信息科学与技术任课教师:学号:姓名:2013年12月目录(0)摘要 (2)(1)引言 (3)1.1关于课程设计 (3)1.1.1课程设计目的 (3)1.1.2课程设计内容 (3)1.2开发工具简介 (4)1.2.1 EDA技术 (4)1.2.2 硬件描述语言-Verilog HDL (4)1.2.3 Verilog HDL设计流程 (5)1.2.4 FPGA基本特点 (5)1.2.5 FPGA工作原理 (5)(2)概述 (5)2.1 设计过程 (5)2.1.1系统设计要求 (5)2.1.2系统设计方案 (6)(3)系统设计 (6)3.1系统组图 (6)3.2系统主源程序 (8)(4)仿真综合 (10)(5)结论 (13)(6)参考文献 (13)(7)附录 (13)0摘要抢答器是在竞赛、文体娱乐活动(抢答活动)中,能准确、公正、直观地判断出抢答者的机器。

电子抢答器的中心构造一般都是由抢答器由单片机以及外围电路组成。

本设计是以四路抢答为基本概念。

从实际应用出发,利用电子设计自动化( EDA)技术,用可编程逻辑器件设计具有扩充功能的抢答器。

它以Verilog HDL硬件描述语言作为平台,结合动手实验而完成的。

它的特点是电路简单、制作方便、操作简单、方便、性能可靠,实用于多种智力竞赛活动。

本抢答器的电路主要有四部分组成:鉴别锁存电路、FPGA主芯片EP1C3T144C8电路、计分电路以及扫描显示模块的电路,并利用Quartus II工具软件完成了Verilog HDL源程序编写和硬件下载。

这个抢答器设计基本上满足了实际比赛应用中的各种需要。

在实际中有很大的用途。

关键词:抢答器 Quartus II Verilog HDL EP1C3T144C81引言硬件描述语言 Hardware Description Language 是硬件设计人员和电子设计自动化 EDA 工具之间的界面。

单周期CPU及其Verilog_HDL实现

单周期CPU及其Verilog_HDL实现

• 为了指出下一条指令的位置(地址),最简单 的办法是设置一个计数器用来指定指令的位 置。该计数器称为程序计数器PC(Program Counter)。
• CPU取指令时是把PC的内容作为存储器地 址,根据它来访问存储器,从指定的存储 器单元中取出一条指令。
– 如果取出的指令执行时没有引起转移,则PC的 值要+―1‖。 – 如果转移,则要将目标地址写入PC,以便在下 一个时钟周期取出下一条指令。
5.1 执行一条指令所需的硬件电路
• 计算机的程序一般存在硬盘等辅存中。当 计算机执行一个程序时,首先由操作系统 把要执行的程序从硬盘调入内存,然后 CPU从内存读出指令开始执行。注意:前 提是操作系统已经调入内存并运行。 • 设计CPU硬件电路的目的是使其能够从存 储器中读取一条指令并执行指令所描述的 操作,且这个过程是循环的,自动的。
op Control Unit
pcsource
aluc
4
sext
+
a do Inst Mem
PC+4 rs rt rt
wreg
P C
地址
指令
we rna qa rnb wn d qb Regfile
a aluc ALU
z
0 1 2 3
b
Clock
imm
e
执行立即数计算类型指令所需的电路
• 从上面可以看出,b输入端为imm,再加上 算术逻辑类型指令的输入,所以b输入端的 前面也必须有一个二选一的多路选择器。 • 符号扩展和零扩展是通过组件e来实现的。
– sext=1,符号扩展。 – sext=0,零扩展。
• 计算结果写入由rt指定的寄存器中。
5.1.4 访问存储器类型的指令执行时所需电路

单周期CPU设计参考

单周期CPU设计参考

单周期CPU及其Verilog HDL设计一、指令的设计MIPS32的指令的三种格式的参考:R类型:I类型:J类型:R类型指令的op为0,具体操作由func指定。

rs和rt是源寄存器号,rd是目的寄存器号。

只有移位指令使用sa来指定移位位数。

I类型指令的低16位是立即数,计算时要把它扩展到32位。

依指令的不同,有零扩展和符号扩展两种。

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

具体的指令格式和内容请参考MIPS32。

设计报告中需自行设计所有指令的二进制格式和对应的汇编指令格式。

二、单周期CPU的设计我们把时钟的电平从低到高变化的瞬间称为时钟上升沿,两个相邻时钟上升沿之间的时间间隔称为一个时钟周期。

单周期CPU指的是一条指令的执行在一个这样的时钟周期内完成,然后开始下一条指令的执行,即一条指令用一个周期。

2.1执行一条指令所需的硬件电路我们的目的地是要设计CPU的硬件电路,使其能够从存储器中读出一条条指令并执行指令所描述的操作。

从存储器中读取指令的动作一般与指令本身的意义无关,可以以同样的方法把指令从存储器中取出。

而执行指令则与指令本身的意义密切相关,因此最重要是首先搞清楚CPU要执行的每条指令的意义。

下面以两种类型的电路来举例。

2.1.1与取指令有关的电路指令存储在存储器中。

CPU取指令时把程序计数器(PC)中的内容作为存储器的地址,根据它来访问存储器,从PC值指定的存储单元中取来一条32位指令。

如果取来的指令执行时没有引起转移,PC的值要加4;如果转移,要把转移的目标地址写入PC,以便在下一个时钟周期取出下一条指令。

图2.1 取指令时用到的硬件电路和指令寄存器如图2.1所示,PC是一个简单的32位寄存器,由32个D触发器构成。

指令存储器(Inst Mem)的输入端a是地址、输出端do是数据输出,即指令。

图中的加法器专供PC+4使用,它的输出接到多路器的一个输入端。

如果取来的指令没有引起转移或跳转,则选择PC+4,在时钟上升沿处将其打入PC;若引起转移或跳转,则用多路器选择下一条指令该打入的PC值。

VerilogHDL程序设计教程

VerilogHDL程序设计教程

Verilog HDL程序设计教程红色:做后有错。

粉红色:有疑问。

紫色:第二次仍有错。

绿色:文字错误第1章EDA技术综述 1.1引言1.摩尔定律1.2EDA的发展阶段1.阶段1.3设计方法与设计技术1.两种设计思路2.IP的含义3. IP核的分类。

4. SOC的含义1.4EDA的实现1.实现方法第2章EDA设计软件与设计流程 2.2EDA的设计流程1(FPGA的设计流程 2(综合的定义与类型。

3(仿真的类型第3章Verilog HDL设计初步(P18) 3.2完整的Verilog HDL设计1. 4位全加器的和4位计数器的程序。

2. 4位全加器的仿真程序(1.时间头文件 2.模块名(没有参数)3.参数规定(端口、延时、时钟)4.调用测试对象 5.设置参数(所有的输入端口都应初始化赋值)6.显示设置)。

3.3Verilog模块基本结构剖析 1.端口定义注意事项。

2.逻辑功能定义的几种方式第4章Verilog HDL语言要素(P32)4.1词法1.verilog中的四种基本逻辑状态4.2数据类型1.连线型(Net Type)的特点2.寄存器型(Register Type):定义、与连线型区别(赋值、保值)3.Parameter的使用格式4.3寄存器和存储器1.寄存器定义格式和标矢性2.存储器:定义、格式、位区选择方法4.3运算符1.等式与全等式的区别2.位拼接运算符第5章Verilog HDL行为语句(P45)5.2 Verilog HDL中的过程语句1.always过程语句格式。

2.initial过程语句格式。

5.3 块语句1.块语句。

2.用begin—end产生周期为10的个单位时间的方波.3.用fork—join产生周期为10的个单位时间的方波5.4赋值语句1.分类。

2.阻塞赋值和非阻塞赋值的区别5.5条件语句1.例5.11(模为60的BCD码加法计数器)2.case语句的三种表达形式5.6循环语句1.Verilog HDL中4种类型循环语句。

用Verilog-HDL做CPLD设计(时序逻辑电路的实现)

用Verilog-HDL做CPLD设计(时序逻辑电路的实现)

用Verilog-HDL做CPLD设计(时序逻辑电路的实现)第8 讲用Verilog-HDL做CPLD设计时序逻辑电路的实现8.1 闪烁灯的实现8.2 流水灯的实现8.3 可编程单脉冲发生器在第七讲中,已经介绍了组合逻辑电路的实现。

组合逻辑电路的特点是:在任意时刻,电路产生的稳定输出仅与当前时刻的输入有关。

时序逻辑电路则不同于它,其特点是:在任意时刻电路产生的稳定输出不仅与当前时刻的输入有关,而且还与电路过去的输入有关。

本讲中将介绍时序逻辑电路的实现。

8.1 闪烁灯的实现在目标板上,设计有一个10MHz的时钟源。

假如直接把它输出到发光二级管LED,由于人眼的延迟性,我们将无法看到LED闪烁,认为它一直亮着。

如果我们期望看到闪烁灯,就需要将时钟源的频率降低后再输出。

因此,可以采用如图1所示的逻辑功能框图。

图1 闪烁灯的逻辑功能框图其中,CLK表示10MHz的时钟源,作为输入;LED0-LED7表示发光二极管,作为输出;6、44、43、38、37、36、35、40和42是上述变量对应芯片XC9536的引脚。

虚线框中的部分是CPLD设计,用于实现闪烁灯的功能。

如图1所示,在XC9536中,加入计数电路与判别电路。

计数电路可用计数器实现。

每来一个时钟脉冲CLK,计数器就加1。

而每当判断出计数器达到某个数值时,就使得灯LED0-LED7的亮灭反转一次,即:周期性地输出高电平"1"和低电平"0"。

这样设计也就相当于把10MHz的时钟源分频后再输出。

如果最终要使得灯1s闪烁一次,即:输出1Hz的时钟脉冲,就需要把10MHz的时钟经过107分频。

根据上述分析,可以得到下面的Verilog- HDL 描述。

/* 闪烁灯的Verilog-HDL描述*/module LIGHT ( CLK, LED ); // 模块名及端口参数,范围至endmoduleinput CLK; // 输入端口定义,对应第6脚output [7:0] LED;// 输出端口定义,LED[0]-LED[7]分别对应第44、43、38、37、36、35、40和42脚reg [7:0] LED; // 输出端口定义为寄存器型reg [22:0] buffer; // 中间变量buffer定义为寄存器型always @ ( posedge CLK )// always语句,表示每当CLK的上升沿到来时,完成begin-end之间语句的操作begin // 顺序语句,到end止buffer = buffer +1; // 缓冲器buffer按位加1if ( buffer == 23'b11111111111111111111111)// 判别buffer中的数值为(2^23-1)≈10^7时,做输出处理//"23"表示以位计的数值长度,"b"表示二进制,"11…1"表示二进制的数字序列beginLED=~LED; // LED[0]-LED[7]反转一次,即:由0变为1,或由1变为0endendendmodule把以上闪烁灯的描述,用WebPACK Project Navigator软件,生成目标文件,并通过下载电缆写入芯片XC9536中。

单周期CPU verilog实现

单周期CPU verilog实现

一、实验目的:通过设计并实现支持10 条指令的CPU,进一步理解和掌握CPU 设计的基本原理和过程。

二、实验内容:设计和实现一个支持如下十条指令的单周期CPU。

➢非访存指令◆清除累加器指令CLA◆累加器取反指令COM◆算术右移一位指令SHR:将累加器ACC 中的数右移一位,结果放回ACC◆循环左移一位指令CSL:对累加器中的数据进行操作◆停机指令STP➢访存指令◆加法指令ADD X:[X] + [ACC] –〉ACC,X 为存储器地址,直接寻址◆存数指令STA X,采用直接寻址方式◆取数指令LDA X,采用直接寻址➢转移类指令◆无条件转移指令JMP imm:signExt(imm) -> PC◆有条件转移(负则转)指令BAN X: ACC 最高位为1 则(PC)+ X -> PC,否则PC不变三、实验原理1.设定机器字长、指令字长和存储字长均为16位。

2.设定指令格式CLA、COM、SHR、CSL、STA、LDA默认操作对象为ACC,ADD的第一操作数使用ACC CLA、COM、SHR、CSL、STP指令格式15 12 11 0ADD、STA、LDA指令格式15 12 11 9 8 0JMP、BAN15 12 11 8 7 0由于pc执行完指令后自动加1,所以BAN指令中的跳转值应减1。

3、指令和相应的操作码对照表3、ALU操作和相应的操作码对照表5.CPU 数据通路图5.数据通路图组合逻辑分析mRW:数据存储器读写控制线,低电平写有效pcwre:pc写控制线,当其为1时能写入新地址;为0时保持原地址(与停机指令有关)uncon:无条件跳转使能,当其为1时允许跳转frommem:当其为1时写入寄存器的值来自数据存储器。

RegWre:当其为1时写入寄存器的值来自ALU输出。

当frommem=0且RegWre=0时禁止写入寄存器ALUop:ALU操作码四、实验步骤4.1 CPU 各模块Verilog 实现Verilog 关键代码:module reg_pc(input clk,input reset,input pcwre,input uncon,input judge,input [7:0]jmp,output reg [7:0] pc_addr);initial beginpc_addr<=0;endalways @(negedge clk or posedge reset) beginif(reset)pc_addr<=0;elsebeginif(pcwre)beginpc_addr=pc_addr+1;if(uncon==1)pc_addr=jmp;else if(judge==1)pc_addr=pc_addr+jmp;endelsepc_addr<=pc_addr;endendendmoduleVerilog 关键代码:module instructionMem(input [7:0] reg_pc,output[15:0] instruction);wire[15:0] mem[2**8-1 : 0];assign mem[0]=16'b0011000000000000;//LDA assign mem[1]=16'b0111000000000000;//CSL assign mem[2]=16'b1001000000000000;//COM assign mem[3]=16'b1000000000000000;//SHR assign mem[4]=16'b1010000000000000;//CLA assign mem[5]=16'b0101000000000001;//ADD assign mem[6]=16'b0100000000000010;//STA assign mem[7]=16'b0010000000001010;//JMP10 assign mem[10]=16'b0001000000000001;//pc+2 assign mem[12]=16'b0110000000000000;//STP assign mem[13]=16'b0011000000000000;//LDA assign instruction=mem[reg_pc];endmoduleVerilog 关键代码:module InstructionCut(input [15:0] instruction,output reg[3:0] op,output reg[2:0] ACCaddr,output reg[9:0] mem_addr,output reg[7:0]jmp);initial beginop = 4'b0000;ACCaddr = 3'b000;endalways@(instruction)beginop = instruction[15:12];ACCaddr = 3'b000;mem_addr = {1'b0,instruction[8:0]};jmp=instruction[7:0];endendmoduleVerilog 关键代码:module regroup(input clk,input wr_en,input frommem,input [15:0]memdata,input[2:0]w_addr,r_addr1,r_addr2,input[15:0]w_data,output[15:0]r_data1,r_data2);reg[15:0]array_reg[7:0];initial beginarray_reg[0]=16'h0011;endalways@(posedge clk)beginif(frommem)array_reg[w_addr]<=memdata;if(wr_en)array_reg[w_addr]<=w_data;endassign r_data1=array_reg[r_addr1];assign r_data2=array_reg[r_addr2]; endmoduleVerilog 关键代码:module alu(input [15:0] ACCdata,input [15:0] mem,input [2:0] ALUop,output reg [15:0] judge,output reg [15:0] result);reg[15:0]a;reg[15:0]b;parameter ADD=3'b000; parameter SUB=3'b001; parameter COM=3'b010; parameter JUDGE=3'b011; parameter CSL=3'b100; parameter SHR=3'b101; parameter CLA=3'B110;initial beginjudge=0;result=0;endalways@*begina=ACCdata;b=mem;case(ALUop)ADD:result=a+b;SUB:result=a-b;COM:result=~a;JUDGE:judge=(a[15]==1)?1:0;CSL:result={a[14:0],a[15]};SHR:result=(a[15]==1)?{1'b1,a[15:1]}:{1'b0,a[15:1]};CLA:result=0;endcaseendendmoduleVerilog 关键代码:module Control(input [15:0] instruction,output reg RegWre,output reg [2:0]ALUop,output reg pcwre,output reg uncon,output reg frommem,output reg mRW);always@(instruction)beginmRW = 1; //strpcwre=1;uncon=0;frommem=0;case(instruction[15:12]) //CLA4'b1010:beginRegWre=1;ALUop = 3'b110;end//COM4'b1001:beginRegWre=1;ALUop = 3'b010;end//SHR4'b1000:beginRegWre=1;ALUop = 3'b101;end//CSL4'b0111:beginRegWre=1;ALUop = 3'b100;end//STP4'b0110:beginRegWre=0;ALUop = 3'b111;pcwre=0;end//ADD4'b0101:beginRegWre=1;ALUop = 3'b000;end//STA4'b0100:beginRegWre = 0;mRW=0;ALUop = 3'b111;end//LDA4'b0011:beginfrommem=1;RegWre = 0;ALUop = 3'b111;end//JMP4'b0010:beginRegWre = 0;uncon=1;ALUop = 3'b111;end//BAN4'b0001:beginRegWre = 0;ALUop = 3'b011;endendcaseendendmoduleVerilog 关键代码:module mem(input wire clk,we,input wire[9:0]mem_addr,input wire[15:0]din,output wire[15:0]dout);reg[15:0] rammem[2**10-1:0];initial beginrammem[0]=16'b1000000000000001;rammem[1]=16'b1000000000000000; endalways@(posedge clk)beginif(!we)rammem[mem_addr]<=din;endassign dout=rammem[mem_addr]; endmodule4.2顶层模块的实现用于连接各个部件Verilog 关键代码:module CycleCPU(input clk,input reset,output frommem,output [3:0] op,output pcwre,output uncon,output judge,output [7:0]jmp,output [2:0] ACCaddr,output [15:0] instruction,output [15:0] ACCdata,output [15:0] result,output RegWre,output [2:0]ALUop,output mRW,output [9:0] mem_addr,output [7:0]pc_addr,output [15:0]memdata);reg_pc reg_pc(.clk(clk),.reset(reset),.pcwre(pcwre),.uncon(uncon),.judge(judge),.jmp(jmp),.pc_addr(pc_addr));instructionMem instructionMem(.reg_pc(pc_addr),.instruction(instruction)); InstructionCut InstructionCut(.instruction(instruction),.op(op),.ACCaddr(ACCaddr),.mem_addr(mem_addr),.jmp(jmp) );Control Control(.instruction(instruction),.RegWre(RegWre),.ALUop(ALUop),.pcwre(pcwre),.uncon(uncon),.frommem(frommem),.mRW(mRW) );regroup regroup(.clk(clk),.wr_en(RegWre),.frommem(frommem),.memdata(memdata),.w_addr(ACCaddr),.r_addr1(ACCaddr),.r_addr2(ACCaddr),.w_data(result),.r_data1(ACCdata),.r_data2(ACCdata));mem mem(.clk(clk),.we(mRW),.mem_addr(mem_addr),.din(ACCdata),.dout(memdata));alu alu(.ACCdata(ACCdata),.mem(memdata),.ALUop(ALUop),.judge(judge),.result(result)); Endmodule4.3 模拟仿真1.仿真代码module Cpu_tb;reg clk;reg reset;wire frommem;wire [3:0] op;wire pcwre;wire uncon;wire judge;wire [7:0]jmp;wire [2:0] ACCaddr;wire [15:0] instruction;wire [15:0] ACCdata;wire [15:0] result;wire RegWre;wire [2:0]ALUop;wire mRW;wire [9:0]mem_addr;wire[7:0] pc_addr;wire[15:0] memdata; CycleCPU lz(.clk(clk),.reset(reset),.frommem(frommem),.op(op),.pcwre(pcwre),.uncon(uncon),.judge(judge),.jmp(jmp),.ACCaddr(ACCaddr),.instruction(instruction),.ACCdata(ACCdata),.result(result),.RegWre(RegWre),.ALUop(ALUop),.mRW(mRW),.mem_addr(mem_addr),.pc_addr(pc_addr),.memdata(memdata));initial begin#0 reset=1;clk=0;#5 reset=0;#5 reset=0;#5 reset=0;#5 reset=0;#5 reset=0;#5 reset=0;endalways#5 clk = ~clk;endmodule2.仿真分析指令1 LDA 取数指令这条指令在指令存储器的地址00000000处。

类MIPS单周期微处理器设计

类MIPS单周期微处理器设计

类MIPS单周期微处理器设计1.实验任务、目标利用Verilog HDL语言,基于Xilinx FPGA nexys4实验平台,设计一个能够执行以下MIPS指令集的单周期类MIPS处理器,要求完成所有支持指令的功能仿真,验证指令执行的正确性,要求编写汇编程序将本人学号的ASCII码存入RAM的连续内存区域。

▪支持基本的算术逻辑运算如add,sub,and,or,slt,andi指令▪支持基本的内存操作如lw,sw指令▪支持基本的程序控制如beq,j指令(由于特殊情况,此次实验仅完成Reg、ALU、ALUCtr三个模块并分别加以仿真和验算)2.微处理器各个模块硬件设计原理、verilog代码(1)Reg设计Reg是指令操作地主要对象,MIPS微处理器中一共32个32位寄存器。

该模块输入为 RsAddr,RtAddr,WriteAddr,RegWr,WriteData,clk,reset有两项输出 RsData,RtData。

其中当复位信号reset为1时所有寄存器清零,当复位信号为0且写信号有效时数据才写入writedata寄存器。

(其中0号寄存器永远为0)具体代码如下:module RegFile(input [4:0] RsAddr,input [4:0] RtAddr,input [4:0] WriteAddr,input RegWr,input [31:0] WriteData,input clk,input reset,output [31:0] RsData,output [31:0] RtData);reg [31:0] regs[0:31];assign RsData =(RsAddr==5'b0) ? 32'b0:regs[RsAddr];assign RtData =(RtAddr==5'b0) ? 32'b0:regs[RtAddr];integer i;always @(negedge clk) //下降沿回写到寄存器if(!reset&RegWr)regs[WriteAddr]=WriteData;else if(reset)for(i=0;i<32;i=i+1)regs[i]=4*i; //寄存器的值初始化为编号乘以4Endmodule(2)ALU设计微处理器支持add,sub,and,or,slt运算指令,需要用ALU单元实现运算,同时sw,lw,beq等指令也要用到ALU单元计算地址,比较数据,因此我们设计此模块输入为in1,in2,(此处要设置为signed类型,不然无法执行slt指令),ALUctr两个输出Res,zero。

单周期CPU——verilog语言实现

单周期CPU——verilog语言实现

单周期CPU——verilog语⾔实现⼀. 实验内容设计⼀个单周期CPU,要求:1. 实现MIPS的20条指令2. 在该CPU上实现斐波那契函数计算机每执⾏⼀条指令都可分为三个阶段进⾏。

即取指令(IF)——>分析指令(ID)——>执⾏指令(EXE)取指令:根据程序计数器PC中的指令地址,从存储器中取出⼀条指令,同时,根据控制信号,决定选择某个来源的指令地址作为下⼀条指令的地址。

分析指令:对取指令操作中得到的指令进⾏分析并译码,确定这条指令需要完成的操作,从⽽产⽣相应的操作控制信号,⽤于驱动执⾏状态中的各种操作。

执⾏指令:根据指令译码得到的操作控制信号,具体地执⾏指令动作。

⼆. 20条指令的情况R指令I指令J指令三. 取指令(IF)的相关模块代码//PCmodule PC(input [31:0] next_addr,input rst,input clk,output reg [31:0] addr);always @(posedge clk)beginif(rst==1'b1)beginaddr<=next_addr;endelsebeginaddr<=32'b0;endendinitial$monitor($time,,"PC:addr=%h",addr);endmodule//ROMmodule rom(input [31:0] addr,output [31:0] data);reg[31:0] romdata;always @(*)case(addr[31:2])4'h0:romdata=32'b10001100000000110000000000100000; //lw $0,$3,32 *4'h1:romdata=32'b00110100000100000000000000000010; //ori $0,$16,2 *4'h2:romdata=32'b00000000000000111000100000100101; //or $0,$3,$17 * 4'h3:romdata=32'b00110100000100110000000000000001; //ori $0,$19,1 *4'h4:romdata=32'b00110100000001000000000000000001; //ori $0,$4,1 *4'h5:romdata=32'b00010010001100110000000000001011; //beq $17,$19,11 * 4'h6:romdata=32'b00000000000001000100000000100101; //or $0,$4,$8 *4'h7:romdata=32'b00100010011100110000000000000001; //addi $19,$19,1 * 4'h8:romdata=32'b00110100000001000000000000000001; //ori $0,$4,1 *4'h9:romdata=32'b00010010001100110000000000000111; //beq $17,$19,7 * 4'ha:romdata=32'b00000000000001000100100000100101; //or $0,$4,$9 * 4'hb:romdata=32'b00000001000010010010000000100000; //add $8,$9,$4 * 4'hc:romdata=32'b00000000000010010100000000100101; //or $0,$9,$8 *4'hd:romdata=32'b00000000000001000100100000100101; //or $0,$4,$9 *4'he:romdata=32'b00100010000100000000000000000001; //addi $16,$16,1 * 4'hf:romdata=32'b00010110000100011111111111111011; //bne $16,$17,-5 * default:romdata=32'b10101100000001000000000000010000; //sw $0,$4,16 endcaseassign data=romdata;initial$monitor($time,,"rom:romdata=%h",romdata);endmodule//Selectormodule selector(input [31:0] addr0,input [31:0] addr1,input [31:0] addr2,input [31:0] addr3,input [1:0] pcsource,output reg [31:0] next_addr);always @(*)begincase(pcsource)2'b00:beginnext_addr=addr0;end2'b01:beginnext_addr=addr1; //bne,beqend2'b10:beginnext_addr=addr2; //jend2'b11:beginnext_addr=addr3; //jal,jrendendcaseendinitial$monitor($time,,"selector: pcsource=%h, next_addr=%h",pcsource,next_addr); endmodule四. 所使⽤的控制信号pcindex: pc值的来源ram2reg: 是否将数据从RAM写⼊到寄存器中,=1为是,否则为否ramWE: 是否写内存,=1为是,否则为否aluOP: ALU的运算类型regWE: 是否写寄存器,=1为是,否则为否imm: 是否产⽣⽴即数,=1为是,否则为否shift: 是否移位,=1为是,否则为否isrt: ⽬的寄存器地址,=1选择rt,否则选择rdsign_ext: ⽴即数拓展,=1为符号数拓展,否则为零拓展jal: 是否调⽤⼦程序跳转,=1为是,否则为否五. 各指令对应产⽣的控制信号pcindex ram2reg ramWE aluOP regWE imm shift isrt sign_ext jal add 0 0 0 0001 1 0 00 00 sub 0 0 0 0010 1 0 0 0 0 0 and 0 0 0 00111 0 00 0 0 or0 0 0 0100 1 0 0 0 0 0 xor0 0 0 01011 0 0 0 0 0 sll0 0 0 01101 0 1 1 0 0 srl0 0 0 01111 0 1 1 0 0 sra0 0 0 1000 1 0 1 1 0 0 jr10 0 0 0 0 0 0 0 0 0 addi0 0 0 00011 1 0 1 1 0 andi0 0 0 0011 1 1 0 1 0 0 ori0 0 0 01001 1 0 1 0 0 xori0 0 0 01011 1 0 1 0 0 lw0 1 0 0001 1 1 0 1 1 0 sw 0 0 1 000101 0 1 1 0 beq00/01 0 0 00100 0 0 0 1 0 bne00/01 0 0 0010 0 0 0 0 1 0 lui 0 0 0 100111 0 1 0 0 j 11 0 0 00 0 0 0 0 0 jal 11 0 0 01 0 0 0 0 1六. 分析指令(ID)相关模块代码//IDmodule ID(input [31:0] instrument,output reg [5:0] opcode,output reg [5:0] func,output reg [4:0] rs,output reg [4:0] rt,output reg [4:0] rd,output reg [4:0] sa,output reg [15:0] immediate,output reg [25:0] addr);always @(*)beginopcode=instrument[31:26];rs=5'b0;rt=5'b0;rd=5'b0;sa=5'b0;immediate=16'b0;addr=25'b0;case(opcode)6'b000000: //R类型beginfunc=instrument[5:0];sa=instrument[10:6];rd=instrument[15:11];rt=instrument[20:16];rs=instrument[25:21];end6'b001000,6'b001100,6'b001101,6'b001110,6'b100011,6'b101011,6'b000100,6'b000101,6'b001111: beginimmediate=instrument[15:0];rt=instrument[20:16];rs=instrument[25:21];end6'b000010,6'b000011:beginaddr=instrument[25:0];enddefault: rs=5'b00000;endcaseendendmodule//CUmodule CU(input [5:0] opcode,input [5:0] func,input z,output reg [1:0] pcindex,output reg ram2reg,output reg ramWE,output reg [3:0] aluOP,output reg regWE,output reg imm,output reg shift,output reg isrt,output reg sign_ext,output reg jal);always @(*)begin//设置默认值shift=1'b0;ram2reg=1'b0;ramWE=1'b0;regWE=1'b0;imm=1'b0;isrt=1'b0;sign_ext=1'b0;pcindex=2'b00;aluOP=4'b0000;jal=1'b0;case(opcode)//R指令6'b000000:begincase(func)6'b100000: //add指令beginaluOP=4'b0001;regWE=1'b1;end6'b100010: //sub指令beginaluOP=4'b0010;regWE=1'b1;end6'b100100: //and指令beginaluOP=4'b0011;regWE=1'b1;end6'b100101: //or指令beginaluOP=4'b0100;regWE=1'b1;end6'b100110: //xor指令beginaluOP=4'b0101;regWE=1'b1;end6'b000000: //sll指令beginaluOP=4'b0110; regWE=1'b1;shift=1'b1;isrt=1'b1;end6'b000010: //srl指令beginaluOP=4'b0111; regWE=1'b1;shift=1'b1;isrt=1'b1;end6'b000011: //sra指令beginaluOP=4'b1000; regWE=1'b1;shift=1'b1;isrt=1'b1;end6'b001000: //jr指令beginpcindex=2'b10;endendcaseend//I指令6'b001000: //addi指令beginaluOP=4'b0001;imm=1'b1;regWE=1'b1;sign_ext=1'b1;isrt=1'b1;end6'b001100: //andi指令beginaluOP=4'b0011;imm=1'b1;regWE=1'b1;isrt=1'b1;end6'b001101: //ori指令beginaluOP=4'b0100;imm=1'b1;regWE=1'b1;isrt=1'b1;end6'b001110: //xori指令beginaluOP=4'b0101;imm=1'b1;regWE=1'b1;isrt=1'b1;end6'b100011: //lw指令beginram2reg=1'b1;aluOP=4'b0001;imm=1'b1;regWE=1'b1;sign_ext=1'b1;isrt=1'b1;end6'b101011: //sw指令beginramWE=1'b1;aluOP=4'b0001;imm=1'b1;sign_ext=1'b1;isrt=1'b1;end6'b000100: //beq指令beginaluOP=4'b0010;sign_ext=1'b1;if(z==1'b1)beginpcindex=2'b01;endend6'b000101: //bne指令beginaluOP=4'b0010;sign_ext=1'b1;if(z==1'b0)beginpcindex=2'b01;endend6'b001111: //lui指令beginregWE=1'b1;imm=1'b1;isrt=1'b1;aluOP=4'b1001;end//J指令6'b000010: //j指令beginpcindex=2'b11;end6'b000011: //jal指令beginjal=1'b1;regWE=1'b1;pcindex=2'b11;endendcaseendinitial$monitor($time,,"CU:imm=%b,op=%h, isrt=%h, pcindex=%h, regWE=%h, shift=%h, ram2reg=%h, ramWE=%h ",imm,aluOP,isrt,pcindex,regWE,shift,ram2reg,ramWE); endmodule七. 总体电路图⼋. 执⾏指令(EXE)相关模块的代码//selector_5module selector_5(input [4:0] a,input [4:0] b,input choice,output [4:0] f);assign f=(choice==1'b0)?a:b;initial$monitor($time,,"selector_5: a=%h, b=%h, f=%h",a,b,f);endmodule//selector_32module selector_32(input [31:0] a,input [31:0] b,input choice,output [31:0] f);assign f=(choice==1'b0)?a:b;initial$monitor($time,,"selector_32: f=%h",f);endmodule//ext_immmodule ext_imm(input [15:0] immediate,input sign_ext,output [31:0] imm);//sign_ext为1时,有符号拓展;为0时,0拓展assign imm=(sign_ext==0)?{{16{1'b0}},immediate}:{{16{immediate[15]}},immediate}; initial$monitor($time,,"ext_imm: imm=%h",imm);endmodule//alu_add_4module alu_add_4(input [31:0] a,output [31:0] f);assign f=a+32'b0100;initial$monitor($time,,"alu_add_4:f=%h",f);endmodule//registersmodule registers(input clk,input oc,input [4:0] raddr1,input [4:0] raddr2,input [4:0] waddr,input [31:0] wdata,input we,output reg [31:0] rdata1,output reg [31:0] rdata2);reg[31:0] regts[1:31];always @(*)beginif(oc==1'b1)beginrdata1=32'bz;endelse if(raddr1==5'b00000)beginrdata1=32'b0;endelsebeginrdata1=regts[raddr1];$monitor($time,,"Read R %d data1=%d",raddr1,rdata1); endalways @(*)beginif(oc==1'b1)beginrdata2=32'bz;endelse if(raddr2==5'b00000)beginrdata2=32'b0;endelsebeginrdata2=regts[raddr2];end$monitor($time,,"Read R %d data2=%d",raddr2,rdata2); endalways @(posedge clk)begin#1if((we==1'b1)&&(waddr!=5'b00000))beginregts[waddr]<=wdata;$monitor($time,,"write %h to data=%d",waddr,wdata);endendendmodule//isimmmodule isimm(input [31:0] rt,input [31:0] immediate,input imm,output [31:0] b);assign b=imm?immediate:rt;initial$monitor($time,,"isimm:b=%h",b);endmodule//ALUmodule alu(input [31:0] a,input [31:0] b,input [3:0] op,output [31:0] f,output z);reg [31:0]result;always@(*)begincase(op)4'b0000:result=32'b0;4'b0001:result=a+b;4'b0010:result=a-b;4'b0011:result=a&b;4'b0100:result=a|b;4'b0101:result=a^b;4'b0110:result=b<<a;4'b0111:result=b>>a;4'b1000:result=$signed(b)>>>a;4'b1001:result={b,{16{1'b0}}};default:result=32'b0;endcaseendassign f=result;assign z=~(|result);initial$monitor($time,,"alu:a:%h,b:%h,op:%h,",a,b,op);initial$monitor($time,,"alu:f:%h,z:%b",f,z);endmodulemodule IOManager(input [5:0] addr,input [31:0] din,output [31:0] dout,input we,input clk,input [3:0] switch,output reg[31:0] displaydata);reg [31:0] indata,outdata;wire [31:0] ramdout;wire ramWE;wire enable;assign enable=(|addr[5:4]);ram dram(addr[3:0],din,clk,enable,ramWE,ramdout);assign dout=(addr[5]==1'b1)?{{28{1'b0}},switch}:ramdout;assign ramWE=we&(~addr[4]);always @(posedge clk)beginif((addr[4]==1'b1)&&we)displaydata<=din;endinitial$monitor($time,,"IOM: addr=%h, din=%h, dout=%h",addr,din,dout); initial$monitor($time,,"IOM: switch=%h, displaydata=%h",switch,displaydata); endmodule//rammodule ram(input [3:0] addr,input [31:0] wdata,input clk,input ce,input we1,output reg[31:0] rdata);reg [31:0] ram[0:30];always @(*)beginif(ce==1'b0)beginrdata=ram[addr];endendalways @(posedge clk)begin#1if((ce==1'b0)&&(we1==1'b1))beginram[addr]<=wdata;endendinitial$monitor($time,,"ram: ram=%h,rdata=%h",ram[addr],rdata); endmodule//leftmodule left(input [31:0] a,output [31:0] b);assign b=a<<2;endmodule//alu_add_bmodule alu_add_b(input [31:0] addr,input [31:0] immediate,output [31:0] f);assign f=addr+immediate;initial$monitor($time,,"alu_add_b: addr=%h, immediate=%h, f=%h ",addr,immediate,f); endmodule//ext_addermodule ext_adder(input [25:0] address,output [27:0] f);assign f={address,{2{1'b0}}};initial$monitor($time,,"ext_addr: address=%h, f=%h ",address,f);endmodule//mixaddrmodule mixAddr(input [31:0] addr,input [27:0] address,output [31:0] f);assign f={{addr[31:28]},address};initial$monitor($time,,"mixAddr: addr=%h, address=%h, f=%h",addr,address,f);endmodule九. TOP⽂件代码1module top(2input clk,3input rst,4input [4:0] n,5output [31:0] result6 );78wire [31:0] next_addr;9wire [31:0] addr,addr0,addr1,addr2,addr3;10wire [31:0] immediate;11wire [27:0] fAddress;12wire [31:0] instrument;13wire [5:0] opcode,func;14wire [4:0] rs,rt,rd,sa;15wire [15:0] imm;16wire [25:0] address;17wire z;18wire [1:0] pcindex;19wire ram2reg,ramWE,regWE,isimm,shift,isrt,sign_ext,jal;20wire [3:0] aluOP;21wire [4:0] waddr;22wire [4:0] tmp_waddr;23wire [4:0] regs31=5'b11111;24wire [31:0] wdata,rdata1,rdata2,f,tmp_f;25wire oc=1'b0;26wire [31:0] a,b;27wire [31:0] dout;28wire [31:0] lImmediate;29wire [31:0] fsa;3031 PC myPC(next_addr,rst,clk,addr);32 rom myRom(addr,instrument);33 ID myID(instrument,opcode,func,rs,rt,rd,sa,imm,address);34 CU myCU(opcode,func,z,pcindex,ram2reg,ramWE,aluOP,regWE,isimm,shift,isrt,sign_ext,jal);35 ext_imm myExtImm(imm,sign_ext,immediate);36 selector_5 mySelector5_1(rd,rt,isrt,tmp_waddr); //⽬的寄存器是否rt37 selector_5 mySelector5_2(tmp_waddr,regs31,jal,waddr); //是否调⽤⼦程序调转wa38 alu_add_4 myAdd4(addr,addr0);39 selector_32 mySelector32_1(f,addr0,jal,wdata); //是否调⽤⼦程序调转wd40 registers myRegs(clk,oc,rs,rt,waddr,wdata,regWE,rdata1,rdata2);41 isimm myIsImm(rdata2,immediate,isimm,b);42assign fsa={{27{1'b0}},sa};43 selector_32 mySelector32_2(rdata1,fsa,shift,a); //选择sa和rs数据44 alu myAlu(a,b,aluOP,tmp_f,z);45 IOManager myIOM(tmp_f,rdata2,dout,ramWE,clk,n,result);46 selector_32 mySelector32_3(tmp_f,dout,ram2reg,f); //是否将数据从ram中写⼊reg47 left myLeft(immediate,lImmediate);48 alu_add_b myAddb(addr0,lImmediate,addr1);49 ext_adder myExtAddr(address,fAddress);50 mixAddr myMixAddr(addr,fAddress,addr3);51 selector mySelector(addr0,addr1,rdata1,addr3,pcindex,next_addr);525354initial55 $monitor($time,,"top: n=%h, result=%h",n,result);5657endmodule。

Verilog HDL程序设计

Verilog HDL程序设计

Verilog HDL程序设计一、实验目的:1.掌握Verilog HDL程序的设计方法2.熟悉Quartus_II 9.0的安装3.熟悉Quartus_II 9.0的使用二、实验工具:Quartus_II 9.0三、上机内容:本上机实验采用Verilog HDL描述一个基本的数字逻辑单元(数据选择器、加法器等),在Quartus_II 9.0中进行仿真,并观察逻辑综合后得到的RTL图。

Verilog HDL是一种硬件描述语言(HDL: Hardware Discription Language),是一种以文本形式来描述数字系统硬件的结构和行为的语言,用它可以表示逻辑电路图、逻辑表达式,还可以表示数字逻辑系统所完成的逻辑功能。

模块是Verilog 的基本描述单位,用于描述某个设计的功能或结构及其与其他模块通信的外部端口。

一个设计的结构可使用开关级原语、门级原语和用户定义的原语方式描述; 设计的数据流行为使用连续赋值语句进行描述; 时序行为使用过程结构描述。

一个模块可以在另一个模块中调用。

模块的定义从关键字module开始,到关键字endmodule结束,每条Verilog HDL语句以“;”做为结束(块语句、编译向导、endmodule等少数除外)。

一个完整的Verilog模块由以下五个部分组成:1.模块定义行:module module_name (port_list);2.说明部分用于定义不同的项,例如模块描述中使用的寄存器和参数。

语句定义设计的功能和结构。

说明部分和语句可以散布在模块中的任何地方;但是变量、寄存器、线网和参数等的说明部分必须在使用前出现。

为了使模块描述清晰和具有良好的可读性, 最好将所有的说明部分放在语句前。

说明部分包括:寄存器,线网,参数:reg, wire, parameter端口类型说明行:input, output, inout函数、任务:function, task, 等3.描述体部分:这是一个模块最重要的部分,在这里描述模块的行为和功能,子模块的调用和连接,逻辑门的调用,用户自定义部件的调用,初始态赋值,always块,连续赋值语句等等。

Verilog HDL简明教程中文版

Verilog HDL简明教程中文版

中文版Verilog HDL简明教程Verilog HDL是一种硬件描述语言,用于从算法级、门级到开关级的多种抽象设计层次的数字系统建模。

被建模的数字系统对象的复杂性可以介于简单的门和完整的电子数字系统之间。

数字系统能够按层次描述,并可在相同描述中显式地进行时序建模。

Verilog HDL 语言具有下述描述能力:设计的行为特性、设计的数据流特性、设计的结构组成以及包含响应监控和设计验证方面的时延和波形产生机制。

所有这些都使用同一种建模语言。

此外,Verilog HDL语言提供了编程语言接口PLI,通过该接口可以在模拟、验证期间从设计外部访问设计,包括模拟的具体控制和运行。

Verilog HDL语言不仅定义了语法,而且对每个语法结构都定义了清晰的模拟、仿真语义。

因此,用这种语言编写的模型能够使用Verilog仿真器进行验证。

语言从C编程语言中继承了多种操作符和结构。

Verilog HDL提供了扩展的建模能力,其中许多扩展最初很难理解。

但是,Verilog HDL语言的核心子集非常易于学习和使用,这对大多数建模应用来说已经足够。

当然,完整的硬件描述语言足以对从最复杂的芯片到完整的电子系统进行描述。

第1章简介Verilog HDL是一种硬件描述语言,用于从算法级、门级到开关级的多种抽象设计层次的数字系统建模。

被建模的数字系统对象的复杂性可以介于简单的门和完整的电子数字系统之间。

数字系统能够按层次描述,并可在相同描述中显式地进行时序建模。

Verilog HDL 语言具有下述描述能力:设计的行为特性、设计的数据流特性、设计的结构组成以及包含响应监控和设计验证方面的时延和波形产生机制。

所有这些都使用同一种建模语言。

此外,Verilog HDL语言提供了编程语言接口,通过该接口可以在模拟、验证期间从设计外部访问设计,包括模拟的具体控制和运行。

Verilog HDL语言不仅定义了语法,而且对每个语法结构都定义了清晰的模拟、仿真语义。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Project4 VerilogHDL 完成单周期处理器开发
一、 设计说明
1. 处理器应 MIPS-Lite3 指令集。 a) MIPS-Lite3={MIPS-Lite2,addi,addiu, slt,j,jal,jr}。 b) MIPS-Lite2 指令集:addu,subu,ori,lw,sw,beq,lui。 c) addi 可以不支持溢出。 2. 处理器为单周期设计。
Figure2 参考的 project 目录组织
b) 顶层设计文件命名为 mips.v。 c) 建议 datapath 中的每个 module 都由一个独立的 VerilogHDL 文件组成。 d) 建议所有 mux (包括不同位数、 不同端口数等) 都建模在一个 mux.v 中。 可以有多个 module。 6. code.txt 中存储的是指令码 a) 用 VerilogHDL 建模 IM 时,必须以读取文件的方式将 code.txt 中指令加 载至 IM 中。 b) code.txt 的格式如 Figure3 所示。每条指令占用 1 行,指令二进制码以文 本方式存储。
15. 详细说明你的测试程序原理及测试结果。 【WORD】 a) 应明确说明测试程序的测试期望,即应该得到怎样的运行结果。 b) 每条汇编指令都应该有注释。
五、 问答【WORD】
16. C 语言是一种弱类型程序设计语言。C 语言中不对计算结果溢出进行处理, 这意味着 C 语言要求程序员必须很清楚计算结果是否会导致溢出。因此,如 果仅仅支持 C 语言,MIPS 指令的所有计算指令均可以忽略溢出。 a) 请说明为什么在忽略溢出的前提下, addi 与 addiu 是等价的, add 与 addu 是等价的。 提示: 阅读 《MIPS32® Architecture For Programmers Volume II: The MIPS32® Instruction Set》中相关指令的 Operation 部分。
四、 测设要求
12. 所有指令都应被测试充分。 13. 构造至少包括 40 条以上指令的测试程序,并测试通过。 a) MIPS-Lite3 定义的每条指令至少出现 1 次以上。 b) 必须有函数,并至少 1是较为复杂的指令,其正确性不仅涉及到自身的正确 性,还与堆栈调整等操作相关。因此为了更充分的测试,你必须在测试程序 中组织一个循环, 并在循环中多次函数调用, 以确保正确实现了这 2 条指令。
八、 开发与调试技巧
25. 对于每条指令,请认真阅读《MIPS32® Architecture For Programmers Volume II: The MIPS32® Instruction Set》 ! a) 如果测试时,你无法清楚的解释所要求的指令,测试成绩将减一档! 26. 建议先在 MARS 中编写测试程序并调试通过。注意 memory configuration 的 具体设置。 a) 为 了 便 于 你 初 步 测 试 你 的 处 理 器 , 我 们 提 供 了 一 个 汇 编 程 序 (proj4_test_fibonacci-2.asm)及其对应的指令码文件(code.txt)。 b) proj4_test_fibonacci-2.asm 首先初始化了 F0 和 F1,然后以函数调用的方 式计算 F2 至 F19,并在 F19(其值为 0x1A6D)后写入 0xABCD_0000,然 后进入死循环,运行结果如图所示。
七、 成绩及实验测试要求
21. 实验成绩包括但不限于如下内容:初始设计的正确性、增加新指令后的正确 性、实验报告等。 22. 实验测试时,你必须已经完成了处理器设计及开发。 a) 允许实验报告可以未完成。 23. 实验测试时,你需要展示你的设计并证明其正确性。 a) 应简洁的描述你的验证思路,并尽可能予以直观展示。 24. 实验指导教师会临时增加 1~2 条指令,你需要在规定时间内完成对原有设 计的修改,并通过实验指导教师提供的测试程序。 a) 考查时,教师将用专用 testbench 和 code.txt 检测代码执行情况。
Figure4 MIPS 存储配置模式(MARS memory configuration)
三、 模块定义【WORD】
9. 仿照下面给出的 PC 模块定义,给出所有功能部件的模块定义。 10. PC 模块定义(参考样例) (1) 基本描述 PC 主要功能是完成输出当前指令地址并保存下一条指令地址。复位后,PC 指向 0x0000_3000,此处为第一条指令的地址。 (2) 模块接口
11. 下列模块必须严格满足如下的接口定义: a) 你必须在 VerilogHDL 设计中建模这 3 个模块。 b) 不允许修改模块名称、端口各信号以及变量的名称/类型/位宽。
文件 mips.v 模块接口定义 module mips(clk, rst) ; input clk ; input rst ; im_4k( addr, dout ) ; input [11:2] addr ; output [31:0] dout ; reg [31:0] // clock // reset // address bus // 32-bit memory output
信号名 NPC[31:2] clk 方向 I I 描述 下条指令的地址 时钟信号
Reset PC[31:2]
I O
复位信号。 1:复位 0:无效 30 位指令存储器地址(最低 2 位省略)
(3) 功能定义
序号 1 2 功能名称 复位 保存 NPC 并输出 功能描述 当复位信号有效时,PC 被设置为 0x0000_3000。 在每个 clock 的上升沿保存 NPC,并输出。
reg [31:0] my_memory[1023:0] ; initial $readmemh( “code.txt”, my_memory ) ;
28. 有时我们需要较为集中的在顶层 testbench 中观察甚至修改下层模块的变量, 那么你可以通过使用层次路径名来非常方便的达到这一目的。例如:
30. JR 指令
31. JAL 指令
32. LW 指令 a) Operation Addr sign_extend(offset) + GPR[base]
GPR[rt] Memory[Addr] 33. SW 指令 a) Operation Addr sign_extend(offset) + GPR[base] Memory[Addr] GPR[rt]
二、 设计要求
3. 单周期处理器由 datapath(数据通路)和 controller(控制器)组成。 a) 数据通路由如下 module 组成: PC(程序计数器)、 NPC(NextPC 计算单元)、 GPR (通用寄存器组,也称为寄存器文件、寄存器堆)、ALU(算术逻辑单 元)、EXT(扩展单元)、IM(指令存储器)、DM(数据存储器)。 b) IM:容量为 4KB(32bit×1024 字)。 c) DM:容量为 4KB(32bit×1024 字)。 4. Figure1 为供你参考的数据通路架构图。 a) 我们不确保 Figure1 是完全正确的;我们也不确保 Figure1 能够满足 MIPS-Lite3 b) 鼓励你从数据通路的功能合理划分的角度自行设计更好的数据通路架构。 c) 如果你做了比较大的调整,请务必注意不要与要求 5 矛盾。
im.v
im[1023:0] ;
dm.v
dm_4k( addr, din, we, clk, dout ) ; input [11:2] addr ; // address bus input [31:0] din ; // 32-bit input data input we ; // memory write enable input clk ; // clock output [31:0] dout ; // 32-bit memory output reg [31:0] dm[1023:0] ;
Figure5 proj4_test_fibonacci-2.asm 运行结果
c) 你应该加载 code.txt 至指令存储器以测试你的处理器设计。假设你的处 理器设计是正确的, 那么数据存储器的前 22 个 word 的值应该如图所示。 d) 你需要参照 Figure4 设置 MARS,否则该程序将无法运行。 e) 注意: 你不能将我们提供 proj4_test_fibonacci.asm 直接作为你写的测试程 序提交。你需要编写一个不同的测试程序。 27. 利用$readmemh 系统任务可以给存储器初始化数据。例如可以把 code.txt 文 件中的数据加载至 my_memory 模块。
module testbench ; Chil C1(…) ; $display(C1.Art) ; endmodule module Chil(…) ; reg Art; … endmodule
九、 补充说明
由于 MIPS-Lite3 部分指令(主要是 JAL、JR)涉及非常复杂的运行模式,故你 在 阅 读 《MIPS32® Architecture For Programmers Volume II: The MIPS32® Instruction Set》时可能存在困难。为此我们做了简化处理以便于你理解。简化 主要是去除所有与 exception、delay slot 有关的描述。J、JAL、JR 所有简化后的 描述陈列如下。 29. J 指令
六、 其他要求
17. 打包文件:VerilogHDL 工程文件、code.txt、code.txt 所对应的汇编程序、项 目报告。 18. 时间要求:各班实验指导教师指定。 19. 本实验要求文档中凡是出现了【WORD】字样,就意味着该条目需要在实验 报告中清晰表达。 20. 实验报告请按照《计算机组成原理实验报告撰写规则.doc》要求排版。
Figure1 数据通路(供参考)
5. 整个 project 必须采用模块化和层次化设计。 a) Figure2 为参考的目录结构和文件命名。其中红色框的目录名称及文件名 称不允许调整(control、datapath、mips.v、code.txt 都属于同一层;control 目录下包括 ctrl.v;datapath 目录下包括 im.v、dm.v,等等)。
相关文档
最新文档