Logical elements
Good day, I am starting a series of articles on writing a virtual machine in the Golang language. I chose this language because it is easy to read and has the necessary functions in the standard library that will come in handy in the future.
This article does not contain absolutely any new information for those who know how to make truth tables for simple logic gates. If you know how, then do not waste time and move on to the second part.
A logic gate is a device with one or more inputs and one or more outputs. In this part we will consider only the simplest of them. For modeling gates, we will use only signals 0 and 1, without using the input, output characteristics of real gates.
Since we will work with Golang, each element can be represented as a function.
In Go, the function looks like this:
func ( ) { // return }
Buffer
This is the simplest element having one input and one output. In practice, it is used to amplify a signal or create a delay; sometimes it can be replaced by a conductor.
a | BUF a |
0 | 0 |
one | one |
in the case of the buffer, our function will look like this:
func Buf(v bool) bool { return v }
Inverter
The same buffer, only the output inverts the signal.
a | NOT a |
0 | one |
one | 0 |
in the case of an inverter, the function will look like this:
func Inv(v bool) bool { return !v }
OR
This element needs at least one signal equal to 1 in order to get 1 at the output.
a | b | a OR b |
0 | 0 | 0 |
0 | one | one |
one | 0 | one |
one | one | one |
func Or(v, s bool) bool { return v || s }
AND
It always returns 1, when 1 is supplied to all its inputs, in all other cases it returns 0.
a | b | a AND b |
0 | 0 | 0 |
0 | one | 0 |
one | 0 | 0 |
one | one | one |
func And(v, s bool) bool { return v && s }
Exclusive OR
In order to get 1 at the output, it is necessary that different signals (0 and 1) or (1 and 0) be applied to the input. This operation is useful because it allows you to swap two variables without using additional memory.
a | b | a xor b |
0 | 0 | 0 |
0 | one | one |
one | 0 | one |
one | one | 0 |
func Xor(v, s bool) bool { // (v ^ s) , bool , return (v || s) && !(v && s) }
OR NO
It works as an OR element, only an inverter is connected to its output, from which we get a signal.
a | b | a nor b |
0 | 0 | one |
0 | one | 0 |
one | 0 | 0 |
one | one | 0 |
func Nor(v, s bool) bool { return !(v || s) }
AND NOT
The element works in the same way as the And element, only the signal is inverted at the output.
a | b | a nand b |
0 | 0 | one |
0 | one | one |
one | 0 | one |
one | one | 0 |
func Nand(v, s bool) bool { return !(v && s) }
Exclusive OR with inversion
The element works in the same way as the OR element, only the signal is inverted at the output.
a | b | a XNOR b |
0 | 0 | one |
0 | one | 0 |
one | 0 | 0 |
one | one | one |
func Xnor(v, s bool) bool { // return !((v || s) && !(v && s)) }
Now that the functions are written, you can assemble them into the Gate package, on the basis of which we will implement more complex things. Our package hierarchy will be similar to a real computer abstraction hierarchy. Source code can be found here .