Four bit adder: Difference between revisions
Content added Content deleted
Line 1,213: | Line 1,213: | ||
=={{header|MyHDL}}== |
=={{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}}== |
=={{header|OCaml}}== |