2021/03/21

Refactorizaciones de MD5 en FPGA: 2 VIO

El contexto de esta nota está en la anterior.

Habiendo recuperado el proyecto y migrado a Vivado 2019.2 (cosa que me olvidé de mencionar antes) y hecho algunas correcciones y la simulación, la siguiente tarea es agregar VIO.

 

VIO es Virtual Input Output, un IP que te permite interactuar desde Vivado con la placa conectándole entradas y salidas virtuales, esto es muy útil para interactuar con una placa que no tiene leds, botones y switches, por ejemplo las que están en AWS. Si a esto le sumanos el programa hw_server, que permite "compartir" una placa en red, podemos tener la placa en casa y con un tunel ssh programarla y verla en acción desde afuera. Si le sumanos un par de dólares la hora, podemos probarlo en AWS, me han dicho que se hace así o similar, pero, otro día.

El escenario que más me habilita ahora es migrar de la Nexys4DDR que tiene 8 dígitos de siete segmentos, 16 leds, 16 switches y 5 botones a la PYNQ que tiene 4 leds, 2 switches y 4 botones o incluso a la Parallella, que tiene... nada.

De no utilizar VIO para poder interactuar con el circuito debería hacerlo vía AXI desde las CPUs de las ZYNQ (PYNQ y Parallella son ZYNQ), cosa que sé a un nivel muy elemental según he practicado en PYNQ en el 2020, pero es el objetivo final de esta seguidilla de pruebas, no nos adelantemos.

Pasamos de un una interfaz muy sencilla para ver en el resultado gracias a los 8 dígitos de 7 segmentos pero muy díficil de cambiar el hash a buscar, por ahora tengo unos precargados  que se seleccionan con 4 switches.

 

Para aplicar VIO hay que agregarlo con IP Catalog y definir sus características.

Recordá que los pasos que anoto acá son más un machete para mí que un tutorial para vos, así que no capturo paso a paso, blogger no es una buena herramienta para hacer esto, quizás junte ganas y haga un video en algún momento.


IP Catalog ->

Buscar VIO

Solapa General options
   Input probe count (en mi caso dos pues quiero separar el contador del estado)
   Output probe count

Solapa PROBE_IN ports
   ajustar cantidad de bits
Solapa PROBE_OUT ports
   ajustar cantidad de bits y valores iniciales


Observá que el input y output es respecto al VIO, es complementario a tus inputs y outputs.


Al igual que en el caso de la simulación, he optado por crear un nuevo top que instancie al existente en lugar de incorporar el VIO en el top original. De un modo u otro, en el template obtenés lo que hay que pegar en tu código:

 

Project manager
  sources
    IP
      vio_0
        instantation template
          vio_0.vho (VHDL)
          vio_0.veo (Verilog) 

 

vio_0 vio_driver (
 .clk(CLK),              // input  wire clk
 .probe_in0(probe_in0),  // input  wire [ 4 : 0] probe_in0
 .probe_in1(probe_in1),  // input  wire [31 : 0] probe_in1
 .probe_out0(probe_out0) // output wire [ 4 : 0] probe_out0
);

Customize IP
Customize IP

 

 

 

Salvo el clock y las entradas y salidas que quieras conservar de la placa, hay que eliminarlas del xdc y pasarlas al nuevo top. Dejé el botón de reset:


## Clock signal
set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 }
      [get_ports {  CLK }];
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5}
      [get_ports {  CLK }];

##Buttons
set_property -dict { PACKAGE_PIN C12   IOSTANDARD LVCMOS33 }
      [get_ports { CPU_RESETN }];



Podés conectar directamente probe_in y probe_out, pero si usás unos wires en el medio, luego la vista de VIO se dá cuenta y usa esos nombres, que es mucho más cómodo.

 

 

   wire [ 4 : 0] probe_in0;
   wire [31 : 0] probe_in1;
   wire [ 4 : 0] probe_out0;
  
   assign probe_in0  = { status_paused,
                         status_running,
                         status_warming,
                         status_found,
                         status_done };
   assign probe_out0 = { enable_switch, target_switch };
   assign probe_in1  = target;

 


Se puede apreciar que el VIO ocupa poco lugar:

 

VIO footprint
VIO footprint
 

 

Lo que cambia con respecto a la grabación normal es que en el diálogo ahora hay un archivo extra, que es el VIO:

 

 

Archivo extra
Archivo extra



 Así quedan las conexiones entre el top original y VIO:


VIO conectado
VIO conectado
 


Esa diferencia entre [29:0] y [31:0] en counter es por que, recordá, los tres bits menos significativos no son parte del contador, dependen de a que pipeline nos estemos refiriendo, así que le ponemos 0:

 

assign target = {counter_out,3'b000};

 

Esa característica me hizo perder varias horas pues la adaptación la estaba haciendo en el VIO en lugar de lo más cerca posible de la diferencia: lección, hay que ser lo menos inteligente posible, si hay algo raro, debe ser lo más reducido posible.

Para comprender y corregir, tuve que volver un paso atrás a simular, pero sin el VIO, sólo con el cambio que éste había producido. Queda pendiente simular con VIO si es que es posible.

En algún momento haré que se pongan los tres bits del pipeline que lo halló.

Al descargar el bitstream se abre un dashboard que desaparece si te vas al Project Manager, pero regresa si volvés a Program & Debug.

VIO en acción
VIO en acción

 


Si no hubiera puesto los wires que mencioné antes, diría probe_xxx, menos legible.


El mensaje original es 0xBEBACAFE, pero tal como he mencionado, este diseño trae un valor cercano, me falta investigar bien esa diferencia para compensarla, pero para elllo, necesito pasar al siguiente nivel, sacarle realmente el jugo al VIO, voy a prescindir del selector de hashes e ingresar hashes arbitrarios... en la próxima entrada.

El código en github

Notas relacionadas





No hay comentarios:

Publicar un comentario