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.

Wilmer Suarez
  • 41
  • 1
  • 6
  • Possible duplicate of [shift a std\_logic\_vector of n bit to right or left](http://stackoverflow.com/questions/9018087/shift-a-std-logic-vector-of-n-bit-to-right-or-left) – Sami Kuhmonen Apr 13 '16 at 03: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 – Wilmer Suarez Apr 13 '16 at 04:38

2 Answers2

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.

Matthew Taylor
  • 13,365
  • 3
  • 17
  • 44
  • 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. – Jim Lewis Dec 19 '17 at 17:31
  • OTOH, as Matthew also recommends, just use concatenation - particularly for this problem. – Jim Lewis Dec 19 '17 at 17:34
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 ;
michi.b
  • 264
  • 1
  • 4
  • 14