- Joined
- May 7, 2015
- Messages
- 151
- Reaction score
- 88
So, recently i've been toying with logic and more specifically with something i call "instant pulses". I also got the impression that they aren't really well known (along with another rule which might be useful) so i thought that maybe i could make a thread to explain how it works and how to use it.
Let's start with an example:
You might have recognized a Xor (exclusive or, true if its inputs are different) with both inputs (the activation blocks) connected to a button and its output (the Or) connected to a Flip-flop.
Now what will happen if i push the button? Let's name the state of the button B, and the state of the Or-gate R (because O looks too much like 0).
At first glance, R = (A./A) + (/A.A)
(this means R = (A and (not A)) or ((not A) and A), i'll note "and" with ".", "not" with "/" and or with "+")
A./A = 0 (false) hence R = 0 + 0 = 0
So the or gate should always remain false, shouldn't it? Let's try to push that button and see if we guessed right:
Wait. What? Why is the flip-flop on? I didn't even see the Or gate turning on (well this is an image after i press the button so you can't see the Or gate turning on, but if you reproduce the circuit that's what you should get). Obviously this is a bug. Or is it, really?
There's something we didn't take into account when we analyzed the Xor circuit: how is the signal propagated through the gates?
In fact Starmade seems to behave exactly as if it was a synchronous circuit (except starmade doesn't use an internal clock but we'll come back to that later), this means that the Or gate won't be updated instantly, instead we'll first update the activation blocks then the Not-gates and so on.
So what? Well, let's just reanalyze the circuit:
- i press the button
- the two activation modules turn on (at the same time)
- the two Not-gates turn off, the two And-gates turn on (at the same time)
- the Or-gate turns on, the two And-gates turn off (at the same time)
- the Flip-Flop turns on, the Or-gate turns off (at the same time)
- we wait a fraction of a second before the button turns off
- the two activation modules turn off (at the same time)
- the two Not-gates turn on (at the same time)
Now i reach the good conclusion: the problem came from the And-gates, one of their input was late relatively to the other so for a moment the And-gate turned on but then, they turned off immediately after when the Not-gate signal was eventually propagated.
The And-gates outputed what i call an "instant pulse" (it's not a proper term, but it describes quite well what it is).
Let's say that this behaviour isn't wanted and see if we can "repair" the circuit to avoid this "instant pulse":
Since the problem was just the signal of the Not-gate being late relatively to the signal of the bottom activation block, i just added an activation block between the first activation block and the and-gate to "delay the signal" a bit. Now, it works: the Or-gate never turns on, and the Flip-flop stays off as expected.
(Of course there are other ways to "repair" this circuit, introducing delay blocks for instance)
You probably already know about this thing:
This is basically a counter, a decreasing counter actually, the current state can be seen as the binary number 111 (7 in decimal) and if i press the button i get:
110 (6 in decimal)
once again:
101 (5 in decimal)
That's great, but what if i want an increasing counter?
Well actually if i say that on=0 and off=1 instead of on=1 and off=0, i get 000 then 001 then 010, so it can also be seen as an increasing counter.
Okay, but if i want two buttons, an increase AND a decrease one? Now this is less trivial.
Actually there is a really simple solution:
just press that new button and...
Nice! But why does it work?
Well remember how sending a signal to the rightmost block can be seen as decrementing the counter? Actually sending a signal the middle block can also be seen as decrementing the counter but by 10 (binary) instead of 1, and sending a signal to the leftmost can be seen as decrementing the counter by 100.
So what we're really doing here is decrementing the counter by 111 (7 in decimal) and obviously:
5 - 7 = 6
Wait, let me correct that:
5 - 7 ≡ 6 [8]
Remember that our little counter can only store numbers from 0 (000) to 7 (111), if you try to get a number outside of these bounds, the counter just wraps around (by adding or substracting 8 until you have a valid number if you want, in french we say that "5-7" and "6" are "congrus modulo 8", i don't know how it's called in english).
In general if you have N Flip-flop you make computations modulo 2^N and sending a signal to each Flip-flop can be seen as decrementing by (2^N - 1), here N=3 so 2^3=8 and 2^3-1=7.
Still, we haven't shown that sending all these "substraction signals" at the same time won't mess up the counter yet.
[TODO]
Buttons (or delays) already give us relatively short signals, but sometimes you need even shorter, so why not using this small defect of our first Xor circuit at out advantage?
This is a very small and simple circuit, but it can be useful sometimes. Let's see what will happen if i press the button:
- i press the button
- the bottom Flip-flop turns on; the activation module turns on
- the top Flip-flop turns on; the bottom Flip-flop turns off
- a little while later the button turns off
- the activation module turns off
The top Flip-flop is only needed to see the signal here, what is interesting is what the bottom one does: each time you press the button it will send a very short true signal (you can also activate the Flip-flop beforehand so that it will send a very short false signal instead).
When i first toyed with these very short signals, one of my first circuits was the following:
This circuit is a bit more complicated than the previous ones, my intent was to send a pulse each time i received a signal except if that signal caused the last Flip-flop to flip. It works well. But then, i tried to connect the final And-gate to the first flip-flop, so that this circuit would pulse 4 times at each button press (my goal was to make a circuit which could pulse 2^n times with O(log2) blocks) and sadly it doesn't work. But, why?
Well remember when i told you that starmade doesn't use an internal clock to synchronize the logic? This is important now. The thing is: when a block changes its state, starmade tries to reach a stable state for the whole circuit at once. All the tiny steps i described for the previous circuits are followed by starmade in the right order, but he doesn't wait between then: once it finishes a step it immediately starts the next one, but then, when does it stop?
Obviously, starmade can stop if there's no step left, but what if there is always a next step? What if there is an infinite loop in the circuit? Then you have to stop early and that's why this circuit doesn't work.
But, why? This circuit doesn't have an infinite loop, it would only pulse 4 times! That's right, but the game doesn't know that (it could but the only algorithm i know is exponential in the number of logic blocks), all that the game sees is that there is a loop, hence there is an infinite loop possibility.
[TODO]
Let's start with an example:
You might have recognized a Xor (exclusive or, true if its inputs are different) with both inputs (the activation blocks) connected to a button and its output (the Or) connected to a Flip-flop.
Now what will happen if i push the button? Let's name the state of the button B, and the state of the Or-gate R (because O looks too much like 0).
At first glance, R = (A./A) + (/A.A)
(this means R = (A and (not A)) or ((not A) and A), i'll note "and" with ".", "not" with "/" and or with "+")
A./A = 0 (false) hence R = 0 + 0 = 0
So the or gate should always remain false, shouldn't it? Let's try to push that button and see if we guessed right:
Wait. What? Why is the flip-flop on? I didn't even see the Or gate turning on (well this is an image after i press the button so you can't see the Or gate turning on, but if you reproduce the circuit that's what you should get). Obviously this is a bug. Or is it, really?
Introducing time
There's something we didn't take into account when we analyzed the Xor circuit: how is the signal propagated through the gates?
In fact Starmade seems to behave exactly as if it was a synchronous circuit (except starmade doesn't use an internal clock but we'll come back to that later), this means that the Or gate won't be updated instantly, instead we'll first update the activation blocks then the Not-gates and so on.
So what? Well, let's just reanalyze the circuit:
- i press the button
- the two activation modules turn on (at the same time)
- the two Not-gates turn off, the two And-gates turn on (at the same time)
- the Or-gate turns on, the two And-gates turn off (at the same time)
- the Flip-Flop turns on, the Or-gate turns off (at the same time)
- we wait a fraction of a second before the button turns off
- the two activation modules turn off (at the same time)
- the two Not-gates turn on (at the same time)
Now i reach the good conclusion: the problem came from the And-gates, one of their input was late relatively to the other so for a moment the And-gate turned on but then, they turned off immediately after when the Not-gate signal was eventually propagated.
The And-gates outputed what i call an "instant pulse" (it's not a proper term, but it describes quite well what it is).
Let's say that this behaviour isn't wanted and see if we can "repair" the circuit to avoid this "instant pulse":
Since the problem was just the signal of the Not-gate being late relatively to the signal of the bottom activation block, i just added an activation block between the first activation block and the and-gate to "delay the signal" a bit. Now, it works: the Or-gate never turns on, and the Flip-flop stays off as expected.
(Of course there are other ways to "repair" this circuit, introducing delay blocks for instance)
Practical example: two way counter
You probably already know about this thing:
This is basically a counter, a decreasing counter actually, the current state can be seen as the binary number 111 (7 in decimal) and if i press the button i get:
110 (6 in decimal)
once again:
101 (5 in decimal)
That's great, but what if i want an increasing counter?
Well actually if i say that on=0 and off=1 instead of on=1 and off=0, i get 000 then 001 then 010, so it can also be seen as an increasing counter.
Okay, but if i want two buttons, an increase AND a decrease one? Now this is less trivial.
Actually there is a really simple solution:
just press that new button and...
Nice! But why does it work?
Well remember how sending a signal to the rightmost block can be seen as decrementing the counter? Actually sending a signal the middle block can also be seen as decrementing the counter but by 10 (binary) instead of 1, and sending a signal to the leftmost can be seen as decrementing the counter by 100.
So what we're really doing here is decrementing the counter by 111 (7 in decimal) and obviously:
5 - 7 = 6
Wait, let me correct that:
5 - 7 ≡ 6 [8]
Remember that our little counter can only store numbers from 0 (000) to 7 (111), if you try to get a number outside of these bounds, the counter just wraps around (by adding or substracting 8 until you have a valid number if you want, in french we say that "5-7" and "6" are "congrus modulo 8", i don't know how it's called in english).
In general if you have N Flip-flop you make computations modulo 2^N and sending a signal to each Flip-flop can be seen as decrementing by (2^N - 1), here N=3 so 2^3=8 and 2^3-1=7.
Still, we haven't shown that sending all these "substraction signals" at the same time won't mess up the counter yet.
[TODO]
Practical example: Pulse shortener
Buttons (or delays) already give us relatively short signals, but sometimes you need even shorter, so why not using this small defect of our first Xor circuit at out advantage?
This is a very small and simple circuit, but it can be useful sometimes. Let's see what will happen if i press the button:
- i press the button
- the bottom Flip-flop turns on; the activation module turns on
- the top Flip-flop turns on; the bottom Flip-flop turns off
- a little while later the button turns off
- the activation module turns off
The top Flip-flop is only needed to see the signal here, what is interesting is what the bottom one does: each time you press the button it will send a very short true signal (you can also activate the Flip-flop beforehand so that it will send a very short false signal instead).
Beware of the loop
When i first toyed with these very short signals, one of my first circuits was the following:
This circuit is a bit more complicated than the previous ones, my intent was to send a pulse each time i received a signal except if that signal caused the last Flip-flop to flip. It works well. But then, i tried to connect the final And-gate to the first flip-flop, so that this circuit would pulse 4 times at each button press (my goal was to make a circuit which could pulse 2^n times with O(log2) blocks) and sadly it doesn't work. But, why?
Well remember when i told you that starmade doesn't use an internal clock to synchronize the logic? This is important now. The thing is: when a block changes its state, starmade tries to reach a stable state for the whole circuit at once. All the tiny steps i described for the previous circuits are followed by starmade in the right order, but he doesn't wait between then: once it finishes a step it immediately starts the next one, but then, when does it stop?
Obviously, starmade can stop if there's no step left, but what if there is always a next step? What if there is an infinite loop in the circuit? Then you have to stop early and that's why this circuit doesn't work.
But, why? This circuit doesn't have an infinite loop, it would only pulse 4 times! That's right, but the game doesn't know that (it could but the only algorithm i know is exponential in the number of logic blocks), all that the game sees is that there is a loop, hence there is an infinite loop possibility.
[TODO]
Last edited: