0
\$\begingroup\$

I'm writing a vhdl model and I'm stuck with a problem about port declaration. Let's say that I have an entity entityA that instantiates N entityB. Now, entityB has a port, out, with size M bits, and M can vary among all entities, so out is std_logic_vector(M-1 downto 0). These ports need to be propagated outsize entityB.

If all entityB components would have the same port size, say FIX_M, the solution would be to use a std_logic_vector(N*FIX_M-1 downto 0) in entityA. My problem is that the size M can vary. The first solution that comes to my mind is to use the same solution, using instead of M a MAX_M, but in that case a lot of pins would be left unused (and for input it is a problem, right?).

Do you have a better idea? Thank you in advance.

\$\endgroup\$
  • \$\begingroup\$ Are all instances of entityB created in a for generate loop? If so, I can write down a solution for you :). \$\endgroup\$ – Paebbels Jun 25 '17 at 7:20
  • \$\begingroup\$ @Paebbels yeah, exactly, but the generic passed to the entity is different for each one, so they have different port sizes \$\endgroup\$ – Alessandro Jun 25 '17 at 7:43
2
\$\begingroup\$

It uses an array of sizes to specify the individual sizes of EntityB. The port of EntityA has the size calculated by sum.

The matching bits are sliced by high and low.

global function:

function sum(SIZES) is
  variable count : integer := 0;
begin
  for i in SIZES'range loop
    count := count + SIZES(i);
  end loop;
  return count;
end function;

Example:

entity EntityA is
  genierc (
    SIZES : integer_vector
  );
  port (
    data(sum(SIZES) - 1 downto 0)
  );
end entity;

architecture rtl of EntityA is
  function high(SIZES, idx) is
  begin
    for i in 0 to idx loop
      pos := pos + SIZES(i);
    end loop;
    return pos - 1;
  end function;
  function low(SIZES, idx) is
  begin
    for i in 0 to idx - 1 loop
      pos := pos + SIZES(i);
    end loop;
    return pos;
  end function;
begin
  genB : for i in SIZES'range generate
    instB : entity work.EntityB
      generic map (
        N => SIZES(i)
      )
      port map (
        data => data(high(SIZES, i) downto low(SIZES, i))
      );
end architecture;

Usage:

signal input : std_logic_vector(13 downto 0);

ex : entity work.EntityA
  generic map (
    SIZES => (2, 3, 4, 5)
  );
  port map (
    data => input
  );
\$\endgroup\$
  • \$\begingroup\$ thank you for your complete explanation. But, let's say that I create all the entities EntityB with their ports data having the maximum possible size. Each entity will then drive and read only a subset of these bits, specified by the generic SIZES(i). Can I rely on the synthesis tool that it will not create more logic than needed? \$\endgroup\$ – Alessandro Jun 27 '17 at 22:22
  • \$\begingroup\$ If you have four instances with sizes 2, 3, 4 and 5 bits, then EntityA will have a port with 14 bit and each instance of EntityB will use its assigned bits. So 1 downto 0, 5 downto 2, 8 downto 6 and finally 13 downto 9. So every bit is use. No unconnected wires. \$\endgroup\$ – Paebbels Jun 28 '17 at 19:03
  • \$\begingroup\$ Note your global function sum has no initial value for integer variable count, where the default value would be integer'left (the most negative value for type integer). count should be initialized (to 0), otherwise most declarations (noting the example is misformed and uses direction downto) of data in EntityA would be null arrays (having no elements). \$\endgroup\$ – user8352 Jan 12 '18 at 23:49
  • \$\begingroup\$ @user8352 Good catch. I added an init value. \$\endgroup\$ – Paebbels Jan 13 '18 at 9:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.