Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing Generics to Record Port Types

Tags:

vhdl

I did recently start to use records for my port definitions, especially if I want to group signals that belong to a certain interface. However, the problem I'm facing here is that I cannot pass, say the width of a std_logic_vector, to the entity by means of a generic. So what I basically want to do is the following:

library ieee;
use ieee.std_logic_1164.all;
use work.math_pkg.all;

package fifo_pkg is

  type fifo_in_type is record
    data_in : std_logic_vector(DATA_WIDTH_??- 1 downto 0);
    rd      : std_logic;
    wr      : std_logic;
  end record;

  type fifo_out_type is record
    data_out : std_logic_vector(DATA_WIDTH_?? - 1 downto 0);
    empty    : std_logic;
    full     : std_logic;
  end record;

  component fifo is
    generic
      (
        MIN_DEPTH  : integer;
        DATA_WIDTH : integer
        );
    port
      (
        clk   : in  std_logic;
        res_n : in  std_logic;
        i     : in  fifo_in_type;
        o     : out fifo_out_type
        );
  end component fifo;

end fifo_pkg;   

So the ideal solutions would be when i can use the same generic in my record as i did in the entity. (So that DATA_WIDTH is the same as DATA_WIDTH_??). I know that this should work somehow with vhdl 2008, however my quartus II 11sp1 does not support generics in records.

Is there an elegant way to achieve that kind of "generic passing" that is synthesizable? I know that one could just store a constant in the package, but then I cannot use the same fifo package to instantiate several fifo's with different widths.

Thanks a million, T

like image 780
tjr Avatar asked Oct 28 '11 05:10

tjr


1 Answers

Can you use type generics with Quartus?

Then you leave the type completely unspecified, so that you can create a FIFO of integers or any other data type:

package fifo_pkg is
  generic (type element_type);

  type fifo_in_type is record
    data_in : element_type;
    rd      : std_logic;
    wr      : std_logic;
  end record;

  type fifo_out_type is record
    data_out : element_type;
    empty    : std_logic;
    full     : std_logic;
  end record;

  component fifo is
    generic
      (
        MIN_DEPTH  : integer;
        DATA_WIDTH : integer
        );
    port
      (
        clk   : in  std_logic;
        res_n : in  std_logic;
        i     : in  fifo_in_type;
        o     : out fifo_out_type
        );
  end component fifo;

end fifo_pkg;

Then when you want to use it:

package wide_fifo_pkg is new fifo_pkg
   generic map (type => std_logic_vector(31 downto 0));

and then you can use fifo_in_type and fifo_out_type:

signal i : fifo_in_type;

If you have more than one FIFO in a design unit you can create several versions of the package and use the package prefix to get the right type:

package narrow_fifo_pkg is new fifo_pkg
   generic map (type => std_logic_vector(3 downto 0));

signal i32 : wide_fifo_pkg.fifo_in_type;
signal i4  : narrow_fifo_pkg.fifo_in_type;

Another VHDL 2008 option: you can have an unconstrained record type:

 type fifo_in_type is record
    data_in : std_logic_vector;
    rd      : std_logic;
    wr      : std_logic;
  end record;

which you can then create subtypes of for your various uses:

subtype fifo1_data_type is fifo_in_type(data_in(31 downto 0));
subtype fifo2_data_type is fifo_in_type(data_in(15 downto 0));

No idea if Quartus supports either of those options - please let us know!

like image 149
Martin Thompson Avatar answered Nov 03 '22 02:11

Martin Thompson