RobyJacob
RobyJacob

Reputation: 1

display 3-bit on 7 segment display

I want to display 3-bit binary on 4-digit 7 segment display with appropriate switch pressed. For eg :- if switch positon is 001(switch2-off switch1-off switch0-on) then i want to display 001 on 7 segment display. Im doing this using VHDL. Tried multiplexing but still not working. Below is the code.

    entity test is
    Port(Seg_AN :out std_logic_vector(3 downto 0);
            Seg7    :out std_logic_vector(6 downto 0);
            SWITCH  :in std_logic_vector(2 downto 0);
            CLK :in std_logic
            );
end test;

architecture Behavioral of test is
    signal sel  :natural range 0 to 8;
    signal anode_sel    :std_logic_vector(2 downto 0);
--  signal number   :std_logic_vector(2 downto 0);
    constant c_cnt_200hz    :natural    := 87500;
--  constant c_cnt_1hz  :natural    := 17500000;
    signal r_cnt_200hz  :natural range 0 to c_cnt_200hz;
--  signal r_cnt_1hz    :natural range 0 to c_cnt_1hz;
    signal anode    :std_logic_vector(2 downto 0);
    signal segment  :std_logic_vector(6 downto 0);
--  signal digit    :std_logic;
begin
    process(CLK)
    begin
        if rising_edge(CLK) then
            if r_cnt_200hz = c_cnt_200hz - 1 then
                r_cnt_200hz <= 0;
                if sel = 8 then
                    sel <= 0;
                else
                    sel <= sel + 1;
                end if;
            else
                r_cnt_200hz <= r_cnt_200hz + 1;
            end if;
        end if;
    end process;

    process(sel)
    begin
        case sel is
            when 1 => anode_sel <= "001";
            when 2 => anode_sel <= "010";
            when 3 => anode_sel <= "100";
            when 4 => anode_sel <= "011";
            when 5 => anode_sel <= "101";
            when 6 => anode_sel <= "110";
            when others => anode_sel <= "111";
        end case;
        anode <= not anode_sel;
    end process;

    process(anode)
    begin
        if SWITCH(0)='1' or SWITCH(1)='1' or SWITCH(2)='1' then
            segment <= "1111001";
        else 
            segment <= "1000000";
        end if;
    end process;

    Seg_AN <= '1' & anode;
    Seg7 <= segment;
end Behavioral;

Upvotes: 0

Views: 1688

Answers (2)

CJC
CJC

Reputation: 817

I recommend to implement the solution by pure combinational logic, you don't really need the registers (synthesized when you use rising/falling edge of clock).

You can clock it(put it through some registers) outside the clock.

LIBRARY     ieee;
    USE     ieee.std_logic_1164.all;

Entity SEG7_LUT is
port(   oSEG  : out std_logic_vector (6 downto 0); 
        iDIG  : in std_logic_vector  (3 downto 0));
end entity SEG7_LUT;

Architecture RTL of SEG7_LUT is
begin

logic : process (iDIG) begin 
    case iDIG is 
        when x"1" => oSEG <= "1111001";
        when x"2" => oSEG <= "0100100";     -- |--rt--|
        when x"3" => oSEG <= "0110000";     -- lt    rt
        when x"4" => oSEG <= "0011001";     -- |      |
        when x"5" => oSEG <= "0010010";     -- ---m----
        when x"6" => oSEG <= "0000010";     -- |      |
        when x"7" => oSEG <= "1111000";     -- lb    rb
        when x"8" => oSEG <= "0000000";     -- |      |
        when x"9" => oSEG <= "0011000";     -- ---b----
        when x"a" => oSEG <= "0001000";
        when x"b" => oSEG <= "0000011";
        when x"c" => oSEG <= "1000110";
        when x"d" => oSEG <= "0100001";
        when x"e" => oSEG <= "0000110";
        when x"f" => oSEG <= "0001110";
        when x"0" => oSEG <= "1000000";
    end case; 
end process logic; 

end;

The code below gives an example of representing 32 bit number in hexadecimal format on eight 7 segment displays.

LIBRARY     ieee;
    USE     ieee.std_logic_1164.all;

Entity SEG7_LUT_8 is
    port( oSEG0 : out std_logic_vector (6 downto 0); 
          oSEG1 : out std_logic_vector (6 downto 0); 
          oSEG2 : out std_logic_vector (6 downto 0); 
          oSEG3 : out std_logic_vector (6 downto 0); 
          oSEG4 : out std_logic_vector (6 downto 0); 
          oSEG5 : out std_logic_vector (6 downto 0); 
          oSEG6 : out std_logic_vector (6 downto 0); 
          oSEG7 : out std_logic_vector (6 downto 0);
          iDIG  : in std_logic_vector (31 downto 0));
end;

Architecture RTL of SEG7_LUT_8 is 
begin 
u0  : entity work.SEG7_LUT port map(    oSEG0,iDIG(3  downto 0)     );
u1  : entity work.SEG7_LUT port map(oSEG1,iDIG(7  downto 4)     );
u2  : entity work.SEG7_LUT port map(oSEG2,iDIG(11 downto 8)     );
u3  : entity work.SEG7_LUT port map(oSEG3,iDIG(15 downto 12)    );
u4  : entity work.SEG7_LUT port map(oSEG4,iDIG(19 downto 16)    );
u5  : entity work.SEG7_LUT port map(oSEG5,iDIG(23 downto 20)    );
u6  : entity work.SEG7_LUT port map(oSEG6,iDIG(27 downto 24)    );
u7  : entity work.SEG7_LUT port map(oSEG7,iDIG(31 downto 28)    );

end;

Upvotes: 0

Oldfart
Oldfart

Reputation: 6259

Referring to the picture below:

  • To show a ONE you need B and C on.

  • To show a ZERO you need A, B, C, D, E, F on.

So in effect you only need to switch A,D,E,F on or off. For ONE they need to be off, for a ZERO they need to be on.

Typical & segment

Your code needs to:

  • Keep B and C on all the time. (Two outputs which do not change)

  • Keep G off all the time. (A third outputs which does not change)

  • Switch all of A,D,E,F simultaneous on or off depending on your bit switch position. That is four outputs which all have the same value.

The only problem is if you need an inverter or not. That depends on if the switch and/or the LEDS are connected for active high or active low operation.

Upvotes: 1

Related Questions