Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VHDL arithmetic shift_left

Tags:

vhdl

With the shift_left function of ieee.numeric_std, I want to shift a signal to left and insert 1 or 0 from the right.

signal qo: signed (3 downto 0) := (others=>'0');
qo <= shift_left(qo,1);

That will only insert 0 from right. I want to insert 1 upon some conditions.

like image 753
mahmood Avatar asked Oct 10 '17 12:10

mahmood


People also ask

What is the difference between logical and arithmetic shift?

Logical shift treats the number as a bunch of bits, and shifts in zeros. This is the >> operator in C. Arithmetic shift treats the number as a signed integer (in 2s complement), and "retains" the topmost bit, shifting in zeros if the topmost bit was 0, and ones if it was one.

What does shift right arithmetic do?

A Right Arithmetic Shift of one position moves each bit to the right by one. The least significant bit is discarded and the vacant MSB is filled with the value of the previous (now shifted one position to the right) MSB.

What does /= mean in VHDL?

Operator: /= The inequality operator which can be used in an expression on any type except file types. The resulting type of an expression using this operator is Boolean (that is, True or False). The expression "A /= B" returns True only if A and B are not equal.


2 Answers

Instead of using the shift_left function, how about using slicing and concatenation:

qo <= qo(2 downto 0) & '1';

or

qo <= qo(2 downto 0) & '0';

Personally, I recommend using slicing and concatenation for shifts and rotates. There are issues with the operators (sra etc) and, as you can see, using slicing and concatenation gives you complete control.

like image 51
Matthew Taylor Avatar answered Oct 06 '22 00:10

Matthew Taylor


Inserting '1' at the rightmost position of a signal of type signed means incrementing its value by 1. Likewise, not inserting '1' means incrementing its value by 0.

This is best expressed by the + operator which is overloaded by the numeric_std package:

-- Id: A.8
function "+" (L: SIGNED; R: INTEGER) return SIGNED;
-- Result subtype: SIGNED(L'LENGTH-1 downto 0).
-- Result: Adds a SIGNED vector, L, to an INTEGER, R.

So simply use:

shift_left(qo, 1) + 1

respectively

shift_left(qo, 1) + 0

This works irrespective of how qo is defined, so if you later change the length of qo you don't need to adjust any slicing operations.

like image 42
mkrieger1 Avatar answered Oct 06 '22 00:10

mkrieger1