Timing/buffering issue with Digilent’s EPP on Basys2

fpgatimingverilogvhdl

I have a Digilent Basys2 FPGA, and I'm implementing the EPP interface described in http://www.digilentinc.com/Data/Products/ADEPT/DpimRef%20programmers%20manual.pdf. This allows a program called Adept to send and receive bytes from an FPGA design over the USB cable.

After following those instructions I had something that seemed to work. I could send bytes from Adept and they would be successfully displayed on the seven segment display. Unfortunately, when I sent a 100 byte file to be stored in register array, only 83 bytes arrived. (It's a bit tricky to debug in this situation, because there are only so many simple outputs on the FPGA, and using Adept to read the bytes back from the FPGA opens the possibility that it's the read implementation that's buggy. I ended up adding the ability to step through the array showing each byte in turn.)

I've rewritten my implementation a few times and looked at other people's examples (they were mostly in VHDL) but still it's not reliable. Some writes, even single bytes one at a time, are just not picked up by the design, though Adept does not report any error.

Update — tried VHDL sample design

I've now managed to run the code and design here: http://hamsterworks.co.nz/mediawiki/index.php/Digilent_EPP_Performance

It works, but a simple counter I added shows slightly more writes are performed than expected, in a few repeated tests I ran (reload the design, then send a file using Adept):

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

For the compiled C++ program from that tutorial, 1440000 = 0 (mod 256) bytes were sent, but the number written was 32 (mod 256) (I only have 8 LEDs!). In another the numbers were 1430000 = 240 (mod 256) vs 253 (mod 256).

So I still think there's a timing thing going on. Can anyone with a Basys 2 try the same experiment? My slightly altered VHDL is at https://gist.github.com/ejrh/6ba768499319e9945bd0

Small testcase from before I learned VHDL

I ended up with a small test case for EPP's WRITE signal:

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

Usually when I send a byte using adept, write_count is incremented by 2, as expected. (WRITE goes low to write an address byte and a data byte, then returns to high). The LED stays lit between operations, indicating that prev_write is high.

But sometimes, the count is only incremented by 1, while the led still returns to high. It's as if different parts of my always @(posedge mclk) block were using different values of usb_write.

Is there some kind of buffering I need to do on these input/output wires? I haven't found any examples for this.

Later today I'll update the question with some of the actual EPP code I'm working with. I also mean to try one of the VHDL examples, though I'm new to VHDL.

Best Answer

Following this page https://embeddedmicro.com/tutorials/mojo/metastability-and-debouncing

I added buffering to the control signals sent by the host. They weren't in my original question, since I was having strange results even with just usb_write.

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

Buffering just these two has fixed it the data problems. The other signals are usb_write and usb_data[7:0], but these do not appear to need buffering at this point.

I have been able to send 100 and receive 100 bytes with no additions, losses or mutations, at which I'm relieved, as now I don't need to implement an error correcting protocol.