Verilog没有葵花宝典——day8(计数器)
题目
- 用verilog实现一个4bit二进制计数器。
a) 异步复位
b) 同步复位
input clk, rst_n;
output [3:0] o_cnt;- 用verilog实现4bit约翰逊(Johnson)计数器。
- 用verilog实现4bit环形计数器:复位有效时输出0001,复位释放后依次输出0010,0100,1000,0001,0010...
- 比较一下以上三种计数器的特点。
- 记录1,2,3题目使用的工具,操作步骤,以及出现的错误和提示信息。
第一题
用verilog实现一个4bit二进制计数器。
Verilog描述
module cnt2s(
input clk, rst_n,
output [3:0] o_cnt
);
reg [3:0] cnt;
//异步复位
/* always @ (posedge clk or negedge rst_n) begin
if ( !rst_n )
cnt <= 4'b0000;
else if ( cnt == 4'b1111 )
cnt <= 4'b0000;
else
cnt <= cnt + 1'b1;
end */
//同步复位
always @ (posedge clk) begin
if ( !rst_n )
cnt <= 4'b0000;
else if ( cnt == 4'b1111 )
cnt <= 4'b0000;
else
cnt <= cnt + 1'b1;
end
assign o_cnt = cnt;
endmodule
vcs仿真结果
- 同步复位
第二题
用verilog实现4bit约翰逊(Johnson)计数器。
Verilog描述
module cnt_johnson(
input clk, rst_n,
output [3:0] o_cnt
);
reg [3:0] cnt;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
cnt <= 4'b0000;
end else begin
cnt <= {~cnt[0],cnt[3:1]};
end
end
assign o_cnt = cnt;
endmodule
VCS仿真
第三题
用verilog实现4bit环形计数器
Verilog描述
module cnt_ring(
input clk, rst_n,
output [3:0] o_cnt
);
reg [3:0] cnt;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
cnt <= 4'b0001;
end else begin
cnt <= {cnt[0],cnt[3:1]};
end
end
assign o_cnt = cnt;
endmodule
VCS仿真
三个计数器均用此tb:
module tb_cnt4( );
reg clk,rst_n;
wire [3:0] o_cnt;
initial fork
clk = 1'b0;
rst_n = 1'b0;
#20 rst_n = 1'b1;
#455 rst_n = 1'b0;
#475 rst_n = 1'b1;
#600 $finish;
join
always #10 clk = ~ clk;
cnt** cnt4(
.clk (clk ),
.rst_n (rst_n),
.o_cnt (o_cnt)
);
endmodule
第四题
比较一下以上三种计数器的特点。
- 环形计数器:n比特的环形计数器会循环n次,每计数一次的汉明距离是2。一般来说,环形计数器中循环的数据是只有一个比特为1的数据,因此任一时刻只有一个触发器输出为高电位。
- 约翰逊记数器:是修改过的环形计数器,最后一个触发器的输出反相后再接到第一个触发器。n比特的环形计数器会循环2n次,每计数一次的汉明距离是1。电路译码是不会产生竞争冒险且译码电路简单。
- 二进制计数器:n位二进制计数器(n为触发器的个数)有2n个状态。
参考链接:维基百科
另附一份更进一步解决前两种计数器自启动问题的文档
第五题
编辑器:VS Code,vim
仿真工具:VCS
vcs ./tb.v ./cnt.v +v2k -debug_all -R -gui
halftop
即将入行的数字IC设计工程师