- 環形計數器
- 扭環形計數器
- 順序脈沖發生器
環形計數器
將移位寄存器首位相接,連續不斷的數據將在寄存器內循環右移。
如初始狀態為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] 數字電子技術基礎(第五版) 閻石主編