Just another update

This commit is contained in:
Ingy döt Net 2015-02-20 00:35:01 -05:00
parent a25938f123
commit 00a190b0a6
6591 changed files with 94363 additions and 23227 deletions

View file

@ -1,6 +1,10 @@
The aim of this task is to "''simulate''" a four-bit adder "chip". This "chip" can be realized using four [[wp:Adder_(electronics)#Full_adder|1-bit full adder]]s. Each of these 1-bit full adders can be with two [[wp:Adder_(electronics)#Half_adder|half adder]]s and an ''or'' [[wp:Logic gate|gate]]. Finally a half adder can be made using a ''xor'' gate and an ''and'' gate. The ''xor'' gate can be made using two ''not''s, two ''and''s and one ''or''.
The aim of this task is to "''simulate''" a four-bit adder "chip".
This "chip" can be realized using four [[wp:Adder_(electronics)#Full_adder|1-bit full adder]]s.
Each of these 1-bit full adders can be built with two [[wp:Adder_(electronics)#Half_adder|half adder]]s and an ''or'' [[wp:Logic gate|gate]]. Finally a half adder can be made using a ''xor'' gate and an ''and'' gate.
The ''xor'' gate can be made using two ''not''s, two ''and''s and one ''or''.
'''Not''', '''or''' and '''and''', the only allowed "gates" for the task, can be "imitated" by using the [[Bitwise operations|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.
'''Not''', '''or''' and '''and''', the only allowed "gates" for the task, can be "imitated" by using the [[Bitwise operations|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.
@ -17,7 +21,8 @@ Instead of optimizing and reducing the number of gates used for the final 4-bit
|[[File:4bitsadder.png|frameless|A 4-bit adder]]
|}
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.
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).
<div style="clear:both"></div>

View file

@ -4,22 +4,22 @@ void fourBitsAdder(T)(in T a0, in T a1, in T a2, in T a3,
in T b0, in T b1, in T b2, in T b3,
out T o0, out T o1,
out T o2, out T o3,
out T overflow) pure nothrow {
out T overflow) pure nothrow @nogc {
// A XOR using only NOT, AND and OR, as task requires.
static T xor(in T x, in T y) pure nothrow {
static T xor(in T x, in T y) pure nothrow @nogc {
return (~x & y) | (x & ~y);
}
static void halfAdder(in T a, in T b,
out T s, out T c) pure nothrow {
out T s, out T c) pure nothrow @nogc {
s = xor(a, b);
// s = a ^ b; // The built-in D xor.
c = a & b;
}
static void fullAdder(in T a, in T b, in T ic,
out T s, out T oc) pure nothrow {
out T s, out T oc) pure nothrow @nogc {
T ps, pc, tc;
halfAdder(/*in*/a, b, /*out*/ps, pc);

View file

@ -6,124 +6,120 @@ import "fmt"
// You can feed it a single value without blocking.
// Reading a value blocks until a value is available.
type Wire chan bool
func MakeWire() Wire {
return make(Wire,1)
func MkWire() Wire {
return make(Wire, 1)
}
// A source for zero values.
func Zero() Wire {
r := MakeWire()
go func() {
for {
r <- false
}
}()
return r
func Zero() (r Wire) {
r = MkWire()
go func() {
for {
r <- false
}
}()
return
}
// And gate.
func And(a,b Wire) Wire {
r := MakeWire()
go func() {
for {
x := <-a
y := <-b
r <- (x && y)
}
}()
return r
func And(a, b Wire) (r Wire) {
r = MkWire()
go func() {
for {
r <- (<-a && <-b)
}
}()
return
}
// Or gate.
func Or(a,b Wire) Wire {
r := MakeWire()
go func() {
for {
x := <-a
y := <-b
r <- (x || y)
}
}()
return r
func Or(a, b Wire) (r Wire) {
r = MkWire()
go func() {
for {
r <- (<-a || <-b)
}
}()
return
}
// Not gate.
func Not(a Wire) Wire {
r := MakeWire()
go func() {
for {
x := <-a
r <- !x
}
}()
return r
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 := MakeWire()
r2 := MakeWire()
go func() {
for {
x := <-a
r1 <- x
r2 <- x
}
}()
return r1, r2
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)))
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
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
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 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 := MakeWire()
a2 := MakeWire()
a3 := MakeWire()
a4 := MakeWire()
b1 := MakeWire()
b2 := MakeWire()
b3 := MakeWire()
b4 := 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])
// 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])
}

View file

@ -0,0 +1,43 @@
sub dec2bin { sprintf "%04b", shift }
sub bin2dec { oct "0b".shift }
sub bin2bits { reverse split(//, substr(shift,0,shift)); }
sub bits2bin { join "", map { 0+$_ } reverse @_ }
sub bxor {
my($a, $b) = @_;
(!$a & $b) | ($a & !$b);
}
sub half_adder {
my($a, $b) = @_;
( bxor($a,$b), $a & $b );
}
sub full_adder {
my($a, $b, $c) = @_;
my($s1, $c1) = half_adder($a, $c);
my($s2, $c2) = half_adder($s1, $b);
($s2, $c1 | $c2);
}
sub four_bit_adder {
my($a, $b) = @_;
my @abits = bin2bits($a,4);
my @bbits = bin2bits($b,4);
my($s0,$c0) = full_adder($abits[0], $bbits[0], 0);
my($s1,$c1) = full_adder($abits[1], $bbits[1], $c0);
my($s2,$c2) = full_adder($abits[2], $bbits[2], $c1);
my($s3,$c3) = full_adder($abits[3], $bbits[3], $c2);
(bits2bin($s0, $s1, $s2, $s3), $c3);
}
print " A B A B C S sum\n";
for my $a (0 .. 15) {
for my $b (0 .. 15) {
my($abin, $bbin) = map { dec2bin($_) } $a,$b;
my($s,$c) = four_bit_adder( $abin, $bbin );
printf "%2d + %2d = %s + %s = %s %s = %2d\n",
$a, $b, $abin, $bbin, $c, $s, bin2dec($c.$s);
}
}

View file

@ -1,35 +1,30 @@
/*REXX program shows (all) the sums of a full 4-bit adder (with carry).*/
call hdr1; call hdr2
do j=0 for 16
/*REXX program shows (all) the sums of a full 4bit adder (with carry).*/
call hdr1; call hdr2 /*note order of headers (& below)*/
/* [↓] traipse all possibilities*/
do j=0 for 16
do m=0 for 4; a.m=bit(j,m); end
do k=0 for 16
do m=0 for 4; b.m=bit(k,m); end
sc=4bitAdder(a.,b.)
sc=4bitAdder(a., b.)
z=a.3 a.2 a.1 a.0 '_+_' b.3 b.2 b.1 b.0 '_=_' sc ',' s.3 s.2 s.1 s.0
say translate(space(z,0),,'_')
say translate(space(z,0),,'_') /*remove all underbars (_) from Z*/
end /*k*/
end /*j*/
call hdr2; call hdr1
call hdr2; call hdr1 /*display 2 headers (note order).*/
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────subroutines/functions───────────────*/
hdr1: say 'aaaa + bbbb = c, sum [c=carry]'; return
hdr2: say ' ' ; return
/*──────────────────────────────────one─line subroutines────────────────*/
bit: procedure; arg x,y; return substr(reverse(x2b(d2x(x))),y+1,1)
/*──────────────────────────────────HALFADDER subroutine-───────────────*/
halfAdder: procedure expose c; parse arg x,y; c=x & y; return x && y
/*──────────────────────────────────FULLADDER subroutine-───────────────*/
halfAdder: procedure expose c; parse arg x,y; c=x & y; return x && y
hdr1: say 'aaaa + bbbb = c, sum [c=carry]'; return
hdr2: say ' ' ; return
/*──────────────────────────────────FULLADDER subroutine────────────────*/
fullAdder: procedure expose c; parse arg x,y,fc
_1=halfAdder(fc,x); c1=c
_2=halfAdder(_1,y); c=c | c1; return _2
/*──────────────────────────────────3BITADDER subroutine-───────────────*/
_1 = halfAdder(fc,x); c1=c
_2 = halfAdder(_1,y); c=c | c1; return _2
/*──────────────────────────────────4BITADDER subroutine────────────────*/
4bitAdder: procedure expose s. a. b.; carry.=0
do j=0 for 4; n=j-1
s.j=fullAdder(a.j, b.j, carry.n); carry.j=c
end /*j*/
do j=0 for 4; n=j-1
s.j=fullAdder(a.j, b.j, carry.n); carry.j=c
end /*j*/
return c

View file

@ -28,18 +28,20 @@ def xor(a, b)
end
# "and", "or" and "not" are Ruby keywords
def _and(a, b); a & b; end
def _or(a, b); a | b; end
def _not(a); ~a & 1; end
def _and(a, b) a & b end
def _or(a, b) a | b end
def _not(a) ~a & 1 end
def int_to_binary_string(n, length)
("0"*length + n.to_s(2))[-length .. -1]
"%0#{length}b" % n
end
def binary_string_to_bits(s, length)
(s.reverse + "0"*length)[0..length-1].chars.map(&:to_i)
("%#{length}s" % s).reverse.chars.map(&:to_i)
end
def bits_to_binary_string(bits)
bits.map(&:to_s).reverse.join("")
bits.map(&:to_s).reverse.join
end
puts " A B A B C S sum"
@ -48,8 +50,7 @@ puts " A B A B C S sum"
bin_a = int_to_binary_string(a, 4)
bin_b = int_to_binary_string(b, 4)
sum, carry = four_bit_adder(bin_a, bin_b)
puts "%2d + %2d = %s + %s = %s %s = %2d" % [
a, b, bin_a, bin_b, carry, sum, (carry + sum).to_i(2)
]
puts "%2d + %2d = %s + %s = %s %s = %2d" %
[a, b, bin_a, bin_b, carry, sum, (carry + sum).to_i(2)]
end
end