4
\$\begingroup\$

Lets say we want to create a generic t flip flop counter, the structure of this kind of counter is perfectly repetitive, and you can synthesize one with arbitrary length just using a for generate

however the bound for that for and the length of the output is internal to the file, a constant, is there a way to sort of passing an argument when creating a component so as to define the length of the counter when creating the component instead of in the file?

here is the code of the counter i made

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

entity counterTst is
port(
    enable: in      STD_LOGIC;
    clk:        in      STD_LOGIC;
    rst:        in      STD_LOGIC;
    output: out STD_LOGIC_VECTOR(3 downto 0)
    );
end counterTst;


architecture rtl of counterTst is

constant COUNTER_LEN:   integer := 4;

component t_ff  is
port(
    rst:    in      STD_LOGIC;
    clk:    in      STD_LOGIC;
    inp:    in      STD_LOGIC;
    t:      out STD_LOGIC
    );
end component t_ff;

signal  tin:    STD_LOGIC_VECTOR(COUNTER_LEN-2 downto 0);
signal  tout:   STD_LOGIC_VECTOR(COUNTER_LEN-1 downto 0);

begin

T_CHAIN_GEN:    for i in 0 to COUNTER_LEN-1 generate
    START_POS: if i = 0 generate
        FF0:    t_ff    port    map(rst, clk, enable, tout(0));
    end generate START_POS;

    POS_1:  if i = 1 generate
        tin(0) <= tout(0) and enable;
        FF1:    t_ff    port    map(rst, clk, tin(0), tout(1));
    end generate POS_2;

    POS_N:  if i > 1 generate
        tin(i-1) <= tout(i-1) and tin(i-2);
        FFX:    t_ff    port    map(rst, clk, tin(i-1), tout(i));
    end generate POS_N;
end generate T_CHAIN_GEN;

output <= tout;

end rtl;
\$\endgroup\$
  • \$\begingroup\$ Either add a generic above your ports or put the constant into a package. \$\endgroup\$ – TonyM Jul 7 '19 at 7:12
  • \$\begingroup\$ Relevant (old) Code Review answer \$\endgroup\$ – Mast Jul 7 '19 at 18:41
  • \$\begingroup\$ Generic with default values. Then in the component instantiation part(in other modules), initialise it with the desired value. \$\endgroup\$ – Meenie Leis Jul 8 '19 at 6:32
6
\$\begingroup\$

Yes, it is called a 'generic':

I could show an example here, but there are plenty of example on the WWW once you know what to look for: https://www.nandland.com/vhdl/examples/example-generic.html

\$\endgroup\$
9
\$\begingroup\$

Add a generic clause to your entity. It allows you to pass in e.g. constants:

entity counterTst is
  generic (
    constant COUNTER_LEN : integer -- := 4
  );
  port (
    enable: in  STD_LOGIC;
    clk:    in  STD_LOGIC;
    rst:    in  STD_LOGIC;
    output: out STD_LOGIC_VECTOR(COUNTER_LEN - 1 downto 0)
  );
end counterTst;


architecture rtl of counterTst is

  -- constant COUNTER_LEN:   integer := 4;

Moreover generic values can be used in you port clause to size ports. A generic can have a default value, thus the user doesn't need to apply it in a generic map. In you case, you shouldn't apply a default value to force the user to think about his choice :).

And here is the usage:

cnt : entity work.counterTst
  generic map (
    COUNTER_LEN => 4
  )
  port map (
    -- ...
  );

Like in a port map, you map generics in a generic map.

\$\endgroup\$
5
\$\begingroup\$

Since VHDL 2008, you can also make output an unconstrained port and then infer the counter length from that port, as given during instantiation:

entity counterTst is
    port(
        enable: in  std_logic;
        clk:    in  std_logic;
        rst:    in  std_logic;
        output: out std_logic_vector
    );
end entity;

architecture rtl of counterTst is
    constant counter_len: natural := output'length;

    -- ...
end architecture;

Just one thing to be careful about: The instantiation will define the full range of output, so it might be an std_logic_vector(counter_len downto 1) or even a dreaded to range. Since you assign output from a local signal, this is not an issue, but it could be problematic if you try to index output directly.

\$\endgroup\$
  • \$\begingroup\$ Quite nifty. Another thing to be careful about (almost a meme at this point) is that VHDL 2008 support can still(!) be rather flaky, with different synthesis/simulation tools supporting a different subset of the standard, if any at all. \$\endgroup\$ – Richard the Spacecat Jul 7 '19 at 23:48
  • \$\begingroup\$ It's e.g. supported by Vivado 2018.3. \$\endgroup\$ – Paebbels Jul 8 '19 at 10:58

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.