Four bit adder: Difference between revisions

++ sather impl
(Fixed up description more (wording only))
(++ sather impl)
Line 138:
 
See also: "A Formal Description of System/360” by Adin Falkoff
 
=={{header|Sather}}==
<lang sather>-- a "pin" can be connected only to one component
-- that "sets" it to 0 or 1, while it can be "read"
-- ad libitum. (Tristate logic is not taken into account)
-- This class does the proper checking, assuring the "circuit"
-- and the connections are described correctly.
class PIN is
private attr v:INT;
readonly attr name:STR;
private attr connected:BOOL;
 
create(n:STR):SAME is -- n = conventional name for this "pin"
res ::= new;
res.name := n;
res.connected := false;
return res;
end;
val:INT is
if self.connected.not then
#ERR + "pin " + self.name + " is undefined\n";
return 0; -- could return a random bit to "simulate" undefined
-- behaviour
else
return self.v;
end;
end;
 
-- connect ...
val(v:INT) is
if self.connected then
#ERR + "pin " + self.name + " is already 'assigned'\n";
else
self.connected := true;
self.v := v.band(1);
end;
end;
 
-- connect to existing pin
val(v:PIN) is
self.val(v.val);
end;
end;
 
-- XOR "block"
class XOR is
readonly attr xor :PIN;
 
create(a, b:PIN):SAME is
res ::= new;
res.xor := #PIN("xor output");
l ::= a.val.bnot.band(1).band(b.val);
r ::= a.val.band(b.val.bnot.band(1));
res.xor.val := r.bor(l);
return res;
end;
end;
 
-- HALF ADDER "block"
class HALFADDER is
readonly attr s, c:PIN;
 
create(a, b:PIN):SAME is
res ::= new;
res.s := #PIN("halfadder sum output");
res.c := #PIN("halfadder carry output");
res.s.val := #XOR(a, b).xor.val;
res.c.val := a.val.band(b.val);
return res;
end;
end;
 
-- FULL ADDER "block"
class FULLADDER is
readonly attr s, c:PIN;
 
create(a, b, ic:PIN):SAME is
res ::= new;
res.s := #PIN("fulladder sum output");
res.c := #PIN("fulladder carry output");
halfadder1 ::= #HALFADDER(a, b);
halfadder2 ::= #HALFADDER(halfadder1.s, ic);
res.s.val := halfadder2.s;
res.c.val := halfadder2.c.val.bor(halfadder1.c.val);
return res;
end;
end;
 
-- FOUR BITS ADDER "block"
class FOURBITSADDER is
readonly attr s0, s1, s2, s3, v :PIN;
create(a0, a1, a2, a3, b0, b1, b2, b3:PIN):SAME is
res ::= new;
res.s0 := #PIN("4-bits-adder sum outbut line 0");
res.s1 := #PIN("4-bits-adder sum outbut line 1");
res.s2 := #PIN("4-bits-adder sum outbut line 2");
res.s3 := #PIN("4-bits-adder sum outbut line 3");
res.v := #PIN("4-bits-adder overflow output");
zero ::= #PIN("zero/mass pin");
zero.val := 0;
fa0 ::= #FULLADDER(a0, b0, zero);
fa1 ::= #FULLADDER(a1, b1, fa0.c);
fa2 ::= #FULLADDER(a2, b2, fa1.c);
fa3 ::= #FULLADDER(a3, b3, fa2.c);
res.v.val := fa3.c;
res.s0.val := fa0.s;
res.s1.val := fa1.s;
res.s2.val := fa2.s;
res.s3.val := fa3.s;
return res;
end;
end;
 
-- testing --
 
class MAIN is
main is
a0 ::= #PIN("a0 in"); b0 ::= #PIN("b0 in");
a1 ::= #PIN("a1 in"); b1 ::= #PIN("b1 in");
a2 ::= #PIN("a2 in"); b2 ::= #PIN("b2 in");
a3 ::= #PIN("a3 in"); b3 ::= #PIN("b3 in");
ov ::= #PIN("overflow");
 
a0.val := 1; b0.val := 1;
a1.val := 1; b1.val := 1;
a2.val := 0; b2.val := 0;
a3.val := 0; b3.val := 1;
 
fba ::= #FOURBITSADDER(a0,a1,a2,a3,b0,b1,b2,b3);
#OUT + #FMT("%d%d%d%d", a3.val, a2.val, a1.val, a0.val) +
" + " +
#FMT("%d%d%d%d", b3.val, b2.val, b1.val, b0.val) +
" = " +
#FMT("%d%d%d%d", fba.s3.val, fba.s2.val, fba.s1.val, fba.s0.val) +
", overflow = " + fba.v.val + "\n";
end;
end;</lang>