Quartus13.0使用
编译下载:
添加引脚:
# ---------------- LED ---------------- #
set_location_assignment PIN_K2 -to led_out[11]
set_location_assignment PIN_J1 -to led_out[10]
set_location_assignment PIN_J2 -to led_out[9]
set_location_assignment PIN_L1 -to led_out[8]
set_location_assignment PIN_L2 -to led_out[7]
set_location_assignment PIN_K1 -to led_out[6]
set_location_assignment PIN_N1 -to led_out[5]
set_location_assignment PIN_N2 -to led_out[4]
set_location_assignment PIN_L3 -to led_out[3]
set_location_assignment PIN_P2 -to led_out[2]
set_location_assignment PIN_P1 -to led_out[1]
set_location_assignment PIN_N3 -to led_out[0]
# ---------------- clk and rst ---------------- #
set_location_assignment PIN_E1 -to sys_clk
set_location_assignment PIN_D1 -to sys_rst_n
# ---------------- clk and rst ---------------- #
set_location_assignment PIN_E1 -to sys_clk
set_location_assignment PIN_D1 -to sys_rst_n
# -------------------- KRY ------------------- #
set_location_assignment PIN_R3 -to key1
set_location_assignment PIN_P3 -to key2
set_location_assignment PIN_D1 -to key3
set_location_assignment PIN_K1 -to led3
# -------------------- KRY ------------------- #
set_location_assignment PIN_K16 -to rx
set_location_assignment PIN_L16 -to tx
字体调整:
文件转换:
引脚分配:
配置引脚
打开qsf文件
程序固化:
选择设备型号
选择 .sof文件 一般再output文件夹
看见型号后,再点击生成。
烧录:
先删除之前的文件,添加新生成的 .jic文件 文件
SingnalTap II的使用
占用一部分FPGA的资源。
选择采样时钟:
通过 <删除信号 > 添加信号(双击也可以)
看见上面的红色,说明要编译下载到板子里面
看见由 .stp 文件,说明添加成功,点击文件也可以进去。
调试界面:
关闭此功能
Modelsim使用
创建模板:
打开该文件:
`timescale 1 ns/ 1 ns
module flow_led_vlg_tst(); //定义模块名
reg sys_clk;
reg sys_rst_n;
wire [3:0] led;
// 例化端口
flow_led i1 (
.led(led),
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n)
);
initial
begin
sys_clk=1'b0;
sys_rst_n=1'b0;
#100 sys_rst_n=1'b1;
#1000 $stop;
end
always #10 sys_clk=~sys_clk;
endmodule
添加仿真文件
选择功能仿真或者时序仿真
设置:
添加其它信号
一.Verilog 代码
数值种类
标识符:
数据类型:
寄存器变量
reg [ 31 :0] cnt;
reg: 类型
[ 31 :0] 高位和低位,代表32位宽,没有时表示位宽为1
变量名: 后面要加分号
线网数据类型:
wire
参数类型:
类似C语言里面的 #define PI 3.14
用于定义状态 运行参数
parameter size=8;
parameter a=4,b=6;
parameter clock=a+b;
运算符:
程序框架:
注释:
关键字:
程序框架:
module 模块开始 模块名字 (a,b) ; 模块参数 ,结束加分号
intput a,b; //输入信号
output c,d; //输出信号
assign c = a|b; //assign复制语句
assign d = a&b; //会生成实际电路(可综合模块(不可综合模块不能生成电路)
endmodule 模块结束
模块调用:
结构语句:
inital 初始化语句
always 循环执行
触发方式:
沿触发: 通常用来表示时序逻辑
posedge 上升沿触发
negedge 下降沿触发
or 链接多个事件,只要有一个条件就执行一次
电平触发: 通常用来表示组合逻辑
等号右边的数字要全部添加到列表里面,可以用 * 来替代,只要有一个电平发生,就会执行
组合逻辑:输出只取决与改时刻的输入。
时序逻辑:输出不仅取决与当前状态还与上一个状态有关。记忆功能
赋值语句:
阻塞赋值 = : 赋值从上到下一条条赋值语句执行。顺序执行,和C语言一样。
非阻塞赋值 <= : 每条赋值语句同时执行,所有赋值语句同时执行。它会将所有右边全部计算完后再同时赋值给左边。只能给寄存器类型赋值。
组合逻辑和时序逻辑判断:
时序逻辑:就是有一个D触发器,要随着时钟周期触发: always@(posedge clk or negedge res_n) ,但是组合逻辑是通过电平状态来判断的:always@( * )或always@(a or b or ...)
所以再时序逻辑里面,一个时钟到来,要执行所有的事情,赋值是要用 <= 赋值,一次将全部的值赋过去。
而组合逻辑,当触发后依次执行一次,所以用 = 赋值 ,执行一次。
组合逻辑和时序逻辑:
reg scl
input wire next_state ,
时序逻辑:运行与系统时钟有关
always @(posedge dri_clk or negedge rst_n) begin
scl <= 1'b1;
end
组合逻辑:因为某个电平的跳变而运行
always @( * ) begin
next_state = st_idle;
end
assign cam_rst_n = 1'b1;
条件语句:
if
case
状态机:
概述:
实现顺序逻辑,实现不同状态进行切换。
状态机设计:
例子:
尽量使用时序逻辑:
语法注意:
1. 端口加 wire 还是reg?
1. 三种类型 wire reg parameter 。 ( wire assign ; assign led_out =) 表示连线,输入输出的端口,或者和其它模块之间的连线; (reg led_out ; led_out <=) 寄存器类型,用于存储数据。 parameter 类似宏定义的值。
2.模块的输入输出端口类型都默认为wire型
3.变量放在begin……end之内必须使用reg变量
4.在initial语句中使用必须使 用reg变量
6.如果output作为过程赋值语句的左值,则应该用reg类型;如果output作为连续赋值语句的左值,则应该用wire类型
7. 输入的端口都不用写reg,因为值是外面给的,只有输出要区分是否写reg
8.reg信号一般情况下代表寄存器,wire信号定义, wire信号就是硬件连线
3. 函数和函数调用:
1.在Verilog中,输入值和输出值全部在模块端口进行定义
二.代码实践:
计数器:
实例化:
// 左侧为源模块名 右侧为新模块名
// 源端口前加上 . 新端口前加上括号 ()
// 名称可有新名称,也可以用旧的名称
实例化 示例1:
// 源模块端口
module key_debounce(
input sys_clk, //外部50M时钟
input sys_rst_n, //外部复位信号,低有效
input key, //外部按键输入
output reg key_flag, //按键数据有效信号 低电平有效
output reg key_value //按键消抖后的数据
);
key_debounce key1_debounce(
.sys_clk (sys_clk ), //外部50M时钟
.sys_rst_n (sys_rst_n ), //外部复位信号,低有效
.key (key1 ), //外部按键输入
.key_flag (key1_flag ), //按键数据有效信号 低电平有效
.key_value (key1_value ) //按键消抖后的数据
);
key_debounce key2_debounce(
.sys_clk (sys_clk ), //外部50M时钟
.sys_rst_n (sys_rst_n ), //外部复位信号,低有效
.key (key2 ), //外部按键输入
.key_flag (key2_flag ), //按键数据有效信号 低电平有效
.key_value (key2_value ) The port of the source module
module key_debounce(
input sys_clk, //External 50M clock
input sys_rst_n, //External reset signal, low valid
input key, //external key input
output reg key_flag, //Valid signal for key data Valid low
output reg key_value //The data after the key is debited
);
实例化 示例2:
module uart_tx
#(
parameter UART_BPS = 'd9600, //串口波特率
parameter CLK_FREQ = 'd50_000_000 //时钟频率
)
(
input wire sys_clk , //系统时钟50MHz
input wire sys_rst_n , //全局复位
input wire [7:0] pi_data , //模块输入的8bit数据
input wire pi_flag , //并行数据有效标志信号
output reg tx //串转并后的1bit数据
);
uart_rx
#(
.UART_BPS (UART_BPS ), //串口波特率
.CLK_FREQ (CLK_FREQ ) //时钟频率
)
(
.sys_clk (sys_clk ), //系统时钟50MHz
.sys_rst_n (sys_rst_n ), //全局复位
.po_data (po_data ), //串转并后的8bit数据
.po_flag (po_flag ), //串转并后的数据有效标志信号
.rx (rx ) //串口接收数据
);
parameter 与localparam 区分
module uart_rx
#(
parameter UART_BPS = 'd9600, //parameter 可在上层模块实例化时修改
parameter CLK_FREQ = 'd50_000_000 //时钟频率
)
(
input wire sys_clk , //系统时钟50MHz
);
//localparam define
localparam BAUD_CNT_MAX =CLK_FREQ/UART_BPS ; //localparam 本地,仅在本模块内可修改
状态机:
reg [ 7:0] cur_state ; // 状态机当前状态
reg [ 7:0] next_state ; // 状态机下一状态
//(三段式状态机)同步时序描述状态转移
always @(posedge dri_clk or negedge rst_n) begin
if(!rst_n)
cur_state <= st_idle;
else
cur_state <= next_state;
end