移位寄存器型计数器与顺序脉冲发生器

  • 环形计数器
  • 扭环形计数器
  • 顺序脉冲发生器

环形计数器

将移位寄存器首位相接,连续不断的数据将在寄存器内循环右移。

如初始状态为1000,则电路的循环变化为:1000 --> 0001 --> 0010 --> 0100 --> 1000 ,可以把这个电路作为时钟脉冲的计数器。
状态利用:n个
反馈逻辑函数:

egin{align} otag D_{0} = Q_{n-1} end{align}

扭环形计数器

若改变反馈逻辑函数(如下),则可以得到扭环形计数器(约翰逊计数器)。
状态利用:2n个
反馈逻辑函数:

egin{align} otag 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

截图

ringcounter

参考资料

[1] 数字电子技术基础(第五版) 阎石主编

原文地址:https://www.cnblogs.com/OneFri/p/6034393.html