Decimal number on 7 segment display

2020-07-25 09:22发布

I've got a big problem with VHDL for a project. I want to see on 7 segment display a number that user sets with switches. For example if the low-order 5 switches are turned on then they will represent the binary number "11111" that is 31 in decimal. So I want to see 31 on 7 segment display.

To do that I plan these steps:

  • Insert the 5 value of the switch into an array
  • Convert the array into an integer number
  • See the integer number into 7 segment display

Point 1) insert into an array

     signal first: std_logic_vector (0 to 4);
     signal temp: integer range 0 to 9999:=0;
     for i in 0 to 4 loop
           first(i)<=SW(i);
     end loop;
     temp<=VEC_TOINT(first);
     HEX0<=INT_TO7SEG(temp);

Point 2) Vector to Integer

     Function VEC_TOINT(Vector: in std_logic_vector) return integer is
     variable temp: bit_vector(Vector'range);
     variable result: integer :=0;
     Begin
          for index in Vector'range loop
               result:=result * 2 + bit'pos(temp(index));
          end loop;
          if Vector(Vector'left) = '1' then 
               result:=(-result)-1;
          end if;
          return result;
     End VEC_TOINT;

For the third point at the moment I don't have any idea.

标签: arrays vhdl
3条回答
2楼-- · 2020-07-25 09:40

Last questions i promise :)

I start to study your code and think about work, and so i decide to insert another input with the last two hex display that i have and sum them

so i create ad insert this part of code

      -- insert into entity         
      key: in std_logic_vector(3 downto 0);
      clock_50: in std_logic;

      signal input2: integer;
      signal result: integer;
      signal result1: unsigned;
      .............. -- the declaration of the 2° input is the same of the first

      Process(Clock_50)
      Begin
      if(CLOCK_50' EVENT AND CLOCK_50='1' AND KEY(0)='1') THEN
             result <= input1 + input2;
             result1 <=to_unsigned(integer((result), result1'length));
             segmentsR <= unsigned_to_seven_segment(Value => unsigned(result1), number_of_digits =>2, value_is_bcd =>false);
      HEX1 <= segmentsR(13 downto 7);
      HEX0 <= segmentsR(6 downto 0);
  End if;
  End Process;

There is a mistake that i can't find "Near text ":"; expecting ")", or "," .....according me the synthax is correct because on input1, input2 i already use the function to_integer....

Best Regards

Michele

查看更多
Anthone
3楼-- · 2020-07-25 09:40

To solve 3) you'll have to understand how a 7 segment display works, specifically character display. Basically you'll have to implement an encoder from integer to the hexadecimal encoding of the display. The hexadecimal encoding is provided in the data sheet of the display, e.g. this datasheet shows you which display pins are connected to which segment. An exemplary hexadecimal code is provided at wikipedia.

查看更多
欢心
4楼-- · 2020-07-25 09:47

I've written a small package that does what you want. Given an unsigned input value, it breaks down this value into a series of decimal digits, and generates signals that can drive any number of seven-segments displays.

Here's an example of how you'd use it:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.seven_segment_pkg.all;

entity switches_to_7seg_displays is
    port (
        switches: in std_logic_vector(4 downto 0);
        seven_segments_display_1: out std_logic_vector(6 downto 0);
        seven_segments_display_2: out std_logic_vector(6 downto 0)
    );
end entity switches_to_7seg_displays;

architecture behavior of switches_to_7seg_displays is
    signal segments: std_logic_vector(13 downto 0);
    signal input: integer;
begin

    input <= to_integer(unsigned(switches));

    segments <= unsigned_to_seven_segment(
        value => unsigned(switches),
        number_of_digits => 2,
        value_is_bcd => false          
    );

    seven_segments_display_1 <= segments(13 downto 7);
    seven_segments_display_2 <= segments(6 downto 0);

end;

Note that the input value is an unsigned. To convert (actually, "type cast") an std_logic_vector to an unsigned, just use:

switches_uns <= unsigned(switches_slv);

If for some reason you decide to convert the value from the switches to an integer, there's a function in ieee.numeric_std that does that. It's a good idea to use it rather than writing your own. You can use it as:

switches_int <= to_integer(unsigned(switches_slv));

Finally, here's the code for the package. You are welcome to use it or study it and come up with your own solution.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

package seven_segment_pkg is

    -- Return a std_logic_vector ready for driving a number of 7-segment displays.
    function unsigned_to_seven_segment(
        value: unsigned;
        number_of_digits: integer;
        value_is_bcd: boolean
    ) return std_logic_vector;

end;

package body seven_segment_pkg is

    function seven_seg_from_bcd_digit(bcd_digit: std_logic_vector(3 downto 0)) 
        return std_logic_vector 
    is begin
        case bcd_digit is
            --                   abcdefg
            when x"0" => return "0111111";
            when x"1" => return "0000110";
            when x"2" => return "1011011";
            when x"3" => return "1001111";
            when x"4" => return "1100110";
            when x"5" => return "1101101";
            when x"6" => return "1111101";
            when x"7" => return "0000111";
            when x"8" => return "1111111";
            when x"9" => return "1101111";
            when x"a" => return "1110111";
            when x"b" => return "1111100";
            when x"c" => return "0111001";
            when x"d" => return "1011110";
            when x"e" => return "1111001";
            when x"f" => return "1110001";
            when others => return "0000000";
        end case;
    end;

    -- Return a vector ready for driving a series of 7-segment displays.
    function unsigned_to_seven_segment(
        value: unsigned;
        -- Number of 7-segment displays (determines output vector width: W = 7*N)
        number_of_digits: integer;
        -- When true, treat the input value as a BCD number where every 4 bits hold one
        -- digit from 0 to A. When false, treat the input number as an unsigned integer.       
        value_is_bcd: boolean
    ) return std_logic_vector is

        variable segments: std_logic_vector(number_of_digits*7-1 downto 0);
        variable bcd_quotient: unsigned(value'range);
        variable bcd_remainder: unsigned(3 downto 0);
    begin

        if value_is_bcd then
            for i in 0 to number_of_digits-1 loop
                segments(i*7+6 downto i*7) := seven_seg_from_bcd_digit(
                    std_logic_vector(value(i*4+3 downto i*4))
                );
            end loop;
        else
            bcd_quotient := value;
            for i in 0 to number_of_digits-1 loop
                bcd_remainder := resize(bcd_quotient mod 10, 4);
                bcd_quotient := bcd_quotient / 10;
                segments(i*7+6 downto i*7) := seven_seg_from_bcd_digit(
                    std_logic_vector(bcd_remainder)
                );
            end loop;

        end if;

        return segments;
    end;

end;
查看更多
登录 后发表回答