VHDL Code for Johnson Counter: Syntax and Example
A
Johnson counter in VHDL is implemented using a shift register where the inverted output of the last flip-flop is fed back to the input of the first. The code uses a clocked process to shift bits and create the Johnson counting sequence.Syntax
The Johnson counter uses a process triggered by the clock edge to shift bits in a register. The inverted last bit is fed back to the first bit. The main parts are:
- Signal declaration: a vector to hold the counter bits.
- Clock process: shifts bits on rising clock edge.
- Feedback: inverted last bit assigned to first bit.
vhdl
process(clk, reset) begin if reset = '1' then q <= (others => '0'); elsif rising_edge(clk) then q <= q(q'left-1 downto 0) & not q(q'left); end if; end process;
Example
This example shows a 4-bit Johnson counter. It resets to 0000 and on each clock cycle, the bits rotate with the inverted last bit fed back to the front.
vhdl
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity johnson_counter is
Port (
clk : in STD_LOGIC;
reset : in STD_LOGIC;
q : out STD_LOGIC_VECTOR (3 downto 0)
);
end johnson_counter;
architecture Behavioral of johnson_counter is
signal count : STD_LOGIC_VECTOR (3 downto 0) := (others => '0');
begin
process(clk, reset)
begin
if reset = '1' then
count <= (others => '0');
elsif rising_edge(clk) then
count <= count(2 downto 0) & not count(3);
end if;
end process;
q <= count;
end Behavioral;Output
On each rising clock edge, the output q cycles through: 0000, 1000, 1100, 1110, 1111, 0111, 0011, 0001, then repeats.
Common Pitfalls
Common mistakes when coding a Johnson counter in VHDL include:
- Not inverting the last bit before feeding it back, which breaks the counting sequence.
- Incorrect bit slicing in the shift operation causing wrong bit order.
- Forgetting to reset the counter properly, leading to unknown start states.
Always verify the bit ranges and feedback logic carefully.
vhdl
process(clk, reset) begin if reset = '1' then count <= (others => '0'); elsif rising_edge(clk) then -- Wrong: missing inversion of last bit count <= count(2 downto 0) & count(3); end if; end process;
Quick Reference
| Concept | Description |
|---|---|
| Clock edge | Use rising_edge(clk) to trigger shifts |
| Reset | Asynchronously reset all bits to '0' |
| Shift operation | Shift left bits and append inverted last bit |
| Output | Assign internal register to output port |
| Bit slicing | Use correct downto ranges for shifting |
Key Takeaways
A Johnson counter shifts bits with the inverted last bit fed back to the first.
Use a clocked process with rising_edge(clk) and proper reset handling.
Carefully slice bits and invert the last bit to maintain correct sequence.
Initialize the counter to a known state to avoid unpredictable outputs.
Test the counter output sequence to verify correct Johnson counting behavior.