mirror of
https://github.com/ehw-fit/ariths-gen.git
synced 2025-04-08 08:12:11 +01:00
Updated exportation of signed arithmetic circuits to python representation. Also unified some methods from arithmetic_circuit.py into general_circuit.py.
This commit is contained in:
parent
cfb5bba3ec
commit
d41c5f3c94
@ -50,22 +50,7 @@ class ArithmeticCircuit(GeneralCircuit):
|
||||
"""
|
||||
return f"{self.c_data_type} {self.prefix}({self.c_data_type} {self.a.prefix}, {self.c_data_type} {self.b.prefix})" + "{" + "\n"
|
||||
|
||||
def get_function_block_c(self):
|
||||
"""Generates hierarchical C code representation of corresponding multi-bit arithmetic circuit used as function block in hierarchical circuit description.
|
||||
|
||||
Returns:
|
||||
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"), name=circuit_prefix)
|
||||
return f"{circuit_block.get_circuit_c()}\n\n"
|
||||
|
||||
""" 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.
|
||||
|
||||
@ -73,50 +58,21 @@ class ArithmeticCircuit(GeneralCircuit):
|
||||
str: Module's name and parameters in Verilog code.
|
||||
"""
|
||||
return f"module {self.prefix}(input [{self.N-1}:0] {self.a.prefix}, input [{self.N-1}:0] {self.b.prefix}, output [{self.out.N-1}:0] {self.out.prefix});\n"
|
||||
# HIERARCHICAL VERILOG #
|
||||
def get_function_block_v(self):
|
||||
"""Generates hierarchical Verilog code representation of corresponding multi-bit arithmetic circuit used as function block in hierarchical circuit description.
|
||||
|
||||
""" BLIF CODE GENERATION """
|
||||
def get_declaration_blif(self):
|
||||
"""Generates flat Blif code declaration of input/output circuit wires.
|
||||
|
||||
Returns:
|
||||
str: Hierarchical Verilog code of multi-bit arithmetic circuit's function block description.
|
||||
str: Flat Blif code containing declaration of circuit's wires.
|
||||
"""
|
||||
# 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"), name=circuit_prefix)
|
||||
return f"{circuit_block.get_circuit_v()}\n\n"
|
||||
def get_out_invocation_v(self, circuit_prefix: str):
|
||||
"""Generates hierarchical Verilog code invocation of corresponding arithmetic circuit's generated function block.
|
||||
|
||||
Assigns input values from other subcomponents into multi-bit input buses used as inputs for function block invocation.
|
||||
Assigns output values from invocation of the corresponding function block into inner wires present inside
|
||||
the upper component from which function block has been invoked.
|
||||
|
||||
Args:
|
||||
circuit_prefix (str): Prefix name of the upper component from which function block is being invoked.
|
||||
|
||||
Returns:
|
||||
str: Hierarchical Verilog code of subcomponent's module invocation and output assignment.
|
||||
"""
|
||||
# Getting name of circuit type and insitu copying out bus for proper Verilog code generation without affecting actual generated composition
|
||||
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"), name=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"
|
||||
|
||||
def get_function_block_blif(self):
|
||||
"""Generates hierarchical Blif code representation of corresponding multi-bit arithmetic circuit used as function block in hierarchical circuit description.
|
||||
|
||||
Returns:
|
||||
str: Hierarchical Blif code of multi-bit arithmetic circuit's function block description.
|
||||
"""
|
||||
# Obtain proper circuit name with its bit width
|
||||
circuit_block = self.__class__(a=Bus(N=self.N, prefix="a"), b=Bus(
|
||||
N=self.N, prefix="b"))
|
||||
return f"{circuit_block.get_circuit_blif()}"
|
||||
if self.N == 1:
|
||||
return f".inputs {self.a.prefix} {self.b.prefix}\n" + \
|
||||
f".outputs{self.out.get_wire_declaration_blif()}\n" + \
|
||||
f".names vdd\n1\n" + \
|
||||
f".names gnd\n0\n"
|
||||
else:
|
||||
return f".inputs{self.a.get_wire_declaration_blif()}{self.b.get_wire_declaration_blif()}\n" + \
|
||||
f".outputs{self.out.get_wire_declaration_blif()}\n" + \
|
||||
f".names vdd\n1\n" + \
|
||||
f".names gnd\n0\n"
|
||||
|
@ -278,6 +278,7 @@ class GeneralCircuit():
|
||||
#file_object.write(self.get_declaration_python_flat()+"\n")
|
||||
file_object.write(self.get_init_python_flat()+"\n")
|
||||
file_object.write(self.get_function_out_python_flat())
|
||||
file_object.write(self.out.return_bus_wires_sign_extend_python())
|
||||
file_object.write(f" return {self.out.prefix}"+"\n")
|
||||
|
||||
""" C CODE GENERATION """
|
||||
@ -336,7 +337,7 @@ class GeneralCircuit():
|
||||
file_object.write(self.get_declaration_c_flat()+"\n")
|
||||
file_object.write(self.get_init_c_flat()+"\n")
|
||||
file_object.write(self.get_function_out_c_flat())
|
||||
file_object.write(self.out.return_bus_wires_sign_extend())
|
||||
file_object.write(self.out.return_bus_wires_sign_extend_c())
|
||||
file_object.write(f" return {self.out.prefix}"+";\n}")
|
||||
|
||||
# HIERARCHICAL C #
|
||||
@ -360,7 +361,7 @@ class GeneralCircuit():
|
||||
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)
|
||||
N=self.N, prefix="b"), name=circuit_prefix)
|
||||
return f"{circuit_block.get_circuit_c()}\n\n"
|
||||
|
||||
def get_declarations_c_hier(self):
|
||||
@ -429,7 +430,7 @@ class GeneralCircuit():
|
||||
f"{self.get_declarations_c_hier()}\n" + \
|
||||
f"{self.get_init_c_hier()}\n" + \
|
||||
f"{self.get_function_out_c_hier()}" + \
|
||||
f"{self.out.return_bus_wires_sign_extend()}" + \
|
||||
f"{self.out.return_bus_wires_sign_extend_c()}" + \
|
||||
f" return {self.out.prefix}"+";\n}"
|
||||
|
||||
# Generating hierarchical C code representation of circuit
|
||||
@ -512,7 +513,7 @@ class GeneralCircuit():
|
||||
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)
|
||||
N=self.N, prefix="b"), name=circuit_prefix)
|
||||
return f"{circuit_block.get_circuit_v()}\n\n"
|
||||
|
||||
def get_declarations_v_hier(self):
|
||||
@ -564,7 +565,7 @@ class GeneralCircuit():
|
||||
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)
|
||||
N=self.N, prefix="b"), name=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"
|
||||
|
||||
@ -615,16 +616,10 @@ class GeneralCircuit():
|
||||
Returns:
|
||||
str: Flat Blif code containing declaration of circuit's wires.
|
||||
"""
|
||||
if self.N == 1:
|
||||
return f".inputs {self.a.prefix} {self.b.prefix}\n" + \
|
||||
f".outputs{self.out.get_wire_declaration_blif()}\n" + \
|
||||
f".names vdd\n1\n" + \
|
||||
f".names gnd\n0\n"
|
||||
else:
|
||||
return f".inputs{self.a.get_wire_declaration_blif()}{self.b.get_wire_declaration_blif()}\n" + \
|
||||
f".outputs{self.out.get_wire_declaration_blif()}\n" + \
|
||||
f".names vdd\n1\n" + \
|
||||
f".names gnd\n0\n"
|
||||
return f".inputs{''.join([w.get_wire_declaration_blif() for w in self.inputs])}\n" + \
|
||||
f".outputs{self.out.get_wire_declaration_blif()}\n" + \
|
||||
f".names vdd\n1\n" + \
|
||||
f".names gnd\n0\n"
|
||||
|
||||
def get_function_blif_flat(self):
|
||||
"""Generates flat Blif code with invocation of subcomponents logic gates functions via their corresponding truth tables.
|
||||
@ -718,7 +713,7 @@ class GeneralCircuit():
|
||||
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)
|
||||
N=self.N, prefix="b"), name=circuit_prefix)
|
||||
return f"{circuit_block.get_circuit_blif()}"
|
||||
|
||||
# Generating hierarchical BLIF code representation of circuit
|
||||
|
@ -119,6 +119,18 @@ class Bus():
|
||||
str: Python code for assigning wire values into bus represented in Python code variable.
|
||||
"""
|
||||
return "".join([f" {self.prefix} = 0\n"] + [f" {self.prefix} |= {w.return_wire_value_python_flat(offset=self.bus.index(w))}" for w in self.bus])
|
||||
|
||||
def return_bus_wires_sign_extend_python(self):
|
||||
"""Sign extends the bus's corresponding Python variable (object) to ensure proper Python code variable signedness.
|
||||
|
||||
Returns:
|
||||
str: Python code for sign extending the bus variable wire values.
|
||||
"""
|
||||
if self.signed is True:
|
||||
last_bus_wire = self.bus[-1]
|
||||
return "".join([f" {self.prefix} |= {last_bus_wire.return_wire_value_python_flat(offset=i)}" for i in range(len(self.bus), 64)])
|
||||
else:
|
||||
return ""
|
||||
|
||||
""" C CODE GENERATION """
|
||||
def get_declaration_c(self):
|
||||
@ -146,7 +158,7 @@ class Bus():
|
||||
"""
|
||||
return "".join([f" {self.prefix} |= {w.return_wire_value_c_hier(offset=self.bus.index(w))}" for w in self.bus])
|
||||
|
||||
def return_bus_wires_sign_extend(self):
|
||||
def return_bus_wires_sign_extend_c(self):
|
||||
"""Sign extends the bus's corresponding C variable to ensure proper C code variable signedness.
|
||||
|
||||
Returns:
|
||||
|
@ -61,7 +61,7 @@ def test_signed_mul():
|
||||
mul = c(a, b)
|
||||
r = mul(av, bv)
|
||||
|
||||
r[r >= 2**(2*N-1)] -= 2**(2*N) # hack!!! two's complement not implemented yet
|
||||
# r[r >= 2**(2*N-1)] -= 2**(2*N) # hack!!! two's complement not implemented yet
|
||||
np.testing.assert_array_equal(expected, r)
|
||||
|
||||
|
||||
@ -94,7 +94,7 @@ def test_signed_add():
|
||||
for c in [SignedCarryLookaheadAdder, SignedPGRippleCarryAdder, SignedRippleCarryAdder, SignedCarrySkipAdder]:
|
||||
mul = c(a, b)
|
||||
r = mul(av, bv)
|
||||
r[r >= 2**(N)] -= 2**(N+1) # hack!!! two's complement not implemented yet
|
||||
# r[r >= 2**(N)] -= 2**(N+1) # hack!!! two's complement not implemented yet
|
||||
np.testing.assert_array_equal(expected, r)
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user