Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TinyFPGA seemingly accepts data even when uart_out_ready = 0 #16

Open
hexdump opened this issue Jan 22, 2021 · 1 comment
Open

TinyFPGA seemingly accepts data even when uart_out_ready = 0 #16

hexdump opened this issue Jan 22, 2021 · 1 comment

Comments

@hexdump
Copy link

hexdump commented Jan 22, 2021

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!

@davidthings
Copy link
Owner

davidthings commented Jan 23, 2021

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants