- 3D printing
- Aeon Dashboard
- CNC Machine 4
- Eagle libraries
- Eagle search
- Lighting Lego
- Making PCBs
- Two layer PCBs
- USB Switch 2
- USB Switch 3
I've been using a simple address offset from the start of the screen rather than coordinates to simplify the PicoBlaze code, because the PicoBlaze does not have a multiply instruction, and to do a multiply would take a few cycles (especially as I'd need to multiply two 10-bit values).
However, a thought struck me: I'm mulitplying by a constant (800) to convert an X and Y value to an address. This can easily be done in the core of the FPGA itself.
In order to implement this, I added sB the PicoBlaze registers that were available to the core, and set the registers as follows:
- sB - write length
- sC - X (low)
- sD - X (high)
- sE - Y (low)
- sF - Y (high)
I also changed the instruction set to:
- 0x0X - NOP
- 0x10 - Set colour
- 0x11 - Set X
- 0x12 - Set Y
- 0x13 - Add 8-bit value to X
- 0x14 - Add 16-bit value to X
- 0x15 - Add 8-bit value to Y
- 0x16 - Add 16-bit value to Y
- 0x17 - Return X to previous set value, and increment Y
- 0x20 - Plot single pixel in current colour
- 0x21 - Plot given pixel value
- 0x22 - Draw horizontal line from 1 to 256 pixels
- 0x23 - Draw horizontal line from 1 to 65536 pixels
- 0x24 - Draw horizontal line in 24-bit value
- 0x25 - Clear screen in current colour
- 0x30 - Draw pixel map
- 0x31 - Draw up to 255 given pixel colours
- 0x32 - 7-segment display
- 0x4V - Draw horizontal line from 1 to 16 pixels (V + 1)
- 0x5V - Add (V + 1) to current X
- 0x6V - Add (V + 1) to current Y
All other commands are currently ignored (NOP).
The code is actually a bit quicker in theory, since when it increments to go to the next address, it only needs to change 2 registers, rather than 3.
There is another, fairly significant advantage - I can now implement line and circle drawing to the PicoBlaze code, rather than in the PIC, which means it would be a lot faster. Although that does assume I've got enough memory for that...
The only downside is that it uses a multiplier - however, there's another 15 left on this chip, so I'm not too worried by that. It could be done with 3 adders instead if I need it (and the delay isn't too much of a problem).
I've written the code for the line drawing algorithm here, but here's a picture of some lines that have been plotted over yesterday's work:
And the command set was extended with:
- 0x26 - Draw line to new X, Y
Note that I've got some problems with the clock synchronisation in that the vertical green line looks like it's missed every other X coordinate - this isn't the case, but it's not picking up those pixels for some reason. I'll look into that next.