Verilog HDL学习笔记五

扭环计数器又叫约翰逊(Johnson)计数器,用n位触发器来表示2n个状态的计数器,若以四位二进制计数器为例,它可表示16个状态。但由于8421码每组代码之间可能有二位或二位以上的二进制代码发生改变,这在计数器中特别是异步计数器中就有可能产生错误的译码信号,从而造成永久性的错误。而约翰逊计数器的状态表中,相邻两组代码只可能有一位二进制代码不同,故在计数过程中不会产生错误的译码信号。

约翰逊计数器的长度N=2n,因为移位寄存器串行输入端的信号是从反向端 ~Q取得的。经过n个时钟后,计数器的状态与初始状态刚好相反,必须再经过n个时钟后才能回到扭环原态。
以四位扭环计数器为图例,如下图所示:
在这里插入图片描述
在这里插入图片描述
设计代码:

module twist_counter8(out,clk,rst_n);
	input clk;
	input rst_n;
	output reg [7:0]out;

reg [31:0] count;
reg clk_div;
localparam N = 50000000;
//Describe the counter in an always block
always @ (posedge clk or negedge rst_n)				//将50MHz的时钟频率分为1Hz
begin
    if (!rst_n)
        count <= 32\'b0;
    else if (count == N - 1)
        count <= 32\'b0;
    else
        count <= count + 1\'b1;
end

//Describe the flip-flop together with the comparator 
always @ (posedge clk or negedge rst_n)
begin
    if (!rst_n)
        clk_div <= 1\'b0;
    else if (count == N- 1)
        clk_div <= ~clk_div;
    else
        clk_div <= clk_div;
end

always @(posedge clk_div or negedge rst_n)
begin
	if(!rst_n)
	out <=8\'b0;
	else
	out[7:0] <= {out[6:0],~out[7]};
end
endmodule

测试代码:

module twist_counter8_tb;
reg clk;
reg rst_n;
wire [7:0]out;

twist_counter8 unit(
	.clk(clk),
	.rst_n(rst_n),
	.out(out));
	#10 clk=~clk;
initial
begin
	clk=1\'b0;rst_n=1\'b0;
	#20 rst_n=1\'b1;
end
endmodule

若需详细了解环形计数器和约翰逊计数器可参考文档:[https://wenku.baidu.com/view/0b116b23c1c708a1294a446e.html]

版权声明:本文为匿名原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: