バイナリー→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;
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ビット単位で、千万、百万、十万、万、左下から千、百、十、一の位。