Design 6 – Counters

This design includes a counter.

But first we will separate the 4-bit-to-7-segment translator, and put that in a separate file. Only the translation is present. The conversion to active-low signals is left outside the separated module.

The VHDL version is:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity Bit4To7Seg is
  port (
    digit:   in  std_logic_vector(3 downto 0);
    led_seg: out std_logic_vector(6 downto 0)
  );
end Bit4To7Seg;

architecture Behavioral of Bit4To7Seg is
begin

  led_seg <=
    "1111110" when digit =  0 else
    "0110000" when digit =  1 else
    "1101101" when digit =  2 else
    "1111001" when digit =  3 else
    "0110011" when digit =  4 else
    "1011011" when digit =  5 else
    "1011111" when digit =  6 else
    "1110000" when digit =  7 else
    "1111111" when digit =  8 else
    "1111011" when digit =  9 else
    "1110111" when digit = 10 else
    "0011111" when digit = 11 else
    "1001110" when digit = 12 else
    "0111101" when digit = 13 else
    "1001111" when digit = 14 else
    "1000111";

end Behavioral;

The Verilog version is:

module Bit4To7Seg (
    input  [3:0] digit,
    output [6:0] led_seg
    );

  assign led_seg =
    (digit ==  0) ? 7'b1111110 :
    (digit ==  1) ? 7'b0110000 :
    (digit ==  2) ? 7'b1101101 :
    (digit ==  3) ? 7'b1111001 :
    (digit ==  4) ? 7'b0110011 :
    (digit ==  5) ? 7'b1011011 :
    (digit ==  6) ? 7'b1011111 :
    (digit ==  7) ? 7'b1110000 :
    (digit ==  8) ? 7'b1111111 :
    (digit ==  9) ? 7'b1111011 :
    (digit == 10) ? 7'b1110111 :
    (digit == 11) ? 7'b0011111 :
    (digit == 12) ? 7'b1001110 :
    (digit == 13) ? 7'b0111101 :
    (digit == 14) ? 7'b1001111 :
                    7'b1000111 ;

endmodule

The rest of the design combines the RS Latch, a Register modified to be a counter, and a modified hexadecimal digit display. The names of the LED signals have been changed to the ones I am using for other projects created with the Starter Kit board.

The RS Latch provides clocking, and its LED's provide a visual indication of the clocking. You can watch the counter count as the lights flip back and forth.

The counter register has a familiar looking assignment for incrementing by 1. Notice that it's written more like an interrupt service routine (or an event handler), rather than being embedded in a loop.

The code examples show how the separated module is utilized by the other module. It's basically the same as what was shown with the FDCPE component. It's possible to use "positional" notation; but with so many names that will be generated, it's a lot easier to check completeness of connection with the "named port" notation.

The new VHDL code:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
library UNISIM;
use UNISIM.VComponents.all;

entity HexCounter1 is
  port (
    R, S:        in  std_logic;
    Q, N_Q:      out std_logic;
    N_LED_7S:    out std_logic_vector(7 downto 0);
    N_LED_7S_EN: out std_logic_vector(3 downto 0)
  );
end HexCounter1;

architecture Behavioral of HexCounter1 is
  signal iQ:      std_logic;
  signal digit:   std_logic_vector(3 downto 0);
  signal led_seg: std_logic_vector(6 downto 0);
  signal led_en:  std_logic_vector(3 downto 0);
begin

  led_en      <= "0001";

  N_LED_7S    <= not ('0' & led_seg);
  N_LED_7S_EN <= not led_en;

U_RSLATCH :
  FDCPE port map (
    C   => '0',
    CE  => '0',
    D   => '0',
    CLR => R,
    PRE => S,
    Q   => iQ
  );

  Q   <= iQ;
  N_Q <= not iQ;

U_COUNTER :
  process (iQ)
  begin
    if rising_edge(iQ) then
      digit <= digit + 1;
    end if;
  end process;

U_BIT4TO7SEG :
  entity Bit4To7Seg port map (
    digit   => digit,
    led_seg => led_seg
  );

end Behavioral;

The new Verilog code:

module HexCounter1Ver (
  input        R, S,
  output       Q, N_Q,
  output [7:0] N_LED_7S,
  output [3:0] N_LED_7S_EN
  );

  reg  [3:0] digit;
  wire [6:0] led_seg;
  wire [3:0] led_en = 4'b0001;

  assign N_LED_7S     = ~{ 1'b0, led_seg };
  assign N_LED_7S_EN  = ~led_en;

  FDCPE U_RSLATCH (
    .C(1'b0),
    .CE(1'b0),
    .D(1'b0),
    .CLR(R),
    .PRE(S),
    .Q(Q)
  );

  assign N_Q = ~Q;

  always @(posedge Q)
  begin
    digit <= digit + 1;
  end

  Bit4To7Seg U_BIT4TO7SEG (
    .digit(digit),
    .led_seg(led_seg)
  );

endmodule