Implementation of Nor Flip Flop Logic Gates in Go

216 views Asked by At

I'm trying to implement the following nor flip flop circuit logic in Go and having some difficulty with variable declarations:

enter image description here

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)
}
1

There are 1 answers

2
Andrew W. Phillips On BEST ANSWER

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 :).