mirror of https://github.com/lnis-uofu/SOFA.git
[HDL] Update wrapper line generator to parse json data
This commit is contained in:
parent
329b6644f3
commit
27da78fe29
|
@ -18,7 +18,8 @@
|
|||
"fpga_gpio_input_name": "gfpga_pad_EMBEDDED_IO_HD_SOC_IN",
|
||||
"fpga_gpio_output_name": "gfpga_pad_EMBEDDED_IO_HD_SOC_OUT",
|
||||
"fpga_gpio_direction_name": "gfpga_pad_EMBEDDED_IO_HD_SOC_DIR",
|
||||
"mode_switch_pin_name": "wb_la_switch"
|
||||
"mode_switch_pin_name": "wb_la_switch",
|
||||
"inverted_mode_switch_pin_name": "wb_la_switch_b",
|
||||
"pins": [
|
||||
{
|
||||
"fpga_pin_type": "io"
|
||||
|
|
|
@ -54,9 +54,9 @@ pin_data = json.load(json_file)
|
|||
# Return pin range format is [LSB, MSB] as a list
|
||||
#####################################################################
|
||||
def parse_json_pin_range(json_range) :
|
||||
pin_range = json_range.split(':')
|
||||
assert(2 == len(pin_range))
|
||||
return pin_range
|
||||
pin_range_str = json_range.split(':')
|
||||
assert(2 == len(pin_range_str))
|
||||
return range(pin_range_str[0], pin_range_str[1] + 1)
|
||||
|
||||
#####################################################################
|
||||
# Generate wrapper lines
|
||||
|
@ -66,82 +66,170 @@ netlist_lines = []
|
|||
# Walk through the array containing the pin information
|
||||
for pin_info in pin_data['pins']:
|
||||
# Deposit a tab to respect the HDL coding indent
|
||||
curr_line = " "
|
||||
curr_line = ""
|
||||
# TODO: Check codes that ensure the pin index should match
|
||||
assert(0 < len(pin_info['caravel_pin_type']))
|
||||
assert(0 < len(pin_info['caravel_pin_index']))
|
||||
#
|
||||
# Branch on the types of connnections:
|
||||
# - FPGA I/O to Caravel GPIO
|
||||
if (("io" == pin_info['fpga_pin_type']) and ("gpio" == pin_info['caravel_pin_type'][0])):
|
||||
if (("io" == pin_info['fpga_pin_type']) \
|
||||
and (1 == len(pin_info['caravel_pin_type'])) \
|
||||
and ("gpio" == pin_info['caravel_pin_type'][0])):
|
||||
# Should have only 1 port in caravel
|
||||
assert(1 == len(pin_info['caravel_pin_type']))
|
||||
assert(1 == len(pin_info['caravel_pin_index']))
|
||||
# Get pin range
|
||||
fpga_io_pin_range = parse_json_pin_range(pin_info['fpga_pin_index'])
|
||||
# Connect all the input, output and direction port
|
||||
# FPGA input <- Caravel input
|
||||
# FPGA output -> Caravel output
|
||||
# FPGA direction -> Caravel direction
|
||||
curr_line += "assign " + pin_data['fpga_gpio_input_name']
|
||||
netlist_lines.append(curr_line + "\n")
|
||||
|
||||
if ((ipin < num_wishbone_pins) and (ipin < num_logic_analyzer_pins)):
|
||||
# If this is an input pin of wishbone interface, whose postfix is '_i', we use MUX
|
||||
# otherwise, this is an output pin, we just wire the input to logic analyzer
|
||||
if ((wishbone_pins[ipin].endswith("_i")) or (re.search(r'_i\[\d+\]$', wishbone_pins[ipin], re.M | re.I))):
|
||||
##############################################################
|
||||
# SOC INPUT will be directly driven by either
|
||||
# - the Wishbone input
|
||||
# or
|
||||
# - the logic analyzer input
|
||||
# through a multiplexer controlled by the signal 'wb_la_switch
|
||||
curr_line = " " + "sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_" + str(135 - ipin) + "_MUX (.S(wb_la_switch), .A1(" + str(
|
||||
wishbone_pins[ipin]) + "), .A0(" + str(logic_analyzer_pins[ipin][0]) + "), .X(gfpga_pad_EMBEDDED_IO_HD_SOC_IN[" + str(135 - ipin) + "]));"
|
||||
netlist_lines.append(curr_line + "\n")
|
||||
##############################################################
|
||||
# SOC OUTPUT will drive an output of logic analyzer
|
||||
# since this I/O is going to interface a Wishbone input only
|
||||
curr_line = " " + "assign " + \
|
||||
str(logic_analyzer_pins[ipin][1]) + \
|
||||
" = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[" + str(135 - ipin) + "];"
|
||||
netlist_lines.append(curr_line + "\n")
|
||||
elif ((wishbone_pins[ipin].endswith("_o")) or (re.search(r'_o\[\d+\]$', wishbone_pins[ipin], re.M | re.I))):
|
||||
##############################################################
|
||||
# SOC INPUT will be directly driven by logic analyzer
|
||||
# since this I/O is going to interface a Wishbone output only
|
||||
curr_line = " " + "assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[" + str(
|
||||
135 - ipin) + "] = " + str(logic_analyzer_pins[ipin][0]) + ";"
|
||||
netlist_lines.append(curr_line + "\n")
|
||||
##############################################################
|
||||
# SOC OUTPUT will drive the Wishbone output through a tri-state buffer
|
||||
# As the buffer is enabled by logic '0', we use the inverted 'wb_la_switch'
|
||||
curr_line = " " + "sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_" + str(135 - ipin) + "_DEMUX_WB (" + \
|
||||
".TE_B(wb_la_switch_b), " + \
|
||||
".A(" + "gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[" + str(135 - ipin) + "]), " + \
|
||||
".Z(" + str(wishbone_pins[ipin]) + ")" + \
|
||||
");"
|
||||
netlist_lines.append(curr_line + "\n")
|
||||
##############################################################
|
||||
# SOC OUTPUT will also drive the Logic Analyzer output through a tri-state buffer
|
||||
# As the buffer is enabled by logic '0', we use the 'wb_la_switch'
|
||||
curr_line = " " + "sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_" + str(135 - ipin) + "_DEMUX_LA (" + \
|
||||
".TE_B(wb_la_switch), " + \
|
||||
".A(" + "gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[" + str(135 - ipin) + "]), " + \
|
||||
".Z(" + str(logic_analyzer_pins[ipin][1]) + ")" + \
|
||||
");"
|
||||
netlist_lines.append(curr_line + "\n")
|
||||
caravel_io_pin_range = parse_json_pin_range(pin_info['caravel_pin_index'][0])
|
||||
assert(len(list(fpga_io_pin_range)) == len(list(caravel_io_pin_range)))
|
||||
for indices in zip(list(fpga_io_pin_range), list(caravel_io_pin_range)) :
|
||||
# Connect all the input, output and direction port
|
||||
# FPGA input <- Caravel input
|
||||
curr_line = "assign " + pin_data['fpga_gpio_input_name'] + "[" + indices[0] + "] = " \
|
||||
+ pin_data['caravel_gpio_input_name'] + "[" + indices[1] + "];";
|
||||
netlist_lines.append(curr_line + "\n")
|
||||
# FPGA output -> Caravel output
|
||||
curr_line = "assign " + pin_data['caravel_gpio_output_name'] + "[" + indices[1] + "] = " \
|
||||
+ pin_data['fpga_gpio_output_name'] + "[" + indices[0] + "];";
|
||||
netlist_lines.append(curr_line + "\n")
|
||||
# FPGA direction -> Caravel direction
|
||||
curr_line = "assign " + pin_data['caravel_gpio_direction_name'] + "[" + indices[1] + "] = " \
|
||||
+ pin_data['fpga_gpio_direction_name'] + "[" + indices[0] + "];";
|
||||
netlist_lines.append(curr_line + "\n")
|
||||
|
||||
elif ((ipin >= num_wishbone_pins) and (ipin < num_logic_analyzer_pins)):
|
||||
# - FPGA control input ports to Caravel GPIO
|
||||
if (("io" != pin_info['fpga_pin_type']) \
|
||||
and (1 == len(pin_info['caravel_pin_type'])) \
|
||||
and ("input" == pin_info['caravel_pin_type'][0])):
|
||||
# Should have only 1 port in caravel
|
||||
assert(1 == len(pin_info['caravel_pin_type']))
|
||||
assert(1 == len(pin_info['caravel_pin_index']))
|
||||
# Get pin range
|
||||
fpga_io_pin_range = parse_json_pin_range(pin_info['fpga_pin_index'])
|
||||
caravel_io_pin_range = parse_json_pin_range(pin_info['caravel_pin_index'][0])
|
||||
assert(len(list(fpga_io_pin_range)) == len(list(caravel_io_pin_range)))
|
||||
for indices in zip(list(fpga_io_pin_range), list(caravel_io_pin_range)) :
|
||||
# Connect the FPGA input port to the Caravel input
|
||||
curr_line = "assign " + pin_data['fpga_pin_type'] + "[" + indices[0] + "] = " \
|
||||
+ pin_data['caravel_gpio_input_name'] + "[" + indices[1] + "];";
|
||||
netlist_lines.append(curr_line + "\n")
|
||||
# Tie Caravel output port to logic '0'
|
||||
curr_line = "assign " + pin_data['caravel_gpio_output_name'] + "[" + indices[1] + "] = 1'b0;"
|
||||
netlist_lines.append(curr_line + "\n")
|
||||
# Tie Caravel direction port to logic '1'
|
||||
curr_line = "assign " + pin_data['caravel_gpio_direction_name'] + "[" + indices[1] + "] = 1'b1"
|
||||
netlist_lines.append(curr_line + "\n")
|
||||
|
||||
# - FPGA control output ports to Caravel GPIO
|
||||
if (("io" != pin_info['fpga_pin_type']) \
|
||||
and (1 == len(pin_info['caravel_pin_type'])) \
|
||||
and ("output" == pin_info['caravel_pin_type'][0])):
|
||||
# Should have only 1 port in caravel
|
||||
assert(1 == len(pin_info['caravel_pin_type']))
|
||||
assert(1 == len(pin_info['caravel_pin_index']))
|
||||
# Get pin range
|
||||
fpga_io_pin_range = parse_json_pin_range(pin_info['fpga_pin_index'])
|
||||
caravel_io_pin_range = parse_json_pin_range(pin_info['caravel_pin_index'][0])
|
||||
assert(len(list(fpga_io_pin_range)) == len(list(caravel_io_pin_range)))
|
||||
for indices in zip(list(fpga_io_pin_range), list(caravel_io_pin_range)) :
|
||||
# Bypass the Caravel input
|
||||
# Connect Caravel output port to FPGA control output
|
||||
curr_line = "assign " + pin_data['caravel_gpio_output_name'] + "[" + indices[1] + "] = " \
|
||||
+ pin_data['fpga_pin_type'] + "[" + indices[0] + "];";
|
||||
netlist_lines.append(curr_line + "\n")
|
||||
# Tie Caravel direction port to logic '0'
|
||||
curr_line = "assign " + pin_data['caravel_gpio_direction_name'] + "[" + indices[1] + "] = 1'b0"
|
||||
netlist_lines.append(curr_line + "\n")
|
||||
|
||||
# - FPGA I/O ports to Caravel logic analyzer I/O only
|
||||
if (("io" == pin_info['fpga_pin_type']) \
|
||||
and (1 == len(pin_info['caravel_pin_type'])) \
|
||||
and ("logic_analyzer_io" == pin_info['caravel_pin_type'][0])):
|
||||
# Should have only 1 port in caravel
|
||||
assert(1 == len(pin_info['caravel_pin_type']))
|
||||
assert(1 == len(pin_info['caravel_pin_index']))
|
||||
# Get pin range
|
||||
fpga_io_pin_range = parse_json_pin_range(pin_info['fpga_pin_index'])
|
||||
caravel_io_pin_range = parse_json_pin_range(pin_info['caravel_pin_index'][0])
|
||||
assert(len(list(fpga_io_pin_range)) == len(list(caravel_io_pin_range)))
|
||||
for indices in zip(list(fpga_io_pin_range), list(caravel_io_pin_range)) :
|
||||
##############################################################
|
||||
# SOC INPUT will be directly driven by logic analyzer
|
||||
# since this I/O is going to interface logic analyzer input only
|
||||
curr_line = "assign " + pin_data['fpga_gpio_input_name'] + "[" + indices[0] + "] = " \
|
||||
+ pin_data['caravel_logic_analyzer_input_name'] + "[" + indices[1] + "]" + ";"
|
||||
netlist_lines.append(curr_line + "\n")
|
||||
##############################################################
|
||||
# SOC OUTPUT will directly drive logic analyzer
|
||||
# since this I/O is going to interface logic analyzer output only
|
||||
curr_line = "assign " + pin_data['caravel_logic_analyzer_output_name'] + "[" + indices[1] + "]" \
|
||||
+ " = " + pin_data['fpga_gpio_output_name'] + "[" + indices[0] + "];"
|
||||
netlist_lines.append(curr_line + "\n")
|
||||
|
||||
# - FPGA I/O ports to Caravel logic analyzer I/O and Wishbone interface
|
||||
if (("io" == pin_info['fpga_pin_type']) \
|
||||
and (2 == len(pin_info['caravel_pin_type'])) \
|
||||
and ("logic_analyzer_io" == pin_info['caravel_pin_type'][0]) \
|
||||
and (pin_info['caravel_pin_type'][1].startswith("wishbone"))):
|
||||
# Should have only 2 port in caravel
|
||||
assert(2 == len(pin_info['caravel_pin_type']))
|
||||
assert(2 == len(pin_info['caravel_pin_index']))
|
||||
# Get pin range
|
||||
fpga_io_pin_range = parse_json_pin_range(pin_info['fpga_pin_index'])
|
||||
la_io_pin_range = parse_json_pin_range(pin_info['caravel_pin_index'][0])
|
||||
wb_io_pin_range = parse_json_pin_range(pin_info['caravel_pin_index'][1])
|
||||
assert(len(list(fpga_io_pin_range)) == len(list(la_io_pin_range)))
|
||||
assert(len(list(fpga_io_pin_range)) == len(list(wb_io_pin_range)))
|
||||
|
||||
# If this is an input pin of wishbone interface, whose postfix is '_i', we use MUX
|
||||
# otherwise, this is an output pin, we just wire the input to logic analyzer
|
||||
if (pin_info['caravel_pin_type'][1].endswith("_input")):
|
||||
for indices in zip(list(fpga_io_pin_range), list(la_io_pin_range), list(wb_la_pin_range)) :
|
||||
##############################################################
|
||||
# SOC INPUT will be directly driven by logic analyzer
|
||||
# since this I/O is going to interface logic analyzer input only
|
||||
curr_line = " " + "assign gfpga_pad_EMBEDDED_IO_HD_SOC_IN[" + str(
|
||||
135 - ipin) + "] = " + str(logic_analyzer_pins[ipin][0]) + ";"
|
||||
# SOC INPUT will be directly driven by either
|
||||
# - the Wishbone input
|
||||
# or
|
||||
# - the logic analyzer input
|
||||
# through a multiplexer controlled by the signal 'wb_la_switch
|
||||
curr_line = "sky130_fd_sc_hd__mux2_1 FPGA2SOC_IN_" + indices[0] + "_MUX (" \
|
||||
+ ".S(" + pin_data['mode_switch_pin_name'] + "), " \
|
||||
+ ".A1(" + pin_data[pin_info['caravel_pin_type'][1] + '_name'] + "[" + indices[2] + "]), " \
|
||||
+ ".A0(" + pin_data['caravel_logic_analyzer_input_name'] + indices[1] + "), " \
|
||||
+ ".X(" + pin_data['fpga_gpio_input_name'] + "[" + indices[0] + "])" \
|
||||
+ ");"
|
||||
netlist_lines.append(curr_line + "\n")
|
||||
##############################################################
|
||||
# SOC OUTPUT will directly drive logic analyzer
|
||||
# since this I/O is going to interface logic analyzer output only
|
||||
curr_line = " " + "assign " + \
|
||||
str(logic_analyzer_pins[ipin][1]) + \
|
||||
" = gfpga_pad_EMBEDDED_IO_HD_SOC_OUT[" + str(135 - ipin) + "];"
|
||||
# SOC OUTPUT will drive an output of logic analyzer
|
||||
# since this I/O is going to interface a Wishbone input only
|
||||
curr_line = "assign " + pin_data['caravel_logic_analyzer_output_name'] + "[" + indices[1] + "]" \
|
||||
+ " = " + pin_data['fpga_gpio_output_name'] + "[" + indices[0] + "];"
|
||||
netlist_lines.append(curr_line + "\n")
|
||||
elif (pin_info['caravel_pin_type'][1].endswith("_output")):
|
||||
for indices in zip(list(fpga_io_pin_range), list(la_io_pin_range), list(wb_la_pin_range)) :
|
||||
##############################################################
|
||||
# SOC INPUT will be directly driven by logic analyzer
|
||||
# since this I/O is going to interface a Wishbone output only
|
||||
curr_line = "assign " + pin_data['fpga_gpio_input_name'] + "[" + indices[0] + "] = " \
|
||||
+ pin_data['caravel_logic_analyzer_input_name'] + "[" + indices[1] + "];"
|
||||
netlist_lines.append(curr_line + "\n")
|
||||
##############################################################
|
||||
# SOC OUTPUT will drive the Wishbone output through a tri-state buffer
|
||||
# As the buffer is enabled by logic '0', we use the inverted 'wb_la_switch'
|
||||
curr_line = "sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_" + indices[0] + "_DEMUX_WB (" \
|
||||
+ ".TE_B(" + pin_data['inverted_mode_switch_pin_name'] + "), " \
|
||||
+ ".A(" + pin_data['fpga_gpio_output_name'] + "[" + indices[0] + "]), " \
|
||||
+ ".Z(" + pin_data[pin_info['caravel_pin_type'][1] + '_name'] + "[" + indices[2] + "])" \
|
||||
+ ");"
|
||||
netlist_lines.append(curr_line + "\n")
|
||||
##############################################################
|
||||
# SOC OUTPUT will also drive the Logic Analyzer output through a tri-state buffer
|
||||
# As the buffer is enabled by logic '0', we use the 'wb_la_switch'
|
||||
curr_line = "sky130_fd_sc_hd__ebufn_4 FPGA2SOC_OUT_" + indices[0] + "_DEMUX_LA (" \
|
||||
+ ".TE_B(" + pin_data['mode_switch_pin_name'] + "), " \
|
||||
+ ".A(" + pin_data['fpga_gpio_output_name'] + "[" + indices[0] + "]), " \
|
||||
+ ".Z(" + pin_data['caravel_logic_analyzer_output_name'] + "[" + indices[1] + "])" \
|
||||
+ ");"
|
||||
netlist_lines.append(curr_line + "\n")
|
||||
|
||||
if isfile(args.output_verilog):
|
||||
|
|
Loading…
Reference in New Issue