Johnson counter (Johnson counter Wiki) 的實作方法為在 shift register 的基礎上不斷循環,在後面多加一個反相器,如下圖所示.。

Johnson counter RTL 如下 :
`timescale 1ns/100ps
////// … . .. –.. . – …. . — — — . -. – //////
// Author : TienYao
// Source Code Name : johnson_ring_counter.v
// Function Description: 16-bit johnson counter
// ===========================================================
module johnson_ring_counter (
input clk,
input rstN,
output [15:0] counter_o
);
reg [15:0] rvCounter_d, rvCounter_q;
always @(posedge clk or negedge rstN) begin
if(!rstN)
rvCounter_q <= 16'h0;
else
rvCounter_q <= rvCounter_d;
end
always @(*) begin
rvCounter_d = {rvCounter_q[14:0],~rvCounter_q[15]};
end
assign counter_o = rvCounter_q;
endmodule
TestBench 如下 :
`timescale 1ns/100ps
////// … . .. –.. . – …. . — — — . -. – //////
// Author : TienYao
// Source Code Name : johnson_ring_counter_tb.v
// Function Description: A signal generation for johnson ring counter module
// ===========================================================
module johnson_ring_counter_tb;
reg clk;
reg rstN;
wire [15:0] counter;
johnson_ring_counter DUT (
.clk(clk),
.rstN(rstN),
.counter_o(counter)
);
initial begin
clk = 0;
rstN = 0;
end
always #10 clk = ~clk;
task SYSTEM_RESET;
begin
repeat(100) @(posedge clk);
rstN = 1;
end
endtask
initial begin
SYSTEM_RESET;
#10000;
$stop;
end
endmodule
模擬結果
