Jump to content

Four bit adder: Difference between revisions

Line 1,213:
=={{header|MyHDL}}==
 
 
<lang MyHDL>PRINT "Four_bit_adder"</lang>
 
{{Verbose Code}}
 
<lang MyHDL>PRINT "#!/usr/bin/env python
# -*- coding: utf8 -*-
 
""" http://rosettacode.org/wiki/Four_bit_adder
Demonstrate theoretical four bit adder simulation
using And, Or & Invert primitives
 
2011-03-18 Add logic_list2intbv to connect sum signals to bit vector bits
2011-03-10 simulation working - added @always_comb... into Adder4b_ST
2011-03-08 tidying - tryng for list-in, list-out
2011-03-08 remove carry in to 4b added - to match spec
2011-02-20 collect bits(gates)
"""
 
from myhdl import always_comb, ConcatSignal, delay, intbv, Signal, \
Simulation, toVerilog, toVHDL
from random import randrange
 
""" define set of primitives
------------------------ """
def inverter(z, a): # define component name & interface
""" z <- not(a) """
@always_comb # define asynchronous logic
def logic():
z.next = not a
return logic # return defined logic, named 'inverter'
 
def and2(z, a, b):
""" z <- a and b """
@always_comb
def logic():
z.next = a and b
return logic
 
def or2(z, a, b):
""" z <- a or b """
@always_comb
def logic():
z.next = a or b
return logic
 
""" build components using defined primitive set
-------------------------------------------- """
def xor2 (z, a, b):
""" z <- a xor b """
# define interconnect signals
nota, notb, annotb, bnnota = [Signal(bool(0)) for i in range(4)]
# name sub-components, and their interconnect
inv0 = inverter(nota, a)
inv1 = inverter(notb, b)
and2a = and2(annotb, a, notb)
and2b = and2(bnnota, b, nota)
or2a = or2(z, annotb, bnnota)
return inv0, inv1, and2a, and2b, or2a
 
def halfAdder(carry, summ, in_a, in_b):
""" carry,sum is the sum of in_a, in_b """
and2a = and2(carry, in_a, in_b)
xor2a = xor2(summ, in_a, in_b)
return and2a, xor2a
 
def fullAdder(fa_c1, fa_s, fa_c0, fa_a, fa_b):
""" fa_c0,fa_s is the sum of fa_c0, fa_a, fa_b """
ha1_s, ha1_c1, ha2_c1 = [Signal(bool(0)) for i in range(3)]
halfAdder01 = halfAdder(ha1_c1, ha1_s, fa_c0, fa_a)
halfAdder02 = halfAdder(ha2_c1, fa_s, ha1_s, fa_b)
or2a = or2(fa_c1, ha1_c1, ha2_c1)
return halfAdder01, halfAdder02, or2a
 
def Adder4b_ST(co,sum4, ina,inb):
''' assemble 4 full adders '''
c = [Signal(bool()) for i in range(0,4)]
sl = [Signal(bool()) for i in range(4)] # sum list
halfAdder_0 = halfAdder(c[1],sl[0], ina(0),inb(0))
fullAdder_1 = fullAdder(c[2],sl[1], c[1],ina(1),inb(1))
fullAdder_2 = fullAdder(c[3],sl[2], c[2],ina(2),inb(2))
fullAdder_3 = fullAdder(co, sl[3], c[3],ina(3),inb(3))
#sum4.next = ConcatSignal(*reversed(sl))
# myhdl.ConversionError: in file ./Four_bit_adder_intbv02.py, line 84:
# Not supported: extra positional arguments '''
@always_comb
def logic_list2intbv():
sumVar = 0
for i in range(4):
if sl[i] <> 0:
sumVar += 2**i
sum4.next = sumVar
return halfAdder_0,fullAdder_1,fullAdder_2,fullAdder_3, logic_list2intbv
 
""" define signals and code for testing
----------------------------------- """
t_co, t_s, t_a, t_b, dbug = [Signal(bool(0)) for i in range(5)]
ina4, inb4, sum4 = [Signal(intbv(0)[4:]) for i in range(3)]
sum4 = Signal(intbv(0)[4:])
 
def test():
print "\n b a | c1 s \n -------------------"
for i in range(15):
ina4.next, inb4.next = randrange(2**4), randrange(2**4)
yield delay(5)
print " %2d %2d | %2d %2d " \
% (ina4,inb4, t_co,sum4)
assert t_co * 16 + sum4 == ina4 + inb4
print
 
""" instantiate components and run test
----------------------------------- """
Adder4b_01 = Adder4b_ST(t_co,sum4, ina4,inb4)
test_1 = test()
 
def main():
sim = Simulation(Adder4b_01, test_1)
sim.run()
toVHDL(Adder4b_ST, t_co,sum4, ina4,inb4)
toVerilog(Adder4b_ST, t_co,sum4, ina4,inb4)
if __name__ == '__main__':
main()
"</lang>
 
 
{{Professional Code}}
 
<lang MyHDL>PRINT "#!/usr/bin/env python
 
from myhdl import *
 
def Half_adder(a, b, s, c):
 
@always_comb
def logic():
s.next = a ^ b
c.next = a & b
 
return logic
 
 
def Full_Adder(a, b, cin, s, c_out):
s_ha1, c_ha1, c_ha2 = [Signal(bool()) for i in range(3)]
ha1 = Half_adder(a=cin, b=a, s=s_ha1, c=c_ha1)
ha2 = Half_adder(a=s_ha1, b=b, s=s, c=c_ha2)
 
@always_comb
def logic():
c_out.next = c_ha1 | c_ha2
 
return ha1, ha2, logic
 
 
def Multibit_Adder(a, b, s):
N = len(s)-1
# convert input busses to lists
al = [a(i) for i in range(N)]
bl = [b(i) for i in range(N)]
# set up lists for carry and output
cl = [Signal(bool()) for i in range(N+1)]
sl = [Signal(bool()) for i in range(N+1)]
# boundaries for carry and output
cl[0] = 0
sl[N] = cl[N]
# create an internal bus for the output list
sc = ConcatSignal(*reversed(sl))
 
# assign internal bus to actual output
@always_comb
def assign():
s.next = sc
# create a list of adders
add = [None] * N
for i in range(N):
add[i] = Full_Adder(a=al[i], b=bl[i], s=sl[i], cin=cl[i], c_out=cl[i+1])
 
return add, assign
 
 
# declare I/Os for a four-bit adder
N=4
a = Signal(intbv(0)[N:])
b = Signal(intbv(0)[N:])
s = Signal(intbv(0)[N+1:])
 
# convert to Verilog and VHDL
toVerilog(Multibit_Adder, a, b, s)
toVHDL(Multibit_Adder, a, b, s)
# set up a test bench
from random import randrange
def tb():
dut = Multibit_Adder(a, b, s)
 
@instance
def check():
yield delay(10)
for i in range(100):
p, q = randrange(2**N), randrange(2**N)
a.next = p
b.next = q
yield delay(10)
assert s == p + q
 
return dut, check
 
# the entry point for the py.test unit test framework
def test_Adder():
sim = Simulation(tb())
sim.run()
"</lang>
 
=={{header|OCaml}}==
Anonymous user
Cookies help us deliver our services. By using our services, you agree to our use of cookies.