From ce36ebf77b638b34c9aed856d2569f6e86247b0b Mon Sep 17 00:00:00 2001 From: honzastor Date: Wed, 17 Apr 2024 18:47:41 +0200 Subject: [PATCH] Fixed hierarchical BLIF generation for popcount_compare. --- .../arithmetic_circuits/general_circuit.py | 33 ++++++++----- .../logic_gate_circuits/logic_gate_circuit.py | 4 +- .../four_input_one_bit_circuit.py | 15 +++--- .../three_input_one_bit_circuit.py | 15 +++--- .../two_input_one_bit_circuit.py | 15 +++--- .../four_input_one_bit_components.py | 7 +-- .../three_input_one_bit_components.py | 49 +++++++++++-------- .../two_input_one_bit_components.py | 21 ++++---- ariths_gen/wire_components/buses.py | 13 ++--- ariths_gen/wire_components/wires.py | 4 +- 10 files changed, 101 insertions(+), 75 deletions(-) diff --git a/ariths_gen/core/arithmetic_circuits/general_circuit.py b/ariths_gen/core/arithmetic_circuits/general_circuit.py index 017c725..2061ee5 100644 --- a/ariths_gen/core/arithmetic_circuits/general_circuit.py +++ b/ariths_gen/core/arithmetic_circuits/general_circuit.py @@ -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)}" + \ diff --git a/ariths_gen/core/logic_gate_circuits/logic_gate_circuit.py b/ariths_gen/core/logic_gate_circuits/logic_gate_circuit.py index 38f91d8..76c122d 100644 --- a/ariths_gen/core/logic_gate_circuits/logic_gate_circuit.py +++ b/ariths_gen/core/logic_gate_circuits/logic_gate_circuit.py @@ -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" + \ diff --git a/ariths_gen/core/one_bit_circuits/four_input_one_bit_circuit.py b/ariths_gen/core/one_bit_circuits/four_input_one_bit_circuit.py index b9e8eee..d04ca8b 100644 --- a/ariths_gen/core/one_bit_circuits/four_input_one_bit_circuit.py +++ b/ariths_gen/core/one_bit_circuits/four_input_one_bit_circuit.py @@ -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: diff --git a/ariths_gen/core/one_bit_circuits/three_input_one_bit_circuit.py b/ariths_gen/core/one_bit_circuits/three_input_one_bit_circuit.py index 5586f22..f061b45 100644 --- a/ariths_gen/core/one_bit_circuits/three_input_one_bit_circuit.py +++ b/ariths_gen/core/one_bit_circuits/three_input_one_bit_circuit.py @@ -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: diff --git a/ariths_gen/core/one_bit_circuits/two_input_one_bit_circuit.py b/ariths_gen/core/one_bit_circuits/two_input_one_bit_circuit.py index 1d442a0..9cd8533 100644 --- a/ariths_gen/core/one_bit_circuits/two_input_one_bit_circuit.py +++ b/ariths_gen/core/one_bit_circuits/two_input_one_bit_circuit.py @@ -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: diff --git a/ariths_gen/one_bit_circuits/one_bit_components/four_input_one_bit_components.py b/ariths_gen/one_bit_circuits/one_bit_components/four_input_one_bit_components.py index 840aa9e..cc51287 100644 --- a/ariths_gen/one_bit_circuits/one_bit_components/four_input_one_bit_components.py +++ b/ariths_gen/one_bit_circuits/one_bit_components/four_input_one_bit_components.py @@ -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) diff --git a/ariths_gen/one_bit_circuits/one_bit_components/three_input_one_bit_components.py b/ariths_gen/one_bit_circuits/one_bit_components/three_input_one_bit_components.py index 2207164..a0fd6e4 100644 --- a/ariths_gen/one_bit_circuits/one_bit_components/three_input_one_bit_components.py +++ b/ariths_gen/one_bit_circuits/one_bit_components/three_input_one_bit_components.py @@ -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) diff --git a/ariths_gen/one_bit_circuits/one_bit_components/two_input_one_bit_components.py b/ariths_gen/one_bit_circuits/one_bit_components/two_input_one_bit_components.py index d6bb318..079f3b6 100644 --- a/ariths_gen/one_bit_circuits/one_bit_components/two_input_one_bit_components.py +++ b/ariths_gen/one_bit_circuits/one_bit_components/two_input_one_bit_components.py @@ -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) diff --git a/ariths_gen/wire_components/buses.py b/ariths_gen/wire_components/buses.py index 3189e0c..24afa4b 100644 --- a/ariths_gen/wire_components/buses.py +++ b/ariths_gen/wire_components/buses.py @@ -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. diff --git a/ariths_gen/wire_components/wires.py b/ariths_gen/wire_components/wires.py index 6df760d..b5797a4 100644 --- a/ariths_gen/wire_components/wires.py +++ b/ariths_gen/wire_components/wires.py @@ -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.