Because you specify i+1
for left shift and i-1
for right shift we can adduce that you're expressing the range as little endian (downto).
The size of the 'register' can assigned via a generic, used to match the port size and any internal array value size.
signal internalInputBus: std_logic_vector (REGSIZE-1 downto 0);
In your process statement, where shifting left
internalInputBus <= internalInputBus(REGSIZE-2 downto 0) & right_shift_input;
Using the concatenation operator on the right most REGSIZE-1 bits and shift input.
When shifting right
internalInputBus <= left_shift_input & internalInputBus(REGSIZE-1 downto 1);
I've seen people use a single shift input before, but have never found an application where it makes sense myself. Without internal tristate signals there is an implied multiplexer somewhere.
Loop statements are allowed sequential statements inside a process statement. I'd imagine you were having trouble with end boundaries. Seeking a solution would lead you to an analog of using concatenation operators.
The left and right boundaries of the two concatenation operator examples above would lead you to how to use a loop not traversing all of the elements along with an additional assignment operator to cover all the elements of the target array.
-- LEFT
for i in REGSIZE-2 downto 0 loop
internalInputBus(i+1) <= internalInputBus(i);
end loop;
internalInputBus(0) <= right_shift_input;
and
-- RIGHT
for i in REGIZE-1 downto 1 loop
internalInputBus(i-1) <= internalInputBus(i);
end loop;
internalInputBus(REGSIZE-1) <= left_shift_input;
These are simply done off the top of my head. Caveat Emptor.
Note that signal assignments without intervening waits (as in a loop statement) can read the current value of a value you've just scheduled for update. If you were using a variable target instead you'd want to reverse the order to prevent overwriting the next value being evaluated. (In this case in the -- RIGHT example, for i in 1 to REGIZE-1 loop
).