1.注释
2.关键字
3.程序框架
1.注释:/**/ ;//,建议使用//
2.关键字
Verilog常用的关键字
注意只有小写的关键字才是保留字。例如,标识符
always(
这是个关键词
)
与标识符
ALWAYS(
非关键词
)是不同的。
3.程序框架
我们以
LED
流水灯程序为例来给大家展示
Verilog
的程序框架,代码如下所示、
1 module led(
2 input sys_clk , //系统时钟
3 input sys_rst_n, //系统复位,低电平有效
4 output reg [3:0] led //4 位 LED 灯
5 );
6
7 //parameter define
8 parameter WIDTH = 25 ;
9 parameter COUNT_MAX = 25_000_000; //板载 50M 时钟=20ns,0.5s/20ns=25000000,需要 25bit
10 //位宽
11
12 //reg define
13 reg [WIDTH-1:0] counter ;
14 reg [1:0] led_ctrl_cnt;
15
16 //wire define
17 wire counter_en ;
18
19 //***********************************************************************************
20 //** main code
21 //***********************************************************************************
22
23 //计数到最大值时产生高电平使能信号
24 assign counter_en = (counter == (COUNT_MAX - 1'b1)) ? 1'b1 : 1'b0;
25
26 //用于产生 0.5 秒使能信号的计数器
27 always @(posedge sys_clk or negedge sys_rst_n) begin
28 if (sys_rst_n == 1'b0)
29 counter <= 1'b0;
30 else if (counter_en)
31 counter <= 1'b0;
32 else
33 counter <= counter + 1'b1;
34 end
36 //led 流水控制计数器
37 always @(posedge sys_clk or negedge sys_rst_n) begin
38 if (sys_rst_n == 1'b0)
39 led_ctrl_cnt <= 2'b0;
40 else if (counter_en)
41 led_ctrl_cnt <= led_ctrl_cnt + 2'b1;
42 end
44 //通过控制 IO 口的高低电平实现发光二极管的亮灭
45 always @(posedge sys_clk or negedge sys_rst_n) begin
46 if (sys_rst_n == 1'b0)
47 led <= 4'b0;
48 else begin
49 case (led_ctrl_cnt)
50 2'd0 : led <= 4'b0001;
51 2'd1 : led <= 4'b0010;
52 2'd2 : led <= 4'b0100;
53 2'd3 : led <= 4'b1000;
54 default : ;
55 endcase
56 end
57 end
58
59 endmodule
首先
//
开头的都是注释,这个之前我们讲解过了。下面我们来看下具体的解释。
第
1
行为模块定义,模块定义以
module
开始,
endmodule
结束,如
59
行所示。
其次
2
到
5 行为端口定义,需要定义 led 模块的输入信号和输出信号,此处输入信号为系统时钟和复位信号,输出为
led
控制信号。
7
到
9
行为参数
parameter
定义,语法如
7
到
9 行所示,定义 parameter 的好处是可以灵活改变参数数字就能控制一些计数器最大计数值或者信号位宽的最大位宽。
12
到
14
行为
reg
信号定义,
reg
信号一般情况下代表寄存器,比如此处控制 0.5 秒使能信号的计数器
counter
。
16
到
17
行为
wire
信号定义,
wire 信号就是硬件连线,比如此处的 counter_en,代表计数到最大值时产生高电平使能,本质上是一个硬件连线,其实代表的是一些计数器
/
寄存器做逻辑判断的结果。
19
到
21 行为 moudle 开始的注释,不添加工具综合也不会报错,但是我们推荐添加,作为一个良好的编程规范。
23
到
24
行为
assign
语句的样式,条件成立选择
1
,否则选择
0
。
26
到
34
行是
always
语句的样式,
27
行代表在时钟上升沿或者复位的下降沿进行信号触发。begin/end
代表语句的开始和结束。
28
到
33
行为
if/else
语句,和
C
语言是比较类似的。
29
行的“
<=”标记代表信号是
非阻塞赋值,信号赋值有非阻塞赋值和阻塞赋值两个方式,这个我们后面会详细解释。
36
和
42
行也是一个
always
语句,和
26
到
34
行类似。
44
和
57
行也是一个
always
语句,不过这个
always
语句中嵌入了一个
case
语句,
case
语句的语法如
49
到
55
行所示,需要一个
case
关键字开始,
endcase
关键字结束,
default
作为默认分支,和
C 语言也是类似的。当然
case
语句也可以用在不带时钟的
always
语句中,不过本例子的 always 都是带有时钟的。不带时钟的
always
和带时钟的
always
语句的差异这个我们后面也会详细解释。
59
行是
endmodule 标记,代表模块的结束。