移位寄存器型计数器与顺序脉冲发生器
- 环形计数器
- 扭环形计数器
- 顺序脉冲发生器
环形计数器
将移位寄存器首位相接,连续不断的数据将在寄存器内循环右移。
如初始状态为1000,则电路的循环变化为:1000 --> 0001 --> 0010 --> 0100 --> 1000 ,可以把这个电路作为时钟脉冲的计数器。
状态利用:n个
反馈逻辑函数:
\begin{align}\notag D_{0} = Q_{n-1} \end{align}
扭环形计数器
若改变反馈逻辑函数(如下),则可以得到扭环形计数器(约翰逊计数器)。
状态利用:2n个
反馈逻辑函数:
\begin{align}\notag D_{0} = {Q_{n}}' \end{align}
顺序脉冲发生器
顺序脉冲发生器可以用移位寄存器构成。当环形计数器工作在每个状态中只有一个1的循环状态时,它就是一个顺序脉冲发生器。
Verilog 代码
module ringcouter(
output [3:0] cnt_o,
output q0_o,
output q1_o,
output q2_o,
output q3_o,
input clk,
input rstn,
input en_i
);
reg [3:0] q;
always@(posedge clk,negedge rstn)
begin
if(!rstn)
q <= 4'b1000;
else if(en_i)
q <= {q[2:0],q[3]}; //环形计数器
end
assign cnt_o = q;
//顺序脉冲输出
assign q0_o = q[0];
assign q1_o = q[1];
assign q2_o = q[2];
assign q3_o = q[3];
endmodule
testbench
module ringcounter_tb;
reg clk;
reg rstn;
reg en_i;
wire [3:0] cnt_o;
wire q0_o;
wire q1_o;
wire q2_o;
wire q3_o;
initial
begin
clk = 0;
rstn = 1;
#50 rstn = 0;
#100 rstn = 1;
en_i = 1;
#800 $finish;
end
always #20 clk = ~clk;
initial begin
$fsdbDumpfile("test.fsdb");
$fsdbDumpvars();
end
ringcouter u_ringcounter(
.cnt_o(cnt_o),
.q0_o(q0_o),
.q1_o(q1_o),
.q2_o(q2_o),
.q3_o(q3_o),
.clk(clk),
.rstn(rstn),
.en_i(en_i)
);
endmodule
截图
参考资料
[1] 数字电子技术基础(第五版) 阎石主编
形而上者谓之道 形而下者谓之器。