Verilog注释
Verilog中有两个注释方式
一种是以**//**开头的语句,它表示以//开始到本行结束都属于注释语句。
//wire define
wire locked; //PLL输出有效标志
wire sys_rst_n; //系统复位信息号
另一种是以"/“符号开始,”/"结束,在两个符号之间的语句都是注释语句,因此可扩展到多行。
//例化PLL,产生各模块所需要的的时钟
/*
pll_clk u_pll_clk(
.inclk0 (clk),
.areset (~rst_n),
.c0 (clk_50m)
)
*/
Verilog关键字
常用的关键字
module:模块开始定义
input:输入端口定义
output:输出端口定义
inout:双向端口定义
parameter:信号的参数定义
wire:wire信号定义
reg:reg信号定义
always:产生Reg信号语句的关键字
assign:产生wire信号语句的关键字
begin:语句的起始标志
end:语句的结束标志
edge/posedge/negedge:时序电路的标志
case:Case语句起始标志
default:Case语句的默认分支标志
endcase:Case语句结束标志
if:if/else语句标记
else:if/else语句标记
for:for语句标记
endmodule:模块结束定义
Verilog模块调用
Verilog的基本设计单元是"模块"(block)。
一个模块由两个部分组成,一部分描述接口,另一部分描述逻辑功能。
module block(a,b,c,d);
input a,b;
output c,d;
assign c = a | b;
assign d = a & b;
endmodule
每个Verilog程序包括4个主要的部分:端口定义、IO说明、内部信号声明、功能定义。
示例:
module flow_led(
input sys_clk, //系统时钟
input sys_rst_n, //系统复位,低电平有效
output reg [3:0] led //4个LED灯
);
//reg define
reg [23:0] counter;
//计数器对系统时钟计数,计时0.2秒
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n)
counter <= 24'd0;
else if (counter < 24'd1000_0000)
counter <= counter + 1'b1;
else
counter <= 24'd0;
end
//通过移位寄存器控制IO口的高低电平,从而改变LED的显示状态
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n)
led <= 4'b0001;
else if (counter == 24'd1000_0000)
led[3:0] <= {led[2:0],led[3]};
else
led <= led;
end
endmodule
功能定义部分有三种方法:
1、assign语句:描述组合逻辑
2、always语句:描述组合/时序逻辑
3、例化实例元件:如 and # 2 u1(q,a,b);
上述三种逻辑功能是并行的
注意:在always块中,逻辑是顺序执行的;而多个always块之间是并行的。
模块的调用
在模块调用时,信号通过模块端口在模块之间传递。
例如已有time_count模块的定义
module time_count(
input clk ,
input rst_n,
output reg flag
);
//parameter define
parameter MAX_NUM = 50000_000;
//reg define
reg [24:0] cnt;
下面的模块将与上面的模块的连接
//上层模块
module seg_led_static_top(
input sys_clk , //系统时钟
input sys_rst_n, //系统复位信号(低有效)
output [5:0] sel , //数码管位选
output [7:0] seg_led //数码管段选
);
//parameter define
parameter TIME_SHOW = 25'd24000_000; //数码管变化的时间间隔0.5s
//wire define
wire add_flag; //数码管变化的通知信号
//注意传递的变脸位宽必须一致【例化模块】
time_count #(
.MAX_NUM (TIME_SHOW)
) u_time_count(
.clk (sys_clk ),
.rst_n (sys_rst_n),
.flag (add_flag)
);
另外一种调用模块写法:
time_count #(
.MAX_NUM (TIME_SHOW)
) u_time_count(
sys_clk,
sys_rst_n,
add_flag
);
程序中另一个模块的调用
seg_led_static u_seg_led_static(
.clk (sys_clk),
.rst_n (sys_rst_n),
.add_flag (add_flag),
.sel (sel),
.seg_led (seg_led)
);
endmodule
在quartus中生成的电路
最左端是顶层模块输入信号,最右端是顶层模块输出信号。