实验1 在MAX10 FPGA上实现组合逻辑
实验1 在MAX10 FPGA上实现组合逻辑
实验前的准备工作:参照讲义步骤安装Quartus,Modelsim和System Builder。阅读材料:1)推荐的文件组织形式;2)Verilog 1:概述和Verilog 2:重点是assign语句。
参考资源:友晶网站上的关于DE10-Lite实验板的资源:用户手册,工具和案例。
http://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=218&No=1021&PartNo=4
Part 0. 使用System
Bulider、Quartus和Modelsim的设计流程
A. 使用System Builder创建工程文件
在用户手册的第4章介绍了System Builder,它是一个windows平台的工具。用来生成Quartus工程文件和分配DE10-Lite实验板的I/O引脚。
(1)
运行DE10_Lite_SystemBuilder.exe
(2)
输入工程名称和勾选在工程里用到I/O设备。
如图1所示,在这里我们设定工程名是majority,勾选了LED,按键,拨动开关,7段数码管这些I/O设备。然后单击Generate按钮,将生成的文件保存到工程目录。当成功生成工程文件后,退出SystemBuilder.

图 1 SystemBuilder界面
如图2所示,在工程目录中,Systembuilder生成了一系列工程文件。

图 2 SystemBuilder生成的工程文件
其中majority.v是顶层设计的Verilog文件模板(如图3所示)。SystemBilder已经在这个模板里把端口声明和引脚分配完成,带来很大的便利。可以更叫专注于功能描述。
//=======================================================
//
This code is generated by Terasic System Builder
//=======================================================
module majority(
////////////
SEG7 //////////
output
[7:0] HEX0,
output
[7:0] HEX1,
output
[7:0] HEX2,
output
[7:0] HEX3,
output
[7:0] HEX4,
output
[7:0] HEX5,
////////////
KEY //////////
input
[1:0] KEY,
////////////
LED //////////
output
[9:0] LEDR,
////////////
SW //////////
input
[9:0] SW
);
//=======================================================
//
REG/WIRE declarations
//=======================================================
//=======================================================
//
Structural coding
//=======================================================
endmodule
图3 Verilog模板文件
在这个案例里,我们描述基本的逻辑门组成的电路功能。如同书中3.6节描述的那样(Digital Design- A System Approach).我们使用拨动开关作为电路的输入,使用LED作为电路的输出。
B.
使用Quartus Prime编译和编程
l 运行Quartus Prime并打开之前用SystemBuilder创建的工程文件。
l 选择File> Open Project,在工程目录,选择majority.qpf.
l 在Project Navigator窗口双击majority实体名,打开其Verilog设计文件。
l 在majority.v的功能描述部分,添加下面一条语句。
assign LEDR[1] =
(SW[0]&SW[1])|(SW[0]&SW[2])|(SW[1]&SW[2]);
这里只有当3个拨动开关有至少2个都是1时,LED才被点亮。实验板上LED的电路如图4所示。

图 4
LED电路
l 当完成Verilog代码编辑后,选择Processing > Start
Compliation。此处应该0个错误。
l 选择Tools > Programmer。通过USB电缆连接DE10-Lite实验板和电脑。如图5所示,在Hardware Setup那里设置为USB-Blaster[USB-0],如果没有,可能是驱动没有安装。确定majority.sof文件显示在下方列表并且已勾选Programe/Configure.然后单击Start按钮。

图 5
编程窗口
现在,可以在实验板上验证这个逻辑门电路的设计。通过拨动SW[2]、SW[1]和SW[0],观察LEDR[1]的亮灭,其中只有在两个或两个以上开关推上去时,LEDR[1]亮,反之则灭。
C.
使用Testbench在ModelSim里仿真
使用功能仿真和时序仿真来仿真设计是一种功能强大的调试技术。它比把设计的电路下载到FPGA里来调试好太多了。因为:1)在功能仿真里,可以像观察I/O端口一样观察电路的内部信号;2)使用testbench节省了每次下载验证所需的下载时间。
我们将使用testbench来做电路的功能仿真。虽然可以手绘波形激励,但最好的方法是编写testbench产生电路的输入并监视输出。
图6列出了逻辑门电路的testbench内容。
module tb_majority;
reg [2:0] count;
wire [7:0] HEX5;
wire [7:0] HEX4;
wire [7:0] HEX3;
wire [7:0] HEX2;
wire [7:0] HEX1;
wire [7:0] HEX0;
wire [9:0] LEDR;
wire [9:0] SW;
assign SW[2:0] = count;
majority maj1(.HEX0(HEX0),
.HEX1(HEX1),
.HEX2(HEX2),
.HEX3(HEX3),
.HEX4(HEX4),
.HEX5(HEX5),
.KEY(KEY),
.LEDR(LEDR),
.SW(SW)
);
initial
begin
count
= 3'b0;
repeat(8)
begin
#100
$display("in
= %b, out = %b",count,LEDR[1]);
count
= count + 1'b1;
end
end
endmodule
图6 testbench
Testbench文件不能综合成实际的电路,只是用来做仿真。因此,它可以使用不可综合的Verilog语句,如延时#,display,initial等。testbench例化被测试的模块,产生输入激励并监视输出。在ModelSim里,波形查看器是一个很方便的检测电路响应的工具。
ModelSim里功能仿真步骤如下:
1) 在majority.v同目录下,新建tb_majority.v文件,并编辑。
2) 在Quartus工程目录,创建一个名为Simulation的子目录,用来存储仿真文件。
3) 运行ModelSime。
4) 选择File > New > Project打开新建工程对话框。设定路径(如前所述)和工程名。其它设置缺省不修改。单击OK。
5) 在Add Items to the Project窗口,添加majority.v和tb_majority.v文件,选择Reference from current
location.
6) 选择Compile > Compile All。此处应该0错误。
7) 单击Simulate > Start Simulation,选择Desing >
work > tb_majority。
8) 查看仿真波形。选择View > Wave。然后,在Objects窗口选择count,右击,选择Add Wave。这样就把count信号添加到波形窗口。再展开LEDR信号,把LEDR[1]添加到波形窗口。这样在波形窗口就可以看到逻辑门电路的输入/出信号。
9) 执行仿真可以通过菜单操作:Simulate > Run > Run 100或者在命令窗口输入run执行。这样将使仿真运行100个时间单位,缺省是100ps。如图7所示,是仿真运行800ps的波形。

图 7 仿真波形
在ModelSim的控制窗口,也可以看到testbench的输出信息,如图8所示,其输入/出信息通图7波形显示结果。

图 8
控制台窗口信息
Part 1. 在DE10-Lite实验板上实现基本的组合逻辑门电路
参照Part 0的设计,新建一个工程,实现逻辑门电路的可以,可以使用2-4输入的与门、与非门、或门和或非门。也可以用按键直接操控LED和7段数码管。这里需要注意,DE10-Lite上的7段数码管是共阳极的连接。下载验证。并编写testbench测试。

图 9 共阳7段数码管
这里决定用KEY[1]和KEY[0]相与后驱动LEDR1和HEX0,设计代码和testbench如下:
//=======================================================
//
This code is generated by Terasic System Builder
//=======================================================
module part2(
////////////
SEG7 //////////
output
[7:0] HEX0,
output
[7:0] HEX1,
output
[7:0] HEX2,
output
[7:0] HEX3,
output
[7:0] HEX4,
output
[7:0] HEX5,
////////////
KEY //////////
input
[1:0] KEY,
////////////
LED //////////
output
[9:0] LEDR,
////////////
SW //////////
input
[9:0] SW
);
//=======================================================
//
REG/WIRE declarations
//=======================================================
//=======================================================
//
Structural coding
//=======================================================
assign LEDR[1] = (KEY[0]&KEY[1]);
assign HEX0 =
~(KEY[1]&KEY[0])?8'b0100_0000:8'b1111_1111;
endmodule
测试代码:
module tb_part2;
reg [1:0] count;
wire [7:0] HEX0;
wire [7:0] HEX1;
wire [7:0] HEX2;
wire [7:0] HEX3;
wire [7:0] HEX4;
wire [7:0] HEX5;
wire [1:0] KEY;
wire [9:0] SW;
wire [9:0] LEDR;
assign KEY = count;
part2 p1(.HEX0(HEX0),
.HEX1(HEX1),
.HEX2(HEX2),
.HEX3(HEX3),
.HEX4(HEX4),
.HEX5(HEX5),
.KEY(KEY),
.LEDR(LEDR),
.SW(SW)
);
initial
begin
count = 2'b00;
repeat(4)
begin
#100
$display("in = %b, out = %b",count,LEDR[1]);
count = count +1'b1;
end
end
endmodule
仿真结果如图10所示:

图 10
part 2 仿真结果

图 11
监视输出
Part 2. 为 4 位开关输入实现组合逻辑十进制 7 段显示
设计一个组合逻辑电路,用SW[3]-SW[0]作输入,HEX1,HEX0作输出。使数码管根据输入显示00、01、02、。。。、13、14、15。另外4个数码管HEX5-HEX2关闭。
按以下步骤完成:
1) 写出真值表(输入是SW[4]-SW[0],输出是HEX1和HEX0的每段);
2) 卡诺图化简;
3) 使用assign语句描述7段数码管每一段的逻辑表达式;
4) 用testbench测试输入的16种情况;
5) 编译并下载验证。
后面会学习使用其它描述方式描述真值表,比如case语句,就不需要推导数码管每一段的逻辑表达式。
参考代码如下:
//=======================================================
// This code is generated by Terasic System
Builder
//=======================================================
module
lab1_part2(
//////////// SEG7 //////////
output [7:0] HEX0,
output [7:0] HEX1,
output [7:0] HEX2,
output [7:0] HEX3,
output [7:0] HEX4,
output [7:0] HEX5,
//////////// KEY //////////
input [1:0] KEY,
//////////// LED //////////
output [9:0] LEDR,
//////////// SW //////////
input [9:0] SW
);
//=======================================================
// REG/WIRE declarations
//=======================================================
//=======================================================
// Structural coding
//=======================================================
assign
HEX1[6] = 1'b1;
assign
HEX1[5] = SW[3]&SW[2] | SW[3]&SW[1];
assign
HEX1[4] = SW[3]&SW[2] | SW[3]&SW[1];
assign
HEX1[3] = SW[3]&SW[2] | SW[3]&SW[1];
assign
HEX1[2] = 1'b0;
assign
HEX1[1] = 1'b0;
assign
HEX1[0] = SW[3]&SW[2] | SW[3]&SW[1];
assign
HEX0[6] = ~SW[3]&~SW[2]&~SW[1] |
~SW[3]&SW[2]&SW[1]&SW[0]
|
SW[3]&~SW[2]&SW[1];
assign
HEX0[5] = SW[3]&SW[2]&~SW[1] |
~SW[3]&~SW[2]&SW[0] |
~SW[3]&~SW[2]&SW[1] |
~SW[3]&SW[1]&SW[0] |
~SW[2]&SW[1]&SW[0];
assign
HEX0[4] = SW[0] | ~SW[3]&SW[2]&~SW[1] |
SW[3]&SW[2]&SW[1];
assign
HEX0[3] = ~SW[3]&SW[2]&~SW[1]&~SW[0] |
~SW[3]&~SW[2]&~SW[1]&SW[0] |
~SW[3]&SW[2]&SW[1]&SW[0] |
SW[3]&SW[2]&SW[1]&~SW[0] |
SW[3]&~SW[2]&SW[1]&SW[0];
assign
HEX0[2] = SW[3]&SW[2]&~SW[1]&~SW[0] |
~SW[3]&~SW[2]&SW[1]&~SW[0];
assign
HEX0[1] = ~SW[3]&SW[2]&~SW[1]&SW[0] |
SW[3]&SW[2]&SW[1]&SW[0] |
~SW[3]&SW[2]&SW[1]&~SW[0];
assign
HEX0[0] = ~SW[3]&~SW[2]&~SW[1]&SW[0] |
~SW[3]&SW[2]&~SW[1]&~SW[0] |
SW[3]&SW[2]&SW[1]&~SW[0] |
SW[3]&~SW[2]&SW[1]&SW[0];
//turn
off HEX5-HEX2
assign
HEX5 = 8'b1111_1111;
assign
HEX4 = 8'b1111_1111;
assign
HEX3 = 8'b1111_1111;
assign HEX2
= 8'b1111_1111;
endmodule
测试代码如下:
module tb_p2;
reg [3:0]
count;
wire
[9:0] SW;
wire
[1:0] KEY;
wire
[9:0] LEDR;
wire
[6:0] HEX5,HEX4,HEX3,HEX2,HEX1,HEX0;
assign
SW[3:0] = count;
lab1_part2
p1(.KEY(KEY),
.SW(SW),
.LEDR(LEDR),
.HEX5(HEX5),
.HEX4(HEX4),
.HEX3(HEX3),
.HEX2(HEX2),
.HEX1(HEX1),
.HEX0(HEX0)
);
initial
begin
count = 4'd0;
repeat(16)
begin
#100
$display("in = %b, out =
%b",count,{HEX1,HEX0});
count = count + 1'b1;
end
end
endmodule
仿真结果如图12所示,类似之前列出的真值表,对应16种SW的组合,生成相应的HEX1和HEX0的状态.

图12
仿真结果
评分标准:
1) 共60分,其中,Part 1占25分,Part 2占35分;
2) 10分,设计Part 1和Part 2的Verilog代码;
3) 10分,Part 2的真值表,卡诺图,逻辑表达式;
4) 20分,Part 1和Part 2的testbench及仿真结果。
References:
1.University of California, Davis
Department
of Electrical and Computer Engineering
EEC180
DIGITAL SYSTEMS II Spring 2021
Lab 1:
Implementing Combinational Logic in the MAX10 FPGA
Written by YongfengXie
2022/06/17
实验1 在MAX10 FPGA上实现组合逻辑的更多相关文章
- 【小梅哥FPGA进阶教程】MC8051软核在FPGA上的使用
十.MC8051软核在FPGA上的使用 本教程内容力求以详细的步骤和讲解让读者以最快的方式学会 MC8051 IP core 的应用以及相关设计软件的使用,并激起读者对 SOPC 技术的兴趣.本实验重 ...
- 基于dsp_builder的算法在FPGA上的实现
基于dsp_builder的算法在FPGA上的实现 一.摘要 结合dsp_builder.matlab.modelsim和quartus ii等软件完成算法的FPGA实现. 二.实验平台 硬件平台 ...
- FPGA上如何求32个输入的最大值和次大值:分治
上午在论坛看到个热帖,里头的题目挺有意思的,简单的记录了一下. 0. 题目 在FPGA上实现一个模块,求32个输入中的最大值和次大值,32个输入由一个时钟周期给出.(题目来自论坛,面试题,如果觉得不合 ...
- PCIE_DMA实例四:xapp1052在Xilinx 7系列(KC705/VC709)FPGA上的移植
PCIE_DMA实例四:xapp1052在Xilinx 7系列(KC705/VC709)FPGA上的移植 一:前言 这段时间有个朋友加微信请求帮忙调试一块PCIe采集卡.该采集卡使用xilinx xc ...
- 云中的机器学习:FPGA 上的深度神经网络
人工智能正在经历一场变革,这要得益于机器学习的快速进步.在机器学习领域,人们正对一类名为“深度学习”算法产生浓厚的兴趣,因为这类算法具有出色的大数据集性能.在深度学习中,机器可以在监督或不受监督的方式 ...
- VLAN实验5(在ensp上利用三层交换机实现VLAN间路由)
原理概述: VLAN将一个物理的LAN在逻辑上划分成多个广播域.VLAN内的主机间可以直接通信,而VLAN间不能直接互通. 在现实网络中,经常会遇到需耍跨VLAN相互访问的情况,工程师通常会选择一些方 ...
- 09B-独立按键消抖实验02——小梅哥FPGA设计思想与验证方法视频教程配套文档
芯航线--普利斯队长精心奉献 实验目的: 1.复习按键的设计 2.用模块化设计的方式实现每次按下按键0,4个LED显示状态以二进制加法格式加1,每次按下按键1,4个LED显示状态以二进制加法格式减 ...
- 09A-独立按键消抖实验01——小梅哥FPGA设计思想与验证方法视频教程配套文档
芯航线--普利斯队长精心奉献 实验目的: 1.复习状态机的设计思想并以此为基础实现按键消抖 2.单bit异步信号同步化以及边沿检测 3.在激励文件中学会使用随机数发生函数$random 4.仿真模 ...
- verilog实验1:基于FPGA蜂鸣器演奏乐曲并数码管显示
一.实验任务 利用FPGA进行代码开发,使蜂鸣器演奏出乐曲<生日快乐>,将音调显示在数码管.原理为蜂鸣器为交流源蜂鸣器,在引脚上加一定频率的方波就可以发声,而且发声的频率由所加方波决定.这 ...
- 基于dsp_builder的算法在FPGA上的实现(转自https://www.cnblogs.com/sunev/archive/2012/11/17/2774836.html)
一.摘要 结合dsp_builder.matlab.modelsim和quartus ii等软件完成算法的FPGA实现. 二.实验平台 硬件平台:DIY_DE2 软件平台:quartus ii9.0 ...
随机推荐
- 面试官:小伙子知道synchronized的优化过程吗?我:嘚吧嘚吧嘚,面试官:出去!
写在开头 面试官:小伙子,多线程中锁用过吗? 我:那是自然! 面试官:那你知道synchronized的优化吗? 我:synchronized作为重锁,开销大,在早期不被推荐使用,后期进行了优化,至于 ...
- 误删除系统超级用户(superuser)权限的恢复方式
在使用KingbaseES数据库的时候,系统默认存在一个跟系统初始化用户同名的Superuser(默认是system用户,可更改). 这个Superuser的存在其实对于权限的管控是很有用的,但是如果 ...
- 简直了,被“Java并发锁”问题追问到自闭...
故事 地铁上,小帅双目空洞地望着窗外...绝望,发自内心地感到绝望... 距离失业已经过去两个月了,这是小帅接到的第四次面试邀请."回去等通知吧...",简简单单的六个字,把小帅的 ...
- #树上差分 or 01-Trie#洛谷 6623 [省选联考 2020 A 卷] 树
题目 分析(01trie) 考虑用trie做需要满足什么操作:加入某个数.01-Trie的合并.全局加一. 主要是全局加一比较难做,考虑改变的地方就是 \(X*2^T+2^T-1\). 把01-Tri ...
- 单元测试篇2-TDD三大法则解密
引言 在我们上一篇文章了解了单元测试的基本概念和用法之后,今天我们来聊一下 TDD(测试驱动开发) 测试驱动开发 (TDD) 测试驱动开发英文全称是Test Driven Development 简称 ...
- 学习如何使用 Python 连接 MongoDB: PyMongo 安装和基础操作教程
Python 可以用于数据库应用程序.最流行的 NoSQL 数据库之一是 MongoDB MongoDB MongoDB 将数据存储在类似 JSON 的文档中,使数据库非常灵活和可扩展. 您可以在 M ...
- Gitee码云:用git上传本地文件到码云gitee的方法
首先登录码云 https://gitee.com/,注册一个账号,并登录账号. 1. 在码云上创建项目 在码云首页顶部,下图所示,右上角头像旁边的加号,鼠标移上去会显示下拉的,点击"新建项目 ...
- 千字干货分享:一文教你ABI增强分析,BI的未来就在这里!
自2017年以来,智能概念开始出现,各类商业智能BI应用的使用门槛逐渐降低,商业智能BI制造商主要竞争增强分析的能力.<2020年Gartner分析与BI平台魔法象限报告>指出,2020年 ...
- 活动开启 | 以梦筑码 · 不负韶华 开发者故事征集令,讲出你的故事,有机会参加HDC.Together 2023
HarmonyOS面世以来,经历了3大版本迭代,系统能力逐步完善,生态加速繁荣.一路前行,是开发者们点亮漫天星光.点滴贡献,聚沙成塔,开发者们正用代码改变世界. 是梦想,激励我们一路前行.在黎明到 ...
- 链表LinkedList
#include <iostream> #include <vector> using namespace std; struct Node{ int val; Node *n ...