September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -1,2 +0,0 @@
result: 1010 ==> carry out: 0
result: 0011 ==> carry out: 1

View file

@ -0,0 +1,136 @@
@echo off
setlocal enabledelayedexpansion
:: ":main" is where all the non-logic-gate stuff happens
:main
:: User input two 4-digit binary numbers
:: There is no error checking for these numbers, however if the first 4 digits of both inputs are in binary...
:: The program will use them. All non-binary numbers are treated as 0s, but having less than 4 digits will crash it
set /p "input1=First 4-Bit Binary Number: "
set /p "input2=Second 4-Bit Binary Number: "
:: Put the first 4 digits of the binary numbers and separate them into "A[]" for input A and "B[]" for input B
for /l %%i in (0,1,3) do (
set A%%i=!input1:~%%i,1!
set B%%i=!input2:~%%i,1!
)
:: Run the 4-bit Adder with "A[]" and "B[]" as parameters. The program supports a 9th parameter for a Carry input
call:_4bitAdder %A3% %A2% %A1% %A0% %B3% %B2% %B1% %B0% 0
:: Display the answer and exit
echo %input1% + %input2% = %outputC%%outputS4%%outputS3%%outputS2%%outputS1%
pause>nul
exit /b
:: Function for the 4-bit Adder following the logic given
:_4bitAdder
set inputA1=%1
set inputA2=%2
set inputA3=%3
set inputA4=%4
set inputB1=%5
set inputB2=%6
set inputB3=%7
set inputB4=%8
set inputC=%9
call:_FullAdder %inputA1% %inputB1% %inputC%
set outputS1=%outputS%
set inputC=%outputC%
call:_FullAdder %inputA2% %inputB2% %inputC%
set outputS2=%outputS%
set inputC=%outputC%
call:_FullAdder %inputA3% %inputB3% %inputC%
set outputS3=%outputS%
set inputC=%outputC%
call:_FullAdder %inputA4% %inputB4% %inputC%
set outputS4=%outputS%
set inputC=%outputC%
:: In order return more than one number (of which is usually done via 'exit /b') we declare them while ending the local environment
endlocal && set "outputS1=%outputS1%" && set "outputS2=%outputS2%" && set "outputS3=%outputS3%" && set "outputS4=%outputS4%" && set "outputC=%inputC%"
exit /b
:: Function for the 1-bit Adder following the logic given
:_FullAdder
setlocal
set inputA=%1
set inputB=%2
set inputC1=%3
call:_halfAdder %inputA% %inputB%
set inputA1=%outputS%
set inputA2=%inputA1%
set inputC2=%outputC%
call:_HalfAdder %inputA1% %inputC1%
set outputS=%outputS%
set inputC1=%outputC%
call:_Or %inputC1% %inputC2%
set outputC=%errorlevel%
endlocal && set "outputS=%outputS%" && set "outputC=%outputC%"
exit /b
:: Function for the half-bit adder following the logic given
:_halfAdder
setlocal
set inputA1=%1
set inputA2=%inputA1%
set inputB1=%2
set inputB2=%inputB1%
call:_XOr %inputA1% %inputB2%
set outputS=%errorlevel%
call:_And %inputA2% %inputB2%
set outputC=%errorlevel%
endlocal && set "outputS=%outputS%" && set "outputC=%outputC%"
exit /b
:: Function for the XOR-gate following the logic given
:_XOr
setlocal
set inputA1=%1
set inputB1=%2
call:_Not %inputA1%
set inputA2=%errorlevel%
call:_Not %inputB1%
set inputB2=%errorlevel%
call:_And %inputA1% %inputB2%
set inputA=%errorlevel%
call:_And %inputA2% %inputB1%
set inputB=%errorlevel%
call:_Or %inputA% %inputB%
set outputA=%errorlevel%
:: As there is only one output, we can use 'exit /b {errorlevel}' to return a specified errorlevel
exit /b %outputA%
:: The basic 3 logic gates that every other funtion is composed of
:_Not
setlocal
if %1==0 exit /b 1
exit /b 0
:_Or
setlocal
if %1==1 exit /b 1
if %2==1 exit /b 1
exit /b 0
:_And
setlocal
if %1==1 if %2==1 exit /b 1
exit /b 0

View file

@ -0,0 +1,33 @@
(defn to-binary-seq [^long x]
(map #(- (int %) (int \0))
(Long/toBinaryString x)))
(defn half-adder [a b]
[(bit-xor a b)
(bit-and a b)])
(defn full-adder [a b carry]
(let [added (half-adder b carry)
half-sum (first added)]
[(first (half-adder a half-sum))
(bit-or (second (half-adder a half-sum)) (second added))]))
(defn ripple-carry-adder [a b]
(loop [a (reverse a)
b (reverse b)
sum '()
carry 0]
(let [added (full-adder (first a) (first b) carry)]
(if (and (empty? (next a)) (empty? (next b)))
(conj sum (first added) (bit-or carry 1))
(recur (next a) (next b) (conj sum (first added)) (second added))))))
(deftest adder
(is (= (Long/parseLong (apply str (ripple-carry-adder (to-binary-seq 10) (to-binary-seq 10))) 2)
(+ 10 10)))
(is (= (Long/parseLong (apply str (ripple-carry-adder (to-binary-seq 50) (to-binary-seq 50))) 2)
(+ 50 50)))
(is (= (Long/parseLong (apply str (ripple-carry-adder (to-binary-seq 32) (to-binary-seq 38))) 2)
(+ 32 38)))
(is (= (Long/parseLong (apply str (ripple-carry-adder (to-binary-seq 130) (to-binary-seq 250))) 2)
(+ 130 250))))

View file

@ -0,0 +1,32 @@
;; returns a list of bits: '(sum carry)
(defun half-adder (a b)
(list (logxor a b) (logand a b)))
;; returns a list of bits: '(sum, carry)
(defun full-adder (a b c-in)
(let*
((h1 (half-adder c-in a))
(h2 (half-adder (first h1) b)))
(list (first h2) (logior (second h1) (second h2)))))
;; a and b are lists of 4 bits each
(defun 4-bit-adder (a b)
(let*
((add-1 (full-adder (fourth a) (fourth b) 0))
(add-2 (full-adder (third a) (third b) (second add-1)))
(add-3 (full-adder (second a) (second b) (second add-2)))
(add-4 (full-adder (first a) (first b) (second add-3))))
(list
(list (first add-4) (first add-3) (first add-2) (first add-1))
(second add-4))))
(defun main ()
(print (4-bit-adder (list 0 0 0 0) (list 0 0 0 0))) ;; '(0 0 0 0) and 0
(print (4-bit-adder (list 0 0 0 0) (list 1 1 1 1))) ;; '(1 1 1 1) and 0
(print (4-bit-adder (list 1 1 1 1) (list 0 0 0 0))) ;; '(1 1 1 1) and 0
(print (4-bit-adder (list 0 1 0 1) (list 1 1 0 0))) ;; '(0 0 0 1) and 1
(print (4-bit-adder (list 1 1 1 1) (list 1 1 1 1))) ;; '(1 1 1 0) and 1
(print (4-bit-adder (list 1 0 1 0) (list 0 1 0 1))) ;; '(1 1 1 1) and 0
)
(main)

View file

@ -0,0 +1,103 @@
#
# 4bitadder.icn, emulate a 4 bit adder. Using only and, or, not
#
record carry(c)
#
# excercise the adder, either "test" or 2 numbers
#
procedure main(argv)
c := carry(0)
# cli test
if map(\argv[1]) == "test" then {
# Unicon allows explicit radix literals
every i := (2r0000 | 2r1001 | 2r1111) do {
write(i, "+0,3,9,15")
every j := (0 | 3 | 9 | 15) do {
ans := fourbitadder(t1 := fourbits(i), t2 := fourbits(j), c)
write(t1, " + ", t2, " = ", c.c, ":", ans)
}
}
return
}
# command line, two values, if given, first try four bit binaries
cli := fourbitadder(t1 := (*\argv[1] = 4 & fourbits("2r" || argv[1])),
t2 := (*\argv[2] = 4 & fourbits("2r" || argv[2])), c)
write(t1, " + ", t2, " = ", c.c, ":", \cli) & return
# if no result for that, try decimal values
cli := fourbitadder(t1 := fourbits(\argv[1]),
t2 := fourbits(\argv[2]), c)
write(t1, " + ", t2, " = ", c.c, ":", \cli) & return
# or display the help
write("Usage: 4bitadder [\"test\"] | [bbbb bbbb] | [n n], range 0-15")
end
#
# integer to fourbits as string
#
procedure fourbits(i)
local s, t
if not numeric(i) then fail
if not (0 <= integer(i) < 16) then {
write("out of range: ", i)
fail
}
s := ""
every t := (8 | 4 | 2 | 1) do {
s ||:= if iand(i, t) ~= 0 then "1" else "0"
}
return s
end
#
# low level xor emulation with or, and, not
#
procedure xor(a, b)
return ior(iand(a, icom(b)), iand(b, icom(a)))
end
#
# half adder, and into carry, xor for result bit
#
procedure halfadder(a, b, carry)
carry.c := iand(a,b)
return xor(a,b)
end
#
# full adder, two half adders, or for carry
#
procedure fulladder(a, b, c0, c1)
local c2, c3, r
c2 := carry(0)
c3 := carry(0)
# connect two half adders with carry
r := halfadder(halfadder(c0.c, a, c2), b, c3)
c1.c := ior(c2.c, c3.c)
return r
end
#
# fourbit adder, as bit string
#
procedure fourbitadder(a, b, cr)
local cs, c0, c1, c2, s
cs := carry(0)
c0 := carry(0)
c1 := carry(0)
c2 := carry(0)
# create a string for subscripting. strings are immutable, new strings created
s := "0000"
# bit 0 is string position 4
s[4+:1] := fulladder(a[4+:1], b[4+:1], cs, c0)
s[3+:1] := fulladder(a[3+:1], b[3+:1], c0, c1)
s[2+:1] := fulladder(a[2+:1], b[2+:1], c1, c2)
s[1+:1] := fulladder(a[1+:1], b[1+:1], c2, cr)
# cr.c is the overflow carry
return s
end

View file

@ -0,0 +1,47 @@
function xor_gate(bool a, bool b)
return (a and not b) or (not a and b)
end function
function half_adder(bool a, bool b)
bool s = xor_gate(a,b)
bool c = a and b
return {s,c}
end function
function full_adder(bool a, bool b, bool c)
bool {s1,c1} = half_adder(c,a)
bool {s2,c2} = half_adder(s1,b)
c = c1 or c2
return {s2,c}
end function
function four_bit_adder(bool a0, a1, a2, a3, b0, b1, b2, b3)
bool s0,s1,s2,s3,c
{s0,c} = full_adder(a0,b0,0)
{s1,c} = full_adder(a1,b1,c)
{s2,c} = full_adder(a2,b2,c)
{s3,c} = full_adder(a3,b3,c)
return {s3,s2,s1,s0,c}
end function
procedure test(integer a, integer b)
bool {a0,a1,a2,a3} = int_to_bits(a,4)
bool {b0,b1,b2,b3} = int_to_bits(b,4)
bool {r3,r2,r1,r0,c} = four_bit_adder(a0,a1,a2,a3,b0,b1,b2,b3)
integer r = bits_to_int({r0,r1,r2,r3})
printf(1,"%04b + %04b = %04b %b (%d+%d=%d)\n",{a,b,r,c,a,b,c*16+r})
end procedure
test(0,0)
test(0,1)
test(0b1111,0b1111)
test(3,7)
test(11,8)
test(0b1100,0b1100)
test(0b1100,0b1101)
test(0b1100,0b1110)
test(0b1100,0b1111)
test(0b1101,0b0000)
test(0b1101,0b0001)
test(0b1101,0b0010)
test(0b1101,0b0011)

View file

@ -0,0 +1,33 @@
(import (scheme base)
(scheme write)
(srfi 60)) ;; for logical bits
;; Returns a list of bits: '(sum carry)
(define (half-adder a b)
(list (bitwise-xor a b) (bitwise-and a b)))
;; Returns a list of bits: '(sum carry)
(define (full-adder a b c-in)
(let* ((h1 (half-adder c-in a))
(h2 (half-adder (car h1) b)))
(list (car h2) (bitwise-ior (cadr h1) (cadr h2)))))
;; a and b are lists of 4 bits each
(define (four-bit-adder a b)
(let* ((add-1 (full-adder (list-ref a 3) (list-ref b 3) 0))
(add-2 (full-adder (list-ref a 2) (list-ref b 2) (list-ref add-1 1)))
(add-3 (full-adder (list-ref a 1) (list-ref b 1) (list-ref add-2 1)))
(add-4 (full-adder (list-ref a 0) (list-ref b 0) (list-ref add-3 1))))
(list (list (car add-4) (car add-3) (car add-2) (car add-1))
(cadr add-4))))
(define (show-eg a b)
(display a) (display " + ") (display b) (display " = ")
(display (four-bit-adder a b)) (newline))
(show-eg (list 0 0 0 0) (list 0 0 0 0))
(show-eg (list 0 0 0 0) (list 1 1 1 1))
(show-eg (list 1 1 1 1) (list 0 0 0 0))
(show-eg (list 0 1 0 1) (list 1 1 0 0))
(show-eg (list 1 1 1 1) (list 1 1 1 1))
(show-eg (list 1 0 1 0) (list 0 1 0 1))

View file

@ -0,0 +1,24 @@
fcn xor(a,b) // a,b are 1|0 -->a^b(1|0)
{ a.bitAnd(b.bitNot()).bitOr(b.bitAnd(a.bitNot())) }
fcn halfAdder(a,b) // -->(carry, a+b) (1|0)
{ return(a.bitAnd(b), xor(a,b)) }
fcn fullBitAdder(c, a,b){ //-->(carry, a+b+c), a,b,c are 1|0
c1,s := halfAdder(a,c);
c2,s := halfAdder(s,b);
c3 := c1.bitOr(c2);
return(c3,s);
}
// big endian
fcn fourBitAdder(a3,a2,a1,a0, b3,b2,b1,b0){ //-->(carry, s3,s2,s1,s0)
c,s0 := fullBitAdder(0, a0,b0);
c,s1 := fullBitAdder(c, a1,b1);
c,s2 := fullBitAdder(c, a2,b2);
c,s3 := fullBitAdder(c, a3,b3);
return(c, s3,s2,s1,s0);
}
// add(10,9) result should be 1 0 0 1 1 (0x13, 3 carry 1)
println(fourBitAdder(1,0,1,0, 1,0,0,1));

View file

@ -0,0 +1,8 @@
fcn nBitAddr(as,bs){ //-->(carry, sn..s3,s2,s1,s0)
(ss:=List()).append(
[as.len()-1 .. 0,-1].reduce('wrap(c,n){
c2,s:=fullBitAdder(c,as[n],bs[n]); ss + s; c2
},0))
.reverse();
}
println(nBitAddr(T(1,0,1,0), T(1,0,0,1)));