一、FPGA中的逻辑值
0: 低电平
1: 高电平
x: 未知电平
z: 高阻态(悬空状态)
二、进制数表示
位宽 ’ 进制符号 进制数
注意: 位宽是二进制位数,不写默认32位;进制符号不写默认十进制
如: 4‘b1010,
表示:4位带宽的二进制数:1010
二进制:b
八进制:o
十进制:d
十六进制:h
为了增加代码的可读性,可以将数据之间加下划线分组
如: 16b’1010_1100_1001_0011
三、标识符
- 区分大小写
- 字母、数字、下划线、$,必须以字母或下划线开头
- 不建议大小写混写
- 普通信号全部小写
四、数据类型
- 寄存器类型
- 线网类型
- 参数类型
五、运算符
运算符 | 优先级 |
---|---|
{} 、 {{}} | 高 |
! 、 ~ | |
** | |
*、 /、 % | I |
+ 、— | I |
>>、 << 、>>>、 <<< | I |
< 、<=、 >、 >= | I |
== 、 !=、 === 、 !== | I |
&、~& | I |
^、~^ | I |
I 、~I | V |
&& | |
II | |
?: | 低 |
**:乘幂运算 |
'>>>:算数右移
<<<:算数左移
!==:事件不相等
===:事件相等
?: :条件运算
六、Vivado实战
一个工程 包含必要的文件:
设计输入文件(.V) + 时序约束文件(.XDC)
下面是一个按键控制LED灯的代码:
设计输入文件:
`timescale 1ns / 1ps
module project_1_led(
input sys_clk,
input sys_rst_n,
input [4:0] key,
output reg [15:0] led
);
reg [25:0] cnt;//计数器寄存器
//assign led=(cnt<26'd50_000000)?16'b0000_0000_0000_0000:16'b1111_1111_1111_1111;
always@(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)//复位
cnt<=26'd0;
else if(cnt<20_000000)//总共计数0.2s
cnt<=cnt+1'b1;
else
cnt<=26'd0;
end
reg [3:0] led_control;
reg [1:0] led_model;
//0:控制led灯左移右移
//1:控制led灯的数量
//低位:
//用于保存LED灯移位的末位数值
always@(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
led=16'b0;
led_control<=4'd0;
end
else if(cnt==20_000000)begin
if(key[2])
led_model[1]=~led_model[1];
if(led_model[1]==1'b0)begin//移位
if(key[1])begin//左移
led_model[0]<=led[15];
led<=led<<1;
led[0]<=led_model[0];
end
if(key[3])begin//右移
led_model[0]<=led[0];
led<=led>>1;
led[15]<=led_model[0];
end
end
else begin//控制灯的数量
if(key[0])
led_control=led_control+1;
if(key[4])
led_control=led_control-1;
case(led_control)
4'd0 :led<=16'b0000_0000_0000_0001;
4'd1 :led<=16'b0000_0000_0000_0011;
4'd2 :led<=16'b0000_0000_0000_0111;
4'd3 :led<=16'b0000_0000_0000_1111;
4'd4 :led<=16'b0000_0000_0001_1111;
4'd5 :led<=16'b0000_0000_0011_1111;
4'd6 :led<=16'b0000_0000_0111_1111;
4'd7 :led<=16'b0000_0000_1111_1111;
4'd8 :led<=16'b0000_0001_1111_1111;
4'd9 :led<=16'b0000_0011_1111_1111;
4'd10:led<=16'b0000_0111_1111_1111;
4'd11:led<=16'b0000_1111_1111_1111;
4'd12:led<=16'b0001_1111_1111_1111;
4'd13:led<=16'b0011_1111_1111_1111;
4'd14:led<=16'b0111_1111_1111_1111;
4'd15:led<=16'b1111_1111_1111_1111;
endcase
end
end
else
led_control=led_control;
end
endmodule
时序约束文件:
//时钟、复位端口
create_clock - period 10.00 -name sys_clk [get_ports sys_clk]
set_property -dict {PACKAGE_PIN P17 IOSTANDARD LVCMOS33} [get_ports sys_clk]
set_property -dict {PACKAGE_PIN P15 IOSTANDARD LVCMOS33} [get_ports sys_rst_n]
//LED端口
set_property -dict {PACKAGE_PIN F6 IOSTANDARD LVCMOS33} [get_ports {led[15]}]
set_property -dict {PACKAGE_PIN G4 IOSTANDARD LVCMOS33} [get_ports {led[14]}]
set_property -dict {PACKAGE_PIN G3 IOSTANDARD LVCMOS33} [get_ports {led[13]}]
set_property -dict {PACKAGE_PIN J4 IOSTANDARD LVCMOS33} [get_ports {led[12]}]
set_property -dict {PACKAGE_PIN H4 IOSTANDARD LVCMOS33} [get_ports {led[11]}]
set_property -dict {PACKAGE_PIN J3 IOSTANDARD LVCMOS33} [get_ports {led[10]}]
set_property -dict {PACKAGE_PIN J2 IOSTANDARD LVCMOS33} [get_ports {led[9]}]
set_property -dict {PACKAGE_PIN K2 IOSTANDARD LVCMOS33} [get_ports {led[8]}]
set_property -dict {PACKAGE_PIN K1 IOSTANDARD LVCMOS33} [get_ports {led[7]}]
set_property -dict {PACKAGE_PIN H6 IOSTANDARD LVCMOS33} [get_ports {led[6]}]
set_property -dict {PACKAGE_PIN H5 IOSTANDARD LVCMOS33} [get_ports {led[5]}]
set_property -dict {PACKAGE_PIN J5 IOSTANDARD LVCMOS33} [get_ports {led[4]}]
set_property -dict {PACKAGE_PIN K6 IOSTANDARD LVCMOS33} [get_ports {led[3]}]
set_property -dict {PACKAGE_PIN L1 IOSTANDARD LVCMOS33} [get_ports {led[2]}]
set_property -dict {PACKAGE_PIN M1 IOSTANDARD LVCMOS33} [get_ports {led[1]}]
set_property -dict {PACKAGE_PIN K3 IOSTANDARD LVCMOS33} [get_ports {led[0]}]
//key端口
set_property -dict {PACKAGE_PIN R17 IOSTANDARD LVCMOS33} [get_ports {key[4]}]
set_property -dict {PACKAGE_PIN R11 IOSTANDARD LVCMOS33} [get_ports {key[3]}]
set_property -dict {PACKAGE_PIN R15 IOSTANDARD LVCMOS33} [get_ports {key[2]}]
set_property -dict {PACKAGE_PIN V1 IOSTANDARD LVCMOS33} [get_ports {key[1]}]
set_property -dict {PACKAGE_PIN U4 IOSTANDARD LVCMOS33} [get_ports {key[0]}]
视频展示:
七、总结
FPGA更多的是考虑硬件电路,考虑到程序的运行是并行的,注意程序之间的逻辑关系,编程结束之后进行综合生成*Bitstream。
对于几点还不熟悉,需要接下来去学习:
1、<=与=之间的关系,到底怎么用,都可以用于赋值
<=:非阻塞赋值,用于时序逻辑电路
=:阻塞赋值,用于组合逻辑电路
2、always的意思,其中的赋值变量是寄存器类型的
重点掌握:
1.设计源文件的创建
2.时序约束文件的创建