¿Problema de tiempo/búfer con EPP de Digilent en Basys2?

Tengo un FPGA Digilent Basys2 y estoy implementando la interfaz EPP descrita en http://www.digilentinc.com/Data/Products/ADEPT/DpimRef%20programmers%20manual.pdf . Esto permite que un programa llamado Adept envíe y reciba bytes desde un diseño de FPGA a través del cable USB.

Después de seguir esas instrucciones, tenía algo que parecía funcionar. Podría enviar bytes desde Adept y se mostrarían con éxito en la pantalla de siete segmentos. Desafortunadamente, cuando envié un archivo de 100 bytes para almacenarlo en una matriz de registros, solo llegaron 83 bytes. (Es un poco complicado depurar en esta situación, porque hay pocas salidas simples en el FPGA, y usar Adept para leer los bytes del FPGA abre la posibilidad de que sea la implementación de lectura la que tenga errores. Terminé agregando el capacidad de recorrer la matriz mostrando cada byte a su vez).

Reescribí mi implementación varias veces y miré los ejemplos de otras personas (en su mayoría estaban en VHDL), pero aún así no es confiable. Algunas escrituras, incluso bytes individuales de uno en uno, simplemente no son detectadas por el diseño, aunque Adept no informa ningún error.

Actualización: probé el diseño de muestra VHDL

Ahora logré ejecutar el código y el diseño aquí: http://hamsterworks.co.nz/mediawiki/index.php/Digilent_EPP_Performance

Funciona, pero un contador simple que agregué muestra que se realizaron un poco más de escritura de lo esperado, en algunas pruebas repetidas que ejecuté (recargué el diseño, luego envié un archivo usando Adept):

Expected    Got
  50        51 to 55
 100        105 to 108
 200        206 to 215

Para el programa C++ compilado de ese tutorial, se enviaron 1440000 = 0 (mod 256) bytes, pero el número escrito fue 32 (mod 256) (¡solo tengo 8 LED!). En otro los números eran 1430000 = 240 (mod 256) vs 253 (mod 256).

Así que sigo pensando que hay una cuestión de sincronización. ¿Alguien con un Basys 2 puede hacer el mismo experimento? Mi VHDL ligeramente alterado está en https://gist.github.com/ejrh/6ba768499319e9945bd0

Pequeño testcase de antes de aprender VHDL

Terminé con un pequeño caso de prueba para la señal WRITE de EPP:

input wire usb_write;  // in constraints file: NET "usb_write" LOC = "C2";
reg prev_write = 1;    // assume initially high
reg [9:0] write_count = 0;

always @(posedge mclk) begin
    if (usb_write != prev_write) begin
        write_count <= write_count + 1;
    end
    prev_write <= usb_write;
end

// display write_count on SSD
// display prev_write on LED 0

Por lo general, cuando envío un byte usando adept, write_countse incrementa en 2, como se esperaba. (WRITE baja para escribir un byte de dirección y un byte de datos, luego vuelve a alto). El LED permanece encendido entre operaciones, indicando que prev_writeestá alto.

Pero a veces, el conteo solo se incrementa en 1, mientras que el led aún vuelve a estar alto. Es como si diferentes partes de mi always @(posedge mclk)bloque estuvieran usando diferentes valores de usb_write.

¿Hay algún tipo de almacenamiento en búfer que deba hacer en estos cables de entrada/salida? No he encontrado ningún ejemplo para esto.

Más tarde hoy actualizaré la pregunta con parte del código EPP real con el que estoy trabajando. También quiero probar uno de los ejemplos de VHDL, aunque soy nuevo en VHDL.

Respuestas (1)

Siguiendo esta página https://embeddedmicro.com/tutorials/mojo/metastability-and-debouncing

Agregué almacenamiento en búfer a las señales de control enviadas por el host. No estaban en mi pregunta original, ya que estaba teniendo resultados extraños incluso con solo usb_write.

always @(posedge clk) begin
    astb_buf <= usb_astb;
    dstb_buf <= usb_dstb;
end

Almacenar en búfer solo estos dos solucionó los problemas de datos. Las otras señales son usb_writey usb_data[7:0], pero no parece que necesiten almacenamiento en búfer en este punto.

He podido enviar 100 y recibir 100 bytes sin adiciones, pérdidas o mutaciones, por lo que estoy aliviado, ya que ahora no necesito implementar un protocolo de corrección de errores.