OpenCores
URL https://opencores.org/ocsvn/ssbcc/ssbcc/trunk

Subversion Repositories ssbcc

[/] [ssbcc/] [trunk/] [doc/] [MemoryInitialization.html] - Blame information for rev 14

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 sinclairrf
<html>
2
<title>
3
Memory Initialization
4
</title>
5
<body>
6
This file describes the contents of the memory intialization file and how to
7
use it for various vendor-specific tools.
8
<h1>Format</h1>
9
  Each line of the file consists of a hex address into which the values are to
10
  be stored and the corresponding value.  For SSBCC.9x8 these are 9-bit
11
  values.<br/><br/>
12
  The format of each line is "<tt>@%04X %03X</tt>" where the 4-digit value is
13
  the hex memory address and the 3-digit hex value is the 9-bit memory
14
  value.<br/><br/>
15
<h1>Xilinx <tt>data2mem</tt></h1>
16
  <tt>data2mem</tt> is a tool for modifying the block ram initialization
17
  contents of bitstreams.  Using this tool allows the micro controller assembly
18
  code to be modified in the bitstream without rerunning the entire build
19
  process.<br/><br/>
20
  The following illustrates how to use <tt>data2mem</tt> using
21
  ISE&nbsp;14.5:<br/><br/>
22
  <ol>
23
  <li>Create a <tt>BMM</tt> file named "<tt>uc.bmm</tt>" for inclusion in the
24
    build process:<br/><br/>
25
    The file should look like the following.  The text
26
    "<tt>top_inst/uc_inst</tt>" needs to be modified to point to your
27
    instantiation of the micro controller.  Sometimes
28
    "<tt>uc_inst/Mram_s_opcodeMemory</tt>" becomes
29
    "<tt>uc_inst_Mram_s_opcodeMemory</tt>"<br/><br/>
30
    <tt>ADDRESS_SPACE&nbsp;uc&nbsp;RAMB18&nbsp;WORD_ADDRESSING&nbsp;[0x0:0x7FF]<br/>
31
    &nbsp;&nbsp;BUS_BLOCK<br/>
32
    &nbsp;&nbsp;&nbsp;&nbsp;top_inst/uc_inst/Mram_s_opcodeMemory&nbsp;[0:8];<br/>
33
    &nbsp;&nbsp;END_BUS_BLOCK;<br/>
34
    END_ADDRESS_SPACE;<br/></tt><br/>
35
    The following command can be used to verify the syntax of this <tt>BMM</tt>
36
    file:<br/><br/>
37
    <tt>&nbsp;&nbsp;data2mem&nbsp;-bm&nbsp;uc_bmm<br/></tt><br/>
38
    WARNING:  Using "<tt>ARCHITECTURE&nbsp;4096</tt>" on a Spartan-6 build
39
    produced two RAMB16's and one RAMB8, not the expected two RAMB18's.
40
    Changing the configuration command to "<tt>ARCHITECTURE&nbsp;2048*2</tt>"
41
    produced the desired results.  The following <tt>BMM</tt> extracted the two
42
    RAMB18 locations with the desired memory mapping:<br/><br/>
43
    <tt>ADDRESS_SPACE&nbsp;uc&nbsp;RAMB18&nbsp;WORD_ADDRESSING&nbsp;[0x0:0xFFF]<br/>
44
    &nbsp;&nbsp;BUS_BLOCK<br/>
45
    &nbsp;&nbsp;&nbsp;&nbsp;top_inst/uc_inst_Mram_s_opcodeMemory_0&nbsp;[0:8];<br/>
46
    &nbsp;&nbsp;END_BUS_BLOCK;<br/>
47
    &nbsp;&nbsp;BUS_BLOCK<br/>
48
    &nbsp;&nbsp;&nbsp;&nbsp;top_inst/uc_inst_Mram_s_opcodeMemory_1&nbsp;[0:8];<br/>
49
    &nbsp;&nbsp;END_BUS_BLOCK;<br/>
50
    END_ADDRESS_SPACE;<br/></tt><br/>
51 9 sinclairrf
    Note:  For a Spartan-3A the bit indices <tt>[0:8]</tt> may need to be reversed.<br/><br/>
52 2 sinclairrf
  <li>Add this file to the build process.<br/><br/>
53
    For a command-line build this is done by adding "<tt>-bm&nbsp;uc.bmm</tt>"
54
    to the argument list for ngdbuild.<br/><br/>
55
    When <tt>bitgen</tt> is run it will create a file named "<tt>uc_bd.bmm</tt>
56
    which will include the memory block address required to run
57
    <tt>data2mem</tt>.<br/><br/>
58
  <li>Perform the build and ensure that <tt>uc_bd.bmm</tt> has the address for
59
    the memory block.<br/><br/>
60
  <li>Run <tt>data2mem</tt> as follows, where "<tt>orig.bit</tt>" is the
61
    assumed name for the original bitstream generated by Xilinx' tools:<br/><br/>
62
    <tt>data2mem&nbsp;-bm&nbsp;uc_bd.bmm&nbsp;-bt&nbsp;orig.bit&nbsp;-bd&nbsp;uc.mem&nbsp;-o&nbsp;b&nbsp;new.bit;<br/></tt><br/>
63
  <li>Compare the original bitstream to the modified bitstream as follows to
64
    ensure this process worked.<br/><br/>
65
    <tt>data2mem&nbsp;-bm&nbsp;uc.bmm&nbsp;-bt&nbsp;orig.bit&nbsp;-d&nbsp;&gt;&nbsp;orig.dump;<br/>
66
    data2mem&nbsp;-bm&nbsp;uc.bmm&nbsp;-bt&nbsp;new.bit&nbsp;-d&nbsp;&gt;&nbsp;new.dump;<br/>
67
    diff&nbsp;orig.dump&nbsp;new.dump&nbsp;|&nbsp;less;<br/></tt><br/>
68
    The only differences other than file names and dates and such should be the
69
    initialization values for the memory block.<br/><br/>
70
    You can validate this process by using the original memory initialization
71
    file, in which case the above differences should be limited to the file
72
    name, data, etc., but not the memory contents.<br/><br/>
73
  </ol>
74
  If you didn't include the <tt>BMM</tt> file in the build process you can use
75
  <tt>fpga_editor</tt> to get the memory names and memory locations.  The
76
  command to invoke it is:<br/><br/>
77
  <tt>&nbsp;&nbsp;fpga_editor&nbsp;-r&nbsp;file.ncd&nbsp;file.pcf<br/></tt><br/>
78
  Then, under "<tt>Name&nbsp;Filter</tt>" type "<tt>*opcodeMemory*</tt>" and hit
79
  the <tt>ENTER</tt> key.
80
<h1>Xilinx <tt>Vivado</tt></h1>
81
  As of this writing, Xilinx' Vivado does not have clean non-SDK support for
82
  generating the files required to modify the processor instruction memory.
83
  However, the TCL scripting language can be used for the following work-around
84
  to this problem:
85
  <ol>
86
  <li>Determine the name of the memory.<br/><br/>
87
    The following commands lists the names of all the block rams.  This
88
    obviously needs to be done after place and route.<br/><br/>
89
    <tt>join [get_cells -hierarchical -filter { LOC =~ "RAMB*" }] "\n";<br/></tt><br/>
90
    or<br/><br/>
91
    <tt>join [filter [get_cells -hierarchical] { BEL =~ "RAMB*" }] "\n"<br/></tt><br/>
92
    Alternatively, the following command lists the names of the block rams, the
93
    type of the block ram, and their locations:<br/><br/>
94
    <tt>foreach a [filter [get_cells -hierarchical] { BEL =~ "RAMB*" }] {
95
      puts "$a [lindex [report_property -return_string $a BEL] 7] [lindex
96
      [report_property -return_string $a LOC] 7]"; }<br/></tt><br/>
97
    Any of these can be included in the build script or can be cut and pasted
98
    into the TCL console in the GUI after place and route.<br/><br/>
99
    Note:  The "<tt>list_property_value</tt>" seems to be more natural to use
100
    than the "<tt>[lindex&nbsp;...</tt>" commands, but can only be used for
101
    enumerated types, i.e., not for <tt>BEL</tt> and <tt>LOC</tt>
102
    properties.<br/><br/>
103
    </li>
104
  <li>Once you've identified the name(s) of the memories, add the following
105
    command to the build script or use it on a checkpoint.  Here,
106
    uc/inst/s_PC_reg_rep was the single memory in the micro controller.<br/><br/>
107
    <tt>foreach&nbsp;memName&nbsp;[list&nbsp;"uc/inst/s_PC_reg_rep"] {<br/>
108
    &nbsp;&nbsp;set&nbsp;memBel&nbsp;[lindex&nbsp;[report_property&nbsp;-return_string&nbsp;[get_cells&nbsp;$memName]&nbsp;BEL]&nbsp;7];<br/>
109
    &nbsp;&nbsp;set&nbsp;memLoc&nbsp;[lindex&nbsp;[report_property&nbsp;-return_string&nbsp;[get_cells&nbsp;$memName]&nbsp;LOC]&nbsp;7];<br/>
110
    &nbsp;&nbsp;puts "MYBMMINFO:&nbsp;$memName&nbsp;$memBel&nbsp;$memLoc]";<br/>
111
    }<br/></tt><br/>
112
    This should add lines starting with "<tt>MYBMMINFO:</tt>" to the Vivado log
113
    file with each memory name, type, and location.<br/><br/>
114
    Note:  If the processor uses more than one block ram, simply append the name
115
    to the "<tt>list</tt>" in this TCL script.<br/><br/>
116
    </li>
117
  <li>Use the following <tt>gawk</tt> script or similar to generate a
118
    <tt>BMM</tt> file from the "<tt>MYBMMINFO:</tt>" lines.  Here, the
119
    "<tt>vivado.log</tt>" is the Vivado log file and "<tt>build-bmm</tt> is the
120
    name of this file.<br/><br/>
121
    <tt>#!/bin/bash<br/>
122
    #<br/>
123
    #&nbsp;Generate&nbsp;a&nbsp;BMM&nbsp;file&nbsp;for&nbsp;the&nbsp;micro&nbsp;controller&nbsp;from&nbsp;the&nbsp;MYBMMINFO&nbsp;lines&nbsp;in&nbsp;the<br/>
124
    #&nbsp;Vivado&nbsp;log&nbsp;file.<br/>
125
    #<br/>
126
    #&nbsp;Usage:&nbsp;&nbsp;./build-bmm<br/>
127
    <br/>
128
    gawk&nbsp;--&nbsp;'<br/>
129
    BEGIN&nbsp;{<br/>
130
    &nbsp;&nbsp;nMemories&nbsp;=&nbsp;0;<br/>
131
    &nbsp;&nbsp;memName[nMemories++]&nbsp;=&nbsp;"uc/inst/s_PC_reg_rep";<br/>
132
    }<br/>
133
    /^MYBMMINFO:/&nbsp;{&nbsp;bel[$2]&nbsp;=&nbsp;$3;&nbsp;loc[$2]&nbsp;=&nbsp;$4;&nbsp;}<br/>
134
    END&nbsp;{<br/>
135
    &nbsp;&nbsp;for&nbsp;(ix=0;&nbsp;ix&lt;nMemories;&nbsp;++ix)<br/>
136
    &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!(memName[ix]&nbsp;in&nbsp;bel))&nbsp;{<br/>
137
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("FATAL&nbsp;ERROR:&nbsp;&nbsp;MYBMMINFO&nbsp;record&nbsp;not&nbsp;found&nbsp;for&nbsp;\"%s\"\n",&nbsp;memName)&nbsp;&gt;&nbsp;"/dev/stderr";<br/>
138
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit&nbsp;1;<br/>
139
    &nbsp;&nbsp;&nbsp;&nbsp;}<br/>
140
    &nbsp;&nbsp;memType&nbsp;=&nbsp;"";<br/>
141
    &nbsp;&nbsp;for&nbsp;(ix=0;&nbsp;ix&lt;nMemories;&nbsp;++ix)&nbsp;{<br/>
142
    &nbsp;&nbsp;&nbsp;&nbsp;split(loc[memName[ix]],splitLoc,"_");<br/>
143
    &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(memType&nbsp;==&nbsp;"")&nbsp;{<br/>
144
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memType&nbsp;=&nbsp;splitLoc[1];<br/>
145
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(memType&nbsp;=&nbsp;"RAMB18")&nbsp;L&nbsp;=&nbsp;2048;<br/>
146
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(memType&nbsp;=&nbsp;"RAMB36")&nbsp;L&nbsp;=&nbsp;4096;<br/>
147
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;L&nbsp;*=&nbsp;nMemories;<br/>
148
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("ADDRESS_SPACE&nbsp;uc&nbsp;%s&nbsp;WORD_ADDRESSING&nbsp;[0x0:0x%x]\n",memType,L-1);<br/>
149
    &nbsp;&nbsp;&nbsp;&nbsp;}<br/>
150
    &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if&nbsp;(splitLoc[1]&nbsp;!=&nbsp;memType)&nbsp;{<br/>
151
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("Inconsistent&nbsp;memory&nbsp;types:&nbsp;&nbsp;%s&nbsp;is&nbsp;%s&nbsp;instead&nbsp;of&nbsp;%s\n",memName[ix],splitLoc[1],memType)&nbsp;>&nbsp;"/dev/stderr";<br/>
152
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit&nbsp;1;<br/>
153
    &nbsp;&nbsp;&nbsp;&nbsp;}<br/>
154
    &nbsp;&nbsp;&nbsp;&nbsp;printf("&nbsp;&nbsp;BUS_BLOCK\n");<br/>
155
    &nbsp;&nbsp;&nbsp;&nbsp;printf("&nbsp;&nbsp;&nbsp;&nbsp;%s&nbsp;[8:0]&nbsp;PLACED&nbsp;=&nbsp;%s;\n",memName[ix],splitLoc[2]);<br/>
156
    &nbsp;&nbsp;&nbsp;&nbsp;printf("&nbsp;&nbsp;END_BUS_BLOCK;\n");<br/>
157
    &nbsp;&nbsp;}<br/>
158
    &nbsp;&nbsp;printf("END_ADDRESS_SPACE;\n");<br/>
159
    }<br/>
160
    '&nbsp;vivado.log&nbsp;&gt;&nbsp;build_uc.bmm<br/></tt><br/>
161
    </li>
162
  <li>Update the contents of the bitstream file as follows.  Here,
163
    <tt>build.bit</tt> is the original bitstream and <tt>build_uc.bit</tt> is
164
    the bitstream updated with the new micro controller instructions.<br/><br/>
165
    <tt>data2mem&nbsp;-bm&nbsp;build_uc.bmm&nbsp;-bt&nbsp;build.bit&nbsp;-bd&nbsp;uc/uc.mem&nbsp;-o&nbsp;b
166
    build_uc.bit<br/></tt><br/>
167
    Alternatively, use something like the following as an "<tt>update_uc</tt>"
168
    script file:<br/><br/>
169
    <tt>#!/bin/bash<br/>
170
    #<br/>
171
    #&nbsp;Update&nbsp;the&nbsp;micro&nbsp;controller&nbsp;instruction&nbsp;memory&nbsp;in&nbsp;the&nbsp;BIT&nbsp;file.<br/>
172
    #<br/>
173
    #&nbsp;Usage:&nbsp;&nbsp;./update-uc<br/>
174
    <br/>
175
    if&nbsp;test&nbsp;!&nbsp;-f&nbsp;build_uc.bmm&nbsp;-o&nbsp;vivado.log&nbsp;-nt&nbsp;build_uc.bmm;&nbsp;then<br/>
176
    &nbsp;&nbsp;./build-bmm&nbsp;||&nbsp;{&nbsp;echo&nbsp;"build-bmm&nbsp;failed"&nbsp;>&nbsp;/dev/stderr;&nbsp;exit&nbsp;1;&nbsp;}<br/>
177
    fi<br/>
178
    <br/>
179
    (&nbsp;cd&nbsp;uc;&nbsp;ssbcc&nbsp;-q&nbsp;--define-clog2&nbsp;uc.9x8&nbsp;)&nbsp;\<br/>
180
    ||&nbsp;{&nbsp;echo&nbsp;"ssbcc&nbsp;failed"&nbsp;>&nbsp;/dev/stderr;&nbsp;exit&nbsp;1;&nbsp;}<br/>
181
    <br/>
182
    data2mem&nbsp;-bm&nbsp;build_uc.bmm&nbsp;-bt&nbsp;build.bit&nbsp;-bd&nbsp;uc/uc.mem&nbsp;-o&nbsp;b&nbsp;build_uc.bit&nbsp;\<br/>
183
    ||&nbsp;{&nbsp;echo&nbsp;"data2mem&nbsp;failed"&nbsp;>&nbsp;/dev/stderr;&nbsp;exit&nbsp;1;&nbsp;}<br/></tt><br/>
184
    </li>
185
  </ol>
186
  Note:  If you want to use these procedures to identify the memories after
187
  you've run Vivado, you must include a "<tt>write_checkpoint</tt>" command in
188
  your TCL script.  For example, include the following command after
189
  "<tt>write_bitstream&nbsp;-force&nbsp;build.bit</tt>"<br/><br/>
190
  <tt>write_checkpoint&nbsp;-force&nbsp;build;<br/></tt><br/>
191
  and then use the following command in a subsequent Vivado session to open the
192
  checkpoint:<br/><br/>
193
  <tt>read_checkpoint&nbsp;build;<br/></tt><br/>
194
  Once these are done you can examine the memory names and so forth.<br/><br/>
195
</body>
196
</html>

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.