BCD/HEX-zu-7-Segment-Decoder und zeitmultiplexe Ansteuerung einer Anzeige

Es werden BCD- oder HEX-Nibbles in Signale für eine 7-Segment-Anzeige dekodiert. 4 Nibbles werden zeitmultiplex auf einer 4-Ziffern-Anzeige dargestellt.

Top-Level-Modul sseg_test.vhd

Die 4 Nibbles werden zuerst auf ein Nibble multiplext, welches anschließend dekodiert wird. Man kann es auch umgekehrt machen, dann braucht man allerdings 4 Dekoder und einen 7 bit breiten Multiplexer.

Für seven_segment_decoder kann je nach Bedarf der BCD- oder der HEX-Decoder instantiiert werden.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
 
entity sseg_test is
    Port ( clk : in  STD_LOGIC;
           sw : in  STD_LOGIC_VECTOR (7 downto 0);
           an : out  STD_LOGIC_VECTOR (3 downto 0);
           seg : out  STD_LOGIC_VECTOR (6 downto 0);
           dp : out  STD_LOGIC);
end sseg_test;
 
architecture default of sseg_test is
  signal inverse: unsigned(7 downto 0);
  signal en: std_logic_vector(3 downto 0);
  signal v: std_logic_vector(3 downto 0);
begin
  inverse <= not unsigned(sw);
 
  display_multiplexer: entity timemux_4x4
                       port map( clk => clk, 
                                 reset => '0',
                                 d0 => sw(3 downto 0),
                                 d1 => sw(7 downto 4),
                                 d2 => std_logic_vector(inverse(3 downto 0)),
                                 d3 => std_logic_vector(inverse(7 downto 4)),
                                 lo_en => en,
                                 q => v);
 
  seven_segment_decoder: entity bcd_to_7seg port map(bcd => unsigned(v), seg => seg);
  dp <= en(2);
  an <= en;
end default;
2009/05/22 11:35 · Niels Böhm

User-Constraints-File sseg_test.ucf für Nexys 2

Die Eingänge sind an die Schiebeschaltern SW0 bis SW7 gelegt, die 7 Signale für die Segmente und das für den Punkt an die gemeinsamen Kathoden der Anzeige, die Aktivierung jeder Ziffer and die 4 Anoden der Anzeige und der Takt wird vom Onboard-50MHz-Signal gespeist.

# clock pin for Nexys 2 Board
NET "clk"   LOC = "B8"; # Bank = 0, Pin name = IP_L13P_0/GCLK8, Type = GCLK, Sch name = GCLK0
# 7 segment display
NET "seg<0>" LOC = "L18"; # Bank = 1, Pin name = IO_L10P_1, Type = I/O, Sch name = CA
NET "seg<1>" LOC = "F18"; # Bank = 1, Pin name = IO_L19P_1, Type = I/O, Sch name = CB
NET "seg<2>" LOC = "D17"; # Bank = 1, Pin name = IO_L23P_1/HDC, Type = DUAL, Sch name = CC
NET "seg<3>" LOC = "D16"; # Bank = 1, Pin name = IO_L23N_1/LDC0, Type = DUAL, Sch name = CD
NET "seg<4>" LOC = "G14"; # Bank = 1, Pin name = IO_L20P_1, Type = I/O, Sch name = CE
NET "seg<5>" LOC = "J17"; # Bank = 1, Pin name = IO_L13P_1/A6/RHCLK4/IRDY1, Type = RHCLK/DUAL, Sch name = CF
NET "seg<6>" LOC = "H14"; # Bank = 1, Pin name = IO_L17P_1, Type = I/O, Sch name = CG
NET "dp"     LOC = "C17"; # Bank = 1, Pin name = IO_L24N_1/LDC2, Type = DUAL, Sch name = DP
NET "an<0>" LOC = "F17"; # Bank = 1, Pin name = IO_L19N_1, Type = I/O, Sch name = AN0
NET "an<1>" LOC = "H17"; # Bank = 1, Pin name = IO_L16N_1/A0, Type = DUAL, Sch name = AN1
NET "an<2>" LOC = "C18"; # Bank = 1, Pin name = IO_L24P_1/LDC1, Type = DUAL, Sch name = AN2
NET "an<3>" LOC = "F15"; # Bank = 1, Pin name = IO_L21P_1, Type = I/O, Sch name = AN3
# Switches
NET "sw<0>" LOC = "G18"; # Bank = 1, Pin name = IP, Type = INPUT, Sch name = SW0
NET "sw<1>" LOC = "H18"; # Bank = 1, Pin name = IP/VREF_1, Type = VREF, Sch name = SW1
NET "sw<2>" LOC = "K18"; # Bank = 1, Pin name = IP, Type = INPUT, Sch name = SW2
NET "sw<3>" LOC = "K17"; # Bank = 1, Pin name = IP, Type = INPUT, Sch name = SW3
NET "sw<4>" LOC = "L14"; # Bank = 1, Pin name = IP, Type = INPUT, Sch name = SW4
NET "sw<5>" LOC = "L13"; # Bank = 1, Pin name = IP, Type = INPUT, Sch name = SW5
NET "sw<6>" LOC = "N17"; # Bank = 1, Pin name = IP, Type = INPUT, Sch name = SW6
NET "sw<7>" LOC = "R17"; # Bank = 1, Pin name = IP, Type = INPUT, Sch name = SW7
 
NET "clk" TNM_NET = clk;
TIMESPEC TS_clk = PERIOD "clk" 20 ns HIGH 50%;
2009/05/22 11:36 · Niels Böhm

Modul bcd_to_7seg.vhd

Dieser Dekoder kann statt dem HEX-Dekoder verwendet werden, wenn man keine hexadezimalen Ziffern benötigt und man auf (ganz leicht) geringeren Ressourcenverbrauch hin optimieren möchte.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
 
entity bcd_to_7seg is
    Port ( bcd : in  unsigned (3 downto 0);
           seg : out  STD_LOGIC_VECTOR (6 downto 0));
end bcd_to_7seg;
 
architecture default of bcd_to_7seg is
begin
  with bcd select
    seg <= "1000000" when "0000",
           "1111001" when "0001",
           "0100100" when "0010",
           "0110000" when "0011",
           "0011001" when "0100",
           "0010010" when "0101",
           "0000010" when "0110",
           "1111000" when "0111",
           "0000000" when "1000",
           "0010000" when "1001",
           "-------" when others;
end default;
2009/05/22 11:37 · Niels Böhm

Modul hex_to_7seg.vhd

Hier sind zusätzlich zu den dekadischen die hexadezimalen Ziffern A, b, C, d, E und F implementiert.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
 
entity hex_to_7seg is
    Port ( hex : in  unsigned (3 downto 0);
           seg : out  STD_LOGIC_VECTOR (6 downto 0));
end hex_to_7seg;
 
architecture default of hex_to_7seg is
begin
  with hex select
    seg <= "1000000" when "0000",
           "1111001" when "0001",
           "0100100" when "0010",
           "0110000" when "0011",
           "0011001" when "0100",
           "0010010" when "0101",
           "0000010" when "0110",
           "1111000" when "0111",
           "0000000" when "1000",
           "0010000" when "1001",
           "0001000" when "1010",
           "0000011" when "1011",
           "1000110" when "1100",
           "0100001" when "1101",
           "0000110" when "1110",
           "0001110" when "1111",
           "-------" when others;
end default;
2009/05/22 11:38 · Niels Böhm

Modul timemux_4x4.vhd

Der Multiplexer teilt zuerst den Takt durch 2^DIVIDER_SHIFT, und erhöht bei Überlauf einen 2-bit-Zähler (beides in einem Signalvektor zusammengefasst).

Je nach Zählerstand wird dann das entsprechende low-aktive Enable-Signal gesetzt (entspricht einem 1-aus-4-Dekoder) und einer der Eingangsvektoren auf den Ausgang geschaltet (entspricht einem 4 bit breiten 4-zu-1-Multiplexer).

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
 
entity timemux_4x4 is
    Port ( clk : in  STD_LOGIC;
           reset : in std_logic;
           d0 : in  STD_LOGIC_VECTOR (3 downto 0);
           d1 : in  STD_LOGIC_VECTOR (3 downto 0);
           d2 : in  STD_LOGIC_VECTOR (3 downto 0);
           d3 : in  STD_LOGIC_VECTOR (3 downto 0);
           lo_en : out  STD_LOGIC_VECTOR (3 downto 0);
           q : out  STD_LOGIC_VECTOR (3 downto 0));
end timemux_4x4;
 
architecture default of timemux_4x4 is
  constant DIVIDER_SHIFT: natural := 16;
  signal combined: unsigned(DIVIDER_SHIFT+1 downto 0);
  signal counter: unsigned(1 downto 0);
begin
  process (clk, reset)
  begin
    if reset = '1' then
      combined <= (others => '0');
    elsif rising_edge(clk) then
      combined <= combined + 1;
    end if;
  end process;
 
  counter <= combined(combined'high downto combined'high+1-counter'length);
 
  process (counter, d0, d1, d2, d3)
  begin
    case counter is
      when "00" =>
        lo_en <= "1110";
        q <= d0;
      when "01" =>
        lo_en <= "1101";
        q <= d1;
      when "10" =>
        lo_en <= "1011";
        q <= d2;
      when "11" =>
        lo_en <= "0111";
        q <= d3;
      when others =>
        lo_en <= "----";
        q <= "----";
    end case;
  end process;
end default;
2009/05/22 11:39 · Niels Böhm

Diskussion

Geben Sie Ihren Kommentar ein (Wiki-Syntax ist zugelassen):
 
fpga/7-segment/start.txt · Zuletzt geändert: 2010/01/14 23:32 (Externe Bearbeitung)
 
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki