Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- TIME_STAMP 2014-07-14 16:09:50 v 0.1
- do
- -----------------------------------------------------------------------------------------------
- -- Objekte:
- -- NOT Ausgangspegel ist invertierter Eingangspegel
- -- AND Ausgangspegel TRUE, wenn beide Eingangspegel TRUE sind
- -- AND_TRIPLE Ausgangspegel TRUE, wenn alle drei Eingangspegel TRUE sind
- -- OR Ausgangspegel TRUE, wenn einer der Eingangspegel TRUE ist
- -- OR_TRIPLE Ausgangspegel TRUE, wenn einer der drei Eingangspegel TRUE ist
- -- XOR Ausgangspegel TRUE, wenn die Eingangspegel ungleich sind
- -- NAND Ausgangspegel FALSE, wenn beide Eingange TRUE, sonst immer TRUE
- -- NOR Ausgangspegel TRUE, wenn beide Eingange FALSE
- -- XNOR Ausgangspegel TRUE, wenn beide Eingange denselben Pegel aufweisen
- -- SPLIT Verknupfungsobjekt um einen Ein-/Ausgangspegel an mehrere Ein-/Ausgange zu legen
- -- [VISITOR] internes Besucherobjekt
- --
- -- Module:
- -- HALFADDER
- --
- -- Globale Methoden:
- -- Wire Verknupft zwei Objekte miteinander
- -- TruthTable Wahrheitstabelle fur ein Gatter ausgeben
- -- [Int2Bool] Integerwert der Eingabe in Boolwert wandeln
- -- [Bool2Int] Boolwert der Ausgabe in Integerwert wandeln
- --
- -- Eingangspins: a NOT
- -- a, b AND, OR, XOR, NAND, NOR, XNOR
- -- a[, b, c] SPLIT, AND_TRIPLE, OR_TRIPLE
- -- Ausgangspins: q NOT, AND, OR, XOR, NAND, NOR, XNOR
- -- q[, b, c] SPLIT
- -----------------------------------------------------------------------------------------------
- Gate = {
- -----------------------------------------------------------------------------------------------
- -- Integer in Boolschen Wert wandeln (0 = false, jeder andere Wert ist true)
- -----------------------------------------------------------------------------------------------
- Int2Bool = function(self, val)
- local sType = type(val)
- if sType == 'boolean' then
- return val
- elseif sType ~= 'number' or val == 0 then
- return false
- else
- return true
- end
- end,
- -----------------------------------------------------------------------------------------------
- -- Boolschen Wert Integer in wandeln (false = 0, jeder andere Wert ist 1)
- -----------------------------------------------------------------------------------------------
- Bool2Int = function(self, val)
- local sType = type(val)
- if sType == 'number' then
- return val
- elseif val == false then
- return 0
- else
- return 1
- end
- end,
- -----------------------------------------------------------------------------------------------
- -- Verbinde: Von-Objekt/Von-Pin An-Objekt/An-Pin
- -----------------------------------------------------------------------------------------------
- Wire = function(self, oFrom, pinFrom, oTo, pinTo)
- -- Im Von-Objekt: Ausgangs-Objekt = Ziel-Objekt, Ausgangs-Pin = Eingangs-Pin Ziel-Objekt
- if pinFrom == 'b' then
- oFrom.obj_b = oTo
- oFrom.pin_b = pinTo
- elseif pinFrom == 'c' then
- oFrom.obj_c = oTo
- oFrom.pin_c = pinTo
- else
- oFrom.obj_q = oTo
- oFrom.pin_q = pinTo
- end
- -- Im Ziel-Objekt: am Output-Objekt eintragen: von-Objekt, von-Pin
- if pinTo == 'b' then
- oTo.obj_b = oFrom
- oTo.pin_b = pinFrom
- elseif pinTo == 'c' then
- oTo.obj_c = oFrom
- oTo.pin_c = pinFrom
- else
- oTo.obj_a = oFrom
- oTo.pin_a = pinFrom
- end
- end,
- -----------------------------------------------------------------------------------------------
- -- Wahrheitstabelle aller Schaltzustande fur das Objekt ausgeben
- -----------------------------------------------------------------------------------------------
- TruthTable = function(self, oFrom)
- local sClass = oFrom.class
- local sOut, tFormat = 'TRUTH TABLE '..sClass..':\n'..('-'):rep(13+#sClass)..'\n'
- if sClass == 'NOT' then
- tFormat = {1, 'A Q\n', '%d %d', {0}, {1}}
- elseif (' AND OR XOR NAND NOR XNOR '):find(' '..sClass..' ') then
- tFormat = {2, 'A B Q\n', '%d %d %d', {0,0}, {0,1}, {1,0}, {1,1}}
- elseif sClass == 'COMPARE' then
- tFormat = {3, 'A B < = >\n', '%d %d %d %d %d', {0,0}, {0,1}, {1,0}, {1,1}}
- elseif sClass == 'HALFADDER' then
- tFormat = {4, 'X Y C S\n', '%d %d %d %d', {0,0}, {0,1}, {1,0}, {1,1}}
- elseif sClass == 'FULLADDER' then
- tFormat = {5, 'X Y Cin S Cout\n', '%d %d %d %d %d', {0,0,0}, {0,0,1}, {0,1,0}, {0,1,1}, {1,0,0}, {1,0,1}, {1,1,0}, {1,1,1}}
- elseif (' AND_TRIPLE OR_TRIPLE '):find(' '..sClass..' ') then
- tFormat = {6, 'A B C Q\n', '%d %d %d %d', {0,0,0}, {0,0,1}, {0,1,0}, {0,1,1}, {1,0,0}, {1,0,1}, {1,1,0}, {1,1,1}}
- end
- sOut = sOut..tFormat[2]
- for i = 4, #tFormat do
- if tFormat[1] == 1 then
- oFrom:Set(tFormat[i][1])
- sOut = sOut..string.format(tFormat[3], tFormat[i][1], Gate:Bool2Int(oFrom.q))..'\n'
- elseif tFormat[1] == 2 then
- oFrom:Set(tFormat[i][1], tFormat[i][2])
- sOut = sOut..string.format(tFormat[3], tFormat[i][1], tFormat[i][2], Gate:Bool2Int(oFrom.q))..'\n'
- elseif tFormat[1] == 3 then
- oFrom:Set(tFormat[i][1], tFormat[i][2])
- sOut = sOut..string.format(tFormat[3], tFormat[i][1], tFormat[i][2], Gate:Bool2Int(oFrom.q_lt), Gate:Bool2Int(oFrom.q_eq), Gate:Bool2Int(oFrom.q_gt))..'\n'
- elseif tFormat[1] == 4 then
- oFrom:Set(tFormat[i][1], tFormat[i][2])
- sOut = sOut..string.format(tFormat[3], tFormat[i][1], tFormat[i][2], Gate:Bool2Int(oFrom.c), Gate:Bool2Int(oFrom.s))..'\n'
- elseif tFormat[1] == 5 then
- oFrom:Set(tFormat[i][1], tFormat[i][2], tFormat[i][3])
- sOut = sOut..string.format(tFormat[3], tFormat[i][1], tFormat[i][2], tFormat[i][3], Gate:Bool2Int(oFrom.c), Gate:Bool2Int(oFrom.s))..'\n'
- elseif tFormat[1] == 6 then
- oFrom:Set(tFormat[i][1], tFormat[i][2], tFormat[i][3])
- sOut = sOut..string.format(tFormat[3], tFormat[i][1], tFormat[i][2], tFormat[i][3], Gate:Bool2Int(oFrom.q))..'\n'
- end
- end
- print(sOut)
- end,
- -----------------------------------------------------------------------------------------------
- -- Eingangssignal wird invertiert ausgegeben NOT --
- -----------------------------------------------------------------------------------------------
- NOT = {
- class = 'NOT', -- Klassenname
- name, -- Name Klasseninstanz-Objekt (optional)
- a_old, -- letzter Wert Eingang
- a, -- Wert Eingang
- q, -- Wert Ausgang
- obj_a, -- Objektverknupfung an Eingang
- obj_q, -- Objektverknupfung an Ausgang
- pin_a, -- Pin des Objektes an a
- pin_q, -- Pin des Objektes an q
- visitor_auto_run = false, -- "true" aktualisiert autom. Objekt am Ausgang bei Refresh
- TruthTable = function(self)
- Gate:TruthTable(self)
- end,
- Trace = function(self, sTrace)
- if sTrace == nil then sTrace = '' end
- sTrace = sTrace..self.name..'\n'
- if self.obj_a ~= nil then
- sTrace = sTrace..'\tIN (Pin: Value)\ta:\t'..Gate:Bool2Int(self.a)..' from '..self.obj_a.name..'/'..self.pin_a..'\n'
- else
- sTrace = sTrace..'\tIN (Pin: Value)\ta:\t'..Gate:Bool2Int(self.a)
- end
- if self.obj_q ~= nil then
- sTrace = sTrace..'\tOUT (Pin: Value)\tq:\t'..Gate:Bool2Int(self.q)..' to '..self.obj_q.name..'/'..self.pin_q..':\t'..Gate:Bool2Int(self.obj_q[self.pin_q])..'\n'
- else
- sTrace = sTrace..'\tOUT (Pin: Value)\tq:\t'..Gate:Bool2Int(self.q)..'\n'
- end
- return sTrace
- end,
- Refresh = function(self) -- Aktualisieren Ausgangswert des Objektes und Setzen des Eingangs an verknupftem Objekt
- if self.a ~= self.a_old then -- Eingangspegel hat sich geandert
- self.a_old = self.a
- self.q = not self.a
- if self.obj_q ~= nil then -- am Ausgang ist ein Objekt verknupft
- self.obj_q[self.pin_q] = self.q
- if self.visitor_auto_run then -- nach Aktualisieren der Werte soll verknupftes Objekt besucht (und aktualisiert) werden
- Gate.VISITOR:visit(self.obj_q)
- end
- end
- end
- end,
- Set = function(self, a)
- self.a = Gate:Int2Bool(a)
- self:Refresh()
- end,
- New = function(self, obj, name, f_auto)
- obj = obj or {}
- setmetatable(obj, self)
- self.__index = self
- if name ~= nil then obj.name = name end
- if f_auto ~= nil then obj.visitor_auto_run = f_auto end
- return obj
- end
- },
- -----------------------------------------------------------------------------------------------
- -- Beide Eingangspegel mussen TRUE sein, damit der Ausgangspegel TRUE ist AND --
- -----------------------------------------------------------------------------------------------
- AND = {
- class = 'AND',
- name,
- a_old,
- b_old,
- a,
- b,
- q,
- obj_a,
- obj_b,
- obj_q,
- pin_a,
- pin_b,
- pin_q,
- visitor_auto_run = false,
- TruthTable = function(self)
- Gate:TruthTable(self)
- end,
- Refresh = function(self)
- if (self.a ~= self.a_old) or
- (self.b ~= self.b_old)then
- self.a_old = self.a
- self.b_old = self.b
- self.q = self.a and self.b
- if self.obj_q ~= nil then
- self.obj_q[self.pin_q] = self.q
- if self.visitor_auto_run then
- Gate.VISITOR:visit(self.obj_q)
- end
- end
- end
- end,
- Set = function(self, a, b)
- if a ~= nil then self.a = Gate:Int2Bool(a) end
- if b ~= nil then self.b = Gate:Int2Bool(b) end
- self:Refresh()
- end,
- New = function(self, obj, name, f_auto)
- obj = obj or {}
- setmetatable(obj, self)
- self.__index = self
- if name ~= nil then obj.name = name end
- if f_auto ~= nil then obj.visitor_auto_run = f_auto end
- return obj
- end
- },
- -----------------------------------------------------------------------------------------------
- -- Alle drei Eingangspegel mussen TRUE sein, damit der Ausgangspegel TRUE ist AND --
- -----------------------------------------------------------------------------------------------
- AND_TRIPLE = {
- class = 'AND_TRIPLE',
- name,
- a_old,
- b_old,
- c_old,
- a,
- b,
- c,
- q,
- obj_a,
- obj_b,
- obj_c,
- obj_q,
- pin_a,
- pin_b,
- pin_c,
- pin_q,
- visitor_auto_run = false,
- TruthTable = function(self)
- Gate:TruthTable(self)
- end,
- Refresh = function(self)
- if (self.a ~= self.a_old) or
- (self.b ~= self.b_old) or
- (self.c ~= self.c_old) then
- self.a_old = self.a
- self.b_old = self.b
- self.c_old = self.c
- self.q = (self.a and self.b) and self.c
- if self.obj_q ~= nil then
- self.obj_q[self.pin_q] = self.q
- if self.visitor_auto_run then
- Gate.VISITOR:visit(self.obj_q)
- end
- end
- end
- end,
- Set = function(self, a, b, c)
- if a ~= nil then self.a = Gate:Int2Bool(a) end
- if b ~= nil then self.b = Gate:Int2Bool(b) end
- if c ~= nil then self.c = Gate:Int2Bool(c) end
- self:Refresh()
- end,
- New = function(self, obj, name, f_auto)
- obj = obj or {}
- setmetatable(obj, self)
- self.__index = self
- if name ~= nil then obj.name = name end
- if f_auto ~= nil then obj.visitor_auto_run = f_auto end
- return obj
- end
- },
- -----------------------------------------------------------------------------------------------
- -- Einer der Eingangspegel muss TRUE sein, damit der Ausgangspegel TRUE ist OR --
- -----------------------------------------------------------------------------------------------
- OR = {
- class = 'OR',
- name,
- a_old,
- b_old,
- a,
- b,
- q,
- obj_a,
- obj_b,
- obj_q,
- pin_a,
- pin_b,
- pin_q,
- visitor_auto_run = false,
- TruthTable = function(self)
- Gate:TruthTable(self)
- end,
- Refresh = function(self)
- if (self.a ~= self.a_old) or
- (self.b ~= self.b_old)then
- self.a_old = self.a
- self.b_old = self.b
- self.q = self.a or self.b
- if self.obj_q ~= nil then
- self.obj_q[self.pin_q] = self.q
- if self.visitor_auto_run then
- Gate.VISITOR:visit(self.obj_q)
- end
- end
- end
- end,
- Set = function(self, a, b)
- if a ~= nil then self.a = Gate:Int2Bool(a) end
- if b ~= nil then self.b = Gate:Int2Bool(b) end
- self:Refresh()
- end,
- New = function(self, obj, name, f_auto)
- obj = obj or {}
- setmetatable(obj, self)
- self.__index = self
- if name ~= nil then obj.name = name end
- if f_auto ~= nil then obj.visitor_auto_run = f_auto end
- return obj
- end
- },
- -----------------------------------------------------------------------------------------------
- -- Einer der Eingangspegel muss TRUE sein, damit der Ausgangspegel TRUE ist OR --
- -----------------------------------------------------------------------------------------------
- OR_TRIPLE = {
- class = 'OR_TRIPLE',
- name,
- a_old,
- b_old,
- c_old,
- a,
- b,
- c,
- q,
- obj_a,
- obj_b,
- obj_c,
- obj_q,
- pin_a,
- pin_b,
- pin_c,
- pin_q,
- visitor_auto_run = false,
- TruthTable = function(self)
- Gate:TruthTable(self)
- end,
- Refresh = function(self)
- if (self.a ~= self.a_old) or
- (self.b ~= self.b_old) or
- (self.c ~= self.c_old) then
- self.a_old = self.a
- self.b_old = self.b
- self.c_old = self.c
- self.q = self.a or self.b or self.c
- if self.obj_q ~= nil then
- self.obj_q[self.pin_q] = self.q
- if self.visitor_auto_run then
- Gate.VISITOR:visit(self.obj_q)
- end
- end
- end
- end,
- Set = function(self, a, b, c)
- if a ~= nil then self.a = Gate:Int2Bool(a) end
- if b ~= nil then self.b = Gate:Int2Bool(b) end
- if c ~= nil then self.c = Gate:Int2Bool(c) end
- self:Refresh()
- end,
- New = function(self, obj, name, f_auto)
- obj = obj or {}
- setmetatable(obj, self)
- self.__index = self
- if name ~= nil then obj.name = name end
- if f_auto ~= nil then obj.visitor_auto_run = f_auto end
- return obj
- end
- },
- -----------------------------------------------------------------------------------------------
- -- Ausgangspegel ist TRUE, wenn die Eingangspegel ungleich sind XOR --
- -----------------------------------------------------------------------------------------------
- XOR = {
- class = 'XOR',
- name,
- a_old,
- b_old,
- a,
- b,
- q,
- obj_a,
- obj_b,
- obj_q,
- pin_a,
- pin_b,
- pin_q,
- visitor_auto_run = false,
- TruthTable = function(self)
- Gate:TruthTable(self)
- end,
- Refresh = function(self)
- if (self.a ~= self.a_old) or
- (self.b ~= self.b_old)then
- self.a_old = self.a
- self.b_old = self.b
- self.q = (self.a ~= self.b)
- if self.obj_q ~= nil then
- self.obj_q[self.pin_q] = self.q
- if self.visitor_auto_run then
- Gate.VISITOR:visit(self.obj_q)
- end
- end
- end
- end,
- Set = function(self, a, b)
- if a ~= nil then self.a = Gate:Int2Bool(a) end
- if b ~= nil then self.b = Gate:Int2Bool(b) end
- self:Refresh()
- end,
- New = function(self, obj, name, f_auto)
- obj = obj or {}
- setmetatable(obj, self)
- self.__index = self
- if name ~= nil then obj.name = name end
- if f_auto ~= nil then obj.visitor_auto_run = f_auto end
- return obj
- end
- },
- -----------------------------------------------------------------------------------------------
- -- Ausgangspegel ist FALSE, wenn beide Eingange TRUE, sonst immer TRUE NAND --
- -----------------------------------------------------------------------------------------------
- NAND = {
- class = 'NAND',
- name,
- a_old,
- b_old,
- a,
- b,
- q,
- obj_a,
- obj_b,
- obj_q,
- pin_a,
- pin_b,
- pin_q,
- visitor_auto_run = false,
- TruthTable = function(self)
- Gate:TruthTable(self)
- end,
- Refresh = function(self)
- if (self.a ~= self.a_old) or
- (self.b ~= self.b_old)then
- self.a_old = self.a
- self.b_old = self.b
- self.q = not (self.a and self.b)
- if self.obj_q ~= nil then
- self.obj_q[self.pin_q] = self.q
- if self.visitor_auto_run then
- Gate.VISITOR:visit(self.obj_q)
- end
- end
- end
- end,
- Set = function(self, a, b)
- if a ~= nil then self.a = Gate:Int2Bool(a) end
- if b ~= nil then self.b = Gate:Int2Bool(b) end
- self:Refresh()
- end,
- New = function(self, obj, name, f_auto)
- obj = obj or {}
- setmetatable(obj, self)
- self.__index = self
- if name ~= nil then obj.name = name end
- if f_auto ~= nil then obj.visitor_auto_run = f_auto end
- return obj
- end
- },
- -----------------------------------------------------------------------------------------------
- -- Ausgangssignal nur TRUE, wenn beide Eingange FALSE NOR --
- -----------------------------------------------------------------------------------------------
- NOR = {
- class = 'NOR',
- name,
- a_old,
- b_old,
- a,
- b,
- q,
- obj_a,
- obj_b,
- obj_q,
- pin_a,
- pin_b,
- pin_q,
- visitor_auto_run = false,
- TruthTable = function(self)
- Gate:TruthTable(self)
- end,
- Refresh = function(self)
- if (self.a ~= self.a_old) or
- (self.b ~= self.b_old)then
- self.a_old = self.a
- self.b_old = self.b
- self.q = (self.a or self.b) == false
- if self.obj_q ~= nil then
- self.obj_q[self.pin_q] = self.q
- if self.visitor_auto_run then
- Gate.VISITOR:visit(self.obj_q)
- end
- end
- end
- end,
- Set = function(self, a, b)
- if a ~= nil then self.a = Gate:Int2Bool(a) end
- if b ~= nil then self.b = Gate:Int2Bool(b) end
- self:Refresh()
- end,
- New = function(self, obj, name, f_auto)
- obj = obj or {}
- setmetatable(obj, self)
- self.__index = self
- if name ~= nil then obj.name = name end
- if f_auto ~= nil then obj.visitor_auto_run = f_auto end
- return obj
- end
- },
- -----------------------------------------------------------------------------------------------
- -- Ausgangspegel TRUE, wenn beide Eingange denselben Pegel aufweisen XNOR --
- -----------------------------------------------------------------------------------------------
- XNOR = {
- class = 'XNOR',
- name,
- a_old,
- b_old,
- a,
- b,
- q,
- obj_a,
- obj_b,
- obj_q,
- pin_a,
- pin_b,
- pin_q,
- visitor_auto_run = false,
- TruthTable = function(self)
- Gate:TruthTable(self)
- end,
- Refresh = function(self)
- if (self.a ~= self.a_old) or
- (self.b ~= self.b_old)then
- self.a_old = self.a
- self.b_old = self.b
- self.q = (self.a == self.b)
- if self.obj_q ~= nil then
- self.obj_q[self.pin_q] = self.q
- if self.visitor_auto_run then
- Gate.VISITOR:visit(self.obj_q)
- end
- end
- end
- end,
- Set = function(self, a, b)
- if a ~= nil then self.a = Gate:Int2Bool(a) end
- if b ~= nil then self.b = Gate:Int2Bool(b) end
- self:Refresh()
- end,
- New = function(self, obj, name, f_auto)
- obj = obj or {}
- setmetatable(obj, self)
- self.__index = self
- if name ~= nil then obj.name = name end
- if f_auto ~= nil then obj.visitor_auto_run = f_auto end
- return obj
- end
- },
- -----------------------------------------------------------------------------------------------
- -- Vergleichsobjekt, 3 Ausgangspegel: groesser, gleich, kleiner COMPARE --
- -----------------------------------------------------------------------------------------------
- COMPARE = {
- class = 'COMPARE',
- name,
- a_old,
- b_old,
- a,
- b,
- q_gt, -- A groesser B
- q_lt, -- A kleiner B
- q_eq, -- A gleich B
- obj_a,
- obj_b,
- obj_q_gt,
- obj_q_lt,
- obj_q_eq,
- pin_a,
- pin_b,
- pin_q_gt,
- pin_q_lt,
- pin_q_eq,
- visitor_auto_run = false,
- TruthTable = function(self)
- Gate:TruthTable(self)
- end,
- Compare = function(self, a, b)
- local lt, eq, gt = false, false, false
- if a == b then
- eq = true
- elseif not a and b then
- lt = true
- else
- gt = true
- end
- return lt, eq, gt
- end,
- Refresh = function(self)
- if (self.a ~= self.a_old) or
- (self.b ~= self.b_old) then
- self.a_old = self.a
- self.b_old = self.b
- self.q_lt, self.q_eq, self.q_gt = self:Compare(self.a, self.b)
- local tQ = {}
- if self.obj_q_lt ~= nil then
- self.obj_q_lt[self.pin_q_lt] = self.q_lt
- tQ[#tQ+1] = self.obj_q_lt
- end
- if self.obj_q_gt ~= nil then
- self.obj_q_gt[self.pin_q_gt] = self.q_gt
- tQ[#tQ+1] = self.obj_q_gt
- end
- if self.obj_q_eq ~= nil then
- self.obj_q_eq[self.pin_q_eq] = self.q_eq
- tQ[#tQ+1] = self.obj_q_eq
- end
- if self.visitor_auto_run then
- if #tQ > 0 then
- for i = 1, #tQ do
- Gate.VISITOR:visit(tQ[i])
- end
- end
- end
- end
- end,
- Set = function(self, a, b)
- if a ~= nil then self.a = Gate:Int2Bool(a) end
- if b ~= nil then self.b = Gate:Int2Bool(b) end
- self:Refresh()
- end,
- New = function(self, obj, name, f_auto)
- obj = obj or {}
- setmetatable(obj, self)
- self.__index = self
- if name ~= nil then obj.name = name end
- if f_auto ~= nil then obj.visitor_auto_run = f_auto end
- return obj
- end
- },
- -----------------------------------------------------------------------------------------------
- -- Verknupfungsobjekt SPLIT --
- -- 1 Eingang(A), 1 Ausgang(Q), --
- -- 2 als Ein- oder Ausgang(B,C) verwendbare Anschlusse --
- -- Ist ein Eingangspegel TRUE sind auch alle Ausgange TRUE --
- -- Nur wenn alle Eingange FALSE sind, sind auch die Ausgange FALSE --
- -- 'A' und 'Q' mussen immer belegt sein, 'B' und 'C' sind optional --
- -----------------------------------------------------------------------------------------------
- SPLIT = {
- class = 'SPLIT',
- name,
- a_old,
- b_old,
- c_old,
- a,
- b,
- c,
- q,
- b_is_out = false,
- c_is_out = false,
- obj_a,
- obj_b,
- obj_c,
- obj_q,
- pin_a,
- pin_b,
- pin_c,
- pin_q,
- visitor_auto_run = false,
- Output = function(self)
- if (not self.b_is_out) and (not self.c_is_out) then
- if self.a or self.b or self.c then
- return true
- else
- return false
- end
- elseif (not self.b_is_out) and self.c_is_out then
- if self.a or self.b then
- return true
- else
- return false
- end
- elseif self.b_is_out and (not self.c_is_out) then
- if self.a or self.c then
- return true
- else
- return false
- end
- elseif self.b_is_out and self.c_is_out then
- return self.a
- end
- end,
- Refresh = function(self)
- local tRefresh, fOut = {}
- if (not self.b_is_out) and (not self.c_is_out) then
- if (self.a ~= self.a_old) or
- (self.b ~= self.b_old) or
- (self.c ~= self.c_old) then
- self.a_old = self.a
- self.b_old = self.b
- self.c_old = self.c
- self.q = self:Output()
- if self.obj_q ~= nil then
- self.obj_q[self.pin_q] = self.q
- if self.visitor_auto_run then
- table.insert(tRefresh, self.obj_q)
- end
- end
- end
- elseif (not self.b_is_out) and self.c_is_out then
- if (self.a ~= self.a_old) or
- (self.b ~= self.b_old) then
- self.a_old = self.a
- self.b_old = self.b
- fOut = self:Output()
- self.c = fOut
- self.q = fOut
- if self.obj_c ~= nil then
- self.obj_c[self.pin_c] = self.c
- if self.visitor_auto_run then
- table.insert(tRefresh, self.obj_c)
- end
- end
- if self.obj_q ~= nil then
- self.obj_q[self.pin_q] = self.q
- if self.visitor_auto_run then
- table.insert(tRefresh, self.obj_q)
- end
- end
- end
- elseif self.b_is_out and (not self.c_is_out) then
- if (self.a ~= self.a_old) or
- (self.b ~= self.b_old) then
- self.a_old = self.a
- self.c_old = self.c
- fOut = self:Output()
- self.b = fOut
- self.q = fOut
- if self.obj_b ~= nil then
- self.obj_b[self.pin_b] = self.b
- if self.visitor_auto_run then
- table.insert(tRefresh, self.obj_b)
- end
- end
- if self.obj_q ~= nil then
- self.obj_q[self.pin_q] = self.q
- if self.visitor_auto_run then
- table.insert(tRefresh, self.obj_q)
- end
- end
- end
- elseif self.b_is_out and self.c_is_out then
- if (self.a ~= self.a_old) then
- self.a_old = self.a
- fOut = self:Output()
- self.b = fOut
- self.c = fOut
- self.q = fOut
- if self.obj_b ~= nil then
- self.obj_b[self.pin_b] = self.b
- if self.visitor_auto_run then
- table.insert(tRefresh, self.obj_b)
- end
- end
- if self.obj_c ~= nil then
- self.obj_c[self.pin_c] = self.c
- if self.visitor_auto_run then
- table.insert(tRefresh, self.obj_c)
- end
- end
- if self.obj_q ~= nil then
- self.obj_q[self.pin_q] = self.q
- if self.visitor_auto_run then
- table.insert(tRefresh, self.obj_q)
- end
- end
- end
- end
- if #tRefresh > 0 then
- for i = 1, #tRefresh do
- Gate.VISITOR:visit(tRefresh[i])
- end
- end
- end,
- Set = function(self, a, b, c)
- if a ~= nil then self.a = Gate:Int2Bool(a) end
- if b ~= nil then self.b = Gate:Int2Bool(b) end
- if c ~= nil then self.b = Gate:Int2Bool(c) end
- self:Refresh()
- end,
- New = function(self, obj, name, f_auto)
- obj = obj or {}
- setmetatable(obj, self)
- self.__index = self
- if name ~= nil then obj.name = name end
- if f_auto ~= nil then obj.visitor_auto_run = f_auto end
- return obj
- end
- },
- -----------------------------------------------------------------------------------------------
- -- Refresh-Visitor VISITOR --
- -- Besucht Objekt am Ausgang und aktualisiert dessen Werte
- -----------------------------------------------------------------------------------------------
- VISITOR = {
- class = 'VISITOR',
- name = 'VisitorRefresh',
- visit = function(self, oVisited)
- oVisited:Refresh()
- end,
- },
- -----------------------------------------------------------------------------------------------
- -- M O D U L E --
- -- Eingangspegel (x, y, c, [x1, x2.., y1, y2..]) an Properties:
- -- Objekt im Modul: mod_oIn_x (mod_oIn_x1, mod_oIn_y1..)
- -- Pin dieses Objektes: mod_pIn_x (mod_pIn_x1, mod_pIn_y1..)
- -----------------------------------------------------------------------------------------------
- HALFADDER = {
- class = 'HALFADDER',
- name,
- c,
- s,
- oAND,
- oXOR,
- oSPLIT_AND,
- oSPLIT_XOR,
- TruthTable = function(self)
- Gate:TruthTable(self)
- end,
- Set = function(self, x, y)
- self.oSPLIT_XOR:Set(x)
- self.oSPLIT_AND:Set(y)
- self.s = Gate:Bool2Int(self.oXOR.q)
- self.c = Gate:Bool2Int(self.oAND.q)
- end,
- New = function(self, obj, name)
- obj = obj or {}
- self.oAND = Gate.AND:New(nil, 'And-Halfadder', true)
- self.oXOR = Gate.XOR:New(nil, 'XOr-Halfadder', true)
- self.oSPLIT_AND = Gate.SPLIT:New(nil, 'SPLIT-And-Halfadder', true)
- self.oSPLIT_XOR = Gate.SPLIT:New(nil, 'SPLIT-XOr-Halfadder', true)
- self.oSPLIT_AND.b_is_out = true
- self.oSPLIT_XOR.b_is_out = true
- Gate:Wire(self.oSPLIT_AND, 'b', self.oAND, 'a')
- Gate:Wire(self.oSPLIT_AND, 'q', self.oXOR, 'a')
- Gate:Wire(self.oSPLIT_XOR, 'b', self.oAND, 'b')
- Gate:Wire(self.oSPLIT_XOR, 'q', self.oXOR, 'b')
- setmetatable(obj, self)
- self.__index = self
- if name ~= nil then obj.name = name end
- return obj
- end
- },
- FULLADDER = {
- class = 'FULLADDER',
- name,
- c,
- s,
- oHA1,
- oHA2,
- oOR,
- TruthTable = function(self)
- Gate:TruthTable(self)
- end,
- Set = function(self, x, y, c_in)
- self.oHA1:Set(x, y)
- self.oHA2:Set(self.oHA1.s, c_in)
- self.oOR:Set(self.oHA1.c, self.oHA2.c)
- self.s = Gate:Bool2Int(self.oHA2.s)
- self.c = Gate:Bool2Int(self.oOR.q)
- end,
- New = function(self, obj, name)
- obj = obj or {}
- self.oHA1 = Gate.HALFADDER:New(nil, 'HA1')
- self.oHA2 = Gate.HALFADDER:New(nil, 'HA2')
- self.oOR = Gate.OR:New(nil, 'Or-Adder', true)
- setmetatable(obj, self)
- self.__index = self
- if name ~= nil then obj.name = name end
- return obj
- end
- },
- ADDER4BIT = {
- class = 'ADDER4BIT',
- name,
- c,
- s1,
- s2,
- s3,
- s4,
- oFA1,
- oFA2,
- oFA3,
- oFA4,
- Set = function(self, x1, x2, x3, x4, y1, y2, y3, y4, c_in)
- if c_in == nil then c_in = 0 end
- self.oFA1:Set(x1, y1, c_in)
- self.oFA2:Set(x2, y2, self.oFA1.c)
- self.oFA3:Set(x3, y3, self.oFA2.c)
- self.oFA4:Set(x4, y4, self.oFA3.c)
- self.s1 = Gate:Bool2Int(self.oFA1.s)
- self.s2 = Gate:Bool2Int(self.oFA2.s)
- self.s3 = Gate:Bool2Int(self.oFA3.s)
- self.s4 = Gate:Bool2Int(self.oFA4.s)
- self.c = Gate:Bool2Int(self.oFA4.c)
- end,
- New = function(self, obj, name)
- obj = obj or {}
- self.oFA1 = Gate.FULLADDER:New(nil, 'FA1')
- self.oFA2 = Gate.FULLADDER:New(nil, 'FA2')
- self.oFA3 = Gate.FULLADDER:New(nil, 'FA3')
- self.oFA4 = Gate.FULLADDER:New(nil, 'FA4')
- setmetatable(obj, self)
- self.__index = self
- if name ~= nil then obj.name = name end
- return obj
- end
- },
- HALFSUBTRACTOR = {
- class = 'HALFSUBTRACTOR',
- name,
- d, -- difference
- b, -- borrow
- oNOT1,
- oNOT2,
- oAND1,
- oAND2,
- oOR,
- Set = function(self, a, b)
- self.oNOT1:Set(a)
- self.oNOT2:Set(b)
- self.oAND1:Set(b)
- self.oAND2:Set(nil, a)
- self.oOR:Set(self.oAND1.q, self.oAND2.q)
- self.b = Gate:Bool2Int(self.oAND1.q)
- self.d = Gate:Bool2Int(self.oOR.q)
- end,
- New = function(self, obj, name)
- obj = obj or {}
- self.oNOT1 = Gate.NOT:New(nil, 'Not1-Halfsubtractor', true)
- self.oNOT2 = Gate.NOT:New(nil, 'Not2-Halfsubtractor', true)
- self.oAND1 = Gate.AND:New(nil, 'And1-Halfsubtractor')
- self.oAND2 = Gate.AND:New(nil, 'And2-Halfsubtractor')
- self.oOR = Gate.OR:New(nil, 'Or-Halfsubtractor')
- Gate:Wire(self.oNOT1, 'q', self.oAND1, 'b')
- Gate:Wire(self.oNOT2, 'q', self.oAND2, 'a')
- Gate:Wire(self.oAND1, 'q', self.oOR, 'b')
- Gate:Wire(self.oAND2, 'q', self.oOR, 'a')
- setmetatable(obj, self)
- self.__index = self
- if name ~= nil then obj.name = name end
- return obj
- end
- },
- FULLSUBTRACTOR = {
- class = 'FULLSUBTRACTOR',
- name,
- d, -- difference
- b, -- borrow
- oSPLITa,
- oSPLITb1,
- oSPLITb2,
- oSPLITc1,
- oSPLITc2,
- oSPLIT_NOTa,
- oNOTa,
- oNOTb,
- oNOTc,
- oAND1b,
- oAND2b,
- oAND3b,
- o3AND1d, -- AND_TRIPLE
- oAND2d,
- oAND3d,
- o3ORb, -- OR_TRIPLE
- o3ORd, -- OR_TRIPLE
- Set = function(self, a, b, c_in)
- self.oSPLITa:Set(a)
- self.oSPLITb1:Set(b)
- self.oSPLITc1:Set(c_in)
- self.b = Gate:Bool2Int(self.o3ORb.q)
- self.d = Gate:Bool2Int(self.o3ORd.q)
- end,
- New = function(self, obj, name)
- obj = obj or {}
- self.oSPLITa = Gate.SPLIT:New(nil, 'SplitA-Fullsubtractor', true)
- self.oSPLITb1 = Gate.SPLIT:New(nil, 'SplitB1-Fullsubtractor', true)
- self.oSPLITb2 = Gate.SPLIT:New(nil, 'SplitB2-Fullsubtractor', true)
- self.oSPLITc1 = Gate.SPLIT:New(nil, 'SplitC1-Fullsubtractor', true)
- self.oSPLITc2 = Gate.SPLIT:New(nil, 'SplitC2-Fullsubtractor', true)
- self.oSPLIT_NOTa = Gate.SPLIT:New(nil, 'Split-NotA-Fullsubtractor', true)
- self.oSPLITa.b_is_out = true
- self.oSPLITa.c_is_out = true
- self.oSPLITb1.b_is_out = true
- self.oSPLITb1.c_is_out = true
- self.oSPLITb2.b_is_out = true
- self.oSPLITc1.b_is_out = true
- self.oSPLITc1.c_is_out = true
- self.oSPLITc2.b_is_out = true
- self.oSPLIT_NOTa.b_is_out = true
- self.oSPLIT_NOTa.c_is_out = true
- self.oNOTa = Gate.NOT:New(nil, 'NotA-Fullsubtractor', true)
- self.oNOTb = Gate.NOT:New(nil, 'NotB-Fullsubtractor', true)
- self.oNOTc = Gate.NOT:New(nil, 'NotC-Fullsubtractor', true)
- self.oAND1b = Gate.AND:New(nil, 'And1-B-Fullsubtractor', true)
- self.oAND2b = Gate.AND:New(nil, 'And2-B-Fullsubtractor', true)
- self.oAND3b = Gate.AND:New(nil, 'And3-B-Fullsubtractor', true)
- self.o3AND1d = Gate.AND_TRIPLE:New(nil, '3And1-D-Fullsubtractor', true)
- self.oAND2d = Gate.AND:New(nil, 'And2-D-Fullsubtractor', true)
- self.oAND3d = Gate.AND:New(nil, 'And3-D-Fullsubtractor', true)
- self.o3ORb = Gate.OR_TRIPLE:New(nil, '3Or-B-Fullsubtractor')
- self.o3ORd = Gate.OR_TRIPLE:New(nil, '3Or-D-Fullsubtractor')
- Gate:Wire(self.oSPLITa, 'b', self.oNOTa, 'a')
- Gate:Wire(self.oSPLITa, 'c', self.oAND3d, 'a')
- Gate:Wire(self.oSPLITa, 'q', self.oAND2d, 'b')
- Gate:Wire(self.oSPLITb1, 'b', self.oNOTb, 'a')
- Gate:Wire(self.oSPLITb1, 'c', self.oAND3d, 'b')
- Gate:Wire(self.oSPLITb1, 'q', self.oSPLITb2, 'a')
- Gate:Wire(self.oSPLITb2, 'b', self.oAND1b, 'a')
- Gate:Wire(self.oSPLITb2, 'q', self.oAND3b, 'b')
- Gate:Wire(self.oSPLITc1, 'b', self.oNOTc, 'a')
- Gate:Wire(self.oSPLITc1, 'c', self.oSPLITc2, 'a')
- Gate:Wire(self.oSPLITc1, 'q', self.o3AND1d, 'c')
- Gate:Wire(self.oSPLITc2, 'b', self.oAND3b, 'a')
- Gate:Wire(self.oSPLITc2, 'q', self.oAND2b, 'a')
- Gate:Wire(self.oNOTa, 'q', self.oSPLIT_NOTa, 'a')
- Gate:Wire(self.oSPLIT_NOTa, 'b', self.oAND2b, 'b')
- Gate:Wire(self.oSPLIT_NOTa, 'c', self.o3AND1d, 'a')
- Gate:Wire(self.oSPLIT_NOTa, 'q', self.oAND1b, 'b')
- Gate:Wire(self.oNOTb, 'q', self.o3AND1d, 'b')
- Gate:Wire(self.oNOTc, 'q', self.oAND2d, 'a')
- Gate:Wire(self.oAND1b, 'q', self.o3ORb, 'a')
- Gate:Wire(self.oAND2b, 'q', self.o3ORb, 'b')
- Gate:Wire(self.oAND3b, 'q', self.o3ORb, 'c')
- Gate:Wire(self.o3AND1d, 'q', self.o3ORd, 'a')
- Gate:Wire(self.oAND2d, 'q', self.o3ORd, 'b')
- Gate:Wire(self.oAND3d, 'q', self.o3ORd, 'c')
- setmetatable(obj, self)
- self.__index = self
- if name ~= nil then obj.name = name end
- return obj
- end
- },
- ADDERSUBTR4BIT = {
- class = 'ADDERSUBTR4BIT',
- name,
- v, -- detecting overflow
- c,
- s1,
- s2,
- s3,
- s4,
- oFA1,
- oFA2,
- oFA3,
- oFA4,
- oXOR1,
- oXOR2,
- oXOR3,
- oXOR4,
- oXORv,
- Set = function(self, x1, x2, x3, x4, y1, y2, y3, y4, m_flag) -- m_flag: 0=adder, 1=subtractor
- if m_flag == nil then m_flag = 0 end -- default: adder
- self.oXOR1:Set(m_flag, y1)
- self.oXOR2:Set(m_flag, y2)
- self.oXOR3:Set(m_flag, y3)
- self.oXOR4:Set(m_flag, y4)
- self.oFA1:Set(x1, self.oXOR1.q, m_flag)
- self.oFA2:Set(x2, self.oXOR2.q, self.oFA1.c)
- self.oFA3:Set(x3, self.oXOR3.q, self.oFA2.c)
- self.oFA4:Set(x4, self.oXOR4.q, self.oFA3.c)
- self.oXORv:Set(self.oFA3.c, self.oFA4.c)
- self.s1 = Gate:Bool2Int(self.oFA1.s)
- self.s2 = Gate:Bool2Int(self.oFA2.s)
- self.s3 = Gate:Bool2Int(self.oFA3.s)
- self.s4 = Gate:Bool2Int(self.oFA4.s)
- self.c = Gate:Bool2Int(self.oFA4.c)
- self.v = Gate:Bool2Int(self.oXORv.q)
- end,
- New = function(self, obj, name)
- obj = obj or {}
- self.oFA1 = Gate.FULLADDER:New(nil, 'FA1-Adder-Subtractor')
- self.oFA2 = Gate.FULLADDER:New(nil, 'FA2-Adder-Subtractor')
- self.oFA3 = Gate.FULLADDER:New(nil, 'FA3-Adder-Subtractor')
- self.oFA4 = Gate.FULLADDER:New(nil, 'FA4-Adder-Subtractor')
- self.oXOR1 = Gate.XOR:New(nil, 'XOR1-Adder-Subtractor', false)
- self.oXOR2 = Gate.XOR:New(nil, 'XOR2-Adder-Subtractor', false)
- self.oXOR3 = Gate.XOR:New(nil, 'XOR3-Adder-Subtractor', false)
- self.oXOR4 = Gate.XOR:New(nil, 'XOR4-Adder-Subtractor', false)
- self.oXORv = Gate.XOR:New(nil, 'XORv-Adder-Subtractor', false)
- setmetatable(obj, self)
- self.__index = self
- if name ~= nil then obj.name = name end
- return obj
- end
- }
- }
- return Gate
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement