Implemented generation to flat Verilog format and improved some other minor bits of code.
This commit is contained in:
parent
c9ddb834f7
commit
ef5dc80382
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,4 +3,5 @@ __pycache__/
|
||||
test.py
|
||||
Makefile
|
||||
*.c
|
||||
*.v
|
||||
t.py
|
@ -12,6 +12,7 @@ class arithmetic_circuit():
|
||||
self.components = []
|
||||
self.circuit_wires = []
|
||||
self.c_data_type = "uint64_t"
|
||||
self.N = 1
|
||||
|
||||
# TODO delete?
|
||||
self.carry_out_gate = None
|
||||
@ -39,7 +40,19 @@ class arithmetic_circuit():
|
||||
def get_carry_wire(self):
|
||||
return self.out.get_wire(1)
|
||||
|
||||
# FLAT C GENERATION #
|
||||
def get_circuit_wires(self):
|
||||
for component in self.components:
|
||||
if not [item for item in self.circuit_wires if item[1] == component.a.name]:
|
||||
self.circuit_wires.append((component.a, component.a.name))
|
||||
|
||||
if not [item for item in self.circuit_wires if item[1] == component.b.name]:
|
||||
self.circuit_wires.append((component.b, component.b.name))
|
||||
|
||||
if not [item for item in self.circuit_wires if item[1] == component.output.name]:
|
||||
self.circuit_wires.append((component.output, component.output.name))
|
||||
|
||||
""" C CODE GENERATION """
|
||||
# FLAT C #
|
||||
@staticmethod
|
||||
def get_includes_c():
|
||||
return f"#include <stdio.h>\n#include <stdint.h>\n\n"
|
||||
@ -71,7 +84,7 @@ class arithmetic_circuit():
|
||||
file_object.write(f" return {self.out.prefix}"+";\n}")
|
||||
file_object.close()
|
||||
|
||||
# HIERARCHICAL C GENERATION #
|
||||
# HIERARCHICAL C #
|
||||
def get_function_blocks_c(self):
|
||||
# Add unique 1-bit adder components (ha, fa)
|
||||
self.component_types = self.get_component_types()
|
||||
@ -116,6 +129,36 @@ class arithmetic_circuit():
|
||||
file_object.write(self.get_circuit_c())
|
||||
file_object.close()
|
||||
|
||||
""" VERILOG CODE GENERATION """
|
||||
# FLAT VERILOG #
|
||||
def get_prototype_v(self):
|
||||
return f"module {self.prefix}(input [{self.N-1}:0] {self.a.prefix}, input [{self.N-1}:0] {self.b.prefix}, output [{self.N}:0] {self.out.prefix});\n"
|
||||
|
||||
def get_declaration_v_flat(self):
|
||||
return f"".join([c.get_declaration_v_flat() for c in self.components])
|
||||
|
||||
def get_init_v_flat(self, offset: int = 0, array: bool = False):
|
||||
return "".join([c.get_init_v_flat(offset=self.components.index(c), array=True) for c in self.components])
|
||||
|
||||
def get_function_sum_cout_v_flat(self):
|
||||
return "".join([c.get_function_sum_cout_v_flat(offset=self.components.index(c)) for c in self.components])
|
||||
|
||||
def get_function_sum_v_flat(self):
|
||||
return "".join([c.get_function_sum_v_flat(offset=self.components.index(c)) for c in self.components])
|
||||
|
||||
def get_function_carry_v_flat(self):
|
||||
return f"{self.get_previous_component().get_function_carry_v_flat(offset=self.out.N-1)}"
|
||||
|
||||
# Generating flat V code representation of circuit
|
||||
def get_v_code_flat(self, file_object):
|
||||
file_object.write(self.get_prototype_v())
|
||||
file_object.write(self.get_declaration_v_flat()+"\n")
|
||||
file_object.write(self.get_init_v_flat(array=False)+"\n")
|
||||
file_object.write(self.get_function_sum_v_flat())
|
||||
file_object.write(self.get_function_carry_v_flat())
|
||||
file_object.write(f"endmodule")
|
||||
file_object.close()
|
||||
|
||||
|
||||
class half_adder(arithmetic_circuit):
|
||||
def __init__(self, a: wire, b: wire, prefix: str = "ha"):
|
||||
@ -125,7 +168,7 @@ class half_adder(arithmetic_circuit):
|
||||
self.a = a
|
||||
self.b = b
|
||||
# 2 wires for component's bus output (sum, cout)
|
||||
self.out = bus("out", 2)
|
||||
self.out = bus("out", self.N+1)
|
||||
|
||||
# Sum
|
||||
# XOR gate for calculation of 1-bit sum
|
||||
@ -139,7 +182,8 @@ class half_adder(arithmetic_circuit):
|
||||
self.add_component(obj_and_gate)
|
||||
self.out.connect(1, obj_and_gate.output)
|
||||
|
||||
# FLAT C GENERATION #
|
||||
""" C CODE GENERATION """
|
||||
# FLAT C #
|
||||
# Half adder function prototype with two inputs
|
||||
def get_prototype_c(self):
|
||||
return f"{self.c_data_type} {self.prefix}({self.c_data_type} {self.a.name}, {self.c_data_type} {self.b.name})" + "{" + "\n"
|
||||
@ -147,23 +191,14 @@ class half_adder(arithmetic_circuit):
|
||||
# Obtaining list of all the unique circuit wires from all contained logic gates
|
||||
# to ensure non-recurring declaration of same wires
|
||||
def get_declaration_c_flat(self):
|
||||
for component in self.components:
|
||||
if not [item for item in self.circuit_wires if item[1] == component.a.name]:
|
||||
self.circuit_wires.append((component.a, component.a.name))
|
||||
|
||||
if not [item for item in self.circuit_wires if item[1] == component.b.name]:
|
||||
self.circuit_wires.append((component.b, component.b.name))
|
||||
|
||||
if not [item for item in self.circuit_wires if item[1] == component.output.name]:
|
||||
self.circuit_wires.append((component.output, component.output.name))
|
||||
|
||||
self.get_circuit_wires()
|
||||
# Unique declaration of all circuit's interconnections
|
||||
return "".join([c[0].get_declaration_c() for c in self.circuit_wires])
|
||||
|
||||
# Half adder wires values initialization
|
||||
def get_init_c_flat(self):
|
||||
self.a.prefix = self.a.name if self.a.prefix == "" else self.a.prefix
|
||||
self.b.prefix = self.b.name if self.b.prefix == "" else self.b.prefix
|
||||
# self.a.prefix = self.a.name if self.a.prefix == "" else self.a.prefix
|
||||
# self.b.prefix = self.b.name if self.b.prefix == "" else self.b.prefix
|
||||
return f" {self.components[0].a.name} = {self.a.get_wire_value_c(offset=self.a.index)};\n" + \
|
||||
f" {self.components[0].b.name} = {self.b.get_wire_value_c(offset=self.b.index)};\n" + \
|
||||
f" {self.components[0].output.name} = {self.components[0].get_init_c_flat()};\n" + \
|
||||
@ -175,7 +210,7 @@ class half_adder(arithmetic_circuit):
|
||||
def get_function_carry_c_flat(self, offset: int = 1):
|
||||
return f" {self.out.prefix} |= {self.components[1].output.return_wire_value_c(offset=offset)};\n"
|
||||
|
||||
# HIERARCHICAL C GENERATION #
|
||||
# HIERARCHICAL C #
|
||||
def get_function_block_c(self):
|
||||
self.component_types = self.get_component_types()
|
||||
self.prefix = "ha"
|
||||
@ -208,6 +243,31 @@ class half_adder(arithmetic_circuit):
|
||||
f"{self.get_function_carry_c_hier()}" + \
|
||||
f" return {self.out.prefix}"+";\n}"
|
||||
|
||||
""" VERILOG CODE GENERATION """
|
||||
# FLAT VERILOG #
|
||||
def get_prototype_v(self):
|
||||
return f"module {self.prefix}(input {self.a.name}, input {self.b.name}, output [{self.N}:0]{self.out.prefix});\n"
|
||||
|
||||
def get_declaration_v_flat(self):
|
||||
self.get_circuit_wires()
|
||||
# Unique declaration of all circuit's interconnections
|
||||
return "".join([c[0].get_declaration_v() for c in self.circuit_wires])
|
||||
|
||||
# Half adder wires values initialization
|
||||
def get_init_v_flat(self, offset: int = 0, array: bool = False, ):
|
||||
self.a.prefix = self.a.name if self.a.prefix == "" else self.a.prefix
|
||||
self.b.prefix = self.b.name if self.b.prefix == "" else self.b.prefix
|
||||
return f" assign {self.components[0].a.name} = {self.a.get_wire_value_v(offset=offset, array=array)};\n" + \
|
||||
f" assign {self.components[0].b.name} = {self.b.get_wire_value_v(offset=offset, array=array)};\n" + \
|
||||
f" assign {self.components[0].output.name} = {self.components[0].get_init_v_flat()};\n" + \
|
||||
f" assign {self.components[1].output.name} = {self.components[1].get_init_v_flat()};\n"
|
||||
|
||||
def get_function_sum_v_flat(self, offset: int = 0):
|
||||
return f" assign {self.out.prefix}[{offset}] = {self.components[0].output.name};\n"
|
||||
|
||||
def get_function_carry_v_flat(self, offset: int = 1):
|
||||
return f" assign {self.out.prefix}[{offset}] = {self.components[1].output.name};\n"
|
||||
|
||||
|
||||
class full_adder(arithmetic_circuit):
|
||||
def __init__(self, a: wire, b: wire, c: wire, prefix: str = "fa"):
|
||||
@ -218,7 +278,7 @@ class full_adder(arithmetic_circuit):
|
||||
self.b = b
|
||||
self.c = c
|
||||
# 2 wires for component's bus output (sum, cout)
|
||||
self.out = bus("out", 2)
|
||||
self.out = bus("out", self.N+1)
|
||||
|
||||
# PG logic
|
||||
propagate_xor_gate1 = xor_gate(a, b, prefix, outid=0)
|
||||
@ -246,7 +306,8 @@ class full_adder(arithmetic_circuit):
|
||||
self.propagate = propagate_xor_gate1.output
|
||||
self.generate = generate_and_gate1.output
|
||||
|
||||
# FLAT C GENERATION #
|
||||
""" C CODE GENERATION """
|
||||
# FLAT C #
|
||||
# Full adder function prototype with three inputs
|
||||
def get_prototype_c(self):
|
||||
return f"{self.c_data_type} {self.prefix}({self.c_data_type} {self.a.name}, {self.c_data_type} {self.b.name}, {self.c_data_type} {self.c.name})" + "{" + "\n"
|
||||
@ -254,16 +315,7 @@ class full_adder(arithmetic_circuit):
|
||||
# Obtaining list of all the unique circuit wires from all contained logic gates
|
||||
# to ensure non-recurring declaration of same wires
|
||||
def get_declaration_c_flat(self):
|
||||
for component in self.components:
|
||||
if not [item for item in self.circuit_wires if item[1] == component.a.name]:
|
||||
self.circuit_wires.append((component.a, component.a.name))
|
||||
|
||||
if not [item for item in self.circuit_wires if item[1] == component.b.name]:
|
||||
self.circuit_wires.append((component.b, component.b.name))
|
||||
|
||||
if not [item for item in self.circuit_wires if item[1] == component.output.name]:
|
||||
self.circuit_wires.append((component.output, component.output.name))
|
||||
|
||||
self.get_circuit_wires()
|
||||
# Unique declaration of all circuit's interconnections
|
||||
return "".join([c[0].get_declaration_c() for c in self.circuit_wires])
|
||||
|
||||
@ -287,7 +339,7 @@ class full_adder(arithmetic_circuit):
|
||||
def get_function_carry_c_flat(self, offset: int = 1):
|
||||
return f" {self.out.prefix} |= {self.components[4].output.return_wire_value_c(offset=offset)};\n"
|
||||
|
||||
# HIERARCHICAL C GENERATION #
|
||||
# HIERARCHICAL C #
|
||||
def get_function_block_c(self):
|
||||
self.component_types = self.get_component_types()
|
||||
self.prefix = "fa"
|
||||
@ -340,6 +392,36 @@ class full_adder(arithmetic_circuit):
|
||||
f"{self.get_function_carry_c_hier()}" + \
|
||||
f" return {self.out.prefix}"+";\n}"
|
||||
|
||||
""" VERILOG CODE GENERATION """
|
||||
# FLAT VERILOG #
|
||||
def get_prototype_v(self):
|
||||
return f"module {self.prefix}(input {self.a.name}, input {self.b.name}, input {self.c.name}, output [{self.N}:0]{self.out.prefix});\n"
|
||||
|
||||
def get_declaration_v_flat(self):
|
||||
self.get_circuit_wires()
|
||||
# Unique declaration of all circuit's interconnections
|
||||
return "".join([c[0].get_declaration_v() for c in self.circuit_wires])
|
||||
|
||||
# Full adder wires values initialization
|
||||
def get_init_v_flat(self, offset: int = 0, array: bool = False):
|
||||
self.a.prefix = self.a.name if self.a.prefix == "" else self.a.prefix
|
||||
self.b.prefix = self.b.name if self.b.prefix == "" else self.b.prefix
|
||||
self.c.prefix = self.c.name
|
||||
return f" assign {self.components[0].a.name} = {self.a.get_wire_value_v(offset=offset, array=array)};\n" + \
|
||||
f" assign {self.components[0].b.name} = {self.b.get_wire_value_v(offset=offset, array=array)};\n" + \
|
||||
f" assign {self.components[2].b.name} = {self.c.get_wire_value_v(offset=offset, array=array)};\n" + \
|
||||
f" assign {self.components[0].output.name} = {self.components[0].get_init_v_flat()};\n" + \
|
||||
f" assign {self.components[1].output.name} = {self.components[1].get_init_v_flat()};\n" + \
|
||||
f" assign {self.components[2].output.name} = {self.components[2].get_init_v_flat()};\n" + \
|
||||
f" assign {self.components[3].output.name} = {self.components[3].get_init_v_flat()};\n" + \
|
||||
f" assign {self.components[4].output.name} = {self.components[4].get_init_v_flat()};\n"
|
||||
|
||||
def get_function_sum_v_flat(self, offset: int = 0):
|
||||
return f" assign {self.out.prefix}[{offset}] = {self.components[2].output.name};\n"
|
||||
|
||||
def get_function_carry_v_flat(self, offset: int = 1):
|
||||
return f" assign {self.out.prefix}[{offset}] = {self.components[4].output.name};\n"
|
||||
|
||||
|
||||
class signed_ripple_carry_adder(arithmetic_circuit):
|
||||
def __init__(self, a: bus, b: bus, prefix: str = "s_rca"):
|
||||
@ -381,7 +463,8 @@ class signed_ripple_carry_adder(arithmetic_circuit):
|
||||
self.add_component(sign_xor_1)
|
||||
self.add_component(sign_xor_2)
|
||||
|
||||
# FLAT C GENERATION #
|
||||
""" VERILOG CODE GENERATION """
|
||||
# FLAT C #
|
||||
# Initialization of 1-bit adders and sign extension XOR gates
|
||||
def get_init_c_flat(self):
|
||||
self.components[-2].output.prefix = self.components[-2].output.name
|
||||
@ -400,7 +483,7 @@ class signed_ripple_carry_adder(arithmetic_circuit):
|
||||
def get_function_carry_c_flat(self):
|
||||
return f" {self.out.prefix} |= {self.get_previous_component().output.return_wire_value_c(offset = self.N)};\n"
|
||||
|
||||
# HIERARCHICAL C GENERATION #
|
||||
# HIERARCHICAL C #
|
||||
def get_declaration_c_hier(self):
|
||||
self.cout = bus(N=self.N, prefix="cout")
|
||||
return "".join(self.a.get_wire_declaration_c()) + \
|
||||
@ -418,6 +501,26 @@ class signed_ripple_carry_adder(arithmetic_circuit):
|
||||
def get_function_carry_c_hier(self):
|
||||
return f" {self.out.prefix} |= {self.get_previous_component().get_gate_output_c(a=self.components[-2].output, b=self.cout.bus[-1], offset=self.out.N-1)};\n"
|
||||
|
||||
""" VERILOG CODE GENERATION """
|
||||
# FLAT C #
|
||||
# Initialization of 1-bit adders and sign extension XOR gates
|
||||
def get_init_v_flat(self, offset: int = 0, array: bool = False):
|
||||
self.components[-2].output.prefix = self.components[-2].output.name
|
||||
self.components[-3].get_carry_wire().prefix = self.components[-3].get_carry_wire().name
|
||||
return f"".join([c.get_init_v_flat(offset=self.components.index(c), array=True) for c in self.components[:-2]]) + \
|
||||
f" assign {self.components[-2].a.name} = {self.a.get_wire_value_v(offset=self.N-1, array=True)};\n" + \
|
||||
f" assign {self.components[-2].b.name} = {self.b.get_wire_value_v(offset=self.N-1, array=True)};\n" + \
|
||||
f" assign {self.components[-2].output.name} = {self.components[-2].get_init_v_flat()};\n" + \
|
||||
f" assign {self.components[-1].a.name} = {self.components[-2].output.get_wire_value_v(offset=offset, array=array)};\n" + \
|
||||
f" assign {self.components[-1].b.name} = {self.components[-3].get_carry_wire().get_wire_value_v()};\n" + \
|
||||
f" assign {self.components[-1].output.name} = {self.components[-1].get_init_v_flat()};\n"
|
||||
|
||||
def get_function_sum_v_flat(self, offset: int = 0):
|
||||
return "".join([c.get_function_sum_v_flat(offset=self.components.index(c)) for c in self.components[:-2]])
|
||||
|
||||
def get_function_carry_v_flat(self):
|
||||
return f" assign {self.out.prefix}[{self.N}] = {self.get_previous_component().output.return_wire_value_v(offset=self.N)};\n"
|
||||
|
||||
|
||||
class unsigned_ripple_carry_adder(arithmetic_circuit):
|
||||
def __init__(self, a: bus, b: bus, prefix: str = "u_rca"):
|
||||
@ -456,14 +559,22 @@ class unsigned_ripple_carry_adder(arithmetic_circuit):
|
||||
if __name__ == "__main__":
|
||||
a = bus(N=8, prefix="a")
|
||||
b = bus(N=8, prefix="b")
|
||||
rca = unsigned_ripple_carry_adder(a, b)
|
||||
|
||||
# rca.get_c_code_hier(open("h_u_rca8.c", "w"))
|
||||
rca = unsigned_ripple_carry_adder(a, b, prefix="u_rca8")
|
||||
# rca.get_c_code_hier(open("h_u_rca4.c", "w"))
|
||||
# rca.get_c_code_flat(open("f_u_rca8.c", "w"))
|
||||
rca.get_v_code_flat(open("f_u_rca8.v", "w"))
|
||||
|
||||
w1 = wire(name="a")
|
||||
w2 = wire(name="b")
|
||||
w3 = wire(name="cout")
|
||||
fa = full_adder(w1, w2, w3, prefix="h_fa")
|
||||
ha = half_adder(w1, w2, prefix="h_ha")
|
||||
fa = full_adder(w1, w2, w3, prefix="f_fa")
|
||||
ha = half_adder(w1, w2, prefix="f_ha")
|
||||
|
||||
# ha.get_c_code_hier(open("h_ha.c","w"))
|
||||
# ha.get_c_code_flat(open("f_ha.c","w"))
|
||||
# ha.get_v_code_flat(open("f_ha.v","w"))
|
||||
# fa.get_c_code_flat(open("f_fa.c","w"))
|
||||
# fa.get_v_code_flat(open("f_fa.v","w"))
|
||||
|
||||
gate = not_gate(w1)
|
||||
# gate.get_c_code(open("not_gate.c","w"))
|
||||
# gate.get_v_code(open("not_gate.v","w"))
|
||||
|
@ -5,7 +5,7 @@ from wire_components import wire
|
||||
|
||||
|
||||
class logic_gate():
|
||||
def __init__(self, a: wire, b: wire, prefix: str = "w"):
|
||||
def __init__(self, a: wire, b: wire, prefix: str = "gate"):
|
||||
self.a = wire(name=prefix+"_"+a.name.replace(prefix+"_", ""), value=a.value)
|
||||
self.b = wire(name=prefix+"_"+b.name.replace(prefix+"_", ""), value=b.value)
|
||||
self.prefix = prefix
|
||||
@ -13,15 +13,19 @@ class logic_gate():
|
||||
def get_component_types(self):
|
||||
return list([self])
|
||||
|
||||
# FLAT C GENERATION #
|
||||
""" C CODE GENERATION """
|
||||
# FLAT C #
|
||||
@staticmethod
|
||||
def get_includes_c():
|
||||
return f"#include <stdio.h>\n#include <stdint.h>\n\n"
|
||||
|
||||
def get_prototype_c(self):
|
||||
self.a.name = self.a.name.replace(self.prefix+"_", "")
|
||||
self.b.name = self.b.name.replace(self.prefix+"_", "")
|
||||
return f"uint8_t {self.gate_type}(uint8_t {self.a.name}, uint8_t {self.b.name})" + "{" + "\n"
|
||||
self.a.name = self.a.name.replace(self.prefix, "", 1)
|
||||
self.b.name = self.b.name.replace(self.prefix, "", 1)
|
||||
return f"uint8_t {self.prefix}_{self.gate_type}(uint8_t {self.a.name}, uint8_t {self.b.name})" + "{" + "\n"
|
||||
|
||||
def get_function_c(self):
|
||||
return f"{self.a.get_wire_value_c()} {self.operator} {self.b.get_wire_value_c()}"
|
||||
|
||||
def get_declaration_c_flat(self):
|
||||
return f"{self.a.get_declaration_c()}{self.b.get_declaration_c()}{self.output.get_declaration_c()}"
|
||||
@ -29,12 +33,7 @@ class logic_gate():
|
||||
def get_init_c_flat(self):
|
||||
return f"{self.a.name} {self.operator} {self.b.name}"
|
||||
|
||||
def get_function_c(self):
|
||||
self.a.prefix = self.a.name.replace(self.prefix+"_", "")
|
||||
self.b.prefix = self.b.name.replace(self.prefix+"_", "")
|
||||
return f"{self.a.get_wire_value_c()} {self.operator} {self.b.get_wire_value_c()}"
|
||||
|
||||
# Generating flat C code representation of separate logic gate
|
||||
# Generating flat C code representation of the logic gate itself
|
||||
# (i.e. not as a component of bigger circuit)
|
||||
def get_c_code(self, file_object):
|
||||
file_object.write(self.get_includes_c())
|
||||
@ -55,13 +54,38 @@ class logic_gate():
|
||||
def get_gate_output_c(self, a: wire, b: wire, offset: int = 0):
|
||||
return f"({self.gate_type}({a.name}, {b.name}) & 0x01) << {offset}"
|
||||
|
||||
""" VERILOG CODE GENERATION """
|
||||
# FLAT VERILOG #
|
||||
def get_prototype_v(self):
|
||||
self.a.name = self.a.name.replace(self.prefix, "", 1)
|
||||
self.b.name = self.b.name.replace(self.prefix, "", 1)
|
||||
self.output.name = self.output.name.replace(self.prefix, "", 1)
|
||||
return f"module {self.prefix}_{self.gate_type}(input {self.a.name}, input {self.b.name}, output {self.output.name});\n"
|
||||
|
||||
def get_declaration_v_flat(self):
|
||||
return f"{self.a.get_declaration_v()}{self.b.get_declaration_v()}{self.output.get_declaration_v()}"
|
||||
|
||||
def get_function_v(self):
|
||||
return f"{self.a.name} {self.operator} {self.b.name}"
|
||||
|
||||
def get_init_v_flat(self):
|
||||
return f"{self.a.name} {self.operator} {self.b.name}"
|
||||
|
||||
# Generating flat Verilog code representation of the logic gate itself
|
||||
# (i.e. not as a component of bigger circuit)
|
||||
def get_v_code(self, file_object):
|
||||
file_object.write(self.get_prototype_v())
|
||||
file_object.write(f" assign {self.output.name} = {self.get_function_v()};\n")
|
||||
file_object.write(f"endmodule")
|
||||
file_object.close()
|
||||
|
||||
|
||||
# Single-input
|
||||
class not_gate(logic_gate):
|
||||
def __init__(self, a: wire, prefix: str = "w", outid: int = 0):
|
||||
def __init__(self, a: wire, prefix: str = "", outid: int = 0):
|
||||
self.gate_type = "not_gate"
|
||||
self.operator = "~"
|
||||
self.a = wire(prefix+"_"+a.name.replace(prefix+"_", ""), a.value)
|
||||
self.a = wire(name=prefix+"_"+a.name.replace(prefix+"_", ""), value=a.value)
|
||||
self.prefix = prefix
|
||||
|
||||
if self.a.value == 1:
|
||||
@ -69,9 +93,14 @@ class not_gate(logic_gate):
|
||||
else:
|
||||
self.output = wire(name=prefix+"_y"+str(outid), value=1)
|
||||
|
||||
# FLAT C GENERATION #
|
||||
""" C CODE GENERATION """
|
||||
# FLAT C #
|
||||
def get_prototype_c(self):
|
||||
return f"uint8_t {self.gate_type}(uint8_t a)" + "{" + "\n"
|
||||
self.a.name = self.a.name.replace(self.prefix, "", 1)
|
||||
return f"uint8_t {self.prefix}_{self.gate_type}(uint8_t {self.a.name})" + "{" + "\n"
|
||||
|
||||
def get_function_c(self):
|
||||
return f"{self.operator}{self.a.get_wire_value_c()} & 0x01 << 0"
|
||||
|
||||
def get_declaration_c(self):
|
||||
return f"{self.a.get_declaration_c()}{self.output.get_declaration_c()}"
|
||||
@ -79,11 +108,7 @@ class not_gate(logic_gate):
|
||||
def get_init_c_flat(self):
|
||||
return f"{self.operator}{self.a.name}"
|
||||
|
||||
def get_function_c(self):
|
||||
self.a.prefix = self.a.name.replace(self.prefix+"_", "")
|
||||
return f"{self.operator}{self.a.get_wire_value_c()} & 0x01 << 0"
|
||||
|
||||
# HIERARCHICAL C GENERATION #
|
||||
# HIERARCHICAL C #
|
||||
def get_function_block_c(self):
|
||||
self.a.name = "a"
|
||||
return f"{self.get_prototype_c()}" + \
|
||||
@ -95,10 +120,27 @@ class not_gate(logic_gate):
|
||||
def get_gate_output_c(self, a: wire, offset: int = 0):
|
||||
return f"({self.gate_type}({a.name}) & 0x01) << {offset}"
|
||||
|
||||
""" VERILOG CODE GENERATION """
|
||||
# FLAT VERILOG #
|
||||
def get_prototype_v(self):
|
||||
self.a.name = self.a.name.replace(self.prefix, "", 1)
|
||||
self.output.name = self.output.name.replace(self.prefix, "", 1)
|
||||
return f"module {self.prefix}_{self.gate_type}(input {self.a.name}, output {self.output.name});\n"
|
||||
|
||||
def get_declaration_v_flat(self):
|
||||
return f"{self.a.get_declaration_v()}{self.output.get_declaration_v()}"
|
||||
|
||||
def get_function_v(self):
|
||||
# self.a.name = self.a.name.replace(self.prefix+"_", "")
|
||||
return f" {self.operator}{self.a.name}"
|
||||
|
||||
def get_init_v_flat(self):
|
||||
return f"{self.a.name} {self.operator} {self.b.name}"
|
||||
|
||||
|
||||
# Two-input
|
||||
class and_gate(logic_gate):
|
||||
def __init__(self, a: wire, b: wire, prefix: str = "w", outid: int = 0):
|
||||
def __init__(self, a: wire, b: wire, prefix: str = "", outid: int = 0):
|
||||
super().__init__(a, b, prefix)
|
||||
self.gate_type = "and_gate"
|
||||
self.operator = "&"
|
||||
@ -110,7 +152,7 @@ class and_gate(logic_gate):
|
||||
|
||||
|
||||
class nand_gate(logic_gate):
|
||||
def __init__(self, a: wire, b: wire, prefix: str = "w", outid: int = 0):
|
||||
def __init__(self, a: wire, b: wire, prefix: str = "", outid: int = 0):
|
||||
super().__init__(a, b, prefix)
|
||||
self.gate_type = "nand_gate"
|
||||
self.operator = "&"
|
||||
@ -120,12 +162,17 @@ class nand_gate(logic_gate):
|
||||
else:
|
||||
self.output = wire(name=prefix+"_y"+str(outid), value=1)
|
||||
|
||||
""" C CODE GENERATION """
|
||||
def get_function_c(self):
|
||||
return "~("+(super().get_function_c())+f") & 0x01 << 0"
|
||||
|
||||
""" VERILOG CODE GENERATION """
|
||||
def get_function_v(self):
|
||||
return "~("+(super().get_function_v())+f")"
|
||||
|
||||
|
||||
class or_gate(logic_gate):
|
||||
def __init__(self, a: wire, b: wire, prefix: str = "w", outid: int = 0):
|
||||
def __init__(self, a: wire, b: wire, prefix: str = "", outid: int = 0):
|
||||
super().__init__(a, b, prefix)
|
||||
self.gate_type = "or_gate"
|
||||
self.operator = "|"
|
||||
@ -137,7 +184,7 @@ class or_gate(logic_gate):
|
||||
|
||||
|
||||
class nor_gate(logic_gate):
|
||||
def __init__(self, a: wire, b: wire, prefix: str = "w", outid: int = 0):
|
||||
def __init__(self, a: wire, b: wire, prefix: str = "", outid: int = 0):
|
||||
super().__init__(a, b, prefix)
|
||||
self.gate_type = "nor_gate"
|
||||
self.operator = "|"
|
||||
@ -147,12 +194,17 @@ class nor_gate(logic_gate):
|
||||
else:
|
||||
self.output = wire(name=prefix+"_y"+str(outid), value=1)
|
||||
|
||||
""" C CODE GENERATION """
|
||||
def get_function_c(self):
|
||||
return "~("+(super().get_function_c())+") & 0x01 << 0"
|
||||
|
||||
""" VERILOG CODE GENERATION """
|
||||
def get_function_v(self):
|
||||
return "~("+(super().get_function_v())+f")"
|
||||
|
||||
|
||||
class xor_gate(logic_gate):
|
||||
def __init__(self, a: wire, b: wire, prefix: str = "w", outid: int = 0):
|
||||
def __init__(self, a: wire, b: wire, prefix: str = "", outid: int = 0):
|
||||
super().__init__(a, b, prefix)
|
||||
self.gate_type = "xor_gate"
|
||||
self.operator = "^"
|
||||
@ -164,7 +216,7 @@ class xor_gate(logic_gate):
|
||||
|
||||
|
||||
class xnor_gate(logic_gate):
|
||||
def __init__(self, a: wire, b: wire, prefix: str = "w", outid: int = 0):
|
||||
def __init__(self, a: wire, b: wire, prefix: str = "", outid: int = 0):
|
||||
super().__init__(a, b, prefix)
|
||||
self.gate_type = "xnor_gate"
|
||||
self.operator = "^"
|
||||
@ -174,5 +226,10 @@ class xnor_gate(logic_gate):
|
||||
else:
|
||||
self.output = wire(name=prefix+"_y"+str(outid), value=1)
|
||||
|
||||
""" C CODE GENERATION """
|
||||
def get_function_c(self):
|
||||
return "~("+(super().get_function_c())+") & 0x01 << 0"
|
||||
|
||||
""" VERILOG CODE GENERATION """
|
||||
def get_function_v(self):
|
||||
return "~("+(super().get_function_v())+f")"
|
||||
|
@ -8,16 +8,31 @@ class wire():
|
||||
self.value = value
|
||||
self.index = index
|
||||
|
||||
# C GENERATION #
|
||||
# C CODE GENERATION #
|
||||
def get_declaration_c(self):
|
||||
return f" uint8_t {self.name} = 0;\n"
|
||||
|
||||
def get_wire_value_c(self, offset: int = 0):
|
||||
return f"(({self.prefix} >> {offset}) & 0x01)"
|
||||
name = self.name if self.prefix == "" else self.prefix
|
||||
return f"(({name} >> {offset}) & 0x01)"
|
||||
|
||||
def return_wire_value_c(self, offset: int = 0):
|
||||
return f"({self.name} & 0x01) << {offset}"
|
||||
|
||||
# VERILOG CODE GENERATION #
|
||||
def get_declaration_v(self):
|
||||
return f" wire {self.name};\n"
|
||||
|
||||
def get_wire_value_v(self, offset: int = 0, array: bool = False):
|
||||
name = self.name if self.prefix == "" else self.prefix
|
||||
if array is True:
|
||||
return f"{name}[{offset}]"
|
||||
else:
|
||||
return f"{name}"
|
||||
|
||||
def return_wire_value_v(self, offset: int = 0):
|
||||
return f"{self.name}"
|
||||
|
||||
|
||||
class bus():
|
||||
def __init__(self, prefix: str = "bus", N: int = 1):
|
||||
@ -40,7 +55,7 @@ class bus():
|
||||
self.bus = [wire(name=prefix+"_"+str(i), index=i) for i in range(N)]
|
||||
self.N = N
|
||||
|
||||
# C GENERATION #
|
||||
# C CODE GENERATION #
|
||||
def get_wire_value_c(self, offset: int = 0):
|
||||
return self.bus[offset].get_wire_value_c(offset=offset)
|
||||
|
||||
@ -55,3 +70,7 @@ class bus():
|
||||
return f" uint64_t {self.prefix} = 0;\n"
|
||||
else:
|
||||
return f" uint8_t {self.prefix} = 0;\n"
|
||||
|
||||
# VERILOG CODE GENERATION #
|
||||
def get_wire_value_v(self, offset: int = 0, array: bool = False):
|
||||
return self.bus[offset].get_wire_value_v(offset=offset, array=array)
|
||||
|
Loading…
x
Reference in New Issue
Block a user