How to resolve the algorithm Four bit adder step by step in the Go programming language

Published on 12 May 2024 09:40 PM
#Go

How to resolve the algorithm Four bit adder step by step in the Go programming language

Table of Contents

Problem Statement

"Simulate" a four-bit adder. This design can be realized using four 1-bit full adders. Each of these 1-bit full adders can be built with two half adders and an   or   gate. ; Finally a half adder can be made using an   xor   gate and an   and   gate. The   xor   gate can be made using two   nots,   two   ands   and one   or. Not,   or   and   and,   the only allowed "gates" for the task, can be "imitated" by using the bitwise operators of your language. If there is not a bit type in your language, to be sure that the   not   does not "invert" all the other bits of the basic type   (e.g. a byte)   we are not interested in,   you can use an extra   nand   (and   then   not)   with the constant   1   on one input. Instead of optimizing and reducing the number of gates used for the final 4-bit adder,   build it in the most straightforward way,   connecting the other "constructive blocks",   in turn made of "simpler" and "smaller" ones.

Solutions should try to be as descriptive as possible, making it as easy as possible to identify "connections" between higher-order "blocks". It is not mandatory to replicate the syntax of higher-order blocks in the atomic "gate" blocks, i.e. basic "gate" operations can be performed as usual bitwise operations, or they can be "wrapped" in a block in order to expose the same syntax of higher-order blocks, at implementers' choice. To test the implementation, show the sum of two four-bit numbers (in binary).

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Four bit adder step by step in the Go programming language

First Code:

This code implements a 4-bit adder using half adders and full adders in the Go programming language.

  • The xor() function computes the bitwise XOR (exclusive OR) operation.
  • The ha() function implements a half adder, returning the sum and carry bits.
  • The fa() function implements a full adder, taking two input bits and a carry-in bit, and returning the sum and carry-out bits.
  • The add4() function adds two 4-bit numbers using the full adder components.

Example usage:

// add 10+9  result should be 1 0 0 1 1
fmt.Println(add4(1, 0, 1, 0, 1, 0, 0, 1))

Second Code:

This code implements a 4-bit adder using a hardware description language (HDL) inspired by Verilog. It uses a wire data structure to represent electrical wires carrying boolean signals.

  • The MkWire() function creates a new wire.
  • The Zero() function creates a wire that always sends false values.
  • The And(), Or(), and Not() functions implement the respective logical gates.
  • The Split() function creates two wires that are connected to the same source wire.
  • The Xor() function implements the bitwise XOR gate using other gates.
  • The HalfAdder() function implements a half adder.
  • The FullAdder() function implements a full adder.
  • The FourBitAdder() function combines four full adders to create a 4-bit adder.

Example usage:

// Create wires
a1, a2, a3, a4 := MakeWire(), MakeWire(), MakeWire(), MakeWire()
b1, b2, b3, b4 := MakeWire(), MakeWire(), MakeWire(), MakeWire()
// Construct circuit
r1, r2, r3, r4, carry := FourBitAdder(a1, a2, a3, a4, b1, b2, b3, b4)
// Feed it some values
a4 <- false
a3 <- false
a2 <- true
a1 <- false // 0010
b4 <- true
b3 <- true
b2 <- true
b1 <- false // 1110
B := map[bool]int{false: 0, true: 1}
// Read the result
fmt.Printf("0010 + 1110 = %d%d%d%d (carry = %d)\n",
   B[<-r4], B[<-r3], B[<-r2], B[<-r1], B[<-carry])

Source code in the go programming language

package main

import "fmt"

func xor(a, b byte) byte {
    return a&(^b) | b&(^a)
}

func ha(a, b byte) (s, c byte) {
    return xor(a, b), a & b
}

func fa(a, b, c0 byte) (s, c1 byte) {
    sa, ca := ha(a, c0)
    s, cb := ha(sa, b)
    c1 = ca | cb
    return
}

func add4(a3, a2, a1, a0, b3, b2, b1, b0 byte) (v, s3, s2, s1, s0 byte) {
    s0, c0 := fa(a0, b0, 0)
    s1, c1 := fa(a1, b1, c0)
    s2, c2 := fa(a2, b2, c1)
    s3, v = fa(a3, b3, c2)
    return
}

func main() {
    // add 10+9  result should be 1 0 0 1 1
    fmt.Println(add4(1, 0, 1, 0, 1, 0, 0, 1))
}


package main

import "fmt"

// A wire is modeled as a channel of booleans.
// You can feed it a single value without blocking.
// Reading a value blocks until a value is available.
type Wire chan bool

func MkWire() Wire {
	return make(Wire, 1)
}

// A source for zero values.
func Zero() (r Wire) {
	r = MkWire()
	go func() {
		for {
			r <- false
		}
	}()
	return
}

// And gate.
func And(a, b Wire) (r Wire) {
	r = MkWire()
	go func() {
		for {
			r <- (<-a && <-b)
		}
	}()
	return
}

// Or gate.
func Or(a, b Wire) (r Wire) {
	r = MkWire()
	go func() {
		for {
			r <- (<-a || <-b)
		}
	}()
	return
}

// Not gate.
func Not(a Wire) (r Wire) {
	r = MkWire()
	go func() {
		for {
			r <- !(<-a)
		}
	}()
	return
}

// Split a wire in two.
func Split(a Wire) (Wire, Wire) {
	r1 := MkWire()
	r2 := MkWire()
	go func() {
		for {
			x := <-a
			r1 <- x
			r2 <- x
		}
	}()
	return r1, r2
}

// Xor gate, composed of Or, And and Not gates.
func Xor(a, b Wire) Wire {
	a1, a2 := Split(a)
	b1, b2 := Split(b)
	return Or(And(Not(a1), b1), And(a2, Not(b2)))
}

// A half adder, composed of two splits and an And and Xor gate.
func HalfAdder(a, b Wire) (sum, carry Wire) {
	a1, a2 := Split(a)
	b1, b2 := Split(b)
	carry = And(a1, b1)
	sum = Xor(a2, b2)
	return
}

// A full adder, composed of two half adders, and an Or gate.
func FullAdder(a, b, carryIn Wire) (result, carryOut Wire) {
	s1, c1 := HalfAdder(carryIn, a)
	result, c2 := HalfAdder(b, s1)
	carryOut = Or(c1, c2)
	return
}

// A four bit adder, composed of a zero source, and four full adders.
func FourBitAdder(a1, a2, a3, a4 Wire, b1, b2, b3, b4 Wire) (r1, r2, r3, r4 Wire, carry Wire) {
	carry = Zero()
	r1, carry = FullAdder(a1, b1, carry)
	r2, carry = FullAdder(a2, b2, carry)
	r3, carry = FullAdder(a3, b3, carry)
	r4, carry = FullAdder(a4, b4, carry)
	return
}

func main() {
	// Create wires
	a1, a2, a3, a4 := MakeWire(), MakeWire(), MakeWire(), MakeWire()
	b1, b2, b3, b4 := MakeWire(), MakeWire(), MakeWire(), MakeWire()
	// Construct circuit
	r1, r2, r3, r4, carry := FourBitAdder(a1, a2, a3, a4, b1, b2, b3, b4)
	// Feed it some values
	a4 <- false
	a3 <- false
	a2 <- true
	a1 <- false // 0010
	b4 <- true
	b3 <- true
	b2 <- true
	b1 <- false // 1110
	B := map[bool]int{false: 0, true: 1}
	// Read the result
	fmt.Printf("0010 + 1110 = %d%d%d%d (carry = %d)\n",
		B[<-r4], B[<-r3], B[<-r2], B[<-r1], B[<-carry])
}


  

You may also check:How to resolve the algorithm Carmichael 3 strong pseudoprimes step by step in the RPL programming language
You may also check:How to resolve the algorithm Palindrome detection step by step in the PHP programming language
You may also check:How to resolve the algorithm Logical operations step by step in the ECL programming language
You may also check:How to resolve the algorithm Sum of squares step by step in the Scala programming language
You may also check:How to resolve the algorithm Sequence of non-squares step by step in the BASIC programming language