【Verilog HDL 训练】第 08 天(二进制、Johnson、环形计数器)
5月6日
计数器 1. 用verilog实现一个4bit二进制计数器。
a) 异步复位
b) 同步复位
input clk, rst_n; output [3:0] o_cnt;
Verilog实现代码:
-
module count_2(
-
input clk,
-
input rst_n,
-
output reg [3:0] o_cnt
-
)
-
always @ (posedge clk or negedge rst_n) begin //异步复位
-
if(!rst_n) begin
-
o_cnt <= 4'b0000;
-
end
-
else if(o_cnt == 4'b1111) begin
-
o_cnt <= 4'b0000;
-
end
-
else begin
-
o_cnt <= o_cnt + 4'b0001;
-
end
-
end
-
/*
-
always @ (posedge clk) begin //同步复位
-
if(!rst_n) begin
-
o_cnt <= 4'b0000;
-
end
-
else if(o_cnt == 4'b1111) begin
-
o_cnt <= 4'b0000;
-
end
-
else begin
-
o_cnt <= o_cnt + 4'b0001;
-
end
-
end
-
*/
-
-
endmodule
仿真代码:
-
module count_tb(
-
);
-
-
reg clk, rst_n;
-
wire [3:0] o_cnt;
-
-
//generate system clock with the period == 2ns;
-
always begin
-
#1 clk = ~clk;
-
end
-
initial begin
-
clk = 0;
-
end
-
-
//initialization
-
initial begin
-
rst_n = 0;
-
#4
-
rst_n = 1;
-
-
#32
-
rst_n = 0;
-
#4
-
rst_n = 1;
-
-
end
-
-
//Instantiation
-
count_2 u0(
-
.clk(clk),
-
.rst_n(rst_n),
-
.o_cnt(o_cnt)
-
);
-
-
-
-
endmodule
仿真时序图:
RTL原理图:
上面是异步复位的仿真图,下面给出同步复位的仿真图:
同步复位的RTL原理图:
2. 用verilog实现4bit约翰逊(Johnson)计数器。
约翰逊(Johnson)计数器又称扭环计数器,是一种用n位触发器来表示2n个状态的计数器。它与环形计数器不同,后者用n位触发器仅可表示n个状态。2进制计数器(n为触发器的个数)有2^n个状态。若以四位二进制计数器为例,它可表示16个状态。但由于8421码每组代码之间可能有二位或二位以上的二进制代码发生改变,这在计数器中特别是异步计数器中就有可能产生错误的译码信号,从而造成永久性的错误。而约翰逊计数器的状态表中,相邻两组代码只可能有一位二进制代码不同,故在计数过程中不会产生错误的译码信号。鉴于上述优点,约翰逊计数器在同步计数器中应用比较广泛。
Verilog代码:
-
`timescale 1ns / 1ps
-
-
module count_tb(
-
);
-
-
reg clk, rst_n;
-
wire [3:0] o_cnt;
-
-
//generate system clock with the period == 2ns;
-
always begin
-
#1 clk = ~clk;
-
end
-
initial begin
-
clk = 0;
-
end
-
-
//initialization
-
initial begin
-
rst_n = 0;
-
#4
-
rst_n = 1;
-
-
#32
-
rst_n = 0;
-
#4
-
rst_n = 1;
-
-
end
-
-
//Instantiation
-
count_johnson u0(
-
.clk(clk),
-
.rst_n(rst_n),
-
.o_cnt(o_cnt)
-
);
-
-
-
-
endmodule
测试文件:
-
`timescale 1ns / 1ps
-
-
-
module count_tb(
-
);
-
-
reg clk, rst_n;
-
wire [3:0] o_cnt;
-
-
//generate system clock with the period == 2ns;
-
always begin
-
#1 clk = ~clk;
-
end
-
initial begin
-
clk = 0;
-
end
-
-
//initialization
-
initial begin
-
rst_n = 0;
-
#4
-
rst_n = 1;
-
-
#32
-
rst_n = 0;
-
#4
-
rst_n = 1;
-
-
end
-
-
//Instantiation
-
count_johnson u0(
-
.clk(clk),
-
.rst_n(rst_n),
-
.o_cnt(o_cnt)
-
);
-
-
-
-
endmodule
时序图:
RTL原理图:
3. 用verilog实现4bit环形计数器:复位有效时输出0001,复位释放后依次输出0010,0100,1000,0001,0010...
Verilog描述:
-
`timescale 1ns / 1ps
-
-
module count_circle(
-
input clk,
-
input rst_n,
-
output reg [3:0] o_cnt
-
-
);
-
-
always @ (posedge clk or negedge rst_n) begin
-
if(!rst_n) begin
-
o_cnt <=4'b0001;
-
end
-
else begin
-
o_cnt <= {o_cnt[2:0],o_cnt[3]};
-
end
-
-
end
-
-
-
-
-
endmodule
测试文件:
-
`timescale 1ns / 1ps
-
-
-
module count_tb(
-
);
-
-
reg clk, rst_n;
-
wire [3:0] o_cnt;
-
-
//generate system clock with the period == 2ns;
-
always begin
-
#1 clk = ~clk;
-
end
-
initial begin
-
clk = 0;
-
end
-
-
//initialization
-
initial begin
-
rst_n = 0;
-
#4
-
rst_n = 1;
-
-
#32
-
rst_n = 0;
-
#4
-
rst_n = 1;
-
-
end
-
-
//Instantiation
-
count_circle u0(
-
.clk(clk),
-
.rst_n(rst_n),
-
.o_cnt(o_cnt)
-
);
-
-
-
-
endmodule
仿真时序图:
RTL原理图:
4. 比较一下以上三种计数器的特点。
假设都是N位的计数器,二进制计数器有2^N个状态,Johnson计数器由2N个状态,而环形计数器由N个状态;
相对于二进制计数器,Johnson计数器相邻两组代码只可能有一位二进制代码不同,环形计数器也是如此。
5. 记录1,2,3题目使用的工具,操作步骤,以及出现的错误和提示信息。
工具:Vivado,notepad++
操作步骤:
先编写Verilog代码,再功能仿真,再生成RTL图。
错误提示:如果用参数,下面就一致用参数,不要用着用着不用了,或者本来没用,又用了。(哈哈)
文章来源: reborn.blog.csdn.net,作者:李锐博恩,版权归原作者所有,如需转载,请联系作者。
原文链接:reborn.blog.csdn.net/article/details/89883249
- 点赞
- 收藏
- 关注作者
评论(0)