mirror of https://github.com/lnis-uofu/SOFA.git
Merge pull request #65 from lnis-uofu/xt_dev
Bug fix in the custom cell code generator
This commit is contained in:
commit
00b1740b44
|
@ -58,9 +58,9 @@ custom_nlist = open(args.output_verilog, "w")
|
||||||
#######################################################################
|
#######################################################################
|
||||||
# A function to generate Verilog codes for a MUX3 custom cell
|
# A function to generate Verilog codes for a MUX3 custom cell
|
||||||
# Given an input index
|
# Given an input index
|
||||||
def generate_verilog_codes_custom_cell_mux3(first_input_index, instance_index):
|
def generate_verilog_codes_custom_cell_mux3(first_input_index, instance_index, add_inverter_follower):
|
||||||
lines = []
|
lines = []
|
||||||
|
# Instanciate a 3-input MUX cell
|
||||||
lines.append("\tscs8hd_muxinv3_1 scs8hd_muxinv3_1_" + str(instance_index) + "(")
|
lines.append("\tscs8hd_muxinv3_1 scs8hd_muxinv3_1_" + str(instance_index) + "(")
|
||||||
lines.append("\t .Q1(in[" + str(first_input_index) + "]),")
|
lines.append("\t .Q1(in[" + str(first_input_index) + "]),")
|
||||||
lines.append("\t .Q2(in[" + str(first_input_index + 1) + "]),")
|
lines.append("\t .Q2(in[" + str(first_input_index + 1) + "]),")
|
||||||
|
@ -71,17 +71,28 @@ def generate_verilog_codes_custom_cell_mux3(first_input_index, instance_index):
|
||||||
lines.append("\t .S1B(mem_inv[" + str(first_input_index + 1) + "]),")
|
lines.append("\t .S1B(mem_inv[" + str(first_input_index + 1) + "]),")
|
||||||
lines.append("\t .S2(mem[" + str(first_input_index + 2) + "]),")
|
lines.append("\t .S2(mem[" + str(first_input_index + 2) + "]),")
|
||||||
lines.append("\t .S2B(mem_inv[" + str(first_input_index + 2) + "]),")
|
lines.append("\t .S2B(mem_inv[" + str(first_input_index + 2) + "]),")
|
||||||
|
if (add_inverter_follower):
|
||||||
|
lines.append("\t .Z(out_inv[0])")
|
||||||
|
else:
|
||||||
lines.append("\t .Z(out[0])")
|
lines.append("\t .Z(out[0])")
|
||||||
lines.append("\t );")
|
lines.append("\t );")
|
||||||
|
|
||||||
|
# Instanciate an inverter follower to pair the MUX cells (which has input inverters)
|
||||||
|
if (add_inverter_follower):
|
||||||
|
lines.append("\tsky130_fd_sc_hd__inv_1 scs8hd_muxinv3_1_inv_follower" + str(instance_index) + "(")
|
||||||
|
lines.append("\t .A(out_inv[0]),")
|
||||||
|
lines.append("\t .Y(out[0])")
|
||||||
|
lines.append("\t );")
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
# A function to generate Verilog codes for a MUX3 custom cell
|
# A function to generate Verilog codes for a MUX3 custom cell
|
||||||
# Given an input index
|
# Given an input index
|
||||||
def generate_verilog_codes_custom_cell_mux2(first_input_index, instance_index):
|
def generate_verilog_codes_custom_cell_mux2(first_input_index, instance_index, add_inverter_follower):
|
||||||
lines = []
|
lines = []
|
||||||
|
|
||||||
|
# Instanciate a 2-input MUX cell
|
||||||
lines.append("\tscs8hd_muxinv2_1 scs8hd_muxinv2_1_" + str(instance_index) + "(")
|
lines.append("\tscs8hd_muxinv2_1 scs8hd_muxinv2_1_" + str(instance_index) + "(")
|
||||||
lines.append("\t .Q1(in[" + str(first_input_index) + "]),")
|
lines.append("\t .Q1(in[" + str(first_input_index) + "]),")
|
||||||
lines.append("\t .Q2(in[" + str(first_input_index + 1) + "]),")
|
lines.append("\t .Q2(in[" + str(first_input_index + 1) + "]),")
|
||||||
|
@ -89,9 +100,19 @@ def generate_verilog_codes_custom_cell_mux2(first_input_index, instance_index):
|
||||||
lines.append("\t .S0B(mem_inv[" + str(first_input_index) + "]),")
|
lines.append("\t .S0B(mem_inv[" + str(first_input_index) + "]),")
|
||||||
lines.append("\t .S1(mem[" + str(first_input_index + 1) + "]),")
|
lines.append("\t .S1(mem[" + str(first_input_index + 1) + "]),")
|
||||||
lines.append("\t .S1B(mem_inv[" + str(first_input_index + 1) + "]),")
|
lines.append("\t .S1B(mem_inv[" + str(first_input_index + 1) + "]),")
|
||||||
|
if (add_inverter_follower):
|
||||||
|
lines.append("\t .Z(out_inv[0])")
|
||||||
|
else:
|
||||||
lines.append("\t .Z(out[0])")
|
lines.append("\t .Z(out[0])")
|
||||||
lines.append("\t );")
|
lines.append("\t );")
|
||||||
|
|
||||||
|
# Instanciate an inverter follower to pair the MUX cells (which has input inverters)
|
||||||
|
if (add_inverter_follower):
|
||||||
|
lines.append("\tsky130_fd_sc_hd__inv_1 scs8hd_muxinv2_1_inv_follower" + str(instance_index) + "(")
|
||||||
|
lines.append("\t .A(out_inv[0]),")
|
||||||
|
lines.append("\t .Y(out[0])")
|
||||||
|
lines.append("\t );")
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
|
@ -116,8 +137,12 @@ def generate_verilog_codes_standard_cell_mux2(first_input_index, instance_index)
|
||||||
# In this case, an standard cell will be outputted
|
# In this case, an standard cell will be outputted
|
||||||
# - If the memory size is larger than 1, the input size should be the same
|
# - If the memory size is larger than 1, the input size should be the same
|
||||||
# as memory size. In this case, we will output custom cells
|
# as memory size. In this case, we will output custom cells
|
||||||
def write_custom_mux_cells_to_file(custom_nlist, input_size, mem_size):
|
def write_custom_mux_cells_to_file(custom_nlist, input_size, mem_size, add_inverter_follower):
|
||||||
lines = []
|
lines = []
|
||||||
|
|
||||||
|
if (add_inverter_follower):
|
||||||
|
lines.append("wire [0:0] out_inv;")
|
||||||
|
|
||||||
if (1 == mem_size):
|
if (1 == mem_size):
|
||||||
assert(2 == input_size)
|
assert(2 == input_size)
|
||||||
# Output a standard cell, currently we support HD cell MUX2
|
# Output a standard cell, currently we support HD cell MUX2
|
||||||
|
@ -132,17 +157,17 @@ def write_custom_mux_cells_to_file(custom_nlist, input_size, mem_size):
|
||||||
# - a few MUX2 cells
|
# - a few MUX2 cells
|
||||||
if (1 == input_size % 2):
|
if (1 == input_size % 2):
|
||||||
assert(3 <= input_size)
|
assert(3 <= input_size)
|
||||||
for line in generate_verilog_codes_custom_cell_mux3(0, 0):
|
for line in generate_verilog_codes_custom_cell_mux3(0, 0, add_inverter_follower):
|
||||||
lines.append(line)
|
lines.append(line)
|
||||||
for mux2_inst in range(int((input_size - 3) / 2)):
|
for mux2_inst in range(int((input_size - 3) / 2)):
|
||||||
for line in generate_verilog_codes_custom_cell_mux2(3 + 2 * mux2_inst, mux2_inst):
|
for line in generate_verilog_codes_custom_cell_mux2(3 + 2 * mux2_inst, mux2_inst, add_inverter_follower):
|
||||||
lines.append(line)
|
lines.append(line)
|
||||||
# - If the input size is an even number, we will use
|
# - If the input size is an even number, we will use
|
||||||
# - a few MUX2 cells
|
# - a few MUX2 cells
|
||||||
else:
|
else:
|
||||||
assert (0 == input_size % 2)
|
assert (0 == input_size % 2)
|
||||||
for mux2_inst in range(int(input_size / 2)):
|
for mux2_inst in range(int(input_size / 2)):
|
||||||
for line in generate_verilog_codes_custom_cell_mux2(2 * mux2_inst, mux2_inst):
|
for line in generate_verilog_codes_custom_cell_mux2(2 * mux2_inst, mux2_inst, add_inverter_follower):
|
||||||
lines.append(line)
|
lines.append(line)
|
||||||
|
|
||||||
# Output lines to file
|
# Output lines to file
|
||||||
|
@ -154,6 +179,7 @@ with open(args.template_netlist, "r") as wp:
|
||||||
template_nlist = wp.readlines()
|
template_nlist = wp.readlines()
|
||||||
# A flag for write the current line or skip
|
# A flag for write the current line or skip
|
||||||
output_action = "copy"
|
output_action = "copy"
|
||||||
|
mux_structure = "1level"
|
||||||
input_size = 0
|
input_size = 0
|
||||||
mem_size = 0
|
mem_size = 0
|
||||||
for line_num, curr_line in enumerate(template_nlist):
|
for line_num, curr_line in enumerate(template_nlist):
|
||||||
|
@ -168,6 +194,12 @@ with open(args.template_netlist, "r") as wp:
|
||||||
mem_size = int(re.findall("input(\d+)_mem(\d+)\(", curr_line)[0][1])
|
mem_size = int(re.findall("input(\d+)_mem(\d+)\(", curr_line)[0][1])
|
||||||
assert(input_size > 0)
|
assert(input_size > 0)
|
||||||
assert(mem_size > 0)
|
assert(mem_size > 0)
|
||||||
|
# Find the MUX structure levels
|
||||||
|
if (re.search("1level", curr_line)):
|
||||||
|
mux_structure = "1level"
|
||||||
|
else:
|
||||||
|
assert(re.search("2level", curr_line))
|
||||||
|
mux_structure = "2level"
|
||||||
# Change status indicating that we are now inside a module
|
# Change status indicating that we are now inside a module
|
||||||
output_action = "copy"
|
output_action = "copy"
|
||||||
|
|
||||||
|
@ -179,7 +211,7 @@ with open(args.template_netlist, "r") as wp:
|
||||||
# Reaching the end of the current module
|
# Reaching the end of the current module
|
||||||
# Now output the custom cell instanciation
|
# Now output the custom cell instanciation
|
||||||
if (curr_line.startswith("endmodule")):
|
if (curr_line.startswith("endmodule")):
|
||||||
write_custom_mux_cells_to_file(custom_nlist, input_size, mem_size)
|
write_custom_mux_cells_to_file(custom_nlist, input_size, mem_size, "1level" != mux_structure)
|
||||||
output_action = "copy"
|
output_action = "copy"
|
||||||
|
|
||||||
if ("skip" != output_action):
|
if ("skip" != output_action):
|
||||||
|
|
Loading…
Reference in New Issue