mirror of
https://github.com/ehw-fit/ariths-gen.git
synced 2025-04-10 09:12:11 +01:00
CGP format
This commit is contained in:
parent
87a7f2b8bb
commit
0a487ee699
@ -14,6 +14,7 @@ class ArithmeticCircuit():
|
||||
The __init__ method fills some mandatory attributes concerning arithmetic circuit
|
||||
that are later used for generation into various representations.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.components = []
|
||||
self.circuit_wires = []
|
||||
@ -123,8 +124,10 @@ class ArithmeticCircuit():
|
||||
list: List of unique component types describing the circuit.
|
||||
"""
|
||||
gate_comps = self.get_unique_types(components=self.get_circuit_gates())
|
||||
one_bit_comps = self.get_unique_types(components=self.get_one_bit_components())
|
||||
multi_bit_comps = self.get_unique_types(components=self.get_multi_bit_components())
|
||||
one_bit_comps = self.get_unique_types(
|
||||
components=self.get_one_bit_components())
|
||||
multi_bit_comps = self.get_unique_types(
|
||||
components=self.get_multi_bit_components())
|
||||
|
||||
all_components = gate_comps + one_bit_comps + multi_bit_comps
|
||||
return all_components
|
||||
@ -172,23 +175,31 @@ class ArithmeticCircuit():
|
||||
"""
|
||||
self.circuit_wires = []
|
||||
if isinstance(self.a, Bus):
|
||||
[self.circuit_wires.append((w, f"{w.name}", self.save_wire_id(wire=w))) for w in self.a.bus]
|
||||
[self.circuit_wires.append((w, f"{w.name}", self.save_wire_id(wire=w))) for w in self.b.bus]
|
||||
[self.circuit_wires.append(
|
||||
(w, f"{w.name}", self.save_wire_id(wire=w))) for w in self.a.bus]
|
||||
[self.circuit_wires.append(
|
||||
(w, f"{w.name}", self.save_wire_id(wire=w))) for w in self.b.bus]
|
||||
else:
|
||||
self.circuit_wires.append((self.a, f"{self.a.name}", self.save_wire_id(wire=self.a)))
|
||||
self.circuit_wires.append((self.b, f"{self.b.name}", self.save_wire_id(wire=self.b)))
|
||||
self.circuit_wires.append(
|
||||
(self.a, f"{self.a.name}", self.save_wire_id(wire=self.a)))
|
||||
self.circuit_wires.append(
|
||||
(self.b, f"{self.b.name}", self.save_wire_id(wire=self.b)))
|
||||
if hasattr(self, 'c'):
|
||||
self.circuit_wires.append((self.c, f"{self.c.name}", self.save_wire_id(wire=self.c)))
|
||||
self.circuit_wires.append(
|
||||
(self.c, f"{self.c.name}", self.save_wire_id(wire=self.c)))
|
||||
|
||||
for gate in self.circuit_gates:
|
||||
if not [item for item in self.circuit_wires if gate.a.name == item[1]]:
|
||||
self.circuit_wires.append((gate.a, gate.a.name, self.save_wire_id(wire=gate.a)))
|
||||
self.circuit_wires.append(
|
||||
(gate.a, gate.a.name, self.save_wire_id(wire=gate.a)))
|
||||
|
||||
if hasattr(gate, 'b') and not [item for item in self.circuit_wires if gate.b.name == item[1]]:
|
||||
self.circuit_wires.append((gate.b, gate.b.name, self.save_wire_id(wire=gate.b)))
|
||||
self.circuit_wires.append(
|
||||
(gate.b, gate.b.name, self.save_wire_id(wire=gate.b)))
|
||||
|
||||
if not [item for item in self.circuit_wires if gate.out.name == item[1]]:
|
||||
self.circuit_wires.append((gate.out, gate.out.name, self.save_wire_id(wire=gate.out)))
|
||||
self.circuit_wires.append(
|
||||
(gate.out, gate.out.name, self.save_wire_id(wire=gate.out)))
|
||||
|
||||
def get_circuit_wire_index(self, wire: Wire):
|
||||
"""Searches for circuit's wire unique index position within the circuit. Used for cgp chromosome generation.
|
||||
@ -283,8 +294,10 @@ class ArithmeticCircuit():
|
||||
str: Hierarchical C code of multi-bit arithmetic circuit's function block description.
|
||||
"""
|
||||
# Obtain proper circuit name with its bit width
|
||||
circuit_prefix = self.__class__(a=Bus("a"), b=Bus("b")).prefix + str(self.N)
|
||||
circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus(N=self.N, prefix="b"), prefix=circuit_prefix)
|
||||
circuit_prefix = self.__class__(
|
||||
a=Bus("a"), b=Bus("b")).prefix + str(self.N)
|
||||
circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus(
|
||||
N=self.N, prefix="b"), prefix=circuit_prefix)
|
||||
return f"{circuit_block.get_circuit_c()}\n\n"
|
||||
|
||||
def get_declarations_c_hier(self):
|
||||
@ -369,6 +382,7 @@ class ArithmeticCircuit():
|
||||
|
||||
""" VERILOG CODE GENERATION """
|
||||
# FLAT VERILOG #
|
||||
|
||||
def get_prototype_v(self):
|
||||
"""Generates Verilog code module header to describe corresponding arithmetic circuit's interface in Verilog code.
|
||||
|
||||
@ -433,8 +447,10 @@ class ArithmeticCircuit():
|
||||
str: Hierarchical Verilog code of multi-bit arithmetic circuit's function block description.
|
||||
"""
|
||||
# Obtain proper circuit name with its bit width
|
||||
circuit_prefix = self.__class__(a=Bus("a"), b=Bus("b")).prefix + str(self.N)
|
||||
circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus(N=self.N, prefix="b"), prefix=circuit_prefix)
|
||||
circuit_prefix = self.__class__(
|
||||
a=Bus("a"), b=Bus("b")).prefix + str(self.N)
|
||||
circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus(
|
||||
N=self.N, prefix="b"), prefix=circuit_prefix)
|
||||
return f"{circuit_block.get_circuit_v()}\n\n"
|
||||
|
||||
def get_declarations_v_hier(self):
|
||||
@ -483,8 +499,10 @@ class ArithmeticCircuit():
|
||||
circuit_type = self.prefix.replace(circuit_prefix+"_", "")
|
||||
|
||||
# Obtain proper circuit name with its bit width
|
||||
circuit_prefix = self.__class__(a=Bus("a"), b=Bus("b")).prefix + str(self.N)
|
||||
circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus(N=self.N, prefix="b"), prefix=circuit_prefix)
|
||||
circuit_prefix = self.__class__(
|
||||
a=Bus("a"), b=Bus("b")).prefix + str(self.N)
|
||||
circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus(
|
||||
N=self.N, prefix="b"), prefix=circuit_prefix)
|
||||
return self.a.return_bus_wires_values_v_hier() + self.b.return_bus_wires_values_v_hier() + \
|
||||
f" {circuit_type} {circuit_type}_{self.out.prefix}(.{circuit_block.a.prefix}({self.a.prefix}), .{circuit_block.b.prefix}({self.b.prefix}), .{circuit_block.out.prefix}({self.out.prefix}));\n"
|
||||
|
||||
@ -521,6 +539,7 @@ class ArithmeticCircuit():
|
||||
|
||||
""" BLIF CODE GENERATION """
|
||||
# FLAT BLIF #
|
||||
|
||||
def get_prototype_blif(self):
|
||||
"""Generates Blif code model name of described arithmetic circuit.
|
||||
|
||||
@ -603,7 +622,8 @@ class ArithmeticCircuit():
|
||||
f".subckt {circuit_type}" + \
|
||||
"".join([f" a[{self.a.bus.index(w)}]={self.a.prefix}[{self.a.bus.index(w)}]" for w in self.a.bus]) + \
|
||||
"".join([f" b[{self.b.bus.index(w)}]={self.b.prefix}[{self.b.bus.index(w)}]" for w in self.b.bus]) + \
|
||||
"".join([f" {circuit_type}_out[{self.out.bus.index(o)}]={o.name}" for o in self.out.bus]) + "\n"
|
||||
"".join(
|
||||
[f" {circuit_type}_out[{self.out.bus.index(o)}]={o.name}" for o in self.out.bus]) + "\n"
|
||||
|
||||
def get_circuit_blif(self):
|
||||
"""Generates hierarchical Blif code subcomponent's function block.
|
||||
@ -635,8 +655,10 @@ class ArithmeticCircuit():
|
||||
str: Hierarchical Blif code of multi-bit arithmetic circuit's function block description.
|
||||
"""
|
||||
# Obtain proper circuit name with its bit width
|
||||
circuit_prefix = self.__class__(a=Bus("a"), b=Bus("b")).prefix + str(self.N)
|
||||
circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus(N=self.N, prefix="b"), prefix=circuit_prefix)
|
||||
circuit_prefix = self.__class__(
|
||||
a=Bus("a"), b=Bus("b")).prefix + str(self.N)
|
||||
circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus(
|
||||
N=self.N, prefix="b"), prefix=circuit_prefix)
|
||||
return f"{circuit_block.get_circuit_blif()}"
|
||||
|
||||
# Generating hierarchical BLIF code representation of circuit
|
||||
@ -652,6 +674,7 @@ class ArithmeticCircuit():
|
||||
|
||||
""" CGP CODE GENERATION """
|
||||
# FLAT CGP #
|
||||
|
||||
def get_parameters_cgp(self):
|
||||
"""Generates CGP chromosome parameters of corresponding arithmetic circuit.
|
||||
|
||||
@ -678,8 +701,8 @@ class ArithmeticCircuit():
|
||||
str: List of triplets each describing logic function of corresponding two input logic gate and as a whole describe the arithmetic circuit.
|
||||
"""
|
||||
self.get_cgp_wires()
|
||||
return "".join([g.get_triplet_cgp(a_id=self.get_circuit_wire_index(g.a)) if isinstance(g, OneInputLogicGate) else
|
||||
g.get_triplet_cgp(a_id=self.get_circuit_wire_index(g.a), b_id=self.get_circuit_wire_index(g.b)) for g in self.circuit_gates])
|
||||
return "".join([g.get_triplet_cgp(a_id=self.get_circuit_wire_index(g.a), out_id=self.get_circuit_wire_index(g.out)) if isinstance(g, OneInputLogicGate) else
|
||||
g.get_triplet_cgp(a_id=self.get_circuit_wire_index(g.a), b_id=self.get_circuit_wire_index(g.b), out_id=self.get_circuit_wire_index(g.out)) for g in self.circuit_gates])
|
||||
|
||||
def get_outputs_cgp(self):
|
||||
"""Generates list of output wires indexes of described arithmetic circuit from MSB to LSB.
|
||||
|
@ -416,7 +416,7 @@ class TwoInputLogicGate():
|
||||
"""
|
||||
return "{2,1,1,1,2,1,0}"
|
||||
|
||||
def get_triplet_cgp(self, a_id: int, b_id: int):
|
||||
def get_triplet_cgp(self, a_id: int, b_id: int, out_id: int):
|
||||
"""Generates logic gate triplet (first input wire, second input wire, logic gate function) using wires unique position indexes within the described circuit.
|
||||
|
||||
Each triplet represents unique logic gate within the described circuit. Besides the contained input wires indexes and gate's inner logic function, an output wire
|
||||
@ -429,11 +429,12 @@ class TwoInputLogicGate():
|
||||
Args:
|
||||
a_id (int): First input wire index position.
|
||||
b_id (int): Second input wire index position.
|
||||
out_id (int): The output wire index position
|
||||
|
||||
Returns:
|
||||
str: Triplet describing function of corresponding two input logic gate.
|
||||
"""
|
||||
return f"({a_id},{b_id},{self.cgp_function})"
|
||||
return f"([{out_id}]{a_id},{b_id},{self.cgp_function})"
|
||||
|
||||
@staticmethod
|
||||
def get_output_cgp(out_id: int):
|
||||
@ -706,7 +707,7 @@ class OneInputLogicGate(TwoInputLogicGate):
|
||||
|
||||
""" CGP CODE GENERATION """
|
||||
# FLAT CGP #
|
||||
def get_triplet_cgp(self, a_id: int):
|
||||
def get_triplet_cgp(self, a_id: int, out_id: int):
|
||||
"""Generates logic gate triplet (first input wire, second input wire, logic gate function) using wires unique position indexes within the described circuit.
|
||||
|
||||
Each triplet represents unique logic gate within the described circuit. In this case of one input logic gate, the same input wire index is driven to both inputs.
|
||||
@ -719,11 +720,12 @@ class OneInputLogicGate(TwoInputLogicGate):
|
||||
|
||||
Args:
|
||||
a_id (int): First (used also as the second) input wire index position.
|
||||
out_id (int): Outpu wire index position
|
||||
|
||||
Returns:
|
||||
str: Triplet describing function of corresponding one input logic gate.
|
||||
"""
|
||||
return f"({a_id},{a_id},{self.cgp_function})"
|
||||
return f"([{out_id}]{a_id},{a_id},{self.cgp_function})"
|
||||
|
||||
@staticmethod
|
||||
def get_output_cgp(out_id: int):
|
||||
|
7
chr2c.py
7
chr2c.py
@ -10,7 +10,7 @@ import argparse
|
||||
|
||||
# Parse all nodes present in input CGP
|
||||
def parse_node(n):
|
||||
return list(map(int, re.match(r"(\d+),(\d+),(\d+)", n).groups()))
|
||||
return list(map(int, re.match(r"\[(\d+)\](\d+),(\d+),(\d+)", n).groups()))
|
||||
|
||||
|
||||
# Recursively detect wires required to get the result wire with id 'id' and activate them (will be generated)
|
||||
@ -56,10 +56,7 @@ def parse_chromosome(chromosome, signed=False, function=None):
|
||||
cdata_dict = [None for i in range(0, c_cols * c_rows)]
|
||||
|
||||
for id, chromosome in enumerate(cdata):
|
||||
a = chromosome[0]
|
||||
b = chromosome[1]
|
||||
f = chromosome[2]
|
||||
|
||||
cid, a, b, f = chromosome
|
||||
cdata_dict[id] = (id + 2 + c_in, a, b, f)
|
||||
|
||||
# Reserve position for all wires present in the genotype
|
||||
|
Loading…
x
Reference in New Issue
Block a user