I'm trying to implement the following nor flip flop circuit logic in Go and having some difficulty with variable declarations:
My goal is to simulate the logic gates and circuitry as it would physically work. I've implemented a function for the nor gates [func nor()] and the flip flop itself [func norFlipFlop()]. The issue I'm facing is in declaring out0 and out1 since they depend on each other. As can be seen below out0 is defined as nor(a1, out1) and out1 is defined as nor(out0, a0). This obviously spits out a compilation error since out1 is not yet initialized and defined when out0 is defined. Is there a way to make this logic work while keeping it as close to the physical circuit logic as possible?
func nor(a int, b int) int {
if a + b == 0 {
return 1
} else {
return 0
}
}
func norFlipFlop(a1 int, a0 int) (int, int) {
out0 := nor(a1, out1)
out1 := nor(out0, a0)
return out1, out0
}
func main() {
out1, out0 := norFlipFlip(1, 1)
out := fmt.Sprint(out1, out0)
fmt.Println(out)
}
First, a flip flop stores state, so you need some sort of value to retain the state. Also, apart from a condition (usually avoided in hardware) where A0 and A1 are 0 (false) and Out0 and Out1 are both 1 (true) the outputs (Out0 and Out1) are usually the complement of each other and a flip flop effectively stores only a single boolean value so you can just use a bool
. You typically "pulse" the inputs to set (make true) or reset (make false) the flip-flop's value. Eg:
package main
import "fmt"
type flipFlop bool
func (ff flipFlop)GetOut0() bool {
return bool(ff)
}
func (ff flipFlop)GetOut1() bool {
return !bool(ff)
}
func (ff *flipFlop)PulseA0() {
*ff = true
}
func (ff *flipFlop)PulseA1() {
*ff = false
}
func main() {
var ff flipFlop
ff.PulseA0()
fmt.Println(ff.GetOut0(), ff.GetOut1())
ff.PulseA1()
fmt.Println(ff.GetOut0(), ff.GetOut1())
}
If you want to more closely simulate the hardware you need to keep track of the hardware states. Maybe something like this:
package main
import "fmt"
type flipFlop struct {
A0, A1 bool
out0, out1 bool
}
func nor(a, b bool) bool { return !(a || b) }
func (ff *flipFlop)Eval() {
// Evaluate the circuit until it is stable
for {
prev0, prev1 := ff.out0, ff.out1
ff.out0 = nor(ff.A1, ff.out1)
ff.out1 = nor(ff.A0, ff.out0)
if ff.out0 == prev0 && ff.out1 == prev1 {
break // flip flop is stable
}
}
}
func main() {
var ff flipFlop
fmt.Println(ff)
// Pulse a0
ff.A0 = true
ff.Eval()
fmt.Println(ff)
ff.A0 = false
ff.Eval()
fmt.Println(ff)
// Pulse a1
ff.A1 = true
ff.Eval()
fmt.Println(ff)
ff.A1 = false
ff.Eval()
fmt.Println(ff)
}
I hope this helps (BTW I'm not an electronics engineer :).