mirror of
https://github.com/ehw-fit/ariths-gen.git
synced 2025-04-04 06:11:41 +01:00
Fixed hierarchical BLIF generation for popcount_compare.
This commit is contained in:
parent
f4b816fc09
commit
ce36ebf77b
@ -162,7 +162,7 @@ class GeneralCircuit():
|
||||
def get_circuit_gates(self, verilog_output: bool = False):
|
||||
"""Gets a list of all the logic gates in circuit that should be generated.
|
||||
|
||||
Args:
|
||||
Args:
|
||||
verilog_output (bool): Specifies whether the call has been invoked by a verilog output generation method.
|
||||
Returns:
|
||||
list: List of composite logic gates.
|
||||
@ -170,13 +170,13 @@ class GeneralCircuit():
|
||||
gates = []
|
||||
for c in self.components:
|
||||
if isinstance(c, TwoInputLogicGate):
|
||||
if c.disable_generation is False and (verilog_output is False or ((hasattr(self, "use_verilog_instance") and self.use_verilog_instance is False) or hasattr(self, "use_verilog_instance") is False)):
|
||||
if (c.disable_generation is False) and (verilog_output is False or getattr(c, "use_verilog_instance", False) is False):
|
||||
gates.append(c)
|
||||
else:
|
||||
# Check whether it is necessary to use gates for the Verilog component
|
||||
# description (ArithsGen internally defined comp) or not (technology specific instance)
|
||||
if verilog_output is False or ((hasattr(c, "use_verilog_instance") and c.use_verilog_instance is False) or hasattr(c, "use_verilog_instance") is False):
|
||||
gates.extend((c.get_circuit_gates(verilog_output)))
|
||||
gates.extend(c.get_circuit_gates(verilog_output))
|
||||
return gates
|
||||
|
||||
def get_one_bit_components(self):
|
||||
@ -214,7 +214,7 @@ class GeneralCircuit():
|
||||
return multi_bit_comps
|
||||
|
||||
@staticmethod
|
||||
def get_unique_types(components: list, name="", multi_bit: bool = False):
|
||||
def get_unique_types(components: list, multi_bit: bool = False):
|
||||
"""Retrieves just the unique representatives of class types present inside the provided components list.
|
||||
|
||||
Args:
|
||||
@ -242,8 +242,8 @@ class GeneralCircuit():
|
||||
gate_comps = self.get_unique_types(components=self.get_circuit_gates(verilog_output))
|
||||
one_bit_comps = self.get_unique_types(
|
||||
components=self.get_one_bit_components())
|
||||
multi_bit_comps = self.get_unique_types(name=self.prefix,
|
||||
components=self.get_multi_bit_components(), multi_bit=True)
|
||||
multi_bit_comps = self.get_unique_types(components=self.get_multi_bit_components(),
|
||||
multi_bit=True)
|
||||
|
||||
all_components = gate_comps + one_bit_comps + multi_bit_comps
|
||||
return all_components
|
||||
@ -711,6 +711,11 @@ class GeneralCircuit():
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# HIERARCHICAL BLIF #
|
||||
def get_invocations_blif_hier(self):
|
||||
"""Generates hierarchical Blif code with invocations of subcomponents function blocks.
|
||||
@ -732,11 +737,17 @@ class GeneralCircuit():
|
||||
init_signature = inspect.signature(self.__class__.__init__)
|
||||
default_circuit_name = init_signature.parameters['name'].default
|
||||
circuit_type = default_circuit_name + "x".join(str(getattr(self, chr(97+i)).N) for i, _ in enumerate(self.inputs))
|
||||
return "".join([w.get_wire_assign_blif(output=True) for w in self.inputs]) + \
|
||||
f".subckt {circuit_type}" + \
|
||||
"".join([f" {chr(97+i)}[{b.bus.index(w)}]={b.prefix}[{b.bus.index(w)}]" for i, b in enumerate(self.inputs) for w in b.bus]) + \
|
||||
"".join([f" {circuit_type}_out[{self.out.bus.index(o)}]={o.name}" for o in self.out.bus]) + "\n"
|
||||
|
||||
if self.out.N > 1:
|
||||
return "".join([w.get_wire_assign_blif(output=True) for w in self.inputs]) + \
|
||||
f".subckt {circuit_type}" + \
|
||||
"".join([f" {chr(97+i)}[{b.bus.index(w)}]={b.prefix}[{b.bus.index(w)}]" if b.N > 1 else f" {chr(97+i)}={b.prefix}" for i, b in enumerate(self.inputs) for w in b.bus]) + \
|
||||
"".join([f" {circuit_type}_out[{self.out.bus.index(o)}]={o.name}" for o in self.out.bus if not o.is_const()]) + "\n"
|
||||
else:
|
||||
return "".join([w.get_wire_assign_blif(output=True) for w in self.inputs]) + \
|
||||
f".subckt {circuit_type}" + \
|
||||
"".join([f" {chr(97+i)}[{b.bus.index(w)}]={b.prefix}[{b.bus.index(w)}]" if b.N > 1 else f" {chr(97+i)}={b.prefix}" for i, b in enumerate(self.inputs) for w in b.bus]) + \
|
||||
"".join([f" {circuit_type}_out={o.name}" for o in self.out.bus if not o.is_const()]) + "\n"
|
||||
|
||||
# TODO delete
|
||||
return f"{self.a.get_wire_assign_blif(output=True)}" + \
|
||||
f"{self.b.get_wire_assign_blif(output=True)}" + \
|
||||
|
@ -344,7 +344,7 @@ class TwoInputLogicGate():
|
||||
Returns:
|
||||
str: Blif logic gate's wires declaration.
|
||||
"""
|
||||
return f".inputs {self.a.get_declaration_blif()} {self.b.get_declaration_blif()}\n" + \
|
||||
return f".inputs {self.a.get_wire_declaration_blif()}{self.b.get_wire_declaration_blif()}\n" + \
|
||||
f".outputs" + \
|
||||
"".join([f" {self.out.name}\n" if self.disable_generation is False else f" {self.out.name}_out\n" for _ in range(1)]) + \
|
||||
f".names vdd\n1\n" + \
|
||||
@ -687,7 +687,7 @@ class OneInputLogicGate(TwoInputLogicGate):
|
||||
Returns:
|
||||
str: Blif logic gate's wires declaration.
|
||||
"""
|
||||
return f".inputs {self.a.get_declaration_blif()}\n" + \
|
||||
return f".inputs {self.a.get_wire_declaration_blif()}\n" + \
|
||||
f".outputs" + \
|
||||
"".join([f" {self.out.name}\n" if self.disable_generation is False else f" {self.out.name}_out\n" for _ in range(1)]) + \
|
||||
f".names vdd\n1\n" + \
|
||||
|
@ -17,10 +17,11 @@ class FourInputOneBitCircuit(TwoInputOneBitCircuit, GeneralCircuit):
|
||||
b (Wire): Second input wire.
|
||||
c (Wire): Third input wire.
|
||||
d (Wire): Fourth input wire.
|
||||
prefix (str, optional): Prefix name of circuit. Defaults to "four_input_one_bit_circuit".
|
||||
prefix (str, optional): Prefix name of circuit. Defaults to "".
|
||||
name (str, optional): Name of circuit. Defaults to "four_input_one_bit_circuit".
|
||||
"""
|
||||
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="c"), d: Wire = Wire(name="d"), prefix: str = "four_input_one_bit_circuit"):
|
||||
GeneralCircuit.__init__(self, inputs=[a, b, c, d], prefix=prefix, name="", out_N=1)
|
||||
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="c"), d: Wire = Wire(name="d"), prefix: str = "", name: str = "four_input_one_bit_circuit"):
|
||||
GeneralCircuit.__init__(self, inputs=[a, b, c, d], prefix=prefix, name=name, out_N=1)
|
||||
self.c_data_type = "uint8_t"
|
||||
|
||||
""" C CODE GENERATION """
|
||||
@ -36,7 +37,7 @@ class FourInputOneBitCircuit(TwoInputOneBitCircuit, GeneralCircuit):
|
||||
|
||||
# HIERARCHICAL C #
|
||||
# Subcomponent generation (four inputs)
|
||||
def get_out_invocation_c(self, *args, **kwargs):
|
||||
def get_out_invocation_c(self):
|
||||
"""Generates hierarchical C code invocation of corresponding four input one bit circuit's generated function block.
|
||||
|
||||
Assigns output values from invocation of the corresponding function block into inner wires present inside the upper
|
||||
@ -117,7 +118,7 @@ class FourInputOneBitCircuit(TwoInputOneBitCircuit, GeneralCircuit):
|
||||
f"" for c in self.components])
|
||||
|
||||
# Subcomponent generation
|
||||
def get_out_invocation_v(self, *args, **kwargs):
|
||||
def get_out_invocation_v(self):
|
||||
"""Generates hierarchical Verilog code invocation of corresponding four input one bit circuit's generated function block.
|
||||
|
||||
Assigns output values from invocation of the corresponding function block into inner wires present inside the upper
|
||||
@ -143,7 +144,7 @@ class FourInputOneBitCircuit(TwoInputOneBitCircuit, GeneralCircuit):
|
||||
"""
|
||||
unique_out_wires = []
|
||||
[unique_out_wires.append(o.name+"_outid"+str(self.out.bus.index(o))) if o.is_const() or o.name in [self.a.name, self.b.name, self.c.name, self.d.name] else unique_out_wires.append(o.name) for o in self.out.bus]
|
||||
return f".inputs {self.a.get_declaration_blif()} {self.b.get_declaration_blif()} {self.c.get_declaration_blif()} {self.d.get_declaration_blif()}\n" + \
|
||||
return f".inputs {self.a.get_wire_declaration_blif()}{self.b.get_wire_declaration_blif()}{self.c.get_wire_declaration_blif()}{self.d.get_wire_declaration_blif()}\n" + \
|
||||
f".outputs" + \
|
||||
"".join([f" {o}" for o in unique_out_wires]) + "\n" + \
|
||||
f".names vdd\n1\n" + \
|
||||
@ -187,7 +188,7 @@ class FourInputOneBitCircuit(TwoInputOneBitCircuit, GeneralCircuit):
|
||||
c.out.get_assign_blif(prefix=f"{unique_out_wires.pop(unique_out_wires.index(c.out.name+'_outid'+str(c.outid)))}", output=True) if f"{c.out.name+'_outid'+str(c.outid)}" in unique_out_wires else
|
||||
"" for c in self.components])
|
||||
|
||||
def get_invocation_blif_hier(self, *args, **kwargs):
|
||||
def get_invocation_blif_hier(self):
|
||||
"""Generates hierarchical Blif code invocation of corresponding four input one bit circuit's generated function block.
|
||||
|
||||
Returns:
|
||||
|
@ -16,10 +16,11 @@ class ThreeInputOneBitCircuit(TwoInputOneBitCircuit, GeneralCircuit):
|
||||
a (Wire): First input wire.
|
||||
b (Wire): Second input wire.
|
||||
c (Wire): Third input wire.
|
||||
prefix (str, optional): Prefix name of circuit. Defaults to "three_input_one_bit_circuit".
|
||||
prefix (str, optional): Prefix name of circuit. Defaults to "".
|
||||
name (str, optional): Name of circuit. Defaults to "three_input_one_bit_circuit".
|
||||
"""
|
||||
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="cin"), prefix: str = "three_input_one_bit_circuit"):
|
||||
GeneralCircuit.__init__(self, inputs=[a, b, c], prefix=prefix, name="", out_N=1)
|
||||
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="cin"), prefix: str = "", name: str = "three_input_one_bit_circuit"):
|
||||
GeneralCircuit.__init__(self, inputs=[a, b, c], prefix=prefix, name=name, out_N=1)
|
||||
self.c_data_type = "uint8_t"
|
||||
|
||||
""" C CODE GENERATION """
|
||||
@ -35,7 +36,7 @@ class ThreeInputOneBitCircuit(TwoInputOneBitCircuit, GeneralCircuit):
|
||||
|
||||
# HIERARCHICAL C #
|
||||
# Subcomponent generation (three inputs)
|
||||
def get_out_invocation_c(self, *args, **kwargs):
|
||||
def get_out_invocation_c(self):
|
||||
"""Generates hierarchical C code invocation of corresponding three input one bit circuit's generated function block.
|
||||
|
||||
Assigns output values from invocation of the corresponding function block into inner wires present inside the upper
|
||||
@ -116,7 +117,7 @@ class ThreeInputOneBitCircuit(TwoInputOneBitCircuit, GeneralCircuit):
|
||||
f"" for c in self.components])
|
||||
|
||||
# Subcomponent generation
|
||||
def get_out_invocation_v(self, *args, **kwargs):
|
||||
def get_out_invocation_v(self):
|
||||
"""Generates hierarchical Verilog code invocation of corresponding three input one bit circuit's generated function block.
|
||||
|
||||
Assigns output values from invocation of the corresponding function block into inner wires present inside the upper
|
||||
@ -142,7 +143,7 @@ class ThreeInputOneBitCircuit(TwoInputOneBitCircuit, GeneralCircuit):
|
||||
"""
|
||||
unique_out_wires = []
|
||||
[unique_out_wires.append(o.name+"_outid"+str(self.out.bus.index(o))) if o.is_const() or o.name in [self.a.name, self.b.name, self.c.name] else unique_out_wires.append(o.name) for o in self.out.bus]
|
||||
return f".inputs {self.a.get_declaration_blif()} {self.b.get_declaration_blif()} {self.c.get_declaration_blif()}\n" + \
|
||||
return f".inputs {self.a.get_wire_declaration_blif()}{self.b.get_wire_declaration_blif()}{self.c.get_wire_declaration_blif()}\n" + \
|
||||
f".outputs" + \
|
||||
"".join([f" {o}" for o in unique_out_wires]) + "\n" + \
|
||||
f".names vdd\n1\n" + \
|
||||
@ -186,7 +187,7 @@ class ThreeInputOneBitCircuit(TwoInputOneBitCircuit, GeneralCircuit):
|
||||
c.out.get_assign_blif(prefix=f"{unique_out_wires.pop(unique_out_wires.index(c.out.name+'_outid'+str(c.outid)))}", output=True) if f"{c.out.name+'_outid'+str(c.outid)}" in unique_out_wires else
|
||||
"" for c in self.components])
|
||||
|
||||
def get_invocation_blif_hier(self, *args, **kwargs):
|
||||
def get_invocation_blif_hier(self):
|
||||
"""Generates hierarchical Blif code invocation of corresponding three input one bit circuit's generated function block.
|
||||
|
||||
Returns:
|
||||
|
@ -13,10 +13,11 @@ class TwoInputOneBitCircuit(GeneralCircuit):
|
||||
Args:
|
||||
a (Wire): First input wire.
|
||||
b (Wire): Second input wire.
|
||||
prefix (str, optional): Prefix name of circuit. Defaults to "two_input_one_bit_circuit".
|
||||
prefix (str, optional): Prefix name of circuit. Defaults to "".
|
||||
name (str, optional): Name of circuit. Defaults to "two_input_one_bit_circuit".
|
||||
"""
|
||||
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), prefix: str = "two_input_one_bit_circuit"):
|
||||
super().__init__(inputs=[a, b], prefix=prefix, name="", out_N=1, one_bit_circuit=True)
|
||||
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), prefix: str = "", name: str = "two_input_one_bit_circuit"):
|
||||
super().__init__(inputs=[a, b], prefix=prefix, name=name, out_N=1, one_bit_circuit=True)
|
||||
self.c_data_type = "uint8_t"
|
||||
|
||||
""" C CODE GENERATION """
|
||||
@ -50,7 +51,7 @@ class TwoInputOneBitCircuit(GeneralCircuit):
|
||||
adder_block = self.__class__()
|
||||
return f"{adder_block.get_circuit_c()}\n\n"
|
||||
|
||||
def get_out_invocation_c(self, *args, **kwargs):
|
||||
def get_out_invocation_c(self):
|
||||
"""Generates hierarchical C code invocation of corresponding two input one bit circuit's generated function block.
|
||||
|
||||
Assigns output values from invocation of the corresponding function block into inner wires present inside the upper
|
||||
@ -165,7 +166,7 @@ class TwoInputOneBitCircuit(GeneralCircuit):
|
||||
adder_block = self.__class__()
|
||||
return f"{adder_block.get_circuit_v()}\n\n"
|
||||
|
||||
def get_out_invocation_v(self, *args, **kwargs):
|
||||
def get_out_invocation_v(self):
|
||||
"""Generates hierarchical Verilog code invocation of corresponding two input one bit circuit's generated function block.
|
||||
|
||||
Assigns output values from invocation of the corresponding function block into inner wires present inside the upper
|
||||
@ -250,7 +251,7 @@ class TwoInputOneBitCircuit(GeneralCircuit):
|
||||
"""
|
||||
unique_out_wires = []
|
||||
[unique_out_wires.append(o.name+"_outid"+str(self.out.bus.index(o))) if o.is_const() or o.name in [self.a.name, self.b.name] else unique_out_wires.append(o.name) for o in self.out.bus]
|
||||
return f".inputs {self.a.get_declaration_blif()} {self.b.get_declaration_blif()}\n" + \
|
||||
return f".inputs {self.a.get_wire_declaration_blif()}{self.b.get_wire_declaration_blif()}\n" + \
|
||||
f".outputs" + \
|
||||
"".join([f" {o}" for o in unique_out_wires]) + "\n" + \
|
||||
f".names vdd\n1\n" + \
|
||||
@ -326,7 +327,7 @@ class TwoInputOneBitCircuit(GeneralCircuit):
|
||||
c.out.get_assign_blif(prefix=f"{unique_out_wires.pop(unique_out_wires.index(c.out.name+'_outid'+str(c.outid)))}", output=True) if f"{c.out.name+'_outid'+str(c.outid)}" in unique_out_wires else
|
||||
"" for c in self.components])
|
||||
|
||||
def get_invocation_blif_hier(self, *args, **kwargs):
|
||||
def get_invocation_blif_hier(self):
|
||||
"""Generates hierarchical Blif code invocation of corresponding two input one bit circuit's generated function block.
|
||||
|
||||
Returns:
|
||||
|
@ -24,10 +24,11 @@ class BlackCell(FourInputOneBitCircuit):
|
||||
b (Wire, optional): Second input wire, represents propagate signal from the current stage. Defaults to Wire(name="p1").
|
||||
c (Wire, optional): Third input wire, represents generate signal from a preceding stage. Defaults to Wire(name="g0").
|
||||
d (Wire, optional): Fourth input wire, represents propagate signal from a preceding stage. Defaults to Wire(name="p0").
|
||||
prefix (str, optional): Prefix name of grey cell. Defaults to "gc".
|
||||
prefix (str, optional): Prefix name of grey cell. Defaults to "".
|
||||
name (str, optional): Name of grey cell. Defaults to "gc".
|
||||
"""
|
||||
def __init__(self, a: Wire = Wire(name="g1"), b: Wire = Wire(name="p1"), c: Wire = Wire(name="g0"), d: Wire = Wire(name="p0"), prefix: str = "bc"):
|
||||
super().__init__(a, b, c, d, prefix)
|
||||
def __init__(self, a: Wire = Wire(name="g1"), b: Wire = Wire(name="p1"), c: Wire = Wire(name="g0"), d: Wire = Wire(name="p0"), prefix: str = "", name: str = "bc"):
|
||||
super().__init__(a, b, c, d, prefix=prefix, name=name)
|
||||
# 2 wires for component's bus output (generate, propagate)
|
||||
self.out = Bus(self.prefix+"_out", 2)
|
||||
|
||||
|
@ -21,12 +21,13 @@ class FullAdder(ThreeInputOneBitCircuit):
|
||||
a (Wire, optional): First input wire. Defaults to Wire(name="a").
|
||||
b (Wire, optional): Second input wire. Defaults to Wire(name="b").
|
||||
c (Wire, optional): Carry input wire. Defaults to Wire(name="cin").
|
||||
prefix (str, optional): Prefix name of full adder. Defaults to "fa".
|
||||
prefix (str, optional): Prefix name of full adder. Defaults to "".
|
||||
name (str, optional): Name of full adder. Defaults to "fa".
|
||||
"""
|
||||
use_verilog_instance = False
|
||||
|
||||
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="cin"), prefix: str = "fa"):
|
||||
super().__init__(a, b, c, prefix)
|
||||
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="cin"), prefix: str = "", name: str = "fa"):
|
||||
super().__init__(a, b, c, prefix=prefix, name=name)
|
||||
# 2 wires for component's bus output (sum, cout)
|
||||
self.out = Bus(self.prefix+"_out", 2)
|
||||
|
||||
@ -129,10 +130,11 @@ class FullAdderP(FullAdder, ThreeInputOneBitCircuit):
|
||||
a (Wire, optional): First input wire. Defaults to Wire(name="a").
|
||||
b (Wire, optional): Second input wire. Defaults to Wire(name="b").
|
||||
c (Wire, optional): Carry input wire. Defaults to Wire(name="cin").
|
||||
prefix (str, optional): Prefix name of full adder with p logic. Defaults to "fa_p".
|
||||
prefix (str, optional): Prefix name of full adder with p logic. Defaults to "".
|
||||
name (str, optional): Name of full adder with p logic. Defaults to "fa_p".
|
||||
"""
|
||||
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="cin"), prefix: str = "fa_p"):
|
||||
super().__init__(a, b, c, prefix)
|
||||
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="cin"), prefix: str = "", name: str = "fa_p"):
|
||||
super().__init__(a, b, c, prefix=prefix, name=name)
|
||||
# 3 wires for component's bus output (sum, cout, propagate)
|
||||
self.out.bus_extend(3)
|
||||
self.out.connect(2, self.get_previous_component(5).out)
|
||||
@ -164,10 +166,11 @@ class FullAdderPG(FullAdder, ThreeInputOneBitCircuit):
|
||||
a (Wire, optional): First input wire. Defaults to Wire(name="a").
|
||||
b (Wire, optional): Second input wire. Defaults to Wire(name="b").
|
||||
c (Wire, optional): Carry input wire. Defaults to Wire(name="cin").
|
||||
prefix (str, optional): Prefix name of full adder with pg logic. Defaults to "fa_pg".
|
||||
prefix (str, optional): Prefix name of full adder with pg logic. Defaults to "".
|
||||
name (str, optional): Name of full adder with pg logic. Defaults to "fa_pg".
|
||||
"""
|
||||
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="cin"), prefix: str = "fa_pg"):
|
||||
super().__init__(a, b, c, prefix)
|
||||
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="cin"), prefix: str = "", name: str = "fa_pg"):
|
||||
super().__init__(a, b, c, prefix=prefix, name=name)
|
||||
# 4 wires for component's bus output (sum, cout, propagate, generate)
|
||||
self.out.bus_extend(4)
|
||||
self.out.connect(2, self.get_previous_component(5).out)
|
||||
@ -207,10 +210,11 @@ class PGSumLogic(ThreeInputOneBitCircuit):
|
||||
a (Wire, optional): First input wire. Defaults to Wire(name="a").
|
||||
b (Wire, optional): Second input wire. Defaults to Wire(name="b").
|
||||
c (Wire, optional): Carry input wire. Defaults to Wire(name="cin").
|
||||
prefix (str, optional): Prefix name of pg sum logic. Defaults to "pg_sum".
|
||||
prefix (str, optional): Prefix name of pg sum logic. Defaults to "".
|
||||
name (str, optional): Name of pg sum logic. Defaults to "pg_sum".
|
||||
"""
|
||||
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="cin"), prefix: str = "pg_sum"):
|
||||
super().__init__(a, b, c, prefix)
|
||||
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="cin"), prefix: str = "", name: str = "pg_sum"):
|
||||
super().__init__(a, b, c, prefix=prefix, name=name)
|
||||
# 3 wires for component's bus output (sum, propagate, generate)
|
||||
self.out = Bus(self.prefix+"_out", 3)
|
||||
|
||||
@ -271,12 +275,13 @@ class TwoOneMultiplexer(ThreeInputOneBitCircuit):
|
||||
a (Wire, optional): First input wire. Defaults to Wire(name="d0").
|
||||
b (Wire, optional): Second input wire. Defaults to Wire(name="d1").
|
||||
c (Wire, optional): Select signal. Defaults to Wire(name="sel").
|
||||
prefix (str, optional): Prefix name of two to one multiplexer. Defaults to "mux2to1".
|
||||
prefix (str, optional): Prefix name of two to one multiplexer. Defaults to "".
|
||||
name (str, optional): Name of two to one multiplexer. Defaults to "mux2to1".
|
||||
"""
|
||||
use_verilog_instance = False
|
||||
|
||||
def __init__(self, a: Wire = Wire(name="d0"), b: Wire = Wire(name="d1"), c: Wire = Wire(name="sel"), prefix: str = "mux2to1"):
|
||||
super().__init__(a, b, c, prefix)
|
||||
def __init__(self, a: Wire = Wire(name="d0"), b: Wire = Wire(name="d1"), c: Wire = Wire(name="sel"), prefix: str = "", name: str = "mux2to1"):
|
||||
super().__init__(a, b, c, prefix=prefix, name=name)
|
||||
# Represents select signal (self.c naming for proper unified generation)
|
||||
self.c = c
|
||||
# 1 wire for component's output bus
|
||||
@ -371,10 +376,11 @@ class FullSubtractor(ThreeInputOneBitCircuit):
|
||||
a (Wire, optional): First input wire. Defaults to Wire(name="a").
|
||||
b (Wire, optional): Second input wire. Defaults to Wire(name="b").
|
||||
c (Wire, optional): Input borrow wire. Defaults to Wire(name="bin").
|
||||
prefix (str, optional): Prefix name of full subtractor. Defaults to "fs".
|
||||
prefix (str, optional): Prefix name of full subtractor. Defaults to "".
|
||||
name (str, optional): Name of full subtractor. Defaults to "fs".
|
||||
"""
|
||||
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="bin"), prefix: str = "fs"):
|
||||
super().__init__(a, b, c, prefix)
|
||||
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), c: Wire = Wire(name="bin"), prefix: str = "", name: str = "fs"):
|
||||
super().__init__(a, b, c, prefix=prefix, name=name)
|
||||
# 2 wires for component's bus output (difference, bout)
|
||||
self.out = Bus(self.prefix+"_out", 2)
|
||||
|
||||
@ -438,10 +444,11 @@ class GreyCell(ThreeInputOneBitCircuit):
|
||||
a (Wire, optional): First input wire, represents generate signal from the current stage. Defaults to Wire(name="g1").
|
||||
b (Wire, optional): Second input wire, represents propagate signal from the current stage. Defaults to Wire(name="p1").
|
||||
c (Wire, optional): Third input wire, represents generate signal from a preceding stage. Defaults to Wire(name="g0").
|
||||
prefix (str, optional): Prefix name of grey cell. Defaults to "gc".
|
||||
prefix (str, optional): Prefix name of grey cell. Defaults to "".
|
||||
name (str, optional): Name of grey cell. Defaults to "gc".
|
||||
"""
|
||||
def __init__(self, a: Wire = Wire(name="g1"), b: Wire = Wire(name="p1"), c: Wire = Wire(name="g0"), prefix: str = "gc"):
|
||||
super().__init__(a, b, c, prefix)
|
||||
def __init__(self, a: Wire = Wire(name="g1"), b: Wire = Wire(name="p1"), c: Wire = Wire(name="g0"), prefix: str = "", name: str = "gc"):
|
||||
super().__init__(a, b, c, prefix=prefix, name=name)
|
||||
# 1 wire for component's bus output (output generate)
|
||||
self.out = Bus(self.prefix+"_out", 1)
|
||||
|
||||
|
@ -19,12 +19,13 @@ class HalfAdder(TwoInputOneBitCircuit):
|
||||
Args:
|
||||
a (Wire, optional): First input wire. Defaults to Wire(name="a").
|
||||
b (Wire, optional): Second input wire. Defaults to Wire(name="b").
|
||||
prefix (str, optional): Prefix name of half adder. Defaults to "ha".
|
||||
prefix (str, optional): Prefix name of half adder. Defaults to "".
|
||||
name (str, optional): Name of half adder. Defaults to "ha".
|
||||
"""
|
||||
use_verilog_instance = False
|
||||
|
||||
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), prefix: str = "ha"):
|
||||
super().__init__(a, b, prefix)
|
||||
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), prefix: str = "", name: str = "ha"):
|
||||
super().__init__(a, b, prefix=prefix, name=name)
|
||||
# 2 wires for component's bus output (sum, cout)
|
||||
self.out = Bus(self.prefix+"_out", 2)
|
||||
|
||||
@ -114,10 +115,11 @@ class PGLogicBlock(TwoInputOneBitCircuit):
|
||||
Args:
|
||||
a (Wire, optional): First input wire. Defaults to Wire(name="a").
|
||||
b (Wire, optional): Second input wire. Defaults to Wire(name="b").
|
||||
prefix (str, optional): Prefix name of pg logic block. Defaults to "pg_logic".
|
||||
prefix (str, optional): Prefix name of pg logic block. Defaults to "".
|
||||
name (str, optional): Name of pg logic block. Defaults to "pg_logic".
|
||||
"""
|
||||
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), prefix: str = "pg_logic"):
|
||||
super().__init__(a, b, prefix)
|
||||
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), prefix: str = "", name: str = "pg_logic"):
|
||||
super().__init__(a, b, prefix=prefix, name=name)
|
||||
# 3 wires for component's bus output (propagate, generate, sum)
|
||||
self.out = Bus(self.prefix+"_out", 3)
|
||||
|
||||
@ -174,10 +176,11 @@ class HalfSubtractor(TwoInputOneBitCircuit):
|
||||
Args:
|
||||
a (Wire, optional): First input wire. Defaults to Wire(name="a").
|
||||
b (Wire, optional): Second input wire. Defaults to Wire(name="b").
|
||||
prefix (str, optional): Prefix name of half subtractor adder. Defaults to "hs".
|
||||
prefix (str, optional): Prefix name of half subtractor adder. Defaults to "".
|
||||
name (str, optional): Name of half subtractor adder. Defaults to "hs".
|
||||
"""
|
||||
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), prefix: str = "hs"):
|
||||
super().__init__(a, b, prefix)
|
||||
def __init__(self, a: Wire = Wire(name="a"), b: Wire = Wire(name="b"), prefix: str = "", name: str = "hs"):
|
||||
super().__init__(a, b, prefix=prefix, name=name)
|
||||
# 2 wires for component's bus output (difference, bout)
|
||||
self.out = Bus(self.prefix+"_out", 2)
|
||||
|
||||
|
@ -18,7 +18,7 @@ class Bus():
|
||||
if wires_list is None:
|
||||
self.prefix = prefix
|
||||
# Adding wires into current bus's wires list (wire names are concatenated from bus prefix and their index position inside the bus in square brackets)
|
||||
self.bus = [Wire(name=prefix+f"[{i}]", prefix=prefix, index=i, parent_bus=self) for i in range(N)]
|
||||
self.bus = [Wire(name=prefix+f"[{i}]" if N != 1 else prefix, prefix=prefix, index=i, parent_bus=self) for i in range(N)]
|
||||
self.N = N
|
||||
else:
|
||||
self.prefix = prefix
|
||||
@ -251,18 +251,16 @@ class Bus():
|
||||
return f" wire [{self.N-1}:0] {self.prefix};\n"
|
||||
|
||||
""" BLIF CODE GENERATION """
|
||||
def get_wire_declaration_blif(self, array: bool = True):
|
||||
def get_wire_declaration_blif(self):
|
||||
"""Declare each wire from the bus independently in Blif code representation.
|
||||
|
||||
Args:
|
||||
array (bool, optional): Specifies whether to declare wires from bus by their offset e.g. out[0] or by their wire name e.g. out_0. Defaults to True.
|
||||
|
||||
Returns:
|
||||
str: Blif code for declaration of individual bus wires.
|
||||
"""
|
||||
# Ensures correct binding between the bus wire index and the wire itself
|
||||
# It is used for the case when multiple of the same wire (e.g. `ContantWireValue0()`) are present in the bus (its id would otherwise be incorrect when using `self.bus.index(_)`)
|
||||
mapped_positions = [(w_id, self.bus[w_id]) for w_id in range(self.N)]
|
||||
array = True if self.N > 1 else False
|
||||
return "".join([f" {w[1].get_declaration_blif(prefix=self.prefix, offset=w[0], array=array)}" for w in mapped_positions])
|
||||
|
||||
def get_wire_assign_blif(self, output: bool = False):
|
||||
@ -277,7 +275,10 @@ class Bus():
|
||||
# Ensures correct binding between the bus wire index and the wire itself
|
||||
# It is used for the case when multiple of the same wire (e.g. `ContantWireValue0()`) are present in the bus (its id would otherwise be incorrect when using `self.bus.index(_)`)
|
||||
mapped_positions = [(w_id, self.bus[w_id]) for w_id in range(self.N)]
|
||||
return "".join([w[1].get_assign_blif(prefix=self.prefix+f"[{w[0]}]", output=output) for w in mapped_positions])
|
||||
if self.N > 1:
|
||||
return "".join([w[1].get_assign_blif(prefix=self.prefix+f"[{w[0]}]", output=output) for w in mapped_positions])
|
||||
else:
|
||||
return "".join([w[1].get_assign_blif(prefix=self.prefix, output=output) for w in mapped_positions])
|
||||
|
||||
def get_unique_assign_out_wires_blif(self, function_block_out_bus: object):
|
||||
"""Assigns unique output wires to their respective outputs of subcomponent's function block modul in hierarchical Blif subcomponent's invocation.
|
||||
|
@ -205,7 +205,7 @@ class Wire():
|
||||
if array is True:
|
||||
return f"{prefix}[{offset}]"
|
||||
else:
|
||||
return f"{self.name}"
|
||||
return f"{prefix}"
|
||||
|
||||
def get_wire_declaration_blif(self):
|
||||
"""Declaration of a single wire in Blif code.
|
||||
@ -215,7 +215,7 @@ class Wire():
|
||||
Returns:
|
||||
str: Blif code for declaration of a wire.
|
||||
"""
|
||||
return f" {self.prefix}\n"
|
||||
return f"{self.prefix} "
|
||||
|
||||
def get_assign_blif(self, prefix: str, output: bool = False):
|
||||
"""Assignment of wire value to another desired wire in Blif code.
|
||||
|
Loading…
x
Reference in New Issue
Block a user