tinyfpga_bx_usbserial icon indicating copy to clipboard operation
tinyfpga_bx_usbserial copied to clipboard

TinyFPGA seemingly accepts data even when `uart_out_ready = 0`

Open hexdump opened this issue 4 years ago • 1 comments

I'm not familiar with the internals of USB Serial whatsoever, and fairly new to FPGAs, so my apologies if I'm missing something obvious. I'm working on a protocol for processing blocks of data on an FPGA (load in some data, FPGA processes it, then returns the output). I'm using a TinyFPGA BX. To get something up and running, I started with your usbserial_tbx.v file (which, when compiled and uploaded, works as expected). As a first step in implementing my protocol, I separated the in and out wires, defining them like so:

// `in` is the pipeline *in* to the host (*out* of the FPGA)
reg [7:0]  uart_in_data;
reg        uart_in_valid;
wire       uart_in_ready;

// `out` is the pipeline *out* of the FPGA (*in* to the host)
wire [7:0] uart_out_data;
wire       uart_out_valid;
reg        uart_out_ready;

As I understand from your description, data is passed in the in or out direction if and only if _ready and _valid for that direction are both 1. Since I'll be setting uart_out_ready and uart_in_valid depending on the state of the device, I figured I'd try the baby step of simply setting uart_out_ready to be 0, and not implementing any further logic. I changed the reg uart_out_ready; line to reg uart_out_ready = 0;, then compiled and uploaded the program with make prog.

I then, using pySerial, attempted to write to the device:

import serial
ser = serial.Serial("/dev/serial/by-id/usb-1d50_6130-if00")
bytes_written = ser.write(b"a")
print(bytes_written)

Strangely, this returned 1. In a REPL, it seems like I can write 1 byte two times before the command hangs. I was also able to write 8, or 20 bytes, however I could only issue the .write() once in those cases. I checked the .in_waiting and .out_waiting attributes, both of which returned 0 after writing, so it doesn't seem to be a buffering issue.

Thanks for your time, and for your effort in making FPGAs more accessible!

hexdump avatar Jan 22 '21 02:01 hexdump

A confession: this gateware does not do well when held up for more than a handful of clocks. All the projects I've used it with are dataflow oriented and consume characters faster than they can be produced by the USB interface at 12Mb/s. Any time someone tries to use this code with a relatively slow SoC, this is an issue.

This means that a test which just stops characters flowing will result in disappointment! Sorry!

Maybe another test where you consume the chars as fast as they are sent? Try sending a few bits out to a few LEDs. Very obvious when new characters arrive...

My boilerplate code for USB includes a FIFO for the rare cases when the downstream gateware might hold the stream up. Then all is well.

When I'm next overhauling the insides of this code, I'll implement back-pressure properly.

davidthings avatar Jan 23 '21 00:01 davidthings