工程模块程序:
module counter(
input clk,
input rst_n,
input en,
output[3:0] cntValue);
reg[3:0] cnt;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
cnt <= 4'b0000;
end
else
begin
if(en == 1'b1)
begin
if(cnt == 4'b1111)
begin
cnt <= 4'b0000;
end
else
begin
cnt <= cnt + 4'b0001;
end
end
else
begin
cnt <= cnt;
end
end
end
assign cntValue = cnt;
endmodule
同步与异步是时序逻辑,指的是与时钟的关系;如果在always敏感信号里写了某一信号,则为异步,否则为同步;如本例中的rst_n信号,无论clk上升沿是否存在,只要rst_n下降沿来临均会触发cnt复位;而en信号仅在clk上升沿来临时才会起作用,所以en信号属于同步信号。通过该程序可以学习了解同步和异步的知识点。
此外,需要注意的时,在always敏感信号列表中写了negedge rst_n,则必须在always块中以!rst_n或rst_n ==0,即低有效的方式表示。
RTL Viewer
测试仿真程序
`timescale 1ns/1ps
`define clk_period 10
module counter_tb;
reg clk;
reg rst_n;
reg en;
wire[3:0] cntValue;
counter counter_inst(
.clk(clk),
.rst_n(rst_n),
.en(en),
.cntValue(cntValue));
initial clk = 1'b0;
always #(`clk_period / 2) clk = ~clk;
initial
begin
rst_n = 1'b1;
en = 1'b0;
#(`clk_period * 20);
rst_n = 1'b0;
#(`clk_period * 20);
rst_n = 1'b1;
#(`clk_period * 21);
en = 1'b1;
#(`clk_period * 200);
en = 1'b0;
#(`clk_period * 100);
rst_n = 1'b0;
#(`clk_period * 100);
$stop;
end
endmodule
仿真波形
百度网盘工程链接:
链接:https://pan.baidu.com/s/16FlvYALv7_p2zBUne3FPGg
提取码:gse3