以前double dabbleアルゴリズムでバイナリー→BCD変換函数を作ったが、今度はBCD→整数変換函数と一緒にパッケージにまとめておく。
slv_to_bcd()
函数で0b10011010010100 (0d9876)を0x9876 (0d39030)に変換し、それをbcd_to_int()
函数で元の0d9876に変換してみた。
VHDL_for_Quartus_Prime/my_conv_pkg_test at main · ti-nspire/VHDL_for_Quartus_Prime · GitHub
↓ これがパッケージ:
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use ieee.math_real.all; package my_conv_pkg is function slv_to_bcd(slv: std_logic_vector; num_bcd: natural) return std_logic_vector; function bcd_to_int(bcd: std_logic_vector) return natural; end package; package body my_conv_pkg is ------------------------------------------------------------------------ function slv_to_bcd(slv: std_logic_vector; num_bcd: natural) return std_logic_vector is -- 出力に必要なビット数。 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; ------------------------------------------------------------------------ ------------------------------------------------------------------------ function bcd_to_int(bcd: std_logic_vector) return natural is constant NUM_BCD: natural := bcd'length / 4; variable sum : natural := to_integer(unsigned(bcd(3 downto 0))); begin for i in 1 to NUM_BCD - 1 loop sum := sum + to_integer(unsigned(bcd(i*4+3 downto i*4))) * (10**i); end loop; return sum; 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.my_conv_pkg.all; entity my_conv_pkg_test is port( slv_in: std_logic_vector(13 downto 0); bcd_out: out std_logic_vector(15 downto 0); outp : out std_logic_vector(15 downto 0) ); end entity; architecture rtl of my_conv_pkg_test is signal bcd_out_temp: std_logic_vector(15 downto 0) := (others => '0'); signal int_out_temp: natural := 0; begin bcd_out_temp <= slv_to_bcd(slv_in, 4); bcd_out <= bcd_out_temp; int_out_temp <= bcd_to_int(bcd_out_temp); outp <= std_logic_vector(to_unsigned(int_out_temp, 16)); end architecture;
↓ これがテストベンチ:
-- Copyright (C) 2020 Intel Corporation. All rights reserved. -- Your use of Intel Corporation's design tools, logic functions -- and other software and tools, and any partner logic -- functions, and any output files from any of the foregoing -- (including device programming or simulation files), and any -- associated documentation or information are expressly subject -- to the terms and conditions of the Intel Program License -- Subscription Agreement, the Intel Quartus Prime License Agreement, -- the Intel FPGA IP License Agreement, or other applicable license -- agreement, including, without limitation, that your use is for -- the sole purpose of programming logic devices manufactured by -- Intel and sold by Intel or its authorized distributors. Please -- refer to the applicable agreement for further details, at -- https://fpgasoftware.intel.com/eula. -- *************************************************************************** -- This file contains a Vhdl test bench template that is freely editable to -- suit user's needs .Comments are provided in each section to help the user -- fill out necessary details. -- *************************************************************************** -- Generated on "10/02/2021 07:52:04" -- Vhdl Test Bench template for design : my_conv_pkg_test -- -- Simulation tool : ModelSim-Altera (VHDL) -- LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY my_conv_pkg_test_vhd_tst IS END my_conv_pkg_test_vhd_tst; ARCHITECTURE my_conv_pkg_test_arch OF my_conv_pkg_test_vhd_tst IS -- constants -- signals SIGNAL bcd_out : STD_LOGIC_VECTOR(15 DOWNTO 0); SIGNAL outp : STD_LOGIC_VECTOR(15 DOWNTO 0); SIGNAL slv_in : STD_LOGIC_VECTOR(13 DOWNTO 0); COMPONENT my_conv_pkg_test PORT ( bcd_out : OUT STD_LOGIC_VECTOR(15 DOWNTO 0); outp : OUT STD_LOGIC_VECTOR(15 DOWNTO 0); slv_in : IN STD_LOGIC_VECTOR(13 DOWNTO 0) ); END COMPONENT; BEGIN i1 : my_conv_pkg_test PORT MAP ( -- list connections between master ports and signals bcd_out => bcd_out, outp => outp, slv_in => slv_in ); process begin slv_in <= d"9876"; --b"10_0110_1001_0100" wait; end process; END my_conv_pkg_test_arch;