Btc Sources
Btc Sources

Reputation: 2061

Unsigned multiplication creates a x2 sized array

I'm trying to create a Shift Register, by using multiplication (*2) to shift bits one position.

However, when I do it, ISE (Xilinx IDE) says me that this expression has x2 the number of elements the original signal has.

To be specific, I've:

if rising_edge(clk) then

  registro <= unsigned(sequence);

  registro <= registro * 2;

  -- Just adds into the last position the new bit, Sin (signal input)
  registro <= registro or (Sin, others => '0');

  sequence <= std_logic_vector(registro);

end if;

And before, I've declared:

signal Sin : std_logic;

signal sequence : std_logic_vector(0 to 14) := "100101010000000";
signal registro : unsigned (0 to 14);

So I'm getting the error (at multiplication line):

Expression has 30 elements ; expected 15

So, why does it creates a x2 sized vector, if I've only multiplied *2?

What am I missing? How can I accomplish it?

Thank you in advance

Upvotes: 1

Views: 612

Answers (1)

user1818839
user1818839

Reputation:

Word width grows because you have used multiplication.

Multiplying 2 16-bit unsigned numbers gives you a 32 bit unsigned, in general.

Now it would be possible to optimise your specific case of multiplication by a constant, 2, and have synthesis do the correct thing. In which case the error message would change to

Expression has 16 elements ; expected 15

but why should the synthesis tool bother?

Use a left shift instead, either using a left (right?) shift operator, or explicit slicing and concatenation, for example:

registro <= registro(1 to registro'length-1) & '0';

Incidentally:

  • Using ascending bit order range is quite unconventional for arithmetic : all I can say is good luck with that...
  • you have three assignments to the same signal within the same process; only the last one will take effect. (See Is process in VHDL reentrant? for some information on the semantics of signal assignment)
  • If you declared "sequence" as unsigned in the first place you'd save a lot of unnecessary conversions and the code inside the process would reduce to a single statement, something like

sequence <= ('0' & sequence(0 to sequence'length-2)) or (0 => Sin, others => '0') when rising_edge(clk);

I am utterly unfamiliar with "wrong way round" arithmetic so I cannot vouch that the shifts actually do what you want.

Upvotes: 3

Related Questions