[Memorias] [Icestudio] Bootloader hardware

100 views
Skip to first unread message

Obijuan

unread,
Aug 26, 2019, 12:08:50 PM8/26/19
to FPGAwars: explorando el lado libre
Hola,

Ahora que estamos ya empezando a sintetizar micros en la FPGA, necesitamos usar memorias que contengan el firmware y los datos

Estas memorias se rellenan en la etapa de síntesis. Luego, al cargar el circuito en la FPGA las memorias ya aprecen llenas con nuestra información


Esto está bien, salvo por un detalle: en micros como el Z80, el proceso de síntesis puede durar unos 2 minutos. Por lo que es muy lento el proceso de prueba y desarrollo del firmware. Sería genial hacerlo más rápido


Una posibilidad es usar un Bootloader de toda la vida: mapear una uart en nuestro sistema digital y poner un firmware que al arrancar lea el programa por el puerto serie y lo almacene en la memoria. Una vez cargado, que lo ejecute

Para hacerlo necesitamos tener un bootloader para el Z80. Buscando por internet hay muchos. Y tampoco es muy complicado hacernos el nuestro... pero...

Hay otra posibilidad más interesante... ¿Y si hacemos el Bootloader hardware? Un circuito que lea los datos del puerto serie y los cargue en la memoria

Voy a poner los avances de este bootloader hardware en este hilo de la lista

Para las pruebas de concepto, yo siempre empiezo diseñando sistemas mínimos, que luego amplio. Así que voy a empezar por lo mímino: una memoria de 2 bytes. En esta memoria grabamos 2 valores y hacemos un circuito para leerlos y sacarlos por los LEDs:

Al cargar este circuito, veremos una secuencia de dos estado en los LEDs: 0xF0 y 0x0F, que se alternan cada medio segundo

Para cargar esta memoria con valores del puerto serie, necesitamos crear otro circuito que acceda a ella y que sea lo más independiente posible de este circuito de aplicación. 
En el próximo mensaje os muestro la solución que estoy probando

Saludos, Obijuan



bootloader-01.ice

charli va

unread,
Aug 26, 2019, 12:25:40 PM8/26/19
to fpga-wars-explora...@googlegroups.com
Super interesante! a por ello!

--
Has recibido este mensaje porque estás suscrito al grupo "FPGAwars: explorando el lado libre" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a fpga-wars-explorando-el...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/fpga-wars-explorando-el-lado-libre/cd6aa478-1e69-40d3-a633-b88e7ebc8e04%40googlegroups.com.

Obijuan

unread,
Aug 27, 2019, 3:58:37 AM8/27/19
to FPGAwars: explorando el lado libre
 La solución que estoy probando para hacerlo fácil es multiplexor los pines de la memoria para se conecte bien el circuito del Bootloader, o bien el circuito de la aplicación

Para ello coloco multiplexores de 2 a 1 en todas las entradas y en la salida. En total 5 multiplexores de 2 a 1. La señal de selección de todos los multiplexores es la misma: mem_sel




Esto lo convertimos en un bloque. Lo he llamado memoria DUAL de 2 B. Sólo hay una única memoria, pero con 2 canales de acceso: el 0 y el 1. Pero de cara al diseño podemos conectar nuestros circuitos independientemente a los pines del canal 0 ó el 1


Los pines son los mismos en las dos memorias, pero en la DUAL tienen el sufijo 0 ó 1 dependiendo del canal. Además tiene un pin adicional, sel, para seleccionar cuál es el canal activo

El ejemplo mostrado anterior, en el que se saca una secuencia de 2 estados por los LEDs lo hacemos con la memoria DUAL así:



El circuito de aplicación está conectado al canal 0. Por eso introducimos un 0 en la entrada sel. El funcionamiento es exactamente igual que cuando se usa la memoria de 2 Bytes

Ya lo tenemos todo lisot para conectar el circuito del bootloader a esta memoria Dual

Saludos, Obijuan

Obijuan

unread,
Aug 27, 2019, 4:00:57 AM8/27/19
to FPGAwars: explorando el lado libre
Se me olvidada adjuntar el .ice de este segundo ejemplo

(Lo nuevos bloques que voy creando los estoy colocando en la versión de desarrollo de la colección Jedi, en github)
bootloader-02.ice

Obijuan

unread,
Aug 27, 2019, 4:44:00 AM8/27/19
to FPGAwars: explorando el lado libre

Ahora añadimos el circuito del Bootloader, que es este:


Se conecta al canal 1 (ch1) de la memoria Dual, mediante etiquetas.  Como es una memoria de 2 Bytes, se utiliza una máquina de contar de 1 bit (que tiene dos estados, q=0, y q=1). El estado de esta máquina determina el modo en el que estamos. Inicialmente está en el modo normal (ch0). Al apretar el pulsador SW1 la máquina se activa y se entra en el modo bootloader. En este modo, la salida de la máquina de contar es 0 y se queda esperando a que llegue un tic por next.  Cuando desde el PC se envía el primer byte, aparece este tic, se graba en la dirección 0 y la máquina cambia a q = 1, y se queda nuevamente esperando.

Al enviar el segundo carácter, se graba en la dirección 1 y la máquina termina, por lo que busy se pone a 0 y por tanto se selecciona otra vez el canal 0, pasando al modo normal.

Con el pulsador SW2 podemos abortar el modo bootloader y volver al normal en cualquier momento

El circuito completo queda así:



Lo he probado y .... ¡Funciona super bien! En el próximo mensaje preparo un vídeo para que lo veáis en acción.Al cargar el circuito, estamos en modo normal, y por los LEDs se verá la secuencia pre-grabada (0xF0, 0x0F). Al apretar el pulsador SW1 entra en modo bootloader y los LEDs se apagan (no hay nada conectado a la salida de la memoria en el modo 1). Desde el script comunicator en el PC enviamos 2 bytes. Se cargan en la memoria y se comienza a reproducir la nueva secuencia

Este proceso lo podemos repetir cuantas veces queramos. ¡Estamos cargando la memoria desde el PC! :-)

Saludos, Obijuan
bootloader-03.ice

Obijuan

unread,
Aug 27, 2019, 5:36:25 AM8/27/19
to FPGAwars: explorando el lado libre
Aquí he subido el vídeo a youtube, para mostrar el funcionamiento


Inicialmente, al hacer reset, la memoria tiene cargados los valores iniciales: 0xF0 y 0x0F 
Al apretar SW1, se entra en el modo bootloader. Desde el script comunicator enviamos los valores 1 y 2. Por lo que la secuencia cambia.
Volvemos a pasar al modo bootloadder para cargar otra secuecia: 0xAA, 0x55

También se muestra cómo se aborta el bootloader al apretar SW2

Funciona muy bien... y el circuito del bootloader es sencillo. Una vez que se comprende cómo funciona es muy fácil de modificar

Saludos, Obijuan


Democrito

unread,
Aug 27, 2019, 5:45:00 AM8/27/19
to FPGAwars: explorando el lado libre
Me encantó!

Obijuan

unread,
Aug 27, 2019, 5:59:19 AM8/27/19
to FPGAwars: explorando el lado libre
¡Gracias! Esto tiene muchas posibilidades! :-)

El martes, 27 de agosto de 2019, 11:45:00 (UTC+2), Democrito escribió:
Me encantó!

Obijuan

unread,
Aug 27, 2019, 6:06:38 AM8/27/19
to FPGAwars: explorando el lado libre
En este otro vídeo se muestra un ejemplo de carga de la memoria desde un script en python. Le carga los valores 0xAA y 0x55:


Primero se entra en modo bootloader apretando el pulsador SW1, y luego se ejecuta el script en python

Os adjunto el programa python. Yo lo estoy ejecutando en Linux, pero es multiplataforma. Sólo tenéis que cambiar el nombre del puerto serie

El script es este:



Saludos, Obijuan
boot-01.py

Foxy CTG21

unread,
Aug 27, 2019, 7:14:51 AM8/27/19
to FPGAwars: explorando el lado libre
Hola me da curiosidad de manejar ese bloque para algunos proyectos, pero no encuentro información principal o el github.

Alexandre Dumont

unread,
Aug 27, 2019, 7:26:44 AM8/27/19
to FPGAwars: explorando el lado libre
Que interesante este hilo, estaba pensando implementar algo así en mi HRM Cpu precisamente. Que guay.

Haces referencia a bootloader software VS hardware, ¿donde puedo ver más info sobre las diferencias? Si lo que implementas aquí es un BL hw, como sería uno sw?


Respecto al comentario de que para cambiar el programa de la ROM (hasta ahora) es necesario resintetizar todo y puede llegar a tardar mucho tiempo, yo lo que empleo en mi HRM CPU es la herramienta icebram que se puede usar para sustituir una rom directamente en el fichero generado por el arachne-pnr, antes de generar de nuevo el Bitstream con icepack. Lo explica Clifford aquí:

https://stackoverflow.com/questions/36852808/modify-ice40-bitstream-to-load-new-block-ram-content

Es muy práctico y rápido (te ahorras los pasos de yosys y arachne-pnr, que son los que tardan, si lo único que ha cambiado es el contenido de una rom).

charli va

unread,
Aug 27, 2019, 7:34:28 AM8/27/19
to fpga-wars-explora...@googlegroups.com
Muchas gracias Juan!! está quedando fenomental!! y por otro lado Alexandre, muchísimas gracias por el aporte del hilo de Clifford!! nos va a venir de perlas :)

--
Has recibido este mensaje porque estás suscrito al grupo "FPGAwars: explorando el lado libre" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a fpga-wars-explorando-el...@googlegroups.com.

Juan Gonzalez Gomez

unread,
Aug 27, 2019, 7:50:16 AM8/27/19
to FPGA-WARS: explorando el lado libre
El bloque lo acabas de ver en tiempo real, recién creado 😂😂😂😂  Todavía no está documentado ni incluido en la colección Jedi. Son pruebas de concepto. Pero en seguida estará subido

Saludos, Obijuan

--
Has recibido este mensaje porque estás suscrito al grupo "FPGAwars: explorando el lado libre" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a fpga-wars-explorando-el...@googlegroups.com.

Juan Gonzalez Gomez

unread,
Aug 27, 2019, 7:56:39 AM8/27/19
to FPGA-WARS: explorando el lado libre
¡iGracias Alexandre!

Recordaba que había una herramienta de clifford para hacerlo, pero no tenía a mano los detalles. ¡Gracias por el enlace! Es exactamente eso lo que necesitamos. Hay que integrarlo primero en apio y luego en icestudio. Es una herramienta muy muy importante! (Y que sólo está disponible para FPGAs libres ya que en las privativas no existe documentación sobre el bitstream, por lo que nadie lo puede hacer, salvo el fabricante)

El Bootloader software es "el de toda vida": Es un firmaware que se ejecuta en tu micro nada más arrancar (como una especie de mini-bios). Lo que hace es leer los bytes que recibe del puerto serie y los guarda en la memoria. Una vez terminado salta a la dirección de comienzo donde ha cargado el programa

La carga de los Arduinos, por ejemplo, es posible por el bootloader firmware que tienen grabado

Saludos, Obijuan


El mar., 27 ago. 2019 a las 13:26, Alexandre Dumont (<adu...@gmail.com>) escribió:
--
Has recibido este mensaje porque estás suscrito al grupo "FPGAwars: explorando el lado libre" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a fpga-wars-explorando-el...@googlegroups.com.

Juan Gonzalez Gomez

unread,
Aug 27, 2019, 8:09:43 AM8/27/19
to FPGA-WARS: explorando el lado libre
Todas las memorias y bloques que estoy usando sí están en la colección Jed (development). Los .ice de los ejemplos son los que no están en github todavía, por eso os los he subido como adjuntos

anunez

unread,
Aug 27, 2019, 8:26:14 AM8/27/19
to fpga-wars-explora...@googlegroups.com
Gracias Obijuan,

Al final encontré una ice40-hx8k con capacidad para meter los PLB's, y me sirve hasta que vuelva a tener la alhambra II. Uso duponts porque no tiene botones. Funciona perfecto.. sigo tus pasos.. 
Gracias,
Agustin (@agnuca)


Obijuan

unread,
Aug 27, 2019, 8:32:16 AM8/27/19
to FPGAwars: explorando el lado libre

El circuito de Bootloader, para esta memoria de 2 Bytes lo he metido en  su propio bloque 
Así queda el ejemplo:


Saludos, Obijuan

bootloader-05.ice

Obijuan

unread,
Aug 27, 2019, 8:35:02 AM8/27/19
to FPGAwars: explorando el lado libre
¡Estupendo Agustín!

¡Gracias por el feedback! :-)

Cuantos más seamos probándolo todo, mucho mejor

Saludos, Obijuan
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a fpga-wars-explorando-el-lado-libre+unsubscribe@googlegroups.com.

--
Has recibido este mensaje porque estás suscrito al grupo "FPGAwars: explorando el lado libre" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a fpga-wars-explorando-el-lado-libre+unsubscribe@googlegroups.com.

Alexandre Dumont

unread,
Aug 27, 2019, 3:34:42 PM8/27/19
to FPGAwars: explorando el lado libre
Me surge una duda, en el caso de Arduino por ejemplo, cuando flasheamos el programa desde el PC, imagino que se envía algún tipo de señal al Arduino, que lo pone en modo de "flasheo", luego supongo que por uart se envía el programa, y luego, se quita el modo de flasheo.

En tu versión del bootloader Juan, entiendo que lo pones en ese modo y lo quitas con los botones 1 y 2. ¿ Eso se podria hacer por el USB, como lo hace el programador de Arduino? (no se si me he explicado bien... ¿Existe alguna señal más que podamos usar?

En el pcf de la Alhambra II esos son las señales del FTD serial port, a parte del RX/TX, ¿se podría usar algún otro para sustituir a sw1/sw2 y hacerlo todo por software sin tener que pulsar botones? 


# --- FTDI 1: (Serial port)
set_io --warn-no-port DCD 47 # output
set_io --warn-no-port DSR 48 # output
set_io --warn-no-port DTR 52 # input
set_io --warn-no-port CTS 56 # output
set_io --warn-no-port RTS 60 # input
set_io --warn-no-port TX 61 # output
set_io --warn-no-port RX 62 # input


Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a fpga-wars-explorando-el...@googlegroups.com.

--
Has recibido este mensaje porque estás suscrito al grupo "FPGAwars: explorando el lado libre" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a fpga-wars-explorando-el...@googlegroups.com.

--
Has recibido este mensaje porque estás suscrito a un tema del grupo "FPGAwars: explorando el lado libre" de Grupos de Google.
Para cancelar la suscripción a este tema, visita https://groups.google.com/d/topic/fpga-wars-explorando-el-lado-libre/P2_NA1t9h-M/unsubscribe.
Para cancelar la suscripción a este grupo y a todos sus temas, envía un correo electrónico a fpga-wars-explorando-el...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/fpga-wars-explorando-el-lado-libre/2aee5b68-7c9b-4d12-93a9-06d679e090e7%40googlegroups.com.

Juan Gonzalez Gomez

unread,
Aug 27, 2019, 4:18:36 PM8/27/19
to FPGA-WARS: explorando el lado libre
Si, por supuesto. Típicamente se usan las señales DTR ó RTS del puerto serie para hacer el reset del micro y que arranque el boorloader

Así lo implementé también en el bootloader del micro símplez [1]. Sólo hay que ejecutar el programa y se carga sin pulsar ningún botón

En esta prueba "hola mundo" con memoria de 2 bytes lo hice manual. Pero es súper fácil hacerlo automático

También es posible hacer reset directamente de la fpga a través del ftdi, usando la libftdi (como hace iceprog) 

En cuanto lo tenga funcionando para el z80 lo paso a reset automático

Saludos, Obijuan




Obijuan

unread,
Sep 1, 2019, 6:50:34 AM9/1/19
to FPGAwars: explorando el lado libre
Hola!


Ya he perfeccionado el Bootloader. El concepto funciona muy bien. En este vídeo podéis ver un ejemplo de carga de una memoria de 16KB, aunque la secuencia que se muestra en los LEDs es de sólo 16 estados


Se hace el reset automáticamente al ejecutar el script de carga. El vídeo aprieto el reset al principio para que se vea la secuencia pre-grabada. Las dos siguientes se cargan desde el PC al ejecutar el script python



He creado un bloque nuevo de memoria: memoria-16KB-boot (está en la colección Jedi de desarrollo).  Se trata de una memoria de 16KB que tiene incorporada la lógica para cargar la memoria desde el exterior. El receptor serie no lo he integrado dentro, para así poder cargarla desde otros luegares: spi, i2c, etc...

Fijaros en los recursos ocupados por este circuito: BRAMs: 32/32. El sisntetizador lo detcta como una memoria de 16KB y asigna todos los bloques de memoria disponibles. Este es el tamaño máximo de memoria que podemos tener en la Alhambra II

Por las pruebas que he estado haciendo... madre mía, esto es super cómodo. Ahora lo voy a probar con el Z80, para cargar programas desde el puerto serie. En el hilo del Z80 os contaré los avances

Saludos, Obijuan

09-test-memory-16KB.ice

charli va

unread,
Sep 1, 2019, 8:30:19 AM9/1/19
to fpga-wars-explora...@googlegroups.com
Me encanta!! Deseando probarlo!!!

--
Has recibido este mensaje porque estás suscrito al grupo "FPGAwars: explorando el lado libre" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a fpga-wars-explorando-el...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages