dual logic

This commit is contained in:
zvasicek 2025-01-20 13:03:20 +01:00
parent fcb81a2231
commit 2e0d3de856
3 changed files with 45 additions and 15 deletions

View File

@ -890,7 +890,7 @@ class GeneralCircuit():
active_outputs.add(g.b.name)
if hasattr(g, "c"):
active_outputs += (g.c.name)
print("Setting active output", g.out, " for gate ", g)
#print("Setting active output", g.out, " for gate ", g)
inputs = []
@ -907,7 +907,7 @@ class GeneralCircuit():
return inputs, gates
# Generating flat C code representation of circuit
def get_cnf_code_flat(self, file_object):
def get_cnf_code_flat(self, file_object, use_dual_logic=False):
"""Generates flat C code representation of corresponding arithmetic circuit.
Args:
@ -931,22 +931,37 @@ class GeneralCircuit():
#file_object.write(self.get_includes_c())
#file_object.write(self.get_prototype_c())
allcnfs = []
for g in active_gates:
allcnfs += g.get_cnf_clause(self)
if (use_dual_logic):
for g in active_gates:
allcnfs += g.get_cnf_clause_dual(self)
allcnfs.append([self.get_cnfvar(self.out[0])])
const1 = ConstantWireValue1()
if str(const1) in self.cnf_vars:
allcnfs.append([self.get_cnfvar(const1)])
outvar = self.get_cnfvar(self.out[0])
allcnfs.append([-outvar])
const1 = ConstantWireValue1()
if str(const1) in self.cnf_vars:
allcnfs.append([-self.get_cnfvar(const1)])
# header p cnf <vars> <clauses>
file_object.write(f"p cnf {self.cnf_varid-1} {len(allcnfs)}\n")
else:
for g in active_gates:
allcnfs += g.get_cnf_clause(self)
file_object.write("c varmap={}\n".format(json.dumps(self.cnf_var_comments)))
for c in allcnfs:
file_object.write(" ".join(map(str, c + [0])) + "\n")
outvar = self.get_cnfvar(self.out[0])
allcnfs.append([outvar])
const1 = ConstantWireValue1()
if str(const1) in self.cnf_vars:
allcnfs.append([self.get_cnfvar(const1)])
if hasattr(file_object, 'write'):
# header p cnf <vars> <clauses>
file_object.write(f"p cnf {self.cnf_varid-1} {len(allcnfs)}\n")
file_object.write("c varmap={}\n".format(json.dumps(self.cnf_var_comments)))
for c in allcnfs:
file_object.write(" ".join(map(str, c + [0])) + "\n")
return allcnfs, outvar
def get_cnfvar(self, wire : Wire, create = False):
@ -955,7 +970,7 @@ class GeneralCircuit():
assert not create, f"Wire {wireid} already found in CNF vars for {wire}"
elif wire.is_const():
# create FALSE variable
print("Creating new CNF var for constant wires", wire, " id ", wireid)
#print("Creating new CNF var for constant wires", wire, " id ", wireid)
self.cnf_vars[str(ConstantWireValue0())] = -self.cnf_varid
self.cnf_vars[str(ConstantWireValue1())] = self.cnf_varid
self.cnf_var_comments[self.cnf_varid] = True
@ -964,7 +979,7 @@ class GeneralCircuit():
self.cnf_varid += 1
else:
assert create, f"Wire {wireid} not found in CNF vars"
print("Creating new CNF var for wire", wire, " id ", wireid)
#print("Creating new CNF var for wire", wire, " id ", wireid)
self.cnf_var_comments[self.cnf_varid] = wire.name
self.cnf_vars[wireid] = self.cnf_varid
self.cnf_varid += 1

View File

@ -86,6 +86,8 @@ class TwoInputLogicGate():
# Obtaining the caller object to gain access into its `components` list Used for adding NOT gates as a replacement for two input logic gates with constant input (optimalization)
# Also used to obtain caller object's `prefix` name for proper wire names generation of flat/hier representations
self.parent_component = parent_component
# Reference to the dual gate (duality logic)
self.dual_gate = None
""" C CODE GENERATION """
# FLAT C #
@ -500,6 +502,12 @@ class TwoInputLogicGate():
file_object.write(self.get_parameters_cgp())
file_object.write(self.get_gate_triplet_cgp())
def get_cnf_clause_dual(self, parent):
if self.dual_gate is None:
raise NotImplementedError(f"CNF generation is not implemented for this class. {self.__class__.__name__}")
return self.dual_gate.get_cnf_clause(self, parent)
def get_cnf_clause(self, parent):
raise NotImplementedError(f"CNF generation is not implemented for this class. {self.__class__.__name__}")

View File

@ -28,6 +28,7 @@ class AndGate(TwoInputLogicGate):
self.gate_type = "and_gate"
self.cgp_function = 2
self.operator = "&"
self.dual_gate = OrGate
# Logic gate output wire generation based on input values
# If constant input is present, logic gate is not generated and corresponding
@ -107,6 +108,7 @@ class NandGate(TwoInputInvertedLogicGate):
self.gate_type = "nand_gate"
self.cgp_function = 5
self.operator = "&"
self.dual_gate = NOrGate
# Logic gate output wire generation based on input values
# If constant input is present, logic gate is not generated and corresponding
@ -191,6 +193,7 @@ class OrGate(TwoInputLogicGate):
self.gate_type = "or_gate"
self.cgp_function = 3
self.operator = "|"
self.dual_gate = AndGate
# Logic gate output wire generation based on input values
# If constant input is present, logic gate is not generated and corresponding
@ -269,6 +272,7 @@ class NorGate(TwoInputInvertedLogicGate):
self.gate_type = "nor_gate"
self.cgp_function = 6
self.operator = "|"
self.dual_gate = NandGate
# Logic gate output wire generation based on input values
# If constant input is present, logic gate is not generated and corresponding
@ -353,6 +357,7 @@ class XorGate(TwoInputLogicGate):
self.gate_type = "xor_gate"
self.cgp_function = 4
self.operator = "^"
self.dual_gate = XnorGate
# Logic gate output wire generation based on input values
# If constant input is present, logic gate is not generated and corresponding
@ -436,6 +441,7 @@ class XnorGate(TwoInputInvertedLogicGate):
self.gate_type = "xnor_gate"
self.cgp_function = 7
self.operator = "^"
self.dual_gate = XorGate
# Logic gate output wire generation based on input values
# If constant input is present, logic gate is not generated and corresponding
@ -518,6 +524,7 @@ class NotGate(OneInputLogicGate):
self.gate_type = "not_gate"
self.cgp_function = 1
self.operator = "~"
self.dual_gate = NotGate
# Logic gate output wire generation based on input values
# If constant input is present, logic gate is not generated and corresponding