wzab / agwb

Support for automatic address map generation and address decoding logic for Wishbone connected hierachical systems
12 stars 6 forks source link

Better granularity of the version identifiers. #47

Closed wzab closed 3 years ago

wzab commented 3 years ago

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 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 a2e79983fd36e9a587311f69314bd7bd29f68211 .

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">