SPL2019 es una conferencia de lógica programable, de la cual me enteré en la
lista de embebidos.
Me hubiese gustado asistir pero tiene poco y nada que ver con mi trabajo, así que no tengo punto de negociación para ausentarme tantos días.
Además tengo una alta ignoracia en el tema y aunque seguro que iba a aprender mucho si asistía, al no ponerlo rápidamente en práctica pronto se me iba a disipar.
Pero, habían varios workshops, uno de los cuales aposté estuviera al alcance de mis limitadas facultades.
- WS1 (Xilinx, English):
FPGA-based Accelerated Cloud Computing with AWS EC2 F1 and SDAccel
- WS2 (Xilinx, English):
PYNQ: Python Productivity for Zynq
- WS3 (UAM, Spanish):
FPGA SoC design from a higher level of abstraction: SDSoC and HLS
- WS4 (Satellogic, Spanish):
Testbenchs in Python: COCOTB
Lo dictó un señor,
Parimal Patel que la tiene muy clara y explica muy bien, además de participar del proyecto activamente.
La placa utilizada para las prácticas fue la
PYNQ-Z2 que obviamente, es rosa.
Se parece a la
Parallella de la que tanto vengo
hablando en que
tiene un Zynq 70x0, pero un poquito más power, un 7020 en lugar de un
7010. Además no tiene el chip característico de la Parallella, que son
los 16 cores del chip
Epiphany. Extra tiene... mejor pongo una tabla
comparativa:
|
PYNQ-Z2 |
Parallella |
Características |
|
|
Zynq |
7020 |
7010 |
RAM [MB] |
512 |
1024 |
Flash [MB] |
16 |
(*) |
SDCard |
si |
si |
Ethernet 1Gb |
si |
si |
USB 2.0 host |
si |
si |
Audio |
si |
hdmi? |
HDMI out |
si |
si |
HDMI in |
si |
no |
Epiphany |
no |
si |
Power [v] |
7-12 |
5 (**) |
Raspberry Pi |
si |
|
Arduino shield |
si |
|
Porcupine (***) |
|
si |
PMOD |
2 |
1 (***) |
JTAG |
? |
si (***) |
Raspberry Pi Camera |
|
si |
Switches, botones y leds |
2+4+4 |
|
Status proyecto |
Vivo |
Muerto |
(*) No me queda claro por la documentación, tiene entre 32 y 128 Mb dice, pero no sé si se adhieren a que Mb es Mbit.
(**) La Parallella es excepcionalmente fastidiosa con la alimentación.
(***) Lo que tiene la Parallella es el
Porcupine, que provee además de un PMOD, un
JTAG y la interfaz para la cámara de la Raspberry Pi, "
240 backside pins and a peak bandwidth of 50 Gbps". Entiendo que las interfaces de la PYNQ son todas lentas, o sea si quisiera sacar video en tiempo real o sería por ethernet o USB.
Volviendo a la PYNQ-Z2, como se puede ver, tiene los conectores de Arduino y Raspberry, lo
que sumando a los
PMOD+
Grove o Arduino+Grove, permite adosarle una
cantidad infernal de accesorios con gran sencillez.
Tambien es la más
barata (u$s120) de
las otras placas soportadas oficialmente por PYNQ. Nos chismorreó Patel que en unos tres
meses (agosto 2019) sale una ZCU no tan cara como la
ZCU104 u$s800 (y ni te digo la
ZCU111 u$s8000), pero no sé si
más que esta.
¿Y cómo funciona esto?
Yo
entiendo que entendí, pero por la dudas no voy a entrar en mucho
detalles por si me he confundido no esparcir errores. Intentaré ser
breve y preciso y para la información posta
RTFM. Si alguien que sabe encuentra algún error, me avisa por favor.
Tenemos
los
overlays, que proveen en la PL una serie de componentes comunes. Por
ejemplo el
overlay "
base.bit" tiene los conectores para PMOD, Arduino Shield, Raspberry Pi y video HDMI.
Lo que tienen en común es
que usan IOP (Input Output Processors), en este caso son MicroBlazes
para parametrizar en tiempo de pre-ejecución que hay en los pines en
lugar de que estén hardcodeado en el bitstream. Luego, durante la
ejecución lo implementan.
Los IOPs son "soft processors", se implementan en la PL si hacen falta, en contraste con los cores ARM que están al costadito y que siempre están.
Dicho de otra manera, entre los buses SPI, UART o GPIO y el componente externo en sí, en lugar de ya estar configurado, tiene una capa que se adapta programáticamente. Entiendo que esto sólo debe funcionar con interfaces de baja velocidad, pues el IOP no deja de ser una CPU y siempre va a ser más lenta que un circuito combinacional y unos pocos flip-flops.
El modo de trabajar es en
cierto modo como usar un Arduino con
Firmata, usado por
Processing o algo parecido,
Scratch. El micro Arduino en un caso, el
MicroBlaze en este, no hace procesamiento, sólo el pasaje de señales de
los pines físicos al procesador "real", en el caso de Firmata la PC donde
tenés Processing, en este los cores de la Zynq 7020.
Concretamente,
si leo un termómetro en PMODA y quiero mostrar en un OLED en PMODB,
el valor pasa por el core ARM, mientras que con VHDL se podría pasar directamente, pero
perdiendo la flexibilidad y implicando mayor conocimiento por parte de
quien implemente.
Está claro que esto está orientado a la gente que sabe programar y tiene una idea no muy profunda de hardware, que el lo que dice el proyecto, ningún engaño.
Un ejercicio que hicimos con Facundo, que fué el que dictó en SASE 2017 el workshop de EDU-CIAA-NXP multicore y me tocó de compañerito es este:
from pynq.overlays.base import BaseOverlay
from pynq.lib.pmod import Pmod_OLED
from pynq.lib.pmod import Grove
from pynq.lib.pmod import PMOD_GROVE_G4
from time import sleep
base = BaseOverlay(“base.bit”)
oled = Pmod_OLED(base.PMODA)
oled.clear()
temp = Grove_TMP(base.PMODB, PMOD_GROVE_G4)
while 1:
temperature = temp.read()
oled.write(temperature)
sleep(1)
Ojo, puede ser que en el dibujito estén invertidos PMODA y PMODB y sin duda en oled.write() había algo más, probablemente un format() cerquita de temperature.
Por
otro lado, en contraposición y recuperando la independiencia del FPGA,
está otro
overlay, "
logictools.bit" que implementa varios "generadores". El
procesamiento está en la FPGA, pero el core ARM le dice que va a hacer
mediante una magia que no me atrevo a describir y que entiendo modifica
las LUTs sueltas, no reenviando el bitstream completo. En cierto
modo es como si vía Firmata se le enviara un programa a un módulo wifi
ESP8266 para que lo ejecute independientemente.
No lo practicamos, así que cuento así nomas los generadores:
Boolean generator
es para armar circuitos combinacionales. Se le provee una o más funciones lógicas tipo
LD2 = PB3 ^ PB0
y mágicamente LD2 será una salida función de las entradas PB0 y PB3
Pattern generator
es para armar patrones, se le provee con un json parecido a esto:
up_counter = {
‘signal’ : [
[‘stimulus’,
{‘name’: ‘bit0’, ‘pin’:’D0’, ‘wave’: ‘lh’ * 8 },
{‘name’: ‘bit1’, ‘pin’:’D1’, ‘wave’: ‘l.h.’ * 4 },
{‘name’: ‘bit2’, ‘pin’:’D2’, ‘wave’: ‘l...h...’ * 2},
etc
]
]
}
FSM generator
Se determinan unas entradas, unas salidas y la tabla de transiciones y... ocurre.
Trace analyzer
Se utiliza para capturar las entradas y salidas. En los ejemplos vistos se usa para ver lo que hacen los generadores.
En
el caso de PYNQ hay una capa extra, que es Jupyter que permite que la
interfaz sea web, usando un concepto llamado "notebooks", cuando sepa más, si lo llega a ocurrir, contaré.
Seguro que se debe poder usar desde una terminal pero
no lo puedo afirmar hasta que le eche mano otra vez a una placa y haga las pruebas pertinentes o lo
lea accidentalmente en la sección "Running from the command line".
La idea es que uno hace o consigue un
overlay, implementa o consigue los c-drivers, implementa o consigue los wrappers, arma un cuaderno y tiene así un proyecto.
Si uno no agrega nada nuevo, usando uno de los
overlays base.bit o
logictools.bit puede hacer un montón de cosas sin bajarse de IPython.
¿Por qué me interesa?
Esta
placa me interesa particularmente por el HDMI in, pues se puede tomar
la salida de la computadora, pasarla por la placa, hacerle algún proceso
y volcarla en la pantalla, para aprender a hacer cosas como:
- Prender leds de colores detrás del monitor dependiendo de la imagen que haya, se lo llama ....
- Agregar cosas a la imagen, como pueden ser letras.
- Botón de pausa, pero perdiendo los frames mientras dure ésta.
- Sacar fotos a la imagen.
- Grabar el video.
Tambien, a mi backlog de proyectos inalcanzables le agrego el port de
PYNQ a la Parallella, que sorprendentemente se llamará... ¡ParaPYNQ! y
sin ninguna sorpresa me llevará mucho tiempo iniciar, si es que lo
hago. Patel está al tanto de mi propósito y me ha ofrecido apoyo, así que... tengo que hacerlo.
Dos sitios con mucha info y código:
http://www.pynq.io/
https://github.com/xilinx/pynq