Quartus II详细使用教程(以定时器设计为例)
设计一个定时器,能够支持以下功能:
1、该定时器的定时时间参数可以通过该模块的一个端口输入,通过调节端口上输入数据的值,就能修改其定时时间。
2、设置一个计数模式控制信号,当该信号为1时,设置为循环定时模式,当该信号为0时,设置为单次定时模式。
3、设置一个计数启动信号,在循环定时模式下,该信号为高电平使能计时,为低电平则停止计时。在单次计数模式下,该信号的一个单基准时钟周期的脉冲使能一次定时。
4、输出计数器实时计数值,该值将用于产生特定占空比的方波。
1、创建Quartus II工程
1.1、创建工程文件夹目录
prj为工程文件存放目录
rtl为verilog可综合代码
img为设计相关图片存放目录(主要为了方便后期写文档)
doc为设计相关文档存放目录
testbench为对应的testbench存放目录
prj文件夹下的ip文件夹存放quartus ii中生成的ip核文件
1.2、创建项目
打开Quartus II,点击File,选择New Project Wizard
选择之前创建好的prj文件夹,并输入项目名称
在Device family选项中选择Cyclone IV E
在Pin count选项中选择256
在Speed grade选项中选择8
最后在Available devices选项中选择EP4CE10F17C8,并点击Next
在Simulation仿真工具中,Tool Name选择:ModelSim-Altera,Format(s)选择:Verilog HDL,并点击Next完成项目创建
2、编写计数器HDL描述文件
2.1、新建Verilog HDL文件
点击新建文件按钮,选择Verilog HDL File
2.2、编写verilog代码,并进行分析与综合
2.2.1、设置输入端口,并给端口定义输入输出类型
module beep_test( Clk, Rst_n, CNT_ACC, //定时预设值 MODE, //模式控制信号 Cnt_go, //计数启动信号 CNT_NOW, //输出计数器实时计数值 Full_Flag //定时完成标志信号 ); //端口类型定义 input Clk; input Rst_n; input [31:0]CNT_ACC; //通用定时器,故设置为32位 input MODE; input Cnt_Go; output [31:0]CNT_NOW; output Full_Flag; endmodule
Clk:时钟信号
Rst_n:复位信号
CNT_ACC:设置定时预设时间(32位)
MODE:模式控制信号。当该信号为1时,设置为循环定时模式,当该信号为0时,设置为单次定时模式
Cnt_go:计数启动信号。在循环定时模式下,该信号为高电平使能计时,为低电平则停止计时。在单次计数模式下,该信号的一个单基准时钟周期的脉冲使能一次定时。
CNT_NOW:输出计数器实时计数值。该值将用于产生特定占空比的方波(32位)
Full_Flag:定时完成标志信号
2.2.2、设置计时器功能
reg [31:0]cnt; //定义一个32位的寄存器用作计数器 reg oneshot; //单次定时的内部使能信号 wire Full_Flag_r; assign CNT_NOW = cnt; assign Full_Flag_r = (cnt == CNT_ACC - 1)?1'b1:1'b0; always@(posedge Clk) Full_Flag <= Full_Flag_r; //时序逻辑的标准结构:always块 always@(posedge Clk or negedge Rst_n) //当Clk上升沿或者Rst_n下降沿时,做以下操作 if(!Rst_n) //当Rst_n低电平时,计数器清零 cnt <= 0; else if(MODE == 1'b1) begin if(Cnt_Go == 1'b1 && (cnt < CNT_ACC)) cnt <= cnt + 1'b1; else cnt <= 0; end else if(!MODE) begin if(oneshot) cnt <= cnt + 1'b1; else cnt <= 0; end always@(posedge Clk or negedge Rst_n) if(!Rst_n) oneshot <= 1'b0; else if(!MODE)begin if(Cnt_Go == 1'b1) oneshot <= 1'b1; else if(Full_Flag) oneshot <= 1'b0; else oneshot <= oneshot; end else oneshot <= 1'b0;
2.2.3、将代码保存至rtl文件夹中,并分析与综合
保存完成后,Ctrl+K进行分析与综合,以确保代码正确性
2.2.4、查看RTL视图
3、编写计数器测试脚本(testbench)
新建一个Verilog文件,并将该文件保存在testbench目录下,注意将文件名改为beep_test_tb
3.1、编写计数器测试脚本:
`timescale 1ns/1ns //时间精度 `define clk_period 20 //定义系统的时钟周期:20ns(如果未定义,则系统用默认的时钟周期,不便于后期移植) module beep_test_tb; //测试模块名称 //产生激励信号 //input型全部定义为reg型 reg Clk; reg Rst_n; reg [31:0]CNT_ACC; reg MODE; reg Cnt_Go; //output型全部定义为wire型 wire [31:0]CNT_NOW; wire Full_Flag; //将激励信号与待测试模块的端口连接起来 beep_test beep_test0( //设置待测试端口名称为beep_test0 //在前面加上'.'显示例化格式 .Clk(Clk), .Rst_n(Rst_n), .CNT_ACC(CNT_ACC), .MODE(MODE), .Cnt_Go(Cnt_Go), .CNT_NOW(CNT_NOW), .Full_Flag(Full_Flag) ); //产生时钟激励信号 initial Clk = 1; always #(`clk_period/2) Clk = ~Clk; //每10ns翻转一次,一个时钟周期为20ns //控制端口 initial begin //凡是语句块后面超过一个语句的都要加begin end //复位 Rst_n = 0; CNT_ACC = 0; MODE = 0; Cnt_Go = 0; //延时20个系统时钟周期 #(`clk_period*20 + 1); //'+1'操作是为了保证复位信号不与Clk信号边沿直接对其,方便观察异步复位功效 Rst_n = 1; #(`clk_period*20); //让信号产生激励以观测定时器工作状态 //设置预设值为1000,模式为循环定时模式 CNT_ACC = 1000; MODE = 1; #(`clk_period*20); Cnt_Go = 1; #(`clk_period*12000); Cnt_Go = 0; #(`clk_period*20); //设置预设值为600,模式为循环定时模式 CNT_ACC = 600; MODE = 1; #(`clk_period*20); Cnt_Go = 1; #(`clk_period*8000); Cnt_Go = 0; #(`clk_period*20); //设置预设值为1000,模式为单次定时模式 CNT_ACC = 1000; MODE = 0; #(`clk_period*20); Cnt_Go = 1; #(`clk_period); Cnt_Go = 0; #(`clk_period*1200); //设置预设值为600,模式为单次定时模式 CNT_ACC = 1000; MODE = 0; #(`clk_period*20); Cnt_Go = 1; #(`clk_period); Cnt_Go = 0; #(`clk_period*1200); // 让仿真停止下来 $stop; end endmodule
(补充:可以按Ctrl+H进行查找和替换操作)
3.2、按Ctrl+K进行分析与综合
3.3、设置native link关联脚本:
选择Assignments,点击Settings
选中Compile test bench,点击Test Benches
选择testbench文件夹中beep_test_tb.v文件,并在Test bench name中输入beep_test_tb
最后点击Apply完成脚本关联
(补充:ModelSim中,信号的定义必须在使用之前,不然会报错)
4、对计数器进行功能仿真
选中Tools->Run Simulation Tool->RTL Simulation
出现波形图:
(补充1:如果想更改HDL文件中代码后再进行仿真,步骤如下:)
(补充2:如果想加入beef_test.v文件中的信号,步骤如下:)
(补充3:如果想对波形进行自动分组,则先Ctrl+A选中所有信号,再Ctrl+G)
5、在Quartus II中执行布局布线
新建一个beef_top文件,并保存在rtl文件夹下
代码如下:
module beep_top( Clk, Rst_n, Cnt_Go, //计数启动信号 在循环定时模式下,该信号为高电平使能计时,为低电平则停止计时。在单次计数模式下,该信号的一个单基准时钟周期的脉冲使能一次定时 beep ); input Clk; input Rst_n; input Cnt_Go; output beep; wire [31:0]CNT_NOW; beep_test beep_test0( .Clk(Clk), .Rst_n(Rst_n), .CNT_ACC(32'd49999), .MODE(1), .Cnt_Go(Cnt_Go), //该信号连接按钮 .CNT_NOW(CNT_NOW), .Full_Flag() ); assign beep = (CNT_NOW >= 24999)?1'b1:1'b0; endmodule
将该文件置于顶层,再进行分析与综合,步骤如下图:
6、对计数器进行时序仿真
选择Tools->Run Simulation Tool->Gate Level Simulation...进行时序仿真
7、分配引脚并编译得到FPGA配置文件.sof
点击Pin Planner图标进行引脚分配
分配表如图所示:
点击全编译按钮
全编译完成后,连接开发板,点击Programmer按钮
点击Add File...,选择prj\output_files文件夹中的beep_test.sof文件,点击Open,最后点击Start烧录程序
8、配置FPGA并运行
本文作者:Yamada_Ryo
本文链接:https://www.cnblogs.com/little55/p/17832731.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步