1
\$\begingroup\$

I'm trying to connect between two components: my TOP_LEVEL component's outputs two my BIN2BCD component which converts binary to BCD. the problem is that the BIN2BCD uses std_logic_vector, and my TOP_LEVEL component uses (mainly) integers, and either of the component's types cant be changed. there is the code:

the problem is on the mapping block of BIN2BCD in the architecture. it gives me some errors that i dont know how to handle (im new to VHDL).

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity logic is
 generic(
 LOGIC_WAVE_SPEED_G : integer := 34300; -- in cm/sec
 LOGIC_CLK_FREQ_G : integer := 50000000; -- in 1/sec
 LOGIC_DELAY_TIME_BETWEEN_MEASURES_G : integer := 1000000
 );
 port(
 LOGIC_RST : in std_logic;
 LOGIC_SYS_CLK : in std_logic;
 LOGIC_START_MEASURE : in std_logic;
 LOGIC_DATA_IN : in integer;
 LOGIC_DATA_IN_VLD : in std_logic;
 LOGIC_SEND_TRIG : out std_logic;
 LOGIC_ONES : out integer range 9 downto 0;
 LOGIC_TENS : out integer range 9 downto 0;
 LOGIC_HUNDS : out integer range 9 downto 0
 );
end entity;
architecture behave of logic is
 constant pulses_per_distance_unit : integer := (1/LOGIC_WAVE_SPEED_G)*(2*LOGIC_CLK_FREQ_G);
 type state_machine is (waiting_to_start_measuring, send_pulse_to_sensor, convert_pulses_to_cm);
 component bin2bcd_12bit_sync is
 port(
 BIN2BCD_binIN : in STD_LOGIC_VECTOR (11 downto 0); -- this is the binary number
 BIN2BCD_CLK : in STD_LOGIC; -- clock input
 BIN2BCD_ONES : out STD_LOGIC_VECTOR (3 downto 0); -- this is the unity digit
 BIN2BCD_TENTHS : out STD_LOGIC_VECTOR (3 downto 0); -- this is the tens digit
 BIN2BCD_HUNDERDTHS : out STD_LOGIC_VECTOR (3 downto 0); -- this is the hundreds digit
 BIN2BCD_THOUSANDS : out STD_LOGIC_VECTOR (3 downto 0) -- 
 );
 end component;
 component derivative is
 port(
 DERIVATIVE_RST : in std_logic;
 DERIVATIVE_CLK : in std_logic;
 DERIVATIVE_D_IN : in std_logic;
 DERIVATIVE_STROBE : out std_logic
 );
 end component;
 component synchronizer
 port
 (
 SYNC_RST : in std_logic;
 SYNC_CLK : in std_logic;
 SYNC_D_IN : in std_logic;
 SYNC_D_OUT : out std_logic
 );
 end component;
 signal count_distance : integer range 350 downto 0 := 0;
 signal count_delay : integer range LOGIC_DELAY_TIME_BETWEEN_MEASURES_G downto 0;
 signal count_pulses_per_distance : integer := 0;
 signal ones, tens, hunds : integer range 9 downto 0 := 0;
 signal start_measure_sync : std_logic;
 signal start_measure_strobe : std_logic;
 signal data_in_vld_strobe : std_logic;
 signal present_state : state_machine := waiting_to_start_measuring;
begin
 bin_to_BCD_converter: bin2bcd_12bit_sync
 port map(
 BIN2BCD_binIN => std_logic_vector(to_unsigned(count_distance, BIN2BCD_binIN'length)),
 BIN2BCD_CLK => LOGIC_SYS_CLK, 
 to_integer(unsigned(BIN2BCD_ONES)) => LOGIC_ONES, 
 to_integer(unsigned(BIN2BCD_TENTHS)) => LOGIC_TENS, 
 to_integer(unsigned(BIN2BCD_HUNDERDTHS)) => LOGIC_HUNDS 
 ); 
 synch_start_measure_button: synchronizer
 port map(
 SYNC_RST => LOGIC_RST,
 SYNC_CLK => LOGIC_SYS_CLK, 
 SYNC_D_IN => LOGIC_START_MEASURE,
 SYNC_D_OUT => start_measure_sync
 );
 derivative_for_start_measure_button: derivative
 port map(
 DERIVATIVE_CLK => LOGIC_SYS_CLK,
 DERIVATIVE_RST => LOGIC_RST,
 DERIVATIVE_D_IN => start_measure_sync,
 DERIVATIVE_STROBE => start_measure_strobe
 );
main: 
 process(LOGIC_RST, LOGIC_SYS_CLK) -- NO OTHER SIGNALS IN SENSITIVITY LIST, ONLY CLK AND RESET
 begin
 if LOGIC_RST = '1' then
 present_state <= waiting_to_start_measuring;
 count_delay <= 0;
 count_distance <= 0;
 count_pulses_per_distance <= 0;
 elsif LOGIC_SYS_CLK'event and LOGIC_SYS_CLK = '1' then
 case present_state is
 when waiting_to_start_measuring => if start_measure_strobe = '1' then
 count_distance <= 0;
 count_pulses_per_distance <= 0;
 LOGIC_SEND_TRIG <= '1';
 present_state <= send_pulse_to_sensor;
 else
 present_state <= waiting_to_start_measuring;
 end if;
 when send_pulse_to_sensor => LOGIC_SEND_TRIG <= '0';
 if LOGIC_DATA_IN_VLD = '1' then
 present_state <= convert_pulses_to_cm;
 else
 present_state <= send_pulse_to_sensor;
 end if;
 when convert_pulses_to_cm => if count_pulses_per_distance < LOGIC_DATA_IN then
 count_pulses_per_distance <= count_pulses_per_distance + pulses_per_distance_unit;
 count_distance <= count_distance + 1;
 end if;
 if count_delay < LOGIC_DELAY_TIME_BETWEEN_MEASURES_G then
 count_delay <= count_delay + 1;
 else
 count_delay <= 0;
 present_state <= waiting_to_start_measuring;
 end if;
 end case;
 end if;
 end process;
end architecture;```
asked May 7, 2020 at 20:51
\$\endgroup\$
1
  • \$\begingroup\$ BIN2BCD_binIN isn't visible directly or by selection. See IEEE Std 1076-2008 12.2 Scope of declarations "The scope of a declaration, except for an architecture body, extends from the beginning of the declaration to the end of the immediately closing declarative region; ...", 12.1 Declarative region para 1 f) a component declaration is a separate declarative region. logic.bin2bcd_12bit_sync.BIN2BCD_binIN doesn't work here either, component names are excluded from prefixes of expanded names see 8.3 Selected names, para 8. \$\endgroup\$ Commented May 7, 2020 at 22:06

1 Answer 1

0
\$\begingroup\$

The problem appears to be in BIN2BCD_binIN'length)), where BIN2BCD_binIN is a port on the component you are trying to connect to, which is not an immediately visible object in the architecture body, so you cannot take its length.

As the length is no secret, being openly displayed in the component name bin2bcd_12bit_sync, this is a long-winded expression for 12 and could be replaced by the same.

I would use a named constant

constant bin2bcd_length : natural := 12;

and refer to it throughout the architecture (it is not exposed in the entity, which is good encapsulation) as follows:

BIN2BCD_binIN : in STD_LOGIC_VECTOR (bin2bcd_length - 1 downto 0); 
... 
port map (
 BIN2BCD_binIN => std_logic_vector(to_unsigned(count_distance, bin2bcd_length)),

Actually, that's not true.

When I see so many type conversions in close proximity, my nose wrinkles; this is a code smell. It makes me question if the component's ports are declared with the correct type in the first place.

Ranged integers are perfectly reasonable port types (even for synthesis) much of the time; so are signed/unsigned if you need to access bits. There's an argument for keeping std_logic_vector at the top level (FPGA pins) but even there, it had better be in your coding standard rules if you want me to agree to it.

Anyway, get the design right, and most of the conversion functions drop away leaving simple, clear code.

answered May 7, 2020 at 21:15
\$\endgroup\$
3
  • \$\begingroup\$ Your suggestion of adding the constant worked, but I have 2 questions: 1. How would u implement it if the length was hidden and not open? 2. I'm getting some more errors on the code (vcom-1022) which I dont understand to. "Error: logic.vhd(79): (vcom-1022) Formal part (type conversion (to ieee.NUMERIC_STD.UNSIGNED)) does not depict an interface object." \$\endgroup\$ Commented May 7, 2020 at 21:20
  • \$\begingroup\$ Anyway, get the design right, and most of the conversion functions drop away leaving simple, clear code. The problem is that the BIN2BCD component isnt mine, and to be honest I dont realy know how to create new one using only integers. (This component implements the double dabble algorithem) \$\endgroup\$ Commented May 7, 2020 at 21:27
  • \$\begingroup\$ 1) If it's hidden, you have bigger problems (not knowing how many output ports there are, for one). 2) You may need an intermediate signal of type UNSIGNED (or even std_logic_vector; some tools have trouble handling type conversions in port maps) instead of to_integer(unsigned(BIN2BCD_ONES)) => LOGIC_ONES, . Re: other people's components; yes, you sometimes have to live with that. \$\endgroup\$ Commented May 7, 2020 at 21:39

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.