# VHDL integer to unsigned cast cost

The code snippet below shows a two-step variable manipulation:

1) Convert an integer to an unsigned number

2) Cast an unsigned number to a std_logic_vector and extract a certain number of uppermost bits.

Could these two steps be consolidated into a single one? That is, is this just typecasting (wire connections) or is some sort of clocked circuitry involved that could potentially result in a problem?

signal integrator_inter_uns :  unsigned(20 downto 0):= (others => '0');

...
...

counter : process(CLK)
begin
if clk'event and clk = '1' then

-- oveflow
if pwm_counter = N then
pwm_counter <= 0;

-- 1
elsif pwm_counter = 1 then
pwm_counter <= pwm_counter + 1;

integrator_inter_uns <= to_unsigned(integrator, integrator_inter_uns'length); -- 20 bit unsigned

-- 2
elsif pwm_counter = 2 then
pwm_counter <= pwm_counter + 1;

data <= std_logic_vector(integrator_inter_uns(15 downto 0));
-- 3
elsif pwm_counter = 3 then
pwm_counter <= pwm_counter + 1;

dac_input <= data;

else
pwm_counter  <= pwm_counter   + 1;

end if;

end if;
end process;

• This is not a minimal code example. If this is inside a standard process structure, the casts will be free, yes, but you're not always writing down to either integrator_inter_uns or data. Controlling the enables of your registers will cost circuitry. – DonFusili Aug 30 '18 at 13:44
• @DonFusili The only purpose of the integrator_inter_uns signal is to hold the value for the conversion steps. If both steps can be done at the same time, the signal does not need to exist. – SunnyBoyNY Aug 30 '18 at 15:07
• I understand that, both steps are just wires and can be done completely free, but the functionality will change if you do them together. It depends where this piece of code is found, until you provide a complete piece of code (I'd say at minimum your process), it's hard to judge. – DonFusili Aug 31 '18 at 6:29
• I see. The "data" signal is used at step 3. This whole exercise is to minimize the pipeline delay to get the data out from the FPGA as soon as possible. The question was edited. – SunnyBoyNY Aug 31 '18 at 14:32
• Is this asynchronous by intention? You're not doing anything on the rising clock edge... – po.pe Aug 31 '18 at 14:41

Yes, you can certainly perform two conversions in a single statement. They would synthesize to wires. BUT your code snippet has state-dependent behavior that would be lost if you combined the conversions. There's something going on with pwm_counter that you haven't told us about. If that state-dependent behavior is necessary then you will need a register to hold the intermediate value, integrator_inter_uns.

• Elliot - I have modified the question. The register is declared as a signal. – SunnyBoyNY Aug 29 '18 at 19:35

There's nothing wrong with

if rising_edge(clk) then
dac_input <= std_logic_vector(to_unsigned(integrator, integrator_inter_uns'length))(15 downto 0);
end if;


and implementing it won't "cost" anything, as long as you keep in mind that your data now arrives on the dac_input port two cycles earlier and that you will now see every change on the integrator signal/variable instead of every Nth change. (Or at least every value that was valid during your setup-hold time interval around each clk rising edge).

If you still only want every Nth clock cycle's value:

if rising_edge(clk) then
if pwm_counter = 1 then
dac_input <= std_logic_vector(to_unsigned(integrator, integrator_inter_uns'length))(15 downto 0);
end if;

if pwm_counter = N then
pwm_counter := 0;
else
pwm_counter := pwm_counter+1;
end if;
end if;

• Keep in mind that your process is not reset, so the = N could fail in simulation since the pwm_counter is not going to be initialized. – DonFusili Sep 4 '18 at 12:58