1
library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; entity shift_reg is port( d : in std_logic; clk : in std_logic; rst_bar : in std_logic; q : out std_logic_vector(7 downto 0) ); end shift_reg; architecture post_vhdl_08 of shift_reg is begin process(clk, rst_bar) variable q_int : std_logic_vector(7 downto 0); begin if rst_bar = '0' then q_int := (others => '0'); elsif rising_edge(clk) then q_int := q_int(6 downto 0) & d; end if; q <= q_int; end process; end post_vhdl_08; 

I've implemented a shift left register with serial input and parallel output using a "slice" to implement the shift; but I can't figure out how to implement the same logic using an overloaded shift operator: 'sll' (shift left logical) operator. Thank you all for any help you can offer.

2
  • Possible duplicate of shift a std_logic_vector of n bit to right or left Commented Apr 13, 2016 at 3:13
  • I'm specifically asking how I would implement the above code using sll shift operator. I don't really know how to use the operator so I need an example... the other post doesn't really help me understand how to use it Commented Apr 13, 2016 at 4:38

2 Answers 2

1

Here is how to use the sll operator for you example. As you can see, it's a pain, because it doesn't do what you want and there's other mucking around to do:

process(clk, rst_bar) variable q_int : unsigned(7 downto 0); subtype st is unsigned(7 downto 0); begin if rst_bar = '0' then q_int := (others => '0'); elsif rising_edge(clk) then q_int := q_int sll 1; q_int := q_int or st'(0=>d,others=>'0'); q <= std_logic_vector(q_int); end if; end process; 

http://www.edaplayground.com/x/3YGu

So, for starters, sll shifts in a '0', which isn't want you want. So you then need an or operation to include the d input. But, sll is not overloaded for std_logic_vector, so you have to use either unsigned or signed (unsigned makes sense here). Not only that, these types of operators do strange things in VHDL. So, I would stick with concatenation if I were you.

Also, your assignment to q is in the wrong place. When you do a sequential process, you must not assign to a signal outside the if rising_edge because otherwise (in this case) q will be assigned on both clock edges - behaviour that is not synthesisable.

Finally, depending on the abilities of your synthesiser, you could get 16 flip-flops instead of 8. This is because your variable will synthesise to 8 flip-flops and your signal will synthesise to 8 more ("every signal assigned in a clocked process infers a flip-flop"). You are then replying on your synthesiser to optimise 8 of these flip-flops away.

Sign up to request clarification or add additional context in comments.

2 Comments

ror, rol, sll, and srl are not so strange, they were not implemented since sla and sra are strange in the VHDL-93 language definition. VHDL-2008 implemented these for std_logic_vector, unsigned and signed. Since sra and sla are "arithmetic" they are only implemented when the package supports arithmetic - hence for std_logic_vector, you will need numeric_std_unsigned. For bit_vector sra and sla are implicitly defined, so if you want the numeric_std sense (MSB on left) of sla and sra, be sure to use numeric_bit_unsigned which overloads them.
OTOH, as Matthew also recommends, just use concatenation - particularly for this problem.
0

I can offer you this method to shift left/right or using rotate (VHDL '87!) ..

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity Barrelshifter is generic (gSize : natural := 3); port ( iPortA : in std_ulogic_vector(2**gSize-1 downto 0); oPortQ : out std_ulogic_vector(2**gSize-1 downto 0); iShiftDigits : in std_ulogic_vector(gSize-1 downto 0); iModeSelect : in std_ulogic_vector(1 downto 0) ); end Barrelshifter; architecture Rtl of Barrelshifter is begin -- architecture Rtl Comb: process (iPortA, iShiftDigits, iModeSelect) -- component variables variable Count : integer; begin -- process Comb Count := to_integer(unsigned(iShiftDigits)); if iModeSelect = "00" then oPortQ <= std_ulogic_vector(shift_left(unsigned(iPortA), Count)); elsif iModeSelect = "01" then oPortQ <= std_ulogic_vector(shift_right(unsigned(iPortA), Count)); elsif iModeSelect = "10" then oPortQ <= std_ulogic_vector(rotate_left(unsigned(iPortA), Count)); else oPortQ <= std_ulogic_vector(rotate_right(unsigned(iPortA), Count)); end if; end process Comb; end Rtl ; 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.