バイナリー→BCD変換函数を作る(範囲を一般化) / double dabbleアルゴリズム / VHDL

VHDL_for_Quartus_Prime/example_slv_to_bcd at main · ti-nspire/VHDL_for_Quartus_Prime · GitHub

バイナリー→BCD変換函数を作る / double dabbleアルゴリズム / VHDL -」のときはテキストどおりにunsigned 12ビット値(0d0000~0d4095)を4桁BCD値 (0x0000~0x4095)に変換する函数を作ったが、今度は範囲を一般化する。パッケージに記述した。

subprograms_pkg.vhd

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

package subprograms_pkg is
    function slv_to_bcd(
        slv: std_logic_vector
    ) return std_logic_vector;
end package;

package body subprograms_pkg is

    function slv_to_bcd(
        slv: std_logic_vector
    ) return std_logic_vector is

       -- 元の値の整数表現
        constant INT: natural := to_integer(unsigned(slv));
       -- BCD表現での桁数
        constant NUM_BCD: natural := natural(floor(log10(real(INT))+1.0));
       -- 出力に必要なビット数。
        constant NUM_OUT_BITS: natural := NUM_BCD*4;
       -- 出力値の假置き変数
        variable bcd: unsigned(NUM_OUT_BITS-1 downto 0) := (others => '0');
    begin
        for i in slv'length-1 downto 1 loop
            bcd := bcd(NUM_OUT_BITS-2 downto 0) & slv(i);
            for j in num_bcd downto 1 loop
                if bcd(j*4-1 downto j*4-4) > 4 then
                    bcd(j*4-1 downto j*4-4) := bcd(j*4-1 downto j*4-4) + 3;
                end if;
            end loop;
        end loop;
        bcd := bcd(NUM_OUT_BITS-2 downto 0) & slv(0);
        return std_logic_vector(bcd);
    end function;
    
end package body;

example_slv_to_bcd.vhd

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
use work.subprograms_pkg.all;

entity example_slv_to_bcd is
    generic(
        INT: positive := 98765432 -- この整数をBCDに変換してみる。
    );
    port(
        bcd_out: out std_logic_vector(positive(floor(log10(real(INT))+1.0))*4-1 downto 0)
    );
end entity;

architecture rtl of example_slv_to_bcd is
   -- 元の数の2進数表現でのビット数
    constant LEN_SLV: positive := positive(floor(log2(real(INT))+1.0));
   -- 元の数の2進数表現
    constant SLV: std_logic_vector(LEN_SLV-1 downto 0) := std_logic_vector(to_unsigned(INT, LEN_SLV));
begin
    bcd_out <= slv_to_bcd(SLV);
end architecture;

今0d98765432を0x98765432に変換している。左上から4ビット単位で、千万、百万、十万、万、左下から千、百、十、一の位。