This is just an idea that i had:

This computer would use not one, but 4 z80 CPUs. Each CPU would have 32k of local ram (0x8000-0xFFFF range), as well as 32k of global ram (0x0000 - 0x7FFF). (all IO is also global.) Some system made from TTL logic gates would need to be employed to make sure two CPUs don't access global at the same time. Cores would have to request access to global; when the CPU sends an IO request, or a MEM request with the MSB of address low, the core will know the CPU want access to global. The controller would detect this, and set the ~WAIT (active low) low. Once it is the turn of that CPU to have access to global, the controller will enable the data buffer between that core and global, and set ~WAIT high again. Once the CPU is done, the controller should shut off the data buffer for that CPU and give the next CPU access.

I am thinking about how to implement such a controller with TTL logic, i am not sure how to detect when the CPU is done reading/writing to global memory.

Another thing is that when the computer first starts, all but one core should be disabled so that they all don't run the bootstrap at the same time Razz

Edit: Ideally there should also be a (software) controlled switch in the controller that when would instruct the controller to give priority to a single core. Other cores should still be able to access global, that core should just have "priority".
c4ooo wrote:
i am not sure how to detect when the CPU is done reading/writing to global memory.
The timing diagrams in the Z80 users manual (pages 11-21) are pretty clear- ~MREQ is asserted when the CPU is accessing memory, with ~RD indicating whether it's a read or write, the address bus with the target address and data bus either providing data to be written or accepting read data. Data is latched on rising clock edges.

The arbitration logic you need then, uses ~MREQ as request and ~WAIT as an ack signal.

Quote:
Another thing is that when the computer first starts, all but one core should be disabled so that they all don't run the bootstrap at the same time Razz
Or more easily, provide a local resource (like a per-CPU IO port) that reads the CPU's ID so they can each vector to whatever they should be doing (which might be nothing).

You could gate the clocks to inactive CPUs and gate all but one at reset, but it seems easier to build ID hardware into the memory controller- just a hard-wired ID on each CPU port.

Quote:
Edit: Ideally there should also be a (software) controlled switch in the controller that when would instruct the controller to give priority to a single core. Other cores should still be able to access global, that core should just have "priority".
Bus arbiters often have hard-coded priority such that a particular device gets priority over others when it requests a shared resource, and that's often enough. It's possible to make bus priority configurable, but often not worth the complexity.

It might be useful to support programmable priority if the CPUs in your system have different fixed capabilities (in particular different local peripherals like a display on one, sound on another and mass storage on another), since if it's a general-purpose system you may not be able to predict at design time which should have higher priority. On the other hand, it's relatively easy to rank by what typically requires lower latency and let programmers make any further tradeoffs. In the earlier example, I might give the audio processor highest priority because audio stuttering is easily noticed then display and give storage lowest priority.

You may also find the architecture of Parallax's Propeller MCUs informative.
ALright, makes sense Smile
I have considered, and priority isn't something that is really needed, but programmatically starting/halting/pausing a core shouldn't be too hard.

The Parallax propeller architecture isn't what i am trying to achieve though. Wink It gives each core the resources in a circular manner, meaning that if a core needs to access global right after its turn is up, it will have to wait for the next 7 cores even if those cores don't need access, or at least i think loI.
If you design your multicpu board with z80s like this it should be relatively easy and not many wait staits and also expandable from 2 cpus to infinity in theory without extra hardware design. There are variants of this design as follows.

Each z80 board has 2 cpus. L and R for left and right.
Each z80 board has 64kb ram but 128kb Ram accessible. Multiple identical boards can be daisy chained but lets imagine one first.

The 2 cpus on 1 board are executing on alternate half clock cycles so there is minimal arbitration necessary for them to both access ram at almost full speed. 64kb ram is directly accessible to both CPUs. 32kb of this board is accessible from the left cpu of this board in the lower address space banked and 32kb of this board is accessible in the upper address space of the right cpu of this board. Left cpu can also access an optional left daisychained boards 32kb upper ram in its lower address space. Right cpu can also access an optional right daisychained boards 32 lower ram in its upper address space.

L = LEFT CPU
R = RIGHT CPU
b = banked ram
r = direct ram

b/ L-r-R /b

Hope it makes sense...
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement