wzab/agwb

Better granularity of the version identifiers.

Closed this issue · 0 comments

wzab commented

In one of designs, where the AGWB is used (namely the firmware for CBM experiment), it was needed to provide version IDs for the individual blocks generated by AGWB. It seems relatively easy, but its implementation may be quite complex. The description below is a result of my discussion with Walter F. J. Müller (@wfjm). Thank's a lot for his remarks and suggestions.

The current implementation (that repeats the same version ID in all blocks) takes the whole XML description resulting from combining the main XML file with all included XML sub-descriptions.
Unfortunately it is not easy to split such description into the parts describing the individual blocks.

The first solution could be to take the XML sub-tree, describing the particular block and all its sub-block, convert it to certain standard string form, (e.g. using the write or tostring methods of the ElementTree module) and calculate its hash.
Such approach seems to be viable, but there are certain traps hidden:

  • The output format of the above functions may change, and the calculated hash function will be different, even though the description is still the same.
  • The description may contain expressions based on constants, defined in the main part of the XML. A solution could be to add definitions of constants to the output string. However, the hash will change even if a changed constant is not used in the particular block.

The better approach could be to use the checksum of the generated VHDL code (the WB interface module and the associated package). This code uses the evaluated expressions, so there is no problem with false dependency on unused constants.
Unfortunately, that approach has also certain disadvantages after the variants have been introduced.
The same VHDL code is generated for all variants, and the right variant is selected using the generics.

Therefore the block version should be generated basing on the representation that is produced from the block definition including the constant values and evaluated expressions. Currently the best choice seems to be the output of the AMAP XML target.

As separate AMAP XML maps are generated for each variant, it is possible to put a different version ID into each of them.
Because the hash values have to be put into the AMAP XML, they are computed for the hash value set to 0 (0x00000000).
After the hash is calculated, the value is replaced with the right one.
The first version is implemented in commit a2e7998 .

For systems that use variants, the additional g_ver_id generic is provided. By default it is set to the value corresponding to the "full" implementation. If the user implements variant nvar, he should set this generic to the corresponding value from the v_BLOCK_ver_id array, as shown in the example below:

  MAIN_1 : entity agwb.MAIN
    generic map(
      g_ver_id => v_MAIN_ver_id(nvar),
      g_LINKS_size => v_LINKS_size(nvar),
      g_EXTHUGE_size => v_EXTHUGE_size(nvar)
)
    port map (
      slave_i	     => wb_s_in,
      slave_o	     => wb_s_out,
      LINKS_wb_m_o   => LINKS_wb_m_o,
      LINKS_wb_m_i   => LINKS_wb_m_i,
      EXTHUGE_wb_m_o => EXTHUGE_wb_m_o,
      EXTHUGE_wb_m_i => EXTHUGE_wb_m_i,
      EXTERN_wb_m_o  => CDC_wb_m_o,
      EXTERN_wb_m_i  => CDC_wb_m_i,
      CTRL_o	     => CTRL_o,
      TEST_IN_i	     => TEST_IN_i,
      TEST_OUT_o     => TEST_OUT_o,
      rst_n_i	     => rst_n_i,
      clk_sys_i	     => clk_sys_i);

The hash of the combined XML is stored in the {TOP}_const_pkg.vhd as

constant C_{TOP}_system_ver : std_logic_vector(31 downto 0)

For the software the hash values of the block id, block version and system version are stored in the block node like in the example below:

<node id="MAIN" id_hash="0x89bd20d0" ver_hash="0xa3285016" system_hash="0xe70dc7
31" addr_bits="17">