Hog flavour

Hog’s flavour allows the same top entity to be used in multiple projects. To differentiate the projects, an integer parameter/generic called FALVOUR is provided to the top module.

What is Hog’s flavour?

We have said that in a Hog-handled repository, the name of the top entity of is top_<project name> for each project. Well, this is not true if the project name has an extension.

So, if the project name is of the form <name>.<ext> and the <ext> is an integer non-negative number (e.g. project.1):

  • The top entity name is top_<name>

  • The extension is passed as a parameter/generic called FLAVOUR to the design.

Let’s say, for example, that we have a project called project.1 in our repository Repo. This means, that the project’s Top directory is Repo/Top/project.1 and the project tcl file is Repo/Top/project.1/project.1.tcl.

In this case the name of the top entity of the project will be called project and the number will be passed to the design in the FLAVOUR parameter/generic.

Possible use cases

This feature can be used to handle multiple FPGAs on the same board.

Different logic can be instantiated using, in VHDL, an if ... generate statement on the FLAVOUR value.

For example:

  U2 : if FLAVOUR = 1 or FLAVOUR = 2 generate
    signal1 <= signal2;

    Module1 : entity lib1.module1
      port map (
        CLK => clk,

        IN_Data => data_merge,
        IN_Sync => sorted_eg_Start,

        --IPBus connection
        ipb_clk   => ipb_clk,
        ipb_rst   => rst_ipb,
        ipb_in    => ipbw(N_SLV),
        ipb_out   => ipbr(N_SLV),
        Sync  => sync,
        Valid => valid,
        Data_out   => data
        );
  end generate U1;

Moreover, subprograms can be used to achieve even more refined results on the basis of the flavour value. For example, you could have different MGTs enabled in different FPGAs and switch them on or off depending on the flavour.

So you could define a std_logic_vector with a function:

  function F_MGT_QUAD_ENABLE (FLAVOUR : in integer) return std_logic_vector is
    variable V_MGT_QUAD_ENABLE : std_logic_vector(19 downto 0);
  begin
    if FLAVOUR = 1 then
      V_MGT_QUAD_ENABLE := "00001111111111111111";
    elsif FLAVOUR = 2 then
      V_MGT_QUAD_ENABLE := "11101100011111111111";
    elsif FLAVOUR = 3 then
      V_MGT_QUAD_ENABLE := "11111011111111100011";
    elsif FLAVOUR = 4 then
      V_MGT_QUAD_ENABLE := "11110111111111100011";
    else
      V_MGT_QUAD_ENABLE := x"00000";
    end if;
    return V_MGT_QUAD_ENABLE;
  end function F_MGT_QUAD_ENABLE;

And then use the string in a for loop to enable/disable an entity:

  QUAD_ENABLE <= F_MGT_QUAD_ENABLE(FLAVOUR);

  MGT_GEN : for i in 0 to num_quad_tx_rx-1
    generate
      mgt_1quad_Rx_Tx : entity work.mgt_selection_wrapper
        generic map (ENABLED       => QUAD_ENABLE(i))
        port map (
        ...
        );
    end generate MGT_GEN;

Flavours can be used to minimise code repetition, even in the case that the devices have different pinout. In fact, being the project decoupled, different list files are used so constraints can be completely different.

On the other hand, if the different flavoured project share many source files (even all of them), recursive Hog list files can be exploited.

In fact, a list file can include another list file, so both projects could include the same list file stored everywhere in the repository. Alternatively, a common list file can be used containing the source files that are shared among the different projects, while files belonging to one specific project are listed elsewhere.

Thanks to Hog flavour, with a little bit of extra work, you can reduce the repetition of your code virtually to zero.