Just in case you were itching to TOTALLY automate your factory and were wondering how to go about it, here's your answer.
New, Improved, MK2 computer (some assembly required ). MK2 is fast(er) ( up to 12 IPS), better ( 32 instructions including BLT & BXRP) and greener (all those adder combinators).
MK2 Instruction Set
Opcodes are always specified by the "blueprint" signals. Operands and data are specified by the "D" signals.
All instructions with the exception of: halt,reset,return,pusha,popa,pushx,popx have 1 operand.
addressing modes
immediate - operand contains the value to be used in the operation e.g. adi 2 will add 2 to the accumulator
direct - operand is the memory address of the value to be used e.g add 2 will add contents of memory address 2 to the accumulator.
indirect - operand is the address of memory cell that has address of the value e.g if #2 contains 3 and #3 has 4 then loadn 2 will return 4
indexed - index register value will be added to the direct or indirect address when determining the actual address of the value
e.g. if index register contains 2 and direct address is 5 then the actual address will be 7
load instructions
load instructions are used to set the contents of registers (a,x,sp)
loadi,load,loadx,loadn,loadnx,popa all load accumulator (a) using immediate, direct,indexed,indirect,indexed indirect and stack address modes.
loadxr and popx load the index (x) register whereas loadsp loads the stack pointer (sp)
arithmetic instructions
arithmetic instructions add,subtract,multiply or divide the accumulator with a value that can be immediate,direct ,or indirect (in case of subn).
adxr instruction will add (or subtract) a specified value to the x register contents, although,there is no explicit way of testing x. x register value can be tested indirectly by pushing x onto stack then popping the value into accumulator I.e pushx popa
store instructions
stor,stor, and pusha will stor accumulators value into memory using direct,indexed or stack addressing modes pushx will store the value of x register on the stack
program control instuctions
jump,blt,bgt,beq are straightforward branch instructions to a specified (absolute) address jump will branch always whereas blt,bgt,beq will branch depending on the accumulators value. blt will branch if result is <0,bgt>0 and beq=0.
call instruction will branch to a specified address but will store its forwarding address on the stack
return instruction will use the address on the stack to return to an instruction after the call
in either case accumulator and index register will not be affected successive (recursive) calls are possible, limited by the size of the stack
bxrp is an acronym for Branch while X Register is Positive and is my second favorite instruction (right after BLT). This instruction will branch to a specified address while x>0 then decrement x (irrespective of whether branch succeeded). bxrp can be useful in the construction of repeat(n) type loops
ex ldxr $n specify # iterations
repeat: do stuff
bxrp repeat
reset when asserted will force immediate jump to address 128 and clear all registers halt will stop execution when encountered- register values will remain unaltered
Demo code (sorry I could not get it to format properly using the CODE tag so for now it's a txt file)
EDIT
Blueprints are posted on factorioblueprints.com
Computer+Input Port http://factorioblueprints.com/view/mtM22gGmJxg6Thjiy
Display Port http://factorioblueprints.com/view/LEk8Qff3Hn7CrwPgx
If anyone cares to (or is brave enough) to work with it you might find the following useful
To force a reset: insert a curved rail into the empty constant combinator labeled R. Removing the curved rail will result in program execution starting at address 128.
I'm particularly interested in feedback on the instruction set and if you have any experience in this area I'm all ears.
Any feedback would be most welcome, and I'll gladly answer any questions.
Re: combinator computer MK2
Posted: Sat Apr 09, 2016 8:52 pm
by XKnight
Why don't you use instruction pipeline?
Several instructions which are processed simultaneously could increase your speed up to 60 IPS.
Also, 64 RAM words is so... small, and so many combinators are wasted on them.
The same RAM memory can be achieved with 1 combinator, and even more, because you could store 180 words in one combinator.
Re: combinator computer MK2
Posted: Sat Apr 09, 2016 9:57 pm
by piriform
Hi, thanks for the feedback.
MK2 is not quite ready for the pipelining as I don't have a good solution for the problem of Locks (i.e. certain instructions overrunning or colliding with the others), and I'm not interested in crocheting the code. I'd be very interested in seeing your approach.
RAM is actually not a problem. 64 words is way more than needed. ROM, on the other hand, continue to grow. I'm guessing that a proper ratio will end up somewhere in the neighborhood of 16 to 1 (1k of ROM for 64 RAM).
I'm not sure I understand your point about encoding the signals in one combinator. Do you mean you can derive and extract the type of the signal using a value (i.e. 1= wood, 2= coal ,...) with 1 combinator in 1 tick?
Re: combinator computer MK2
Posted: Sat Apr 09, 2016 10:27 pm
by XKnight
piriform wrote:
I'm not sure I understand your point about encoding the signals in one combinator. Do you mean you can derive and extract the type of the signal using a value (i.e. 1= wood, 2= coal ,...) with 1 combinator in 1 tick?
Yes, this is possible, but not in a single tick.
Although, amount of ticks is not very important if you are using instruction pipeline, because bigger input/output delay means that your pipeline has more stages but performance remains the same. Bigger pipeline may cause performance problems only in case of branch/data miss-prediction.
From the other side, this technique may reduce overall performance in the single instruction CPU.
Example:
Memory cell (one combinator): 150 "A", 300 "B", 270 "C",
Input: Blue 1, Output: 150 Blue
Input: Blue 2, Output: 300 Blue
Input: Blue 3, Output: 270 Blue
Re: combinator computer MK2
Posted: Sun Apr 10, 2016 2:18 am
by -root
highly impressive. I'm interested in the practical examples though. Can't wait to see a factory that is controlled by this bad boy.
Re: combinator computer MK2
Posted: Sun Apr 10, 2016 11:19 am
by piriform
Will try to oblige, although it might take a week or two. BTW I got started down this path after watching your tutorials #46,#47 and had a thought hm... . Thanks for all the great videos you've made so far, please continue!
Re: combinator computer MK2
Posted: Sun Apr 10, 2016 4:30 pm
by Nanostech
Way beyond me but cool. But now make it so the computer can change the recipe an assembler is using on the fly, change the things a smart inserter moves and change the things a requester chest asks from the logistics network. Then use that control to make a fully automated factory the can switch what it makes on the fly reusing the same set of assemblers, belts/chests to make any arbitrary output product. Once accomplished change the name from computer MK2 to SkyNet.
Re: combinator computer MK2
Posted: Mon Apr 11, 2016 12:20 am
by piriform
Once accomplished change the name from computer MK2 to SkyNet.
Sure, no problem. I'll just put it on my list of things to do
let's see... #786 Skynet!
What's on top of the list
#1 Assembler and loader - OK, working on it
#2 Beg for a compiler
During the demo, MK2:
issues build instructions for several different items
monitors build progress and when complete issues commands to collect the products into logistics inventory
monitors status of raw materials (ores, plates,steel) and fluids (i.e. gas, acid, lube, etc)
issues commands to start or stop production of raw materials/fluids
issues commands to start or stop venting of excessive fluids
Some pictures of the factory itself
demo2factory.jpg (596.27 KiB) Viewed 19721 times
a closer look at some manufacturing cells
demo2closeup.jpg (519.39 KiB) Viewed 19721 times
Smelting buffer and control
demo2smelt.jpg (286.39 KiB) Viewed 19721 times
The program (read it only if you really like assembly level programming)
If you have any questions I'd be happy to answer them.
And now MK3 - this time with interrupts
Posted: Wed Jun 29, 2016 1:28 am
by piriform
I've done some additional work on MK2 CPU in order to improve the throughput and responsiveness. The new MK3 has approx 30% better throughput and supports interrupts which should allow much better reaction to unanticipated events.
A brief video overview showing interrupt handling and explanation of the new asynchronous (clock less) mode of operation is available on YouTube https://www.youtube.com/watch?v=RUVZcV3-Kh4
For those who prefer static pictures I'm including a picture of MK3 overlaid with signal paths for a simple ( load immediate) instruction. Note that the color of the signal path indicates the tick in which it's active and the text besides the arrow shows the principal signals carried.
The instruction starts with address (A) generated in the Program Counter carried by the tan arrow to the memory location.
The following tick, memory cell releases bp (blue print i.e. instruction "load") and D (i.e. the operand) -yellow arrow carries it to the microcode.
The following tick, microcode releases (sg i.e. shotgun which zeroes accumulator, water and crude both used in generating the next address and virtual 1 which selects the ALU operation (i.e. load)
These signal with the exception of virtual 1, together with address (A) and data (D) exit the Instruction Decoder the following tick as depicted by the bright green arrows. A ,water and crude enter the program counter and are used to generate the new instruction address (teal arrow). D and shotgun enter the ALU where shotgun zeroes accumulator and D is delayed by one tick and then is multiplied by virtual 1 which just exited the instruction decoder. The result (of this multiplication is fed into accumulator and several deciders that generate signals used in subsequent branching (light and dark blue arrows).
mk3.gif (150.86 KiB) Viewed 19200 times
Some other architectural changes in MK 3 include addition of 2 base registers used to generate a rough but much faster equivalent to the former indirect addressing mode.
The instruction set was enhanced to handle the added registers and now consists of:
program control : jump, beq,bgt,blt, bxrp,call,return
register load: ldi A,B,C,X,SP lad d+X+B|C pop A,B,X
store instructions: stor d+X+B|C push A,B,X
register moves: tab,tax,txa
Finally, the interrupt hardware (just below and to the right of "bp,D" label) captures about to be executed instruction address and forces a jump to an interrupt vector (which contains another jump to the actual interrupt routine) and releases the captured address when the interrupt handler routine executes RTI (return from interrupt).
I hope the above was fairly clear and informative. If you have any questions, I'll do my best to answer them
Re: combinator computer MK2
Posted: Mon Jul 04, 2016 4:51 pm
by siggboy
This is a very nice project. If you can execute 12 or more IPS it's actually a useful computer. XKnight is probably right that pipelining would make it even better, but it's probably not easy to implement at all -- but you might look into creating a more compact memory.
Maybe you can have 2 tiers of memory, a first level cache which uses the current scheme, and then some RAM which might be slower (I don't even know), and uses XKnight's array lookup method, where you can store 200ish integers in one memory cell.
That way you could have huge amounts of RAM in a very small area and still have a fast machine. I'm not sure though if the array lookup RAM would even slow down the CPU, but probably it would require a complete rework if it was the only type of RAM. That's why I was thinking about two-tiered memory.
I especially like that you have added proper interrupts to the CPU now; I think some interesting projects can only be done if you have interrupts.
Can you do DMA? How do you interface with "hardware", are the inputs from the periphery exposed in memory space?
Re: combinator computer MK2
Posted: Sun Jul 17, 2016 9:54 pm
by toothstone
Hey, would you be so kind to post some blueprint strings or maybe even a savegame? I'm looking for some inspiration for my own computer project, but from pictures alone that is quite hard^^
Re: combinator computer MK2
Posted: Mon Jul 18, 2016 2:01 am
by piriform
Hey, would you be so kind to post some blueprint strings or maybe even a savegame? I'm looking for some inspiration for my own computer project, but from pictures alone that is quite hard^^
Here's the blueprint. Warning! Make sure you have about 1000 combinators before starting the build
Please let me know if you need anything else (instruction set, opcodes?)
This is a very nice project. If you can execute 12 or more IPS it's actually a useful computer. XKnight is probably right that pipelining would make it even better, but it's probably not easy to implement at all -- but you might look into creating a more compact memory
XKnight is right. Pipe-lining would make it faster, and I can kinda/sorta see how to do it. The Branches are a problem however: either you insert bubbles into the pipeline (and lose 6-7 ticks per branch), or go with some sort of predictive branching and introduce whole lot of complexity (i.e. backtracking, etc) . At this point, I'm not sure. The principal concern I have is that even if I can achieve performance close to the maximum possible (i.e. 60 IPS), this may not be enough.
Memory packing without pipe-lining or caching will seriously impact performance so I've put it onto back burner.
DMA? Funny thing you should mention it. I was debating whether to do DMA or Interrupts first. Actually DMA would have been somewhat easier to implement and given that the I/O is memory mapped, DMA could work fairly well. My guesstimate, at the time was that DMA would result in effective performance boost of 10-20% and that interrupts would have greater apparent effect.
Re: combinator computer MK2
Posted: Mon Jul 18, 2016 2:20 am
by siggboy
What you've built is already very impressive. Predictive branching? Sounds like a nightmare to implement in combinators, the complexity is very high.
This is probably about the best you can do without it becoming impractical to design and implement. I would not even attempt what you did for the lack of debugging tools and because it's difficult to impossible to single-step through a circuit. It's already annoying with the project I'm working on, and that's a lot less complex than a real CPU.
I agree that interrupts are more important than DMA, if you want to write useful programs you need to be able to react to external events.
You should install SmartTrains and write a nice train scheduler; that should be a lot of fun with such a computer.
very helpful when designing my (one-tick) CPU. Which I should probably post, since I haven't really touched it for a while
Re: combinator computer MK2
Posted: Mon Jul 25, 2016 5:44 pm
by siggboy
I think minimum game speed is still too fast to debug. There's now a mod that allows you to record all signals tick-by-tick into an CSV file. That's handy for debugging very complicated stuff like CPUs.
If we could clock our circuits manually then it would be easy to build some debugging tools, like a single step debugger. Alas that is not how combinator circuits work (even if you have a global clock that you could manipulate you still can't debug timing issues that way because you can't stop the game ticks).
Re: combinator computer MK2
Posted: Mon Jul 25, 2016 6:32 pm
by Amegatron
siggboy wrote:I think minimum game speed is still too fast to debug. There's now a mod that allows you to record all signals tick-by-tick into an CSV file. That's handy for debugging very complicated stuff like CPUs.
If we could clock our circuits manually then it would be easy to build some debugging tools, like a single step debugger. Alas that is not how combinator circuits work (even if you have a global clock that you could manipulate you still can't debug timing issues that way because you can't stop the game ticks).
Once I started to play with combinators, I got an idea to write a combinator-simulation as a separate tool or game, but unfortunately I have no time for this atm. I think that would be very useful.
Re: combinator computer MK2
Posted: Mon Jul 25, 2016 7:06 pm
by Gertibrumm
siggboy wrote:(even if you have a global clock that you could manipulate you still can't debug timing issues that way because you can't stop the game ticks).
The way my single instruction cpu works is for every instruction there must be some sort of return value to proceed.
Now take out the return values and use your hands to manually go through the steps.
Record everthing happening on the main bus, for single tick operations this is the way to go.
Reset recordings every time you read them.
@piriform how do you clear your memory/registers? for speeds sake I dont want too many combinators to keep the most important MOVE command fast enough.
but the problem is I dont want to store all these extra signals the bus is full of when I open my memory for writing.. so I am varying between memory than accepts negative signals but is slower but can be cleared easily, and one that accepts only positive ones but is a little faster but cannot be cleared so easily
Re: combinator computer MK2
Posted: Mon Jul 25, 2016 10:17 pm
by piriform
think minimum game speed is still too fast to debug. There's now a mod that allows you to record all signals tick-by-tick into an CSV file. That's handy for debugging very complicated stuff like CPUs.
Amen to 1. I'm ashamed to admit that I've even resorted to flashing lamps, and timing it by eye.
As to 2 Do you remember the mod's name?
@piriform how do you clear your memory/registers?
Most of the time I use a decider with Clear=0:StoredValue. It, takes 2 ticks to rewrite (i.e. clear then value). The trick, if any, is to arrange the timing so that clearing does not incur time penalty.
problem is I dont want to store all these extra signals the bus is full of when I open my memory for writing
Not sure I understand, do you store more than one signal per memory cell?
Re: combinator computer MK2
Posted: Mon Jul 25, 2016 10:49 pm
by siggboy
piriform wrote:As to 2 Do you remember the mod's name?