在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 4726|回复: 0

[求助] 关于vivado生成.mmi文件的问题

[复制链接]
发表于 2020-6-15 17:00:37 | 显示全部楼层 |阅读模式
50资产
   我通过下载“Cortex-M3 DesignStart FPGA XilinxEdition”软核,建立了一个自己的工程,由于我Keil软件部分的代码比较多,所以消耗了262144的memory size,所以我就把ARM的ITCM的size调到了256KB,这样的话刚好差不多够用。但是,目前遇到的问题是,官方给的这个软核的例程,里面用于生成.mmi文件的tcl脚本,它对memory的限制是在16KB-128KB之间的,所以,我无法使用官方给的tcl生成.mmi文件。我尝试修改这个tcl文件,无奈总是出现其他别的问题。  开发板的资源是够用的。我现在的想法是需要生成一个.mmi文件,用于后面update合成一个新的bit文件。
  以下是官方提供的脚本:
```
# -----------------------------------------------------------------------------
#  The confidential and proprietary information contained in this file may
#  only be used by a person authorised under and to the extent permitted
#  by a subsisting licensing agreement from ARM limited.
#
#             (C) COPYRIGHT 2018 ARM limited.
#                 ALL RIGHTS RESERVED
#
#  This entire notice must be reproduced on all copies of this file
#  and copies of this file may only be made by a person if such person is
#  permitted to do so under the terms of a subsisting license agreement
#  from ARM limited.
#
#       SVN Information
#
#       Checked In          : $Date$
#
#       Revision            : $Revision$
#
#       Release Information : Cortex-M3 DesignStart-r0p0-00rel0
#                             with V2C-DAPLink adaptor board
# -----------------------------------------------------------------------------
#  Purpose :
#           Script to get ITCM BRAM locations
#           MMI format from following two articles
#
# -----------------------------------------------------------------------------
# Set MMI output file name
set mmi_file "m3.mmi"
set part     "xc7a200tfbg484-1"
# Function to swap bits
proc swap_bits { bit } {
    if { $bit > 23 } {return [expr {24 + (31 - $bit)}]}
    if { $bit > 15 } {return [expr {16 + (23 - $bit)}]}
    if { $bit > 7  } {return [expr {8  + (15 - $bit)}]}
    return [expr {7 - $bit}]
}
# If run from batch file, will need to open project, then open the run
# open_run impl_1
# Find all the ITCM RAMs, place in a list
set itcm_ram [get_cells -hier -regexp {.*u_x_itcm.*ram_block_reg.*} -filter {REF_NAME =~ RAMB36E1}]
# Vivado appears to read the memories in their actual bit order
# However update_mem amongst its very many failings doesn't support endianness, even though you specify it in the file!
# It also pays no attention to the bit_lane definition, it does the conversion based on the order memories are defined
# in the file!  Not clear what the MMI file does achieve!
# So go through and reverse each block of 4 memories
if { [expr {[llength $itcm_ram] % 4}] != 0 } {
    puts "Error - Number of memories not divisible by 4"
    return -1
}
# Number of RAMs details memory size.  Each RAM is 32kb, so 4kB.
set itcm_size_bytes [expr {4096*[llength $itcm_ram]}]
puts "Instruction memory size $itcm_size_bytes"
# Currently only support memory sizes between 16kB, (one byte per mem), and 128kB, (one bit per mem)
if { ($itcm_size_bytes <= (4*4096)) || ($itcm_size_bytes > (32*4096)) } {
    puts "Error - Memory size of $itcm_size_bytes out of range"
    puts "        Script only supports memory sizes between 16kB and 128kB"
    return -1
}
# Create and open target mmi file
set fp [open $mmi_file {WRONLY CREAT TRUNC}]
if { $fp == 0 } {
    puts "Error - Unable to open $mmi_file for writing"
    return -1
}
# Write the file header
puts $fp "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
puts $fp "<MemInfo Version=\"1\" Minor=\"15\">"
puts $fp "    <Processor Endianness=\"ignored\" InstPath=\"dummy\">"
puts $fp "        <AddressSpace Name=\"m3_for_arty_a7_i.Cortex_M3_0.inst.u_x_itcm\" Begin=\"0\" End=\"[expr {$itcm_size_bytes-1}]\">"
puts $fp "            <BusBlock>"
# Create an array to put the location and top memory index into
array set mem_array {}
# Calculate the expected number of bits per memory
set mem_bits [expr {32/[llength $itcm_ram]}]
# set itcm_ram_reordered
    for {set i 0} {$i < [llength $itcm_ram]/4} {incr i} {
        set start     [expr {$i*4}]
        set end       [expr {($i*4)+3}]
        set new_list  [lreverse [lrange $itcm_ram [expr {$i*4}] [expr {($i*4)+3}]]]
    #    puts "$start $end\n$new_list"
        # lreplace $itcm_ram [expr {$i*4}] [expr {($i*4)+3}] [lreverse [lrange $itcm_ram [expr {$i*4}] [expr {($i*4)+3}]]]
    # puts $itcm_ram_reordered
        # For each entry display the location
        foreach ram $new_list {
            # Get the RAM location
            set loc_val [get_property LOC [get_cells $ram]]
            regexp -- {(RAMB36_)([0-9XY]+)} $loc_val full ram_name loc_xy
            # Get the nets driven by the D0 pins
            set data_bus [get_nets -of_objects [get_pins -filter {REF_PIN_NAME =~ DOADO*} -of [get_cells $ram]]]
            
            # Check number of bits is the same as that expected
            if { [llength $data_bus] != $mem_bits } {
                puts "Error - Number of data pins read, [llength $data_bus], does not equal expected memory bits, $mem_bits"
                return -1
            }
            # Number of pins connected to the memory sets the memory depth.
            set memory_depth [expr {(32768/[llength $data_bus])-1}]
            
            set idx_list
              foreach entry $data_bus {
                  # Filter the data_bus down to just the two index numbers
                  set index [regexp -inline -- {[0-9]+} [regexp -inline -- {\[.*} [lindex $entry 0]]]
                  lappend idx_list $index
              }
              
              # Sort the index list from highest to lowest
              set idx_list [lsort -decreasing -integer $idx_list]
              
              # Assign the highest and lowest bits for the range variables
              set index_low  [lindex $idx_list end]
              set index_high [lindex $idx_list 0]
              
              # Debug
              # puts $data_bus
              # puts $idx_list
              # puts "$index_high downto $index_low pos $loc_val"
              array set mem_array [list $index_high $loc_xy]
          }; # foreach
      }; # for
          # Sort array into index order
          array set mem_array_sorted {}
          foreach entry [lsort [array names mem_array]] {
              # puts "$entry : $mem_array($entry)"
              array set mem_array_sorted [list $entry $mem_array($entry)]
          }
         
          foreach entry [array names mem_array_sorted] {
              # puts "$entry : $mem_array_sorted($entry)"
          }
         
          # MMI file needs to be in little endian format because update_mem doesn't actually use the endianness field
          # So first index is 7, next is 15, 23, 31.
          # Number of entries to write is 8/mem_bits.  Lower index is index_high - (mem_bits - 1)
          for {set top_idx 7} {$top_idx < 32} {incr top_idx 8} {
              for {set idx_high $top_idx} {$idx_high > ($top_idx-8)} {incr idx_high -$mem_bits} {
                  # puts $idx_high
                  set loc $mem_array_sorted($idx_high)
                  set idx_low [expr {$idx_high - $mem_bits + 1}]
                  
                  if { $loc == "" } {
                      puts "Error - No location entry for index $idx_high"
                      return -1
                  }
         
                  # Write relevant XML
                  puts $fp "                <BitLane MemType=\"RAMB36\" Placement=\"$loc\">"
                  puts $fp "                    <DataWidth MSB=\"$idx_high\" LSB=\"$idx_low\"/>"
                  puts $fp "                    <AddressRange Begin=\"0\" End=\"$memory_depth\"/>"
                  puts $fp "                    <Parity ON=\"false\" NumBits=\"0\"/>"
                  puts $fp "                </BitLane>"
              }
          }
      # Write the file tail
      puts $fp "            </BusBlock>"
      puts $fp "        </AddressSpace>"
      puts $fp "    </Processor>"
      puts $fp "    <Config>"
      puts $fp "        <Option Name=\"Part\" Val=\"$part\"/>"
      puts $fp "    </Config>"
      puts $fp "    <DRC>"
      puts $fp "      <Rule Name=\"RDADDRCHANGE\" Val=\"false\"/>"
      puts $fp "    </DRC>"
      puts $fp "</MemInfo>"
      # Close the output file
      close $fp
      # Useful facilities
      # Get the bus as a list
      # get_nets -hierarchical -regexp  {.*itcm.*doutA.*}
      ```
      如果直接运行,那肯定是不行的,会出现以下错误:
      ```
      Error - Memory size of 262144 out of range
              Script only supports memory sizes between 16kB and 128kB
      -1
      ```
      请教以下各位,该如何修改这个tcl文件,或者有什么其他的方法可以生成.mmi文件。网上提供的方法我试了,总是行不通,害。

      您需要登录后才可以回帖 登录 | 注册

      本版积分规则

      关闭

      站长推荐 上一条 /1 下一条


      小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
      ( 京ICP备:10050787号 京公网安备:11010502037710 )

      GMT+8, 2024-11-8 15:02 , Processed in 0.013408 second(s), 5 queries , Gzip On, Redis On.

      eetop公众号 创芯大讲堂 创芯人才网
      快速回复 返回顶部 返回列表