Search code examples
concatenationvhdl

VHDL array concatenation of varying types


I am doing some undergraduate research that involved some VHDL coding, something i have virtually no experience with. I am running into some issues and hoping for some help:

I need to read in a signal (array of "std_logic_vectors"), and perform a logical shift on it. My thought was to concatenate an array of 0's with an array that contains the relevant portion of the input. Here is what i've done:

Library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.SignalGen.all;

entity Shifter is
  Port ( xsig_in : in SignalGen;
         shift : in  integer;
         clk : in STD_LOGIC;
         x_out1 : out  SignalGen;
         x_out2 : out SignalGen);
end Shifter;

architecture Behavioral of Shifter is
type x_in_type is array (0 to (1024-shift) of std_logic_vector;
type zeroes_type is array(0 to shift) of std_logic_vector;
signal x_shifted: SignalGen;
signal x_in : x_in_type := xsig_in(1024 downto shift); -- This is line 37
signal zeroes : zeroes_type := (others => (others => '0')); 

begin

process(clk)
begin

   x_shifted <= zeroes & x_in; -- This is line 49

end process;

end Behavioral;

Its important to know what type SignalGen is, so here is my declaraion:

type SignalGen is array (0 to 1024) of STD_LOGIC_VECTOR(15 downto 0);

So as you can see, I've created a type "zeroes_type", which is the length of the desired shift. It is used to generate a signal "zeroes" filled with zeroes. Also x_in is of type x_in_type, which is the length of the input signal minus the shift amount, and is initialized to be the signal minus the values shifted out.

When i try to concatenate them together, I get these errors:

Line 37: Indexed name is not a x_in_type

Line 49: found '0' definitions of operator "&", cannot determine exact     overloaded matching definition for "&"

The line numbers are included in comments in the code posting. I've been tinkering with this segment for hours now and nothing i've tried to do can fix it.

If anyone can shed some light on the matter, or give me a better way to do what I am trying to do, I would be extremely appreciative! Thanks!


Solution

  • I think you were a long way from where you needed to be. This will not be an efficient implementation in terms of area: you will have 16,000+ flip-flops. However, this solution ought to be closer to where you need to be:

    Library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use work.SignalGen.ALL;  
    
    entity Shifter is
      Port ( xsig_in : in SignalGen;
             shift   : in  integer;
             clk     : in STD_LOGIC;
             x_out1  : out SignalGen;
             x_out2  : out SignalGen);
    end Shifter;
    
    architecture Behavioral of Shifter is
    begin
    
    process(clk)
      variable V : SignalGen;
    begin
      if rising_edge(clk) then
        V := xsig_in;
        for I in 1 to xsig_in'RIGHT loop
          if I <= shift then
            V := "0000000000000000" & V(0 to xsig_in'RIGHT-1); 
          end if;
        end loop;
        x_out1 <= V;
      end if;
    end process;
    
    end Behavioral;
    

    http://www.edaplayground.com/x/8AQ

    Variables, loops and concatenation are often useful when doing shifting as you can see in my example. You can jump out of the loop (using exit) when you're finished shifting, but my experience you might get slightly more logic doing that, ie:

        if I <= shift then
          V := "0000000000000000" & V(0 to xsig_in'RIGHT-1); 
        else
          exit;
        end if;
    

    There are many errors in your code. Whilst, I'm sure you will learn something from me just posting the answer, here are some explanations about the errors you are seeing:

    type x_in_type is array (0 to (1024-shift)) of std_logic_vector;
    

    You were missing a right hand parenthesis and this line relies on you using VHDL 2008, because the inner dimension is unconstrained. But even then, you cannot define a type based on a non-static quantity (shift), anyway.

    signal x_in : x_in_type := xsig_in(1024 downto shift);
    

    With you array constrained as it is, you need to skip over the outer dimension to constrain the inner one. In VHDL 2008 you can skip over a constrained dimension like this:

    signal x_in : x_in_type := xsig_in(open)(1024 downto shift);