Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 4 additions & 13 deletions quicklogic/common/cmake/quicklogic_jlink.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -66,24 +66,15 @@ function(ADD_JLINK_OUTPUT)
add_file_target(FILE ${WORK_DIR_REL}/${IOMUX_CONFIG} GENERATED)

# Convert the binary bitstream to a JLINK script
set(BIT_AS_JLINK "top.bit.jlink")

add_custom_command(
OUTPUT ${WORK_DIR}/${BIT_AS_JLINK}
COMMAND ${PYTHON3} -m quicklogic_fasm.bitstream_to_jlink ${BITSTREAM_LOC} ${WORK_DIR}/${BIT_AS_JLINK}
DEPENDS ${BITSTREAM}
)

add_file_target(FILE ${WORK_DIR_REL}/${BIT_AS_JLINK} GENERATED)

# Concatenate th bitstream JLink script and the IOMUX config JLink script
set(OUT_JLINK "top.jlink")
add_custom_command(
OUTPUT ${WORK_DIR}/${OUT_JLINK}
COMMAND cat ${WORK_DIR}/${BIT_AS_JLINK} ${WORK_DIR}/${IOMUX_CONFIG} >${WORK_DIR}/${OUT_JLINK}
DEPENDS ${WORK_DIR}/${BIT_AS_JLINK} ${WORK_DIR}/${IOMUX_CONFIG}
COMMAND ${PYTHON3} -m quicklogic_fasm.bitstream_to_jlink ${BITSTREAM_LOC} ${WORK_DIR}/${OUT_JLINK}
DEPENDS ${BITSTREAM} ${WORK_DIR}/${IOMUX_CONFIG}
)

add_file_target(FILE ${WORK_DIR_REL}/${OUT_JLINK} GENERATED)

add_custom_target(${PARENT}_jlink DEPENDS ${WORK_DIR}/${OUT_JLINK})


Expand Down
18 changes: 5 additions & 13 deletions quicklogic/common/cmake/quicklogic_openocd.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -66,24 +66,16 @@ function(ADD_OPENOCD_OUTPUT)
add_file_target(FILE ${WORK_DIR_REL}/${IOMUX_CONFIG} GENERATED)

# Convert the binary bitstream to a OpenOCD script
set(BIT_AS_OPENOCD "top.bit.openocd")

add_custom_command(
OUTPUT ${WORK_DIR}/${BIT_AS_OPENOCD}
COMMAND ${PYTHON3} -m quicklogic_fasm.bitstream_to_openocd ${BITSTREAM_LOC} ${WORK_DIR}/${BIT_AS_OPENOCD}
DEPENDS ${BITSTREAM}
)

add_file_target(FILE ${WORK_DIR_REL}/${BIT_AS_OPENOCD} GENERATED)

# Concatenate the bitstream OpenOCD script and the IOMUX config OpenOCD script
set(OUT_OPENOCD "top.openocd")

add_custom_command(
OUTPUT ${WORK_DIR}/${OUT_OPENOCD}
COMMAND head -n -1 ${WORK_DIR}/${BIT_AS_OPENOCD} > ${WORK_DIR}/${OUT_OPENOCD} && cat ${WORK_DIR}/${IOMUX_CONFIG} >> ${WORK_DIR}/${OUT_OPENOCD} && echo '}' >> ${WORK_DIR}/${OUT_OPENOCD}
DEPENDS ${WORK_DIR}/${BIT_AS_OPENOCD} ${WORK_DIR}/${IOMUX_CONFIG}
COMMAND ${PYTHON3} -m quicklogic_fasm.bitstream_to_openocd ${BITSTREAM_LOC} ${WORK_DIR}/${OUT_OPENOCD}
DEPENDS ${BITSTREAM} ${WORK_DIR}/${IOMUX_CONFIG}
)

add_file_target(FILE ${WORK_DIR_REL}/${OUT_OPENOCD} GENERATED)

add_custom_target(${PARENT}_openocd DEPENDS ${WORK_DIR}/${OUT_OPENOCD})

endfunction()
188 changes: 149 additions & 39 deletions quicklogic/pp3/utils/eos_s3_iomux_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,57 @@
"SDIOMUX": ["PB-SDIOMUX", ],
}

# Default configuration of the IOMUX pad
PAD_DEFAULT = {
# Default configuration of the specific IOMUX pads
PADS_1 = {
2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 18, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 35, 37, 40, 41, 42, 43
}
PAD_DEFAULTS_1 = {
"func_sel": 0,
"ctrl_sel": "A0",
"mode": "output",
"pull": "none",
"drive": 4,
"slew": "slow",
"schmitt": 0
}
PADS_2 = {6, 14, 15, 17, 34, 36, 38, 39, 44, 45}
PAD_DEFAULTS_2 = {
"func_sel": 0,
"ctrl_sel": "others",
"mode": "output",
"pull": "none",
"drive": 4,
"slew": "slow",
"schmitt": 0
}
PADS_3 = {8, 9, 19, 20}
PAD_DEFAULTS_3 = {
"func_sel": 0,
"ctrl_sel": "A0",
"mode": "inout",
"pull": "down",
"drive": 4,
"slew": "slow",
"schmitt": 0
}
PADS_4 = {0, 1}
PAD_DEFAULTS_4 = {
"func_sel": 0,
"ctrl_sel": 0,
"mode": "none",
"ctrl_sel": "A0",
"mode": "output",
"pull": "up",
"drive": 4,
"slew": "slow",
"schmitt": 0
}
PADS_5 = {16}
PAD_DEFAULTS_5 = {
"func_sel": 0,
"ctrl_sel": "A0",
"mode": "inout",
"pull": "none",
"drive": 2,
"drive": 4,
"slew": "slow",
"schmitt": 0
}
Expand All @@ -53,9 +97,6 @@ def generate_iomux_register_content(config):
pad = int(pad)
reg = 0

# Patch default settings with settings read from the config file
pad_cfg = dict(PAD_DEFAULT, **pad_cfg)

func_sel = pad_cfg["func_sel"]
assert func_sel in [0, 1], func_sel
reg |= func_sel
Expand Down Expand Up @@ -137,6 +178,55 @@ def generate_iomux_register_content(config):
return iomux_regs


def get_pad_no(pad_alias):
pad = None

match = re.match(r"^IO_([0-9]+)$", pad_alias)
if match is not None:
pad = int(match.group(1))

if pad is None or pad < 0 or pad >= 46:
print("Pad not found or out of range: {}".format(pad))
return -1

return pad


def pad_defconfig_lookup(pad):
pad_config = None

if pad in PADS_1:
pad_config = PAD_DEFAULTS_1
elif pad in PADS_2:
pad_config = PAD_DEFAULTS_2
elif pad in PADS_3:
pad_config = PAD_DEFAULTS_3
elif pad in PADS_4:
pad_config = PAD_DEFAULTS_4
elif pad in PADS_5:
pad_config = PAD_DEFAULTS_5
else:
raise ValueError(
"Unknown default IOMUX configuration for pad: {}".format(pad)
)

return pad_config


def prepare_default_config(pad_map):
config = {"pads": {}}

# Populate IO config with default configuration for each pad
for pin in pad_map.items():
pad = get_pad_no(pin[1])
if (pad == -1):
continue

config["pads"][str(pad)] = pad_defconfig_lookup(pad)

return config


# =============================================================================


Expand Down Expand Up @@ -179,16 +269,44 @@ def main():
required=True,
help='Pin map CSV file'
)
parser.add_argument(
"--default-config",
action="store_true",
help='generate default IOMUX config that will be overlaid by the design'
)

parser.add_argument(
"--output-format",
default=None,
type=str,
help='Output format of IOMUX commands (openocd/jlink)'
help='Output format of IOMUX commands (openocd/jlink/binary)'
)

args = parser.parse_args()

pad_map = {}
pad_alias_map = {}

# Read pinmap
for pin_map_entry in csv.DictReader(args.map):

if pin_map_entry['type'] not in IOB_TYPES:
continue

name = pin_map_entry['name']
alias = ""
if 'alias' in pin_map_entry:
alias = pin_map_entry['alias']
pad_alias_map[alias] = name
pad_map[name] = alias
else:
pad_map[name] = name

if (args.default_config):
config = prepare_default_config(pad_map)
else:
config = {"pads": {}}

# Read the requested configurtion from a JSON file
if args.json is not None:

Expand All @@ -197,7 +315,17 @@ def main():
exit(-1)

with open(args.json, "r") as fp:
config = json.load(fp)
json_config = json.load(fp)

# Overlay default config
for design_pad, pad_config in json_config["pads"].items():
if (args.default_config):
config["pads"][str(design_pad)] = dict(
config["pads"][str(design_pad)], **pad_config
)
else:
defconfig = pad_defconfig_lookup(int(design_pad))
config["pads"][design_pad] = dict(defconfig, **pad_config)

# Generate the config according to the EBLIF netlist and PCF constraints.
else:
Expand All @@ -206,23 +334,6 @@ def main():
print("Use either '--json' or '--pcf' + '--eblif' options!")
exit(-1)

pad_map = {}
pad_alias_map = {}

for pin_map_entry in csv.DictReader(args.map):

if pin_map_entry['type'] not in IOB_TYPES:
continue

name = pin_map_entry['name']
alias = ""
if 'alias' in pin_map_entry:
alias = pin_map_entry['alias']
pad_alias_map[alias] = name
pad_map[name] = alias
else:
pad_map[name] = name

# Read and parse PCF
with open(args.pcf, "r") as fp:
pcf = list(parse_simple_pcf(fp))
Expand All @@ -231,9 +342,6 @@ def main():
with open(args.eblif, "r") as fp:
eblif = parse_blif(fp)

# Build the config
config = {"pads": {}}

eblif_inputs = eblif["inputs"]["args"]
eblif_outputs = eblif["outputs"]["args"]

Expand Down Expand Up @@ -261,19 +369,14 @@ def main():
if pad_name in pad_alias_map:
pad_alias = pad_name

pad = None

match = re.match(r"^IO_([0-9]+)$", pad_alias)
if match is not None:
pad = int(match.group(1))

# Pad not found or out of range
if pad is None or pad < 0 or pad >= 46:
pad_no = get_pad_no(pad_alias)
if (pad_no == -1):
continue

# Detect inouts:
is_inout_in = constraint.net + '_$inp' in eblif_inputs
is_inout_out = constraint.net + '_$out' in eblif_outputs

if is_inout_in and is_inout_out:
pad_config = {
"ctrl_sel": "fabric",
Expand All @@ -296,7 +399,14 @@ def main():
else:
assert False, (constraint.net, constraint.pad)

config["pads"][str(pad)] = pad_config
# Overlay default config
if (args.default_config):
config["pads"][str(pad_no)] = dict(
config["pads"][str(pad_no)], **pad_config
)
else:
defconfig = pad_defconfig_lookup(pad_no)
config["pads"][str(pad_no)] = dict(defconfig, **pad_config)

# Convert the config to IOMUX register content
iomux_regs = generate_iomux_register_content(config)
Expand Down