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

ESP8266 support for websvf #2

Open
udif opened this issue Jul 8, 2018 · 12 comments
Open

ESP8266 support for websvf #2

udif opened this issue Jul 8, 2018 · 12 comments

Comments

@udif
Copy link
Contributor

udif commented Jul 8, 2018

I just left PR #1 to start this effort.
My ultimate target (I would love to hear your feedback) is to be able to reuse old ESP8266-01 for JTAG programming via WiFi. I don't want to store any bitstream file on the SPIFFS, just send it to the FPGA on-the-fly. If I need to slow it a bit to get it to work reliably with WiFi, so be it.
Is this feasible with the single core ESP8266?
As I want to be able to reuse tons of old modules lying around, I really hope to be able to squeeze it into 512KB SPI memories.
Currently websvf compiles to 373,160 bytes , hopefully leaving room for a small SPIFFS just for the minimal read-only web files.
As I haven't used ESP8266 in the few years, I need to do some catch-up on SPIFFS and other ESP8266 stuff, so I haven't ran this code yet other than getting it to compile.

@emard
Copy link
Owner

emard commented Jul 8, 2018 via email

@udif
Copy link
Contributor Author

udif commented Jul 9, 2018

I spent some time reading the Xilinx XAPP503 dealing with SVF and XSVF and I see several approaches):

  1. Allow only XSVF commands with a limited record length, and stop the uploader if such a command is detected.
  2. Start with an SVF file, and use the Xilinx SDF2XSVF utility to generate an XSVF file with a limited record length
  3. Preprocess the XSVF file, and do all the magic in the uploader, or in a separate preprocessor.
    Using the uploader is OK when you do command line processing, but if you want to upload an XSVF by a drag-and-drop operation into a web page I don't know if its possible (can you do the local preprocessing using Javascript on the browser, or is the file always uploaded as-is?)

The preprocessing is easy for the XSDRTDO* commands and can simply interleave the TDIvalue and TDOexpected bits, saving us from the need to save the entire TDI vector before shifting it in.
The XTDOMASK command is more problematic since its value has no length limit and needs to be used on all future TDO operations. The only way to cancel the buffering is to add an explicit TDO mask to every XSDRTDO* command preprocessed, potentially increasing the bitstream length.

I also understand that XSETSDRMASK and XSDRINC commands are deprecated and not used even by ISE (Let alone Vivado).

These tools from OpenOCD might help (svf2xsvf.py and xsvfdump.py)
https://github.com/arduino/OpenOCD/tree/master/contrib/xsvf_tools
This one is based on libXSVF:
https://github.com/makestuff/dump-xsvf

I will take a deeper look into libXSVF code and see how it works.

@udif
Copy link
Contributor Author

udif commented Jul 9, 2018

Using the OpenOCD contrib xsvfcdump.py I checked one of my XSVF files generated by ISE 14.7 and it seems that the maximum SDR length in the file is 1024 (128 bytes).
For the moment I will go with this as a hard limit and see if I can get this to work by streaming the XSVF directly to JTAG.

@emard
Copy link
Owner

emard commented Jul 9, 2018 via email

@emard
Copy link
Owner

emard commented Jul 9, 2018 via email

@udif
Copy link
Contributor Author

udif commented Jul 16, 2018

Here is my progress for the last few days:
Compiled and ran some code on ESP01. A modified websvf version, where the actual XSVF code is not called, only some Serial.printf() to see what we get from the client.
For the final version, I intend to disable Serial output and use those pins for TDI/TDO (I can hardly get 4 PIOs on the ESP01).
I may even be able to combine Serial output with JTAG if TCK won't change while serial data is driven out.

I also spent some time working on the (X)SVF code.
I created a new test, xsvftool-test that allows me to capture a JTAG log of XSVF/SVF from either a file or a packetized stream. The TDO and packet size are controlled by 2 separate random streams with different seeds, so they are not affected by each other. This means I can generate several runs with different packet sizes (or no packets at all), and yet generate the same random TDO sequence.
At the moment only 3 combinations are working - SVF from file or packets, and XSVF from files.
Adding the last (packetized XSVF) will be the major work needed.
However, By using this test I will be able to verify that the packetization did not break the JTAG sequences.

I cannot simply use SVF because ISE 14.7 generates SVF files with a single SDR command for the entire FPGA configuration bitsream. Only the XSVF output uses smaller data blocks (1024 bytes).

Also , there is a log of code duplication between the packetized and original SVF drivers.
I will try to factor that out to reduce code size and simplify it. The new xsvftool-test will let me regress any changes so I won't break the code.

For code, see https://github.com/udif/LibXSVF-ESP/tree/add_tests

@udif
Copy link
Contributor Author

udif commented Jul 17, 2018

Also , there is a log of code duplication between the packetized and original SVF drivers.
I will try to factor that out to reduce code size and simplify it. The new xsvftool-test will let me regress any changes so I won't break the code.

Done. Liberally turned some auto vars into static.
I assume that after each upload I may need to call ESP.restart() so that each upload gets a fresh copy of all the static vars.

@emard
Copy link
Owner

emard commented Jul 17, 2018 via email

@udif
Copy link
Contributor Author

udif commented Jul 22, 2018

Quick update:
I've heavily modified libxsvf_xsvf() on my branch to work with streaming data.
The getbyte() function is now allowed to return -2 to indicate data not yet available.
In this case libxsvf_xsvf() will also return -2, and you are expected to subsequently call it again with the same parameters once new data is available.
The price I had to pay for this change was to make the code ugly and non-reentrant, full of static vars.
I definitely want to clean it further, as there is lots of duplication that can be moved into the READ_xx() macros.
It is also possible to move all the static vars to a context struct, giving us back the reentrancy.
All of this was tested on the host (linux) only.
I now need to integrate this with the esp8266 example and test with real hardware.
Relevant branch is:
https://github.com/udif/LibXSVF-ESP/commits/add_tests

Regarding your comment on the DMA engine, I'm familiar with this. The issues with using DMA is that it uses a fixed pinout requiring me to either pull wires directly from the chip and not the existing 4 IOs on the ESP01 connector.
As for whether the performance increase will be worth it (if at all - DMA setup also takes time) remains to be seen. This will definitely wait until I have something simple working with bit banging.

@emard
Copy link
Owner

emard commented Jul 22, 2018 via email

@udif
Copy link
Contributor Author

udif commented Jul 22, 2018

I haven't implied that ESP needs reentrant code.
Given the low memory capacity and the fact that we a single task run bare-metal program, non reentrant code is OK.
However, what I meant was that the original code in LibXSVF was written to be much cleaner -
All variables are local, and all the state is encapsulated in the libxsvf_host structure.
This is OOP done in C, with libxsvf_host as the class, and the function pointers instead of virtual functions.
You could run 2 parallel JTAG interface using the same library and different libxsvf_host structures.
Ofcourse, this is irrelevant for the ESP.

In the meantime, I did some cleanup on libxsvf_xsvf() and moved the retry logic into trhe READ_xxx() macros, making the code much simpler.

@emard
Copy link
Owner

emard commented Jul 23, 2018 via email

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