139 lines
3.5 KiB
Plaintext
139 lines
3.5 KiB
Plaintext
-- 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. Currently can make
|
|
-- hard the implementation of a latch
|
|
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;
|