How do I create multiple common FPGA structures in kristen?

0

I am trying to use Kristen to generate FPGA host verilog and a C++ source software to access the FPGA host. The problem is that I have a several chunks of common registers for controlling several neurotrophic processor instances (which are parametrizable) and I don't want to just make copies of the XML definition. Is there a way to make a section of the definition file replicate? Is there a way to feed it a parameter to make it replicate? So if I increase the NMP instance, I get more instances of the SW host?

Specifically, I want to replicate the nmp register per NMP instance. But I only want one copy of the version, DDR and core registers.

What I don't want to do is make 1000 copies of those lines and give them individual names.

<mmap>
<filename>debug.log</filename>
<global>
     <logo_filename>walker.png</logo_filename>
     <device_name>nmp_mst</device_name>
     <description>NMP master configuration</description>
     <data_path_width>32</data_path_width>
     <auto_ack>127</auto_ack>
     <memory_pack>zero_align</memory_pack>
     <register_pack>zero_align</register_pack>
     <generation_directory>../generated</generation_directory>
     <documentation_directory>../../docs</documentation_directory>
     <xreg_version>xreg_v1_0_0</xreg_version>
     <language>verilog</language>
</global>
<modules>
    <module name="host" offset="0x0">
        <register name="device_id"          type="rdconst" mask="0xFFFFFFFF" default="0x0C002A9D" description="Device ID for NMP controller."></register>
        <register name="version_id0"        type="rdconst" mask="0xFFFFFFFF" default="0x00000001" description="Version register for the top level design.">
            <field name="minor" offset="0b"  size="2B" description="Minor Version."></field>
            <field name="major" offset="16b" size="2B" description="Major Version."></field>
            </register>
        <register name="version_id1"  type="rdconst" mask="0xFFFFFFFF" default="0x00004455" description="Development build version and debug version">
            <field name="build" offset="0b"  size="2B" description="Debug Version."></field>
            <field name="debug" offset="16b" size="2B" description="Build Version."></field>
            </register>
        <register name="core_dp_ctrl"       type="rdwr" mask="0x00000003" default="0x00000000" description="Core control register - controls device datapath.">
            <field name="enable_pcie" offset="0b"  size="1b" description="Enable interface 0 == 1 : Disable interface 0 == 0"></field>
            <field name="enable_1" offset="1b"  size="1b" description="Enable interface 1 == 1 : Disable interface 1 == 0"></field>
        </register>
        <register name="core_ddr4_ctrl"      type="rdwr" mask="0x0000000F" default="0x00000000" description="DDR4 Memory control - control DDR4 memmory interface.">
            <field name="BIST_enable"       size="1b" description="Start BIST == 1 : Auto clears after BIST Begins" ></field>
            <field name="BIST_in_progress"  size="1b" description="BIST is currently in progress == 1 : Bist is idle == 0"></field>
            <field name="BIST_complete"     size="1b" description="BIST Test has complete == 1 : BIST_complete is cleared when BIST_enable is set or BIST_in_progress is set."></field>
            <field name="BIST_OK"           size="1b" description="BIST_OK is only valid when BIST_complete is set.  BIST Test has passed == 1 : Bist Test has failed == 0"></field>
        </register>
        <register name="nmp_start0"     type="rdconst" mask="0xFFFFFFFF" default="0x00000000" description="Lower 64 bit start pointer of persitant NMP storage."></register>
        <register name="nmp_start1"     type="rdconst" mask="0xFFFFFFFF" default="0x00000020" description="Upper 64 bit start pointer of persitant NMP storage."></register>
        <register name="nmp_size"       type="rdconst" mask="0xFFFFFFFF" default="0x10000000" description="Size of NMP persitant storage in Mbytes."></register>
        <register name="nmp_c_start0"       type="rdconst" mask="0xFFFFFFFF" default="0x10000000" description="Lower 64 bit start pointer of cached shared storage."></register>
        <register name="nmp_c_start1"       type="rdconst" mask="0xFFFFFFFF" default="0x00000020" description="Upper 64 bit start pointer of cached shared storage."></register>
        <register name="nmp_c_size"         type="rdconst" mask="0xFFFFFFFF" default="0x10000000" description="Size of cached shared storage in Mbytes."></register>
        <register name="nmp_row"        type="rdwr" mask="0xFFFFFFFF" default="0x00000000" description="Configurable row location for this NMP."></register>
        <register name="nmp_col"        type="rdwr" mask="0xFFFFFFFF" default="0x00000000" description="Configurable col location for this NMP."></register>
        <register name="nmp_threshold"  type="rdwr" mask="0xFFFFFFFF" default="0x00000000" description="Configurable synaptic sum threshold for this instance."></register>
         <memory name="nmp_learn"  memsize="0x00004000" type="mem_ack" description="Learning interface - Map input synapsys to node intensity">
            <field name="input_id"         size="22b" description="Input ID this map data is intended for."></field>
            <field name="scale"            size="16b" description="The intensity scale for this input ID."></field>
         </memory>
    </module>
</modules>

verilog
fpga
asked on Stack Overflow Apr 12, 2020 by Nolen White

1 Answer

1

So you probably need to break this up a little differently. Not totally knowing HOW you want this organized, I would suggest making two seperate modules. One of the modules is your single instance with your device and core stuff, and the second module is your nmp stuff and is replicated X number of times.
There is no way to feed a define or parameter to the XML to control the replication externally, but you can place a fixed number inside of the XML that will cause replication. There are some tradeoff's here. I think one way is more expensive than the other but you can try it out and see what happens.

I break it into two modules below and add a "duplicate" attribute. I think this will litterally create 1000 modules in verilog and will assign them names like nmp1, nmp2... nmp1000. I think this is very simple to do, but it will cost you lots of microprocessor interface logic.

<modules>
    <module name="host" offset="0x0">
        <register name="device_id"          type="rdconst" mask="0xFFFFFFFF" default="0x0C002A9D" description="Device ID for NMP controller."></register>
        <register name="version_id0"        type="rdconst" mask="0xFFFFFFFF" default="0x00000001" description="Version register for the top level design.">
            <field name="minor" offset="0b"  size="2B" description="Minor Version."></field>
            <field name="major" offset="16b" size="2B" description="Major Version."></field>
            </register>
        <register name="version_id1"  type="rdconst" mask="0xFFFFFFFF" default="0x00004455" description="Development build version and debug version">
            <field name="build" offset="0b"  size="2B" description="Debug Version."></field>
            <field name="debug" offset="16b" size="2B" description="Build Version."></field>
            </register>
        <register name="core_dp_ctrl"       type="rdwr" mask="0x00000003" default="0x00000000" description="Core control register - controls device datapath.">
            <field name="enable_pcie" offset="0b"  size="1b" description="Enable interface 0 == 1 : Disable interface 0 == 0"></field>
            <field name="enable_1" offset="1b"  size="1b" description="Enable interface 1 == 1 : Disable interface 1 == 0"></field>
        </register>
        <register name="core_ddr4_ctrl"      type="rdwr" mask="0x0000000F" default="0x00000000" description="DDR4 Memory control - control DDR4 memmory interface.">
            <field name="BIST_enable"       size="1b" description="Start BIST == 1 : Auto clears after BIST Begins" ></field>
            <field name="BIST_in_progress"  size="1b" description="BIST is currently in progress == 1 : Bist is idle == 0"></field>
            <field name="BIST_complete"     size="1b" description="BIST Test has complete == 1 : BIST_complete is cleared when BIST_enable is set or BIST_in_progress is set."></field>
            <field name="BIST_OK"           size="1b" description="BIST_OK is only valid when BIST_complete is set.  BIST Test has passed == 1 : Bist Test has failed == 0"></field>
        </register>
    </module>
    <module name= "nmp" duplicate="1000">
        <register name="start0"     type="rdconst" mask="0xFFFFFFFF" default="0x00000000" description="Lower 64 bit start pointer of persitant NMP storage."></register>
        <register name="start1"     type="rdconst" mask="0xFFFFFFFF" default="0x00000020" description="Upper 64 bit start pointer of persitant NMP storage."></register>
        <register name="size"       type="rdconst" mask="0xFFFFFFFF" default="0x10000000" description="Size of NMP persitant storage in Mbytes."></register>
        <register name="c_start0"       type="rdconst" mask="0xFFFFFFFF" default="0x10000000" description="Lower 64 bit start pointer of cached shared storage."></register>
        <register name="c_start1"       type="rdconst" mask="0xFFFFFFFF" default="0x00000020" description="Upper 64 bit start pointer of cached shared storage."></register>
        <register name="c_size"         type="rdconst" mask="0xFFFFFFFF" default="0x10000000" description="Size of cached shared storage in Mbytes."></register>
        <register name="row"        type="rdwr" mask="0xFFFFFFFF" default="0x00000000" description="Configurable row location for this NMP."></register>
        <register name="col"        type="rdwr" mask="0xFFFFFFFF" default="0x00000000" description="Configurable col location for this NMP."></register>
        <register name="threshold"  type="rdwr" mask="0xFFFFFFFF" default="0x00000000" description="Configurable synaptic sum threshold for this instance."></register>
         <memory name="learn"  memsize="0x00004000" type="mem_ack" description="Learning interface - Map input synapsys to node intensity">
            <field name="input_id"         size="22b" description="Input ID this map data is intended for."></field>
            <field name="scale"            size="16b" description="The intensity scale for this input ID."></field>
         </memory>
    </module>
</modules>

A little more complicated thing to do is to place the duplicate on each of the registers and memories themselves. I think this will save some resources, but it is still going to be a lot of logic for a 1000 instances.

<module name= "nmp" >
            <register duplicate="1000" name="start0"     type="rdconst" mask="0xFFFFFFFF" default="0x00000000" description="Lower 64 bit start pointer of persitant NMP storage."></register>
            <register duplicate="1000" name="start1"     type="rdconst" mask="0xFFFFFFFF" default="0x00000020" description="Upper 64 bit start pointer of persitant NMP storage."></register>
            <register duplicate="1000" name="size"       type="rdconst" mask="0xFFFFFFFF" default="0x10000000" description="Size of NMP persitant storage in Mbytes."></register>
            <register duplicate="1000" name="c_start0"       type="rdconst" mask="0xFFFFFFFF" default="0x10000000" description="Lower 64 bit start pointer of cached shared storage."></register>
            <register duplicate="1000" name="c_start1"       type="rdconst" mask="0xFFFFFFFF" default="0x00000020" description="Upper 64 bit start pointer of cached shared storage."></register>
            <register duplicate="1000" name="c_size"         type="rdconst" mask="0xFFFFFFFF" default="0x10000000" description="Size of cached shared storage in Mbytes."></register>
            <register duplicate="1000" name="row"        type="rdwr" mask="0xFFFFFFFF" default="0x00000000" description="Configurable row location for this NMP."></register>
            <register duplicate="1000" name="col"        type="rdwr" mask="0xFFFFFFFF" default="0x00000000" description="Configurable col location for this NMP."></register>
            <register duplicate="1000" name="threshold"  type="rdwr" mask="0xFFFFFFFF" default="0x00000000" description="Configurable synaptic sum threshold for this instance."></register>
             <memory duplicate="1000" name="learn"  memsize="0x00004000" type="mem_ack" description="Learning interface - Map input synapsys to node intensity">
                <field name="input_id"         size="22b" description="Input ID this map data is intended for."></field>
                <field name="scale"            size="16b" description="The intensity scale for this input ID."></field>
             </memory>
        </module>
answered on Stack Overflow Apr 12, 2020 by Rich Maes

User contributions licensed under CC BY-SA 3.0