MC6000 in hardware - Part 2: XBus

So, we have the instruction set the next step is to design the schematics for the MC6000 in an HDL. HDLs are programming languages which compile to circuit schematics with transistors or program FGPAS which can simulate logic gates many times faster than what a CPU could.

In SHENZHEN I/O components can send each other data over a protocol called XBus:

In this screenshot the microcontroller on the left is sending 69 on the x1 pin and the microcontroller on the right is saving it to acc from the x0 pin.

The difference between this and analog signals is XBus will guarantee the data was received by another component and you can use the SLX instruction to sleep until a specific bus has data.

Traditionally buses have a single master and multiple slaves where the master generates the clock signal and slaves can only talk to the master and vise versa, XBus however appears to be a multi-master bus like CAN which allows any component on the bus to talk to any other.
You can probably point out an issue with doing this, if two components want to talk at the same time they will talk over each other and the data will be corrupted.

To solve this issue we can use uid based delegation, before sending any data you transmit the uid and the highest wins. How it works is you transmit your uid MSB first and then compare it to what you are receiving at the same time and if what you are receiving is different from what you are sending then you lose the delegation.

Here is an example:

This shows what the MCs are transmitting vs what is seen on the bus where the bus is pull-down and the MCs are floating when low and pull up when high. The red means the MC failed arbitration and outputs floating for the remaining bits, you can see this for MC1 and MC2 after they write a 0 but read a 1 meaning there was someone trying to transmit using a higher id.

I used this method to write a multi-master XBus in Verilog that can handle an
arbitrary number of devices to attempt to send data in the same clock cycle, here it is in action:

This is a screenshot of ModelSim PE running a test on my xbus circuit where xb1 is trying to write 0x69 in the same clock as xb2 tries to write 0x7f0, xb1 loses arbitration because it has a lower id and when arbitration is over xb2 goes into the write state

To make it a little easier to understand, here is the state machine diagram of the xbus controller:

When arbitration happens the d1 line goes high for 1ns where the controllers that are trying to write go into the arbitration state and the rest go into the read state.

Note that all controllers but the one sending are required to actively read the data and you might fail arbitration indefinitely if a controller with a higher id is constantly sending data and that might cause a deadlock.

Verilog code: https://gist.github.com/PixelToast/64f05b06537d3043f47ca20d065759c4

Now i'll work on desinging the MC6000 CPU itself!