Skip to content

Commit

Permalink
feat: add experimental IHP support
Browse files Browse the repository at this point in the history
  • Loading branch information
htfab committed Sep 24, 2024
1 parent dd77f85 commit bcbca89
Show file tree
Hide file tree
Showing 19 changed files with 4,035 additions and 48 deletions.
47 changes: 46 additions & 1 deletion config_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import logging
import os
import re
import subprocess
import tkinter
from collections.abc import Iterable

Expand Down Expand Up @@ -42,13 +43,43 @@ def py_set(key: str, value: str | None = None):


def read_json_config(file: str):
return json.load(open(file))
config = json.load(open(file))
config.pop("//", None)
return config


def read_yaml_config(file: str):
return yaml.safe_load(open(file))


def read_mk_config(file: str, design_dir: str | None = None):
logging.warning(
"Reading Makefile configuration files is an experimental feature and could be removed"
)
env_pre = {} if design_dir is None else {"DESIGN_HOME": design_dir}
mk_cg = "all:\n\t@env"
mk_tg = f"-include {file}\n{mk_cg}"
env_cg = subprocess.run(
"make -f -",
shell=True,
env=env_pre,
input=mk_cg,
capture_output=True,
text=True,
).stdout.strip()
env_tg = subprocess.run(
"make -f -",
shell=True,
env=env_pre,
input=mk_tg,
capture_output=True,
text=True,
).stdout.strip()
env_diff = set(env_tg.split("\n")) - set(env_cg.split("\n"))
config = dict(i.split("=", 1) for i in env_diff)
return config


def read_config(basename: str, formats: Iterable[str], design_dir: str | None = None):
for fmt in formats:
file = f"{basename}.{fmt}"
Expand All @@ -59,6 +90,8 @@ def read_config(basename: str, formats: Iterable[str], design_dir: str | None =
return read_json_config(file)
elif fmt == "yaml":
return read_yaml_config(file)
elif fmt == "mk":
return read_mk_config(file)
else:
raise ConfigFileError(f"Unexpected configuration file format: {fmt}")
raise ConfigFileError(
Expand Down Expand Up @@ -89,6 +122,16 @@ def write_yaml_config(config: dict, file: str):
yaml.safe_dump(config, f, default_flow_style=False, sort_keys=False)


def write_mk_config(config: dict, file: str):
with open(file, "w") as f:
for key, value in config.items():
if type(value) in (list, tuple):
value = " ".join(value)
if type(value) == str:
value = value.replace("dir::", "$(DESIGN_HOME)/")
print(f"export {key} = {value}", file=f)


def write_config(config: dict, basename: str, formats: Iterable[str]):
for fmt in formats:
file = f"{basename}.{fmt}"
Expand All @@ -98,5 +141,7 @@ def write_config(config: dict, basename: str, formats: Iterable[str]):
write_json_config(config, file)
elif fmt == "yaml":
write_yaml_config(config, file)
elif fmt == "mk":
write_mk_config(config, file)
else:
raise ConfigFileError("Unexpected configuration file format: {fmt}")
67 changes: 67 additions & 0 deletions ihp/categories.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{
"categories" : [
"AND",
"OR",
"NAND",
"NOR",
"Clock",
"Flip Flops",
"Multiplexer",
"Latch",
"Inverter",
"Buffer",
"Fill",
"Tap",
"Diode",
"Combo Logic",
"Misc"
],
"map" : {
"a21o" : 13,
"a21oi" : 13,
"a22oi" : 13,
"a221oi" : 13,
"and2" : 0,
"and3" : 0,
"and4" : 0,
"antennanp" : 12,
"buf" : 9,
"decap" : 10,
"dfrbp" : 5,
"dlhq" : 7,
"dlhr" : 7,
"dlhrq" : 7,
"dllr" : 7,
"dllrq" : 7,
"dlygate4sd1" : 14,
"dlygate4sd2" : 14,
"dlygate4sd3" : 14,
"ebufn" : 14,
"einvn" : 14,
"fill" : 10,
"inv" : 8,
"lgcp" : 4,
"mux2" : 6,
"mux4" : 6,
"nand2" : 2,
"nand2b" : 2,
"nand3" : 2,
"nand3b" : 2,
"nand4" : 2,
"nor2" : 3,
"nor2b" : 3,
"nor3" : 3,
"nor4" : 3,
"o21ai" : 13,
"or2" : 1,
"or3" : 1,
"or4" : 1,
"sdfbbp" : 5,
"sighold" : 14,
"slgcp" : 4,
"tiehi" : 14,
"tielo" : 14,
"xnor2" : 3,
"xor2" : 1
}
}
13 changes: 13 additions & 0 deletions ihp/constraint.sdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
set clk_name core_clock
set clk_port_name clk
set clk_period 20
set clk_io_pct 0.2

set clk_port [get_ports $clk_port_name]

create_clock -name $clk_name -period $clk_period $clk_port

set non_clock_inputs [lsearch -inline -all -not -exact [all_inputs] $clk_port]

set_input_delay [expr $clk_period * $clk_io_pct] -clock $clk_name $non_clock_inputs
set_output_delay [expr $clk_period * $clk_io_pct] -clock $clk_name [all_outputs]
Loading

0 comments on commit bcbca89

Please sign in to comment.