Sunday, February 28, 2016

Finally moving forward on 1442 card reader and other fronts


Debugging the virtual 1442 functionality

If I had kept the logic for the two card buffers as originally expressed - 160 flipflops that I could address through multiplexors driven by indexes - I could load all 10 columns at a time from a fetch or push transaction, I could copy all 80 columns from pre-read to pre-punch in one cycle. However, because of how many LUTs this consumed on my fgpa board, I switched to a pair of memories.

Each memory can access only one column at a time, thus I had to create an 'inner loop' to read or write ten sequential locations as part of one 'outer loop' fetch or push transaction. The copy function had to loop for all eighty locations. With a memory, there were setup and hold requirements for the addresses, generated by several independent processes depending on whether it was a copy, fetch, XIO Read, etc. All this complicated the logic. Often, designers have to make tradeoffs in execution time versus hardware count versus clear expression of the function.

While I should be able to pipeline the read and write of the pre-read and pre-punch buffers, respectively, in a copy process so that there is a one cycle separation between them, that would have the two buffer processes running asynchronously to each other and make interlocking more complex.

My current design does an interlocked read from pre-read, saves the column contents, then does an interlocked write of those contents to the pre-punch buffer. Only one of the buffer processes runs at a time, well interlocked with the copy process.

Once things are running properly, I could revert to the pipelined copy process and test it, if i wished. I tested the non-pipelined version in the morning. Data is being stored in pre-read, but not showing up at the end. Test 2 in the morning watched the output of the pre-read buffer for column 11 during the copyover process.

Of the sequence of operations, push to pre-read, handle XIO Read, handle XIO Punch, fetch from pre-punch, and copyover pre-read to pre-punch, the first is validated. We are ignoring the XIO versions now by checking Start Feed operations. Test 2 looked at the value in the pre-read buffer to check near the end. Nothing there. I see it at the output of the pre-read buffer when I write it, but it is not there when I read it with the fetch process. A memory that isn't.

This smells like setup/hold issues, so I will look over my logic with that in mind. Could also be a toolchain issue, not linking properly to the generated memory component. After making some changes to improve hold times, my afternoon testing worked no better. I will be extremely unhappy if this turns out to be another Xilinx defect - I have burned so many hours on this.

 I made some redesign changes to further eliminate any changes that could be occurring and tested again. Now I get my input cards coming out to the output file, although I am still experiencing a modulo 10 corruption of the card contents. Progress, at least.

Looking over my code, I saw that the way I terminated the 'loop' process for each group of ten words left a race hazard where the column number and other indexing was changing a bit too fast for the process that read the buffer and the other process that stored the results into the outgoing transaction. I added interlocking to protect against this and retested.

Hurray! Feed mode works and the stacker 1 (output) file is an exact copy of the input file. Next up, testing the Start Read mode, which should place an exact copy of the input file card contents into memory. It did not, but I quickly found that my timing doing the buffer read was wrong.

The XIO Read instruction sets a busy signal as it starts, then that signal goes off at the end of the execution. I was not asking the pre-read buffer process to fetch the data until the XIO Read was complete - therefore it had the default value of a blank column. I adjusted the logic to request the buffer read just as soon as the XIO Read begins, so the value is ready for use while the instruction is working.

As I was testing tonight, I realized that I am doing the buffer read at the wrong point in time entirely. The basic logic of reading fires off a 'loop' process that triggers in IL0 interrupt for each of eighty card columns, waiting in between for the XIO Read to be issued. As I set up to trigger the interrupt, I should read the pre-read buffer contents and hold them in a register for use by the XIO Read instruction.

The punch logic has a similar loop of up to eighty columns with an IL0 interrupt and the XIO Write completion for each. During the XIO Write instruction I should save the value in a register and then write it to the pre-punch buffer before going back to issue the next column's interrupt.

The last functions to test, once reading is storing the card columns in core,  are:

  • Punching a card atop blank cards (input file with blanks)
  • Punching a partial card over a nonblank input file
  • Performing a boot load of the first card in a file into core 0x0000 to 0x0004F

Implementing the timeout and restart function for the high speed fpga-fpga link

The logic is in place for the master side, such that if it gets an uncoverage CRC/Hamming error on the data packet or times out waiting for a response, it goes to a reset state then starts over. Once I put the analogous change in the slave, I can test the link to see if it will deliver reliably.


I ran a full print of an object with a clean nozzle and well adjusted bed, but at the normal temp for the extruder, 210C, a layer would not adhere to the layer below. I upped the temp to 225C but still had major separation of layers. It also seems that I am underextruding, since adjacent lines often have a small gap.

At this point, I need to validate the configuration parameters. In particular, there is a parameter for vertical (Z axis) movement that might be wrong, causing each layer to be placed too much above the prior one. Also, the extruder parameter might not be pushing enough plastic to generate the volume of plastic that the software intends to be produced.

The control software in the printer includes a manual "move" function that can move each of the steppers by a specific number of millimeters. For example, if the extruder is moved 100mm then it should move a mark 100mm up on the plastic fiber exactly down to the throat of the extruder. If the Z axis is commanded to move 20mm up from the home position, it should be exactly 20mm above the bed.

The actual and software values are different - software shows 10X the actual millimeter movement. I moved the X axis 100mm by the move function and measured almost exactly 10mm of travel of the extruder left to right. Same with the Y axis (front to back bed movement) where 100mm on the screen was 10mm of physical travel. The Z axis (vertical movement of the extruder) is not on the same scale. It is off by more than 6X - 100mm on the scale would be well over 60mm of real travel/

This explains my layering problem - the Z axis steps up more than 6 times higher than it should between layers and the first step is too high for the plastic to touch the bed properly so even the first layer doesn't sit properly. Objects will be misshapen because the Z axis is stretched out of proportion.

I hadn't bothered to measure the extruder movement yet, but that is undoubtedly off as well. I will figure out how to update the parameters for the firmware to get the values correct. I also ordered better quality tools and loctite so that I can keep this printer working properly

It turns out that I can stick a line of g-code in my print software, issued at the start of a print job, which will set the Z and extruder steps to the values I want. I chose 384 for the Z step and 630 for the extruder. My first test print is just starting but  looking good. I may or may not decrease the extrude a bit, depending on whether I see artifacts that suggest over extrusion, but the difference is already night and day from what it was producing before.

The object being printed was too flattened, resulting in the nozzle scraping over the prior layer rather than adding new plastic. I adjusted the Z steps to 400 but still having problems. Sigh. Not worth investing more time today. At least my new tools have arrived and are a pleasure to use with the printer.

No comments:

Post a Comment