Copyright (c) 2005 Juan Pablo D. Borgna Copyright (c) 2006-2007 Salvador E. Tropea 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. $CUTLINES(n): Con 0 deja de cortar las líneas largas, con 1 vuelve a cortarlas. Otros valores: reservados. ------------------------------------------------------------------------------- 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