2020/04/05

Generador precario de señales cuadradas con FPGA

Contexto



No estabas leyendo aún pues no terminé con mi intento de hacer que un 8051 recuperado de un disco rígido ejecutara un programa mío usando la ROM externa, cuando nos vimos en la necesidad de demultiplexar datos y direcciones de la ROM y no teníamos un 74ls373 sino un 74ls374 que tiene señal de clock entonces le queríamos dar ese clock, muy alto y no sabemos electrónica básica así que vamos usar una FPFA en forma de iCEstick.

Va a estar en uno de estos días en
https://seguridad-agile.blogspot.com/2020/04/rescatando-un-8051.html

 

Mejor explicado:


Quiero usar una FPGA como generador de señales con frecuencias de hasta 12 Mhz, que por un lado es lo que necesito para otro proyecto y por el otro es lo que me da un iCEstick.


Para programar necesito usar Lattice iCEcube2 que tengo instalado en una máquina virtual con una licencia que venció en el 2018, casi sin usarla, lamentablemente no me di cuenta y la "quemé" por decir de una manera.

Lo más fácil debe ser obtener una nueva licencia, pero eso es un conocimiento de gestión y burocracia, no quiero decir que no lo necesite, pero no tengo ganas de adquirirlo o reforzarlo, así que tomaré un

<desvío>

y le cambiaré la fecha para que iCEcube piense que el tiempo no ha pasado.

Cuando arranque debo tener la precaución de que no tome la fecha y hora por NTP y setearle en el BIOS la fecha que quiero.

Para lo primero basta con desconectar de la red:



Ejemplo sobre otra máquina virtual cualquiera


Luego fijarse cuándo fué la última vez que la encendiste poniéndo el cursor sobre la máquina, como para que no viaje al pasado, luego calculás el tiempo y le cambiás el BIOS:








VBoxManage modifyvm "CIAA Linux" --biossystemtimeoffset  -69379200000

siendo  -31536000000 * 2.2 =  -69379200000,  esto es un año y 10 semanas para atrás, no fué tan difícil, ni califica de subdesvio.



</desvío> 

La vida no es fácil, en esa virtual no tenía mi proyecto de blinky que es el que pienso adaptar, está en otra cuya clave no recuerdo y es Windows 10 y debo tomar otro

<desvío>

Quise montar con una recetita que tenía para luego ejecutar chntpw, pero no, así que tomé otro camino, arrancar desde un linux, pero por ser uefi se resistó.

Mi receta fué:
  • Decirle a virtualbox que no arranque del disco, sólo de cdrom.
  • Conectarle un boot uefi, tenía un puppy.
  • Ver las particiones con fdisk
  • Montarla con mount
  • Ubicarme en el lugar correcto 
  • Ejecutar chntpw -i y pedirle blanqueo, que es lo que no sé ve pues es lo que sigue, pero ya me aburrí de esto.
 



</desvío>

Habiendo tomado el control de la situación, sólo tengo que adaptar el ejemplo de blinky para que en lugar de prender y apagar leds a una velocidad humanamente perceptible, prenda y apague pines a varios Mhz.

¡Maldición! No es Verilog, es VHDL, que es lo que había aprendido originalmente de FPGA y luego olvidé por falta de uso. Tengo entonces varios desafíos:

  • Recuperar VHDL, no debería haber problema pues es sólo mirar fijo.
  • Obtener el clock más alto posible, fácil, mirando el archivo .scf del proyecto hallé definido un clock CLK_32MHZ.
  • Identificar los pines, no hay problema, es sólo mirar una tablita en algún lado.
  • Grabarlo desde la virtual, supongo que ya lo hice antes sin problemas.
  • Hacer la adaptación eléctrica, dado que el alto es 3.3 y no va a leer, no debería haber problema.



Al blinky original lo había toqueteado para mostrar sequencias de leds distintas, pero eso fue hace ya dos años antes de saber casi nada.


Aunque a un nivel muy íntimo entiendo bastante lo que hice y los porqués, no quiero intentar explicarlo pues probablemente esa explicación no sólo sea mala si no perjudicial.

Estos son los pasos que seguí, más que nada como nota para mí, no estoy haciendo un tutorial de VHDL en iCEcube2 Lattice, ahora estoy en sintonía con Verilog en Vivado Xilinx. Podría mejor partir del ejemplo Verilog, pero está bueno ponerle un poco de dificultad, de hecho mi primer lenguaje fué VHDL.


Asi que esto, a menos que tengas exactamente el mismo equipo probablemente no te sirva para nada y puedas saltar hasta el código VHDL.

Si hubiese querido (podido) usar un proyecto nuevo, tendría que haber:


  • New Project
  • Device Family: iCE40
  • Device :       HX1K
  • Device Package: TQ144
  • Next
  • Buscar la carpeta del proyecto
  • Crear un archivo .v
  • Incorporarlo a design files
  • Abrir el archivo y copiar y pegar todo lo que quieras


No se pueden abrir dos proyectos a la vez, pero si dos IDEs a la vez cada una con su proyecto.

No pude hacer un proyecto de cero. Tomé entonces el camino habitual de tomar el blinky que funciona y tras bastante renegar llegué a esto:


library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity Blink is
  port(
    pmod1  : out std_logic;
    pmod2  : out std_logic;
    pmod3  : out std_logic;
    pmod4  : out std_logic;
    clk    : in  std_logic
  );
end Blink;

architecture Behavior of Blink is
  signal count : std_logic_vector(23 downto 0);
begin
  pmod1 <= clk;
  pmod2 <= count(0);
  pmod3 <= count(1);
  pmod4 <= count(2);

  process(clk)
    begin
      count <= count + 1;
    end process;
end Behavior;

Si algo te parece raro puede ser por que quité el código que a la vez hace un blink rotativo con los cuatro leds y blinky central.

No es mucha magia, en pmod1 tenés la 12Mhz, en pmod2 6Mhz y así...

Puse esto en los constraints, pero no me preguntes exactamente en qué archivos:

define_clock -name {icetest|clk} {p:icetest|clk} 
   -period 7.838 -clockgroup Autoconstr_clkgroup_0
   -rise 0.000 -fall 3.919 -route 0.000

set_io clk 21

set_io pmod1 78
set_io pmod2 79
set_io pmod3 80



Le das a

Run all

y tenés un

Bit Stream Generator succeeded

Fijate que si modificaste un archivo y no lo salvaste, iCEcube2 es bastante incapaz... de avistarte.

Luego abrís el Diamond Programmer, todo lo que sigue está en:

https://www.latticesemi.com/icestick -> documentation -> iCEstick User Manual

  • Blank project
  • Detect cable ( a mi me aparece cable HW-usbn-2b (ftdi) port ftusb-0 )
  • device family ice40
  • device ice40hx1k
  • operation
    • access mode: spi flash programming
    • vendor: micron
    • device spi-n25q032
    • package : 8 pin vdfpn8
  •  file: implmnt -> sbt -> outputs -> bitmap -> file.bin


Si tenes la IDE en una virtual como yo, no te olvides de (re)conectar el dispositivo con:

  • virtual box -> devices -> sub -> lattice ftusb





Si la próxima vez que intentar programar la FPGA te equivocás por que no ajustaste todo bien, tipo dispositivo y método de acceso y de ahí en más te dice error de programación, configurás bien y le das un "erase all", restaurás la configuración y si tenés la misma suerte que yo, vuelve a andar

Sólo me queda el último punto, que la salida de 3.3v pueda alimentar un chip de 5v como un arduino o un 8051 y a la vez no se dañe.

Para eso tengo que mirar fijo los siguiente conceptos:

  • HMOS por el lado del 8051
  • SB_LVCMOS por el lado del iCEstick
¿SB_LVCMOS? ¿Cómo me enteré que el iCEstick usa eso? Muy fácil, por el reporte de pines:

78, PIO, pmod1, Output, , SB_LVCMOS, No Pull Up, Simple Output, rightBank
79, PIO, pmod2, Output, , SB_LVCMOS, No Pull Up, Simple Output, rightBank
80, PIO, pmod3, Output, , SB_LVCMOS, No Pull Up, Simple Output, rightBank
81, PIO, pmod4, Output, , SB_LVCMOS, No Pull Up, Simple Output, rightBank

¿HMOS? más fácil aún, lo dice la datasheet del 8051.

He expresado al menos últimamente mi aversión a usar google para resolver problemas, pero mi electrónica es tan precaria y llevo tantas horas a lo largo de tantos días acercándome a un final tan incierto que estoy dispuesto a casi cualquier cosa.

how to connect a SB_LVCMOS output to a HMOS input

O no se llama así o a nadie le ha interesado hacer o es tán fácil que nadie lo ha publicado o google no sabe.

Puedo aflojar un poco ahora que aprendí que HMOS es High Density NMOS y quitar SB, pues en todos los resultado previos aparece LVCMOS.

how to connect a LVCMOS output to a NMOS input

Mis conocimientos de electrónica son muy básicos e insuficientes para resolver esto con un transistor, cosa que intenté, pero sólo funcionó hasta unos 180Khz, para frecuencias mayores hace falta saber más.

Lo que hice entones fué usar un 74ls08, que es una puerta AND y que dice según su datasheet que con 2v le alcanza para pensar que es un true y que tiene una frecuencia de trabajo mucho mayor.



Fijate que cuadradita que estaba la señal azul en la imagen anterior

Quedó horrible la adaptación a 5v, apuesto a que eso se debe a la ausencia de algunos capacitores en los lugares apropiados, si alguien de embebidos o que sepa electróncia lee esto y se apiada de mí, me va a corregir.

Conclusión

  • He podido obtener una POC de un generador de señales cuadradas usando un FPGA que daba por inaproblechable.
  • Para usarlo con 3.3v está ok.
  • Tiene hardcodeadas la cuatro frecuencias, algún día encararé generarle algún tipo de posibilidad de variar.
  • Con la adaptación a 5, está horrible, luego sabré si funciona para mi proyecto de 8051

2 comentarios:

  1. Hola Carlos, cómo estás? Llegué a esta publicación por el mail que mandaste a embeb32.

    El problema con la compuerta and puede ser su capacidad de entrada. Puede ser que esta sea muy grande para la salida de la FPGA, y por eso se está "rompiendo" tu señal de 12 MHz, que sin carga funcionaba bien. Tampoco estoy seguro de que esas compuertas puedan funcionar a 12 MHz, habría que ver cuales son sus tiempos de crecimiento y caída. Las datasheets que encontré no especificaban este tiempo sino el de propagación, que en principio no debería molestarte. Habría que investigar si en alguna documentación esto está especificado.

    Se me ocurre, no es mejor usar un cristal, como lo recomiendan en la hoja de datos del micro? Va ser mucho más facil, es simplemente conectar un cristal y dos capacitores. No vas a tener que mantener código en VHDL, no vas a tener que mantener todo el stack para programar la FPGA que como contas vos te trajo problemas. Entiendo que en estos días de cuarentena está complicado conseguir componentes, pero me parece que sería la solución óptima.

    Como alternativa inmediata, se me ocurre que podes probar con una frecuencia más baja, y ver si funciona.

    ResponderEliminar
  2. Hola Miguel

    Con frecuencias más bajas funciona ok.

    Con respecto al cristal, ya está, el micro lo usa para su clock. La señal de 12 la quiero para compensar la diferencia de funcionamiento entre el 74ls373 y 374, pero eso lo voy a explicar mucho mejor uno de estos días cuando termine de hacer funcionar el 8051.

    Mi objetivo no es el resultado si no el camino, por lo cual hay muchas decisiones que pueden parecer completamente irracionales e ineficientes, pero son las que más me hacen aprender y practicar.

    Tambien es verdad que estoy intentando arreglarme con lo que tengo en el baul.

    ResponderEliminar