1

I am searching for a macro, constant or attribute, whatever it is, replaces "(x downto y)". To explain in detail for example complex numbers,

there is a generic value WIDTH,

signal num : std_logic_vector(2*WIDTH downto 0);

**pseudo** re = 2*WIDTH-1 downto WIDTH; im = WIDTH-1 downto 0; **pseudo**

x <= num(re); y <= num(im); etc

also it could be some attribute like range. eg

x <= num(num're); y <= num(num'im);

I use it a lot and it should be great for better readability and writing clean code

ytukel
  • 53
  • 6

2 Answers2

3

A subtype can be used to declare an integer range like:

-- **pseudo** re = 2*WIDTH-1 downto WIDTH; im = WIDTH-1 downto 0; **pseudo**
subtype re is natural range 2*WIDTH-1 downto WIDTH;
subtype im is natural range   WIDTH-1 downto 0;

Then it is possible to do:

x <= num(re);
y <= num(im);

With x and y declared as std_logic_vector(WIDTH-1 downto 0), or std_logic_vector(re) and std_logic_vector(im).

Btw. num should probably have highest index as 2*WIDTH-1, and not 2*WIDTH (off-by-one error).

Morten Zilmer
  • 15,586
  • 3
  • 30
  • 49
2

Maybe not exactly what you had in mind, but a VHDL record would seem to be a good fit for what you are trying to do.

You define your record type:

type mycomplex_t is record
    re : std_logic_vector(WIDTH-1 downto 0);
    im : std_logic_vector(WIDTH-1 downto 0);
end record;

Then, you declare your signal to be of this type:

signal num : mycomplex_t;

And you use it as such:

x <= num.re;
y <= num.im;

You can also assign it like this :

num <= (re => x2, im => y2);

Or, like this:

num.re  <= x2;
num.im  <= y2;

Or all at once from another signal of the same type:

signal other_complex : mycomplex_t;
-- (...)
num <= other_complex;
Philippe Aubertin
  • 1,031
  • 1
  • 9
  • 22
  • yes, I had been using it. But when you use block ram a lot, assignments gets longer. I mean, `ram_data <= num.re & num.im; num.re <= ram_data(2*W-1 downto W); num.im <= ram_data(W-1 downto 0);` or `num <= (ram_data(2*W-1 downto W),ram_data(W-1 downto 0));` or am I wrong? Is there a simple way to do that. Also I have added it in a package, but I couldn't make it generic. So I think it can cause trouble if I use it in port maps – ytukel Dec 31 '14 at 11:32
  • @ytukel You can create a `function` for each conversion in your package. Then, the assignments become `ram_data <= to_std_logic_vector(num)` and `num <= to_mycomplex(ram_data);`, which greatly improve readability. – Philippe Aubertin Dec 31 '14 at 15:25
  • @ytukel In port maps, your options are 1) have distinct ports for the `re` and `im` parts, then map `re => num.re, im => num.im`, 2) map your port by slices `someport(W-1 downto 0) => num.re, someport(2*W-1 downto W) => num.im` 3) create an intermediate std_logic_vector signal (with your conversion function) and map this, or 4) make the port itself a mycomplex_t. – Philippe Aubertin Dec 31 '14 at 15:26
  • @ytukel As for making it generic, that's a little tricky in VHDL, what you have to do is to make the package itself generic (a VHDL-2008 feature). There is a relevant answer her on Stack Overflow: [Generic Records (attempted via vhdl 2008 generic package)](http://stackoverflow.com/questions/16056291/generic-records-attempted-via-vhdl-2008-generic-package). – Philippe Aubertin Dec 31 '14 at 15:26