1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
|
Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
Copyright (c) 2006-2007 Salvador E. Tropea <salvador en inti gov ar>
Copyright (c) 2005-2007 Instituto Nacional de Tecnología Industrial
Comandos y bloques:
Los archivos de template tienen comandos de bloque y
comandos de operacion. Los comandos de bloque comienzan con
dos signos menos "--" y los de operacion van encerrados entre
signos pesos "$". Los comandos de bloque indican la ejecucion
de un bloque y el fin de bloque debe ser indicado con la
instruccion "--END".
Variables internas:
Se proporcionan las siguientes variables internas que pueden
ser utilizadas invocando su nombre entre signos pesos "$" o
modificados si ademas se les asigna un valor entre
parentesis. Ej. $ADDRESS(0x0000)$ le asignara a esta variable
el valor 0x0000.
$ADDRESS$ :
Acumulador que es util al momento de incrementar la direccion de una
memoria, por ejemplo.
$STEP$ :
Valor con el cual se incrementara la variable $ADDRESS$.
$SBYTES$ :
Cantidad de bytes que posee el bitstream del bitfile.
$SBITES$ :
Cantidad de bits que posee el bitstream del bitfile.
$MSIZE$ :
Obtenido del campo msize de la definicion del dispositivo en el
archivo DEVICES.
Expresa la ultima posicion de memoria de un dispositivo con memoria.
$ID$ :
Obtenido del campo id de la definicion del dispositivo en el archivo
DEVICES.
Expresa el IDCODE del dispositivo actual.
$IDMASK$ :
Obtenido del campo idmask de la definicion del dispositivo en el
archivo DEVICES.
Expresa la mascara que se usara en la comprobacion del IDCODE.
$BSIZE$ :
Obtenido del campo BSIZE de la definicion del dispositivo en el
archivo DEVICES.
Es el "block size" (cantidad de bits) a transferir expresando
en bits.
Nota: El valor BSIZE y el valor STEP no son cosas separadas.
BSIZE es el tamaño en bits de la cache que tiene el dispositivo
para almacenar los datos antes de transferirlos a la flash.
Cada dirección de memoria direcciona una cantidad de bits (64
o 128 es lo común), el STEP es el número de posiciones de memoria
que entran en la cache, luego BSIZE=STEP*bits_por_dirección.
Esto es en las XC18V: 32*64=2048 o 32*128=4096.
$BSIZEB$ :
Obtenido del campo BSIZE de la definicion del dispositivo en el
archivo DEVICES.
Es el "block size" (cantidad de bits) a transferir expresando
en bytes.
$BSIZEB2$ :
$BSIZEB$ multiplicado por 2.
Comandos de bloque:
--LITERAL START :
Indica que se debe copiar en el archivo de salida el contenido
de este bloque y hasta el final del mismo tal y como esta.
Si se encuentra un comando de operacion entre medio este es
ejecutado.
--REPEAT START :
Indica que se repetira de principio a fin el contenido de este
bloque mientras que haya informacion que leer en el bitfile
de entrada.
Este comando de bloque debe tener en su interior algun comando
de operacion que lea informacion del bitfile de entrada, si no
este nunca llegara a su fin y el programa se quedara
repitiendo el bloque hasta agotar el espacio en disco.
Con cada iteracion del bloque se incrementa la variable
$ADDRESS$ en $STEP$.
--REPEAT UNTIL valor :
Indica que se repetira de principio a fin el contenido de
este bloque hasta que la variable $ADDRESS$ tome el valor
pasado como parametro. Con cada iteracion del bloque se
incrementara la variable $ADDRESS$ en $STEP$.
El valor pasado como parametro debe ser multiplo de
$STEP$, si no la condicion de salida del bloque nunca se
conseguira y el programa se quedara repitiendo el bloque
hasta agotar el espacio en disco.
En lugar de valor se puede utilizar una variable:
Ej.: --REPEAT UNTIL MSIZE
--END :
Indica el final de un bloque LITERAL, REPEAT o REPEAT UNTIL.
Comandos de operacion:
Los comandos de operacion pueden recibir como argumento
el nombre de una variable en lugar de una constante:
Ej.: $FILL(0xFF,BSIZE)$
$DATA(ndatabytes)$ :
Escribe en el archivo de salida una cantidad ndatabytes de
bytes del bitfile de entrada expresados en hexadecimal.
$DATA_INV(ndatabytes)$ :
Escribe en el archivo de salida una cantidad ndatabytes
de bytes del bitfile de entrada, invirtiendo el orden
de los bits del bloque, expresados en hexadecimal.
$FILL(VAL,TIMES)$ :
Escribe TIMES veces el valor VAL expresado en hexadecimal en
el archivo de salida.
$REWIND$ :
Vuelve a poner el archivo de bits en la posicion del primer byte del
stream para poder realizar otra pasada completa con un comando de
bloque.
-------------------------------------------------------------------------------
Como crear un template para una FPGA:
-------------------------------------
Autor: Salvador E. Tropea
A) Crear un .SVF válido para esa FPGA:
1) Obtener un .bit para la FPGA en cuestión.
2) Abrir el impact:
$ . /usr/local/ISEWb/settings.sh
$ impact
3) Elegir "I want to (*) Create a new project", Ok. (Darle un nombre si se
quiere).
4) Elegir "(*) Prepare a boundary-scan file [SVF]", Finish.
5) Elegir un nombre para el SVF.
6) Elegir el .bit.
7) Presionar el botón derecho sobre la FPGA y elegir "Program", Ok.
8) Salir del impact
Automáticamente es:
setPreference -pref AutoSignature:FALSE
setPreference -pref KeepSVF:FALSE
setPreference -pref ConcurrentMode:FALSE
setPreference -pref UseHighz:FALSE
setPreference -pref UserLevel:NOVICE
setPreference -pref svfUseTime:FALSE
setMode -bs
setMode -bs
setCable -port svf -file "salida.svf"
addDevice -p 1 -file "archivo.bit"
Program -p 1 -s -defaultVersion 0
B) Crear un nuevo template (ej: alg_Virtex_4.svft)
1) Abrir un template que ya exista para usarlo de guía.
2) Borrar "FREQUENCY 1E6 HZ;"
3) Reemplazar: $ID$ y $IDMASK$ en la parte que dice "Loading device with
'idcode' instruction.". (f167c093)
4) Reemplazar la megalínea del bitstream por:
SDR $SBITS$ TDI ($DATA_INV(-1)$) SMASK ($FILL(0xFF,-1)$);
C) Probar su funcionamiento
1) Colocar el nuevo template en /usr/share/bit2svf/
2) Editar /usr/share/bit2svf/DEVICES agregando el ID de la FPGA y el algoritmo
a usar:
// Virtex 4 family (10 bits IR)
XC4VLX25, f167c093, 0fffffff, alg_Virtex_4, VOID, 0l
3) Probar el template:
$ bit2svf display_test_lx25.bit v4-b2s.svf XC4VLX25
Esto genera v4-b2s.svf que debería ser practicamente idéntico al generado por
impact.
Nota: En este caso observé que el impact agrega 32 bits en 0 extra al
bitstream. Esto no parece ser indispensable y sospecho que sirve para
"limpiar/vaciar" la cadena.
4) Si todo fue OK se puede probar con el dispositivo:
$ jbit display_test_lx25.bit XC4VLX25
-------------------------------------------------------------------------------
Como crear un template para una PROM:
-------------------------------------
Autor: Salvador E. Tropea
A) Crear un archivo de PROM válido.
1) Obtener un .bit para la FPGA en cuestión.
2) Abrir el impact:
$ . /usr/local/ISEWb/settings.sh
$ impact
3) Elegir "I want to (*) Prepare a ROM file", Ok. (Darle un nombre si se
quiere).
4) Elegir "I want to target a (*) Xilinx PROM", "PROM File name" darle un
nombre. Next. (Ojo con el path).
5) Elegir la PROM y Add, luego Next.
6) Agregar el .bit
7) Elegir "Generate File ..." dentro de las acciones disponibles (la única).
8) Esto genera un .MCS con el contenido para la PROM.
B) Crear un .SVF válido para esa PROM. Esto es similar a la FPGA, la única
diferencia es que le especificamos el .MCS en lugar de un .bit. En este caso
nos preguntará cual es el dispositivo haciendo un guess de cual se trata. Esto
es porque el .mcs es un bitstream crudo y no dice para que dispositivo se
hizo.
Durante este proceso se pueden elegir opciones como si la PROM se conecta en
paralelo y si se incluye verificación. Además hay que elegir que primero la
borre.
B) Crear un nuevo template o usar uno ya hecho. Esto es como con la FPGA.
C) Probar su funcionamiento. Esto es más o menos lo mismo que con la FPGA. La
principal diferencia con las PROMs es que acá es necesario configurar su tamaño
y el tamaño de la caché o página donde se guardarán temporalmente los datos:
// XCFxxP memories
XCF08P , f5057093, 0fffffff, alg_XCFP ,8192 , 0x100000
|