title: Structure of VHDL code for barrel shifter with behavior architecture
body: <p>I am trying to build a 16 bit barrel shifter with left and right shift capabilities. I am having some issues with how to structure the code so that it will do what I think I want to do. </p>
  
  <p>I have an opcode input that decides on the direction, an input vector to be shifted, an output vector, and a position vector with 4 bits. </p>
  
  <p>I am using the position vector to set a shift 'level' in a way. I want to check position(0) and if it is set to 1, shift one position. And then check position(1) and shift 2 positions, position(3) 4 positions, and position(3) 8 positions. </p>
  
  <p>I think that if I run through every position in the position vector and sequentially shift the bits it should eventually get all options. I will add the other opcode when this direction works properly.</p>
  
  <p>I am stuck on the assigning the intermediate vectors for the architecture. I am not sure what the proper method should be and I can not find anything in google. Perhaps a Case system would work better. </p>
  
  <pre><code>entity eds_shifter is
  port ( a : in bit_vector(15 downto 0) ; --input
      pos : in bit_vector(3 downto 0); -- position
      opc : in bit_vector(3 downto 0); -- opcode
      y : out bit_vector(15 downto 0) --output
      );
  end entity eds_shifter ;
  
  architecture behavior of eds_shifter is
  begin
  process(a,pos,opc) -- input vectors 
  signal s1,s2,s3,s4 : bit_vector(15 downto 0); -- intermediate steps
  begin
     s1 &lt;= a(14 downto 0) &amp; '0' when pos(0) = '1' and opc = "0000" else -- shifting left by one
     s1 &lt;= a when pos(0) = '0' and opc = "0000" else -- carryover vector to next shift position
     s2 &lt;= s1(13 downto 0) &amp; '0' when pos(1) = '1' and opc = "0000" else -- shift previous vector by 2
     s2 &lt;= s1 when pos(1) = '0' and opc = "0000" else 
     s3 &lt;= s2(12 downto 0) &amp; '0' when pos(2) = '1' and opc = "0000" else -- shift another 4 places
     s3 &lt;= s2 when pos(2) = '0' and opc = "0000" else 
     s4 &lt;= s3(7 downto 0) &amp; '0' when pos(3) = '1' and opc = "0000" else -- shift another 8 places
     s4 &lt;= s3 when pos(3) = '0' and opc = "0000" else 
     y &lt;= s4 when opc = "0000";
  end process;
  end architecture behavior;
  </code></pre>
  
  <p>Error Message</p>
  
  <pre><code>** Error: */02/eds_shifter.vhd(14): Illegal sequential statement.
  ** Error: */02/eds_shifter.vhd(15): Type error resolving infix expression "&lt;=" as type std.standard.bit_vector.
  </code></pre>
  
  <p>EDIT</p>
  
  <p>Thank you for the detailed response. I understand that there are generic shift functions built in but I want to try to figure out how to implement it myself. </p>
  
  <p>Thanks for the tip about the bit_vector. From what I understand bit types are only ok to use when you are sure that the input is not multisourced. In this case it should probably be ok, but I will go ahead and keep it in mind for the future. </p>
  
  <p>I think the concept I want to try is sound. If you check each bit in position for a 1 and shift by the appropriate amount at the end the number of bits shifted will equal the value of the position vector. </p>
  
  <p>a = "1111 1111 1111 1111" and pos = "1010" so we need to shift by decimal 10 places. So we do the first iteration and it has no change, the second shifts by 2 bits, third iteration shifts by 0 bits, and the fourth shifts by 8 bits for a total of 10 bits shifted to get a="1111 1100 0000 0000". </p>
  
  <p>My issue is not with the specific shifting operation (perhaps it is wrong and if so will use a different method, right now I am simply curious about how to implement my idea), my issue is writing code that will update the vector and then check the next position in the position vector. I was looking at what you posted about the delta cycle and sensitivity list. VHDL can be confusing since you have to describe the real world in terms of operations rippling through a processor. And it requires a different thinking than with standard programming. </p>
  
  <p>I tried the below code but it only changes and shifts in my test bench once. I set up a test bench that runs through all combinations of positions but with the following code it only shifts at pos = 1000 and then it shifts 8 places. Is there any of forcing the code to check at each if statement, not only the last one? </p>
  
  <pre><code>entity eds_shifter is
  port ( a : in bit_vector(15 downto 0) ; --input
      pos : in bit_vector(3 downto 0); -- position
      opc : in bit_vector(3 downto 0); -- opcode
      y : out bit_vector(15 downto 0) --output
      );
  end entity eds_shifter ;
  
  architecture behavior of eds_shifter is
  begin
  process(a,pos,opc) -- input vectors 
  begin
     if  pos(0) = '1' and opc = "0000" then  -- shifting left by one
        y &lt;= a(14 downto 0) &amp; "0";
     else
        y &lt;= a;
     end if;
     if  pos(1) = '1' and opc = "0000" then  -- shifting left by two
        y &lt;= a(13 downto 0) &amp; "00";
     else
        y &lt;= a;
     end if; 
     if  pos(2) = '1' and opc = "0000" then  -- shifting left by four
        y &lt;= a(11 downto 0) &amp; "0000";
     else
        y &lt;= a;
     end if;
     if  pos(3) = '1' and opc = "0000" then  -- shifting left by eight
        y &lt;= a(7 downto 0) &amp; "00000000";
     else
        y &lt;= a;
     end if;
  end process;
  </code></pre>
  
  <p>end architecture behavior;</p>
  
  <p>Test Bench</p>
  
  <pre><code>entity eds_shifter_tb is 
  end eds_shifter_tb;
  
  architecture behavior of eds_shifter_tb is
      signal opc: bit_vector(3 downto 0);
      signal pos: bit_vector(3 downto 0);
      signal Y : bit_vector (15 downto 0);
      signal a: bit_vector (15 downto 0);
  
  begin 
      dut: entity work.eds_shifter(behavior)
      port map(opc =&gt; opc,
              pos =&gt; pos,
              Y =&gt; Y,
              a =&gt; a); -- assigns all ports to entity spec
  
     a &lt;= (others =&gt; '1'),
           (others =&gt; '1') after 30 ns;                   
     opc &lt;= "0000",
            "0001" after 30 ns;
     pos &lt;= "0000",
          "0001" after 2 ns,
          "0010" after 4 ns,
          "0011" after 6 ns,
          "0100" after 8 ns,
          "0101" after 10 ns,
          "0110" after 12 ns,
          "0111" after 14 ns,
          "1000" after 16 ns,
          "1001" after 18 ns,
          "1010" after 20 ns,
          "1011" after 22 ns,
          "1100" after 24 ns,
          "1101" after 26 ns,
          "1110" after 28 ns,
          "1111" after 30 ns,
          "0000" after 32 ns,
           "0001" after 34 ns,
           "0010" after 36 ns,
           "0011" after 38 ns,
           "0100" after 40 ns,
           "0101" after 42 ns,
           "0110" after 44 ns,
        "0111" after 46 ns,
        "1000" after 48 ns,
        "1001" after 50 ns,
        "1010" after 52 ns,
        "1011" after 54 ns,
        "1100" after 56 ns,
        "1101" after 58 ns,
        "1110" after 60 ns,
        "1111" after 62 ns;
  end behavior;
  </code></pre>