Our situation

1.  use Vivado 2017 for whole flow

2. Xilinx 7-series or UltraScale+ FPGA without Xilinx embedded processors


Solution:

Step 0. Generate suitable ROM module to be used in design

When generating ROM using Vivado Block Memory Generator, Algorithm Options should be [Fixed Primitives] algorithm to concatenate block RAMs in human readable way (and without using parity storage) which help us to build MyROM.mmi.

In our case, we also use [512x36] primitive to map 8192X32 ROM to 8 BRAM36, each handles 1024X32 ROM data. DataWidth and AddressRange in MyROM.mmi should follow this comination structure accordingly.
 

Step 1. prepare MyRom.mmi 

This file describes how Block RAM is used (type, combination, location) in this design.

Example MyRom.mmi:

//////////////////////////////////////////////////

<?xml version="1.0" encoding="UTF-8"?>
<MemInfo Version="1" Minor="1">

    <Processor Endianness="Little" InstPath="dummy">
        <AddressSpace Name="My_New_ROM" Begin="0" End="32767">
            <BusBlock>
            
                <BitLane MemType="RAMB36" Placement="X3Y83">
                    <DataWidth MSB="31" LSB="0"/>
                    <AddressRange Begin="0" End="1023"/>
                    <Parity ON="false" NumBits="0"/>
                </BitLane>

            </BusBlock>
            <BusBlock>

                <BitLane MemType="RAMB36" Placement="X5Y82">
                    <DataWidth MSB="31" LSB="0"/>
                    <AddressRange Begin="1024" End="2047"/>
                    <Parity ON="false" NumBits="0"/>
                </BitLane>

            </BusBlock>
            <BusBlock>

                <BitLane MemType="RAMB36" Placement="X4Y86">
                    <DataWidth MSB="31" LSB="0"/>
                    <AddressRange Begin="2048" End="3071"/>
                    <Parity ON="false" NumBits="0"/>
                </BitLane>

            </BusBlock>
            <BusBlock>

                <BitLane MemType="RAMB36" Placement="X3Y82">
                    <DataWidth MSB="31" LSB="0"/>
                    <AddressRange Begin="3072" End="4095"/>
                    <Parity ON="false" NumBits="0"/>
                </BitLane>

            </BusBlock>
            <BusBlock>

                <BitLane MemType="RAMB36" Placement="X3Y84">
                    <DataWidth MSB="31" LSB="0"/>
                    <AddressRange Begin="4096" End="5119"/>
                    <Parity ON="false" NumBits="0"/>
                </BitLane>

            </BusBlock>
            <BusBlock>

                <BitLane MemType="RAMB36" Placement="X3Y85">
                    <DataWidth MSB="31" LSB="0"/>
                    <AddressRange Begin="5120" End="6143"/>
                    <Parity ON="false" NumBits="0"/>
                </BitLane>

            </BusBlock>
            <BusBlock>

                <BitLane MemType="RAMB36" Placement="X4Y82">
                    <DataWidth MSB="31" LSB="0"/>
                    <AddressRange Begin="6144" End="7167"/>
                    <Parity ON="false" NumBits="0"/>
                </BitLane>

            </BusBlock>
            <BusBlock>

                <BitLane MemType="RAMB36" Placement="X4Y87">
                    <DataWidth MSB="31" LSB="0"/>
                    <AddressRange Begin="7168" End="8192"/>
                    <Parity ON="false" NumBits="0"/>
                </BitLane>
                                
            </BusBlock>
        </AddressSpace>
    </Processor>

    <Config>
        <Option Name="Part" Val="xc7vx690tffg1926-2"/>

    </Config>
    
</MemInfo>

//////////////////////////////////////////////////

Note that, with new synthesized and generated bitstream, Placement (XY locations) should be updated according to BRAM Cell Properties in Implemented Design in Vivado. Location info can be obtained by:

get_property LOC [get_cells {aa/bb/cc}]

Or before synthesis, specify explicit BRAM XY locations to all BRAMs in .xdc constraint file as follows:

set_property LOC RAMB36_X3Y85 [get_cells {aa/bb/cc}]

aa/bb/cc is the BRAM path in the design.

 

 

 

Step 2. prepare MyNewRom.mem

It is new ROM content we want to update to bitstream.

Example MyNewRom.mem:

//////////////////////////////////////////////////

@0              // only need to indicate address 0 at beginning once
01020304   // each row stores one ROM entry, low byte to high byte. Take this row as example, ROM Dout[31:0] is 32'h04030201   
62f0d026
62f0d034
62f0d042
62f0d050
62f0d06b
62f0d0c7
62f0d0e3

....

//////////////////////////////////////////////////

 

Step 3. execute the command updatemem

updatemem -force -debug --meminfo MyRom.mmi -data MyNewRom.mem -bit top.bit -proc dummy -out top_modify.bit >& debug.log

  --bit arg                    Input bit file
  --proc arg                 Instance path of the processor in the design
  --out arg                  Output bit file
  --force [=arg(=1)]    Overwrite existing output bit file
  --debug                    Hidden debug flag to output the bram init strings
 

All BRAM initialization values are shown in debug.log. We can double check its consistence with MyNewRom.mem.

 


 

Reference:

1.    https://www.xilinx.com/support/answers/63041.html

2.    http://xilinx.eetrend.com/blog/9773

3.    If RAMB18 is used, setenv UPDATEMEM_ALLOW_RAMB18 1 

       I got this from following posts:

           https://forums.xilinx.com/t5/Embedded-Development-Tools/Updating-memories-containing-program-instructions-of-a-Picoblaze/td-p/738315

"The RAMB18 is not officially supported in the updatemem in 2016.3. However, there is an EV that can be set to allow for this. So set this first (UPDATEMEM_ALLOW_RAMB18 1). Also, the minor verison in the MMI needs to be atleast 1. Also, the updatemem does not support parity. I have tested the updatemem on a single RAMB18 and this works for me. See the attached zip for a reference MMI file, and the updatemem command. To test, set the EV mentioned above, and launch Vivado and soruce the TCL script. I used the -debug option here so this will dump into a debug.txt file, you can see that the conents of the mem are populated in the init_strings of the BRAM. "


4.    Another approach for modifying ROM is 

set_property INIT_00 256'h000...0 [get_cells {PATH TO BRAM INSTANCE}]

       This is from https://forums.xilinx.com/t5/Welcome-Join/Block-RAM-initialization-after-implementation/td-p/701478

 

 

 

 

 

 

 

全站熱搜

bamil 發表在 痞客邦 留言(0) 人氣()