Using, learning, programming and modding the Gigatron and anything related.
Forum rules
Be nice. No drama.
Posts: 39
Joined: 08 Jul 2019, 19:40

LUT optimized registry wiring explained

Post by steve » 08 Sep 2020, 20:33

The "LUT optimized" wiring of TUVW registers is the most peculiar part of the microtron proposal and seemed to me difficult to be digested. With this post I will try to explain it with some more details hoping to make the overall architecture more clear.

Let's start describing the function of each register and then detailing one example.

T register

T is a "simple" temporary register with the output always available (meaning no 3state).

It serves many purposes:
  1. Some of its bits are wired to the control logic, to perform conditional jumps, and in particular the fifth one (half carry), the eight one (sign), and the (wired)OR of all its bits (used for conditional jump for zero/not zero condition)
  2. It allows to prepare the Program Counter page for long jumps (similarly as it is done with Y register in the "standard" gigatron)
  3. It allows the proper load of U, V (inputs for LUT operations), and W (output of LUT operations), all explained later

U and V registers

U and V are used to alternatively address the RAM, in the same way that X does.

These registers are wired in a way to permit to load in parallel values present in T register and the BUS (containing one of S, W, ROM D, etc); this load fills with a single instruction both V with high nibbles of T and BUS, and U with low nibbles as in this C pseudo syntax:

Code: Select all

U = (T << 4) + (BUS & $0F) ; V = (T & $F0) + ( BUS >> 4) # both assignment in a single clock cycle load operation
U and V are then used to address a 256 bytes LUT that will provide on the low nibble (with the fifth bit set in case of carry from addition) the result of the logical or arithmetic operation applied on the two nibbles composing the registers (see XOR example later).

W register

W register is used to mix back the results from the lookup of the two nibbles operations.

It is wired in a way that one operation will get the values of the lower nibbles present in the T register and the BUS and combine them into a single byte. As before with pseudo C code:

Code: Select all

W = ( BUS & $F0) + (T & $0F) #


In this example we'll follow the XOR of S holding value "$A1" with T holding value "$B2".

The code taken from first post is:

Code: Select all

1. U, V = S x T # pair the nibbles of the two input operands in U and V
2. Y = XorLutPage # point to the lookup containing in the low nibbles the XOR of the low and high nibble of the index
3. T = [Y,U] # calculate the XOR of the low nibbles
4. W = T + [Y,V] # calculate the XOR of the high nibbles and join them with low ones to store the result in W 
So we have:
  1. After first instruction we have inside V the value "$AB" (the high nibbles of S and T) and inside U the value "$12" (the low nibbles of S and T)
  2. The second step is just assigning to Y to the page where the lookup table of the XOR is located. The 256 byte table is built in a way that the value represented has in the low nibble the XOR of the high nibble and the low nibble of the index
  3. In the third instruction we put in T the value at address [Y,U], that as said contains XOR of the two nibbles of U, and since U is $12 the result of $01 XOR $02 will be $03
  4. In the fourth instruction we put in the low nibble of W the "3" coming from the low nibble of T, while in the high nibble of W will be put the low nibble of the lookup of the V value, and since V is $AB the value in the table at page Y would be $01 ($0A xor $0B); so W will contain $13, that is the result of the XOR of $A1 and $B2
The addition (e.g. vAC instruction in the first post example) follow a similar path, just that the result of the addition of two nibbles can be on five bits, so activating the "halfcarry" signal (fifth bit of the T register) on overflow, that will be used to select an alternative LUT for the final operation (the LUT that will include +1 to the addition of the two nibbles of the index).

Posts: 39
Joined: 08 Jul 2019, 19:40

Microtron schema update

Post by steve » 11 Sep 2020, 19:36

Hoping that the "pull to register" is a viable solution, I did some more simplification on the overall circuit. This changes together with the other things discussed previously are depicted in the overall schema below:
schema2.jpg (64.14 KiB) Viewed 125 times
Now is really Super Micro! :)

Summary of changes:
1. Removal of W register using the pull to register V on data bus (note that U and V were renamed in L and R respectively to avoid confusion with previous schema example code)
2. Removal of X buffer with a pull to register on low ram address bus
3. Utilization of one 74867 (or 54867) instead of the 2x 74161 for X and for PCL (this change can be made optional on the PCB in case, allowing for both options)
4. Removal of the input expansion register, with new I/O expansions done via SPI interface
5. Keyboard rows written via VGA register

Other changes/suggestions not visible related to PCB:
1. Make the keyboard part of it "detachable"
2. Use a 4 layers for better overclocking

And finally areas still to be defined:
1. Circuit for Audio input (for now is 1 bit on Aux in)
2. "Decoupled" VGA rendering solution
3. Aux Out utilization: Audio (3bit), Led (2bit), SPI i/f (3bit); ||OR|| Audio (2bit), Led (1bit), HSync (1bit), VSync (1bit), SPI i/f (3bit)
(note that HSync and VSync via expansion register would allow 256 colors without composite sync or other mechanisms)
4. Decoded IR (3x74377 and 2x27c1024) or encoded IR (1x74377, 1x27c1024 and 2x 4to16 decoders, see below for details)

Single byte instruction encoding
in case of "encoded IR option" the instruction can be simply composed of two nibbles indicating:
a. What value to put to the bus, one of:
. ram[0,L]
. ram[0,R]
. ram[0,X]
. ram[0,X++]
. ram[Y,L]
. ram[Y,R]
. ram[Y,X]
. ram[Y,X++]
. D
. R
. S
. AuxIn
b. What register to write from the bus, one of:
. L and R (mixing bus and T)
. S
. T
. X
. Y
. AuxOut
. Vga/KeyRow
. Audio/Led
. PCL (jump short)
. PCL if Z
. PCL if HC
. PCL if S
. PCL and PCH (with T)
. ram[0,X]
. ram[0,X++]
. ram[Y,X]

PS: the XOR code example becomes

Code: Select all

1.  R, L = S x T    # pair the nibbles of the two input operands in R and L
2.  Y = XorLutPage  # point to the lookup containing in the low nibbles the XOR of the low and high nibble of the index
3.  T = [Y, R]      # calculate the XOR of the low nibbles
4.  R = T + [Y, L]  # calculate the XOR of the high nibbles and join them with low ones to store the result in R

Post Reply