github传送门(练习写的代码,约束文件,仿真文件)html
千万千万千万不要把IP核导入到源代码所在的工程文件里,测试的时候debug有你哭的。git
多个always块并发执行,也就是说不一样的主循环函数并发执行。github
always里不能实例化模块web
通常组合逻辑电路用阻塞赋值(=
),时序逻辑电路用非阻塞赋值(<=
)。数组
always @(触发器变量)
是组合逻辑电路,always @(posedge clk)
是时序逻辑电路。posedge(positive edge) 是上升沿关键字,上升沿指的是变量从0变成1的那个瞬间。对应降低沿(negedge - negative edge)就是变量从1变成0的那一瞬间。所以@(posedge var)
指的是对var的上升沿敏感,意思就是var达到上升沿的时候就会触发。并发
always @(<敏感信号表达式>)
能够理解成onValueChangeListener,当敏感信号表达式的值发生变化时,就会执行always块。dom
所以always @(posedge clk)
表明在每次时钟clk到达上升沿的时候会执行一次(由于并发执行,因此时序逻辑电路用非阻塞赋值就能够实现与时钟上升沿同步修改变量),所以这个always块里的代码能够理解成主循环。tcp
不论上升沿clk仍是降低沿rst,在触发时读取到clk和rst的值都是这两个信号接下来要变成的值。(即clk读取到的值为1,rst读取到的值为0)svg
generate
,对应声明循环控制变量的关键字为genvar
genvar i; generate for(i=0; i<n; i=i+1) begin: tag_name module_name_1 instance_name_1 (input_1,output_1); //能够继续实例化别的模块,如: //module_name_2 instance_name_2 (input_2,output_2); end endgenerate //执行完generate块后的实例名字分别为:tag_name[0].module_name_1, tag_name[1].module_name_1 ...
module_name #(param1[, param2...]) instance_name (inputs,outputs);或
module_name instance_name(inputs, outputs); defparam instance_name.param_1 = param1[, instance_name.param_2 = param2...];
if-else
和for
等语句不能直接写在模块里,须要写在always中。assign
中,能够assign res = (op == 2'b00) ? res1 : (op == 2'b01) ? res2 : defaultres;
input
和output
等信号默认都是wire
类型。通常只有在模块中有赋值语句时才须要将output
信号定义为reg
型。经常使用的函数:函数
函数名 | 描述 |
---|---|
$readmemb(filename, mem) | 从文件读取二进制数据到 mem 数组 |
$readmemh(filename, mem) | 从文件读取十六进制数据到 mem 数组 |
$display(“output” [, var] ); | 在console中输出,语法相似c的printf,%b 二进制, %d, %h, %t表示时间,对应var = $time |
$write(“output”[, var] ); | 同display,但display自带换行,write不带 |
http://www.digilent.com.cn/community/332.html%EF%BC%89
1.基本知识:
2.烧录含义:
3.实现:
新建工程时选择板子型号:xc7a35tcpg236-1
BASYS3板子自带的时钟CLK频率是100MHz,对应引脚名为W5,固定常数:
parameter T1S = 100000000 // 即100M parameter T1MS = 100000; //或 parameter T1S = 10**8; parameter T1MS = 10**5;
按键按下为1,弹起为0
间隔必定时间读取两次按键值,若是两次读取结果同样则认为不抖了。
数码管是一个四位带小数点的七段共阳极数码管(低电平有效,即0是点亮,1是熄灭),共12位。
从高位(第11位)到低位(第0位)分别为:
11 ~ 8位: 控制第几个数码管的显示状况。好比若第10位是0,后面7~0位的值就做用于第二个数码管的显示状况
7 ~ 1位: 从最上面一横开始,顺时针一位对应一个数码管的一小段(一个小直线),中间横线为第1位
0位: 小数点是否显示
e.g.1011_00000000_1表示第二个数码管显示"8",小数点不亮,其余三个数码管均熄灭
要想四个数码管显示不一样的数字,控制数码管以很快的频率一次显示一位便可。
(示例代码)
针脚名 | 位数 | 含义 |
---|---|---|
W4 | 11 | 控制第1个数码管的显示状况 |
V4 | 10 | 控制第2个数码管的显示状况 |
U4 | 9 | 控制第3个数码管的显示状况 |
U2 | 8 | 控制第4个数码管的显示状况 |
W7 | 7 | a |
W6 | 6 | b |
U8 | 5 | c |
V8 | 4 | d |
U5 | 3 | e |
V5 | 2 | f |
U7 | 1 | g |
V7 | 0 | dp(小数点) |
?这种方法不能在硬件上实现,会报错,只能在仿真的时候实现。
input CLK; parameter T1MS = 10**5; always @(posedge CLK) begin repeat(T1MS*200) @(posedge CLK) // wait 200ms //do something like changing input values here... end
或
input CLK; parameter T1MS = 10**5; integer count = 0; always @(posedge CLK) begin count <= count + 1; if (count == T1MS*200) begin count <= 0; //do every 200ms //do something like changing input values here... end end
或
input CLK; parameter T1MS = 10**5; integer count = 0; reg CLK_10HZ = 0; always @(posedge CLK) begin count <= count + 1; if (count == T1MS*100) begin count <= 0; CLK_10HZ = ~CLK_10HZ; end end always @(posedge CLK_10HZ) begin //do every 100ms / 10HZ //do something like changing input values here... end
约束文件是用来把代码里的input、output的变量名和板子上的管脚一一对应起来用的,格式:
配置引脚:
set_property PACKAGE_PIN 引脚名 [get_ports 对应代码里的端口变量名]
配置标准电压:
set_property IOSTANDARD LVCMOS33 [get_ports 对应代码里的端口变量名]
BASYS3板子上全部引脚对应的约束文件(记得端口名改为本身的):
–
overflow = x*y*~s + ~x*~y*s