VHDL将1个4位数,基数10,数字转换为4个1位数,基数10,数字:用于7-SEG显示



我写了一些代码(或者更确切地说从互联网上复制了一些)来驱动单个7段LCD显示器。这可以显示范围内的数字;[0,9],或以16为底;[0 F] .

我有4个这样的显示,我希望将一个整数转换成4个整数,这样预期的数字将出现在显示上。

例如

;数字8765需要转换成4个整数:8,7,6,5。

如果我在C或其他类似的编程语言中这样做,那么我将使用除法和截断来完成转换。然而,我对VHDL不太熟悉,所以我不知道如何进行。

我该如何写VHDL代码来做到这一点?

编辑:

目前我有这样的东西:

variable number: integer; -- This is set to the 4 digit value to be displayed
variable d0: integer; -- Least significant digit (units)
variable d1: integer;
variable d2: integer;
variable d3: integer; -- Most significant digit (thousands)

所有这些都是(应该)以10为基数,而不是16。

十六进制输出

嗯,这很简单。假设你有一个signal x : unsigned(15 downto 0)。分别用

驱动7段显示:
  • x(3 downto 0)
  • x(7 downto 4)
  • x(11 downto 8)
  • x(15 downto 9)
<标题> 十进制输出

嗯,你需要把二进制输入转换成二进制编码的十进制。一种推荐的方法是使用Double Dabble,您可以在链接的维基百科文章中了解更多信息。

如果你想要更慢的,你可以用手工除法。从整个数字中减去10的次数当然可以,但它会比double dabble更昂贵和昂贵。

不管怎样,你都应该有足够的时间来做这项工作。因为你只有4个7段显示,所以最大的数字是9999。如果你的时钟运行在1Mhz,你需要1000个周期来执行转换,那么它仍然只需要1ms来产生结果。

双涉水是一种方法,但在FPGA上实现它对于初学者来说可能是一个进步。您可以考虑其他方法。如果要显示的值只是一个计数器,则可以创建一个以10为基数的数组,类似于:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity decimal_counter is
    port (
        clk             : in  std_logic;
        overflow_in     : in  std_logic;
        arst                : in  std_logic;
        value               : out  std_logic_vector(7 downto 0);
        overflow_out    : out  std_logic
    );
end decimal_counter;
architecture rtl of decimal_counter is
    constant ASCII_0        : natural := 48;
    constant ASCII_9        : natural := 57;
    signal counter : integer range ASCII_0 to ASCII_9 := ASCII_0;
begin
    p_decimal_counter : process (clk, arst)
    begin
        if (arst = '1') then
            counter         <= ASCII_0;
        elsif (rising_edge(clk)) then
            if (overflow_in = '1') then
                if (counter = ASCII_9) then
                    counter     <= ASCII_0;
                else
                    counter     <= counter + 1;
                end if; -- (counter = ASCII_9) then
            end if; -- if (overflow_in = '1') then
        end if; -- if (rising_edge(clk)) then
    end process p_decimal_counter;
  value <= std_logic_vector(to_unsigned(counter, value'length));
  overflow_out  <= '1' when ((counter = ASCII_9) and (overflow_in = '1')) else '0';
end rtl;

type ascii_digit_type is array ((NUM_DIGITS - 1) downto 0) of std_logic_vector(7 downto 0); 
signal counting_digits      : ascii_digit_type  :=      (OTHERS => (OTHERS => '0'));
...
-- Generate a counter to count ticks on an input pin
gen_counter : for i in 0 to (NUM_DIGITS - 1) generate
    lowest_digits: if (i = 0) generate
        lowest_digit : decimal_counter 
        port map
        (
            clk            => EXP_I(9),
            overflow_in     => '1',
            arst                => start_tx_tick,
            value               => counting_digits(i)
            overflow_out    => digits_overflow(i)
        );
    end generate lowest_digits;
    upper_digits: if (i > 0) generate
        upper_digit : decimal_counter 
        port map
        (
            clk           => EXP_I(9),
            overflow_in     => digits_overflow(i - 1),
            arst                => start_tx_tick,
            value               => counting_digits(i)
            overflow_out    => digits_overflow(i)
        );
    end generate upper_digits;
end generate gen_counter;

相关内容

最新更新