Search code examples
algorithmgovariablescircuit-diagramnor

Implementation of Nor Flip Flop Logic Gates in Go


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

Solution

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