Skip to content
Merged
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
38 changes: 38 additions & 0 deletions .github/workflows/ci_nix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -262,3 +262,41 @@ jobs:
ciel enable --pdk-family ${{ matrix.pdk_family }} \
--pdk-root ./.ciel-${{ matrix.pdk_family }} \
${{ env.PDK_HASH }}
- name: Compile Verilog-A (ihp-sg13g2)
if: matrix.pdk_family == 'ihp-sg13g2'
run: |
wget https://fides.fe.uni-lj.si/openvaf/download/openvaf-reloaded-20260616-linux_x64.tar.gz
sudo tar -xvzf openvaf-reloaded-20260616-linux_x64.tar.gz -C /usr/bin/
cd ./.ciel-${{ matrix.pdk_family }}/${{ matrix.pdk }}/libs.tech/verilog-a; source openvaf-compile-va.sh
- name: Run Example (sky130)
if: matrix.pdk_family == 'sky130'
run: |
PDK_ROOT=$(realpath ./.ciel-${{ matrix.pdk_family }}) PDK=${{ matrix.pdk }} nix develop --command bash -c "cd examples/sky130_cace_ip__ota5t/; cace"
- name: Run Example (ihp-sg13g2)
if: matrix.pdk_family == 'ihp-sg13g2'
run: |
PDK_ROOT=$(realpath ./.ciel-${{ matrix.pdk_family }}) PDK=${{ matrix.pdk }} nix develop --command bash -c "cd examples/sg13g2_cace_ip__ota5t/; cace"
# Upload artifacts
- name: Upload Artifacts
if: matrix.pdk_family == 'sky130'
uses: actions/upload-artifact@v4
with:
name: runs_sky130
path: |
examples/sky130_cace_ip__ota5t/runs/
# Add summary
- name: Add Markdown to Step Summary
if: matrix.pdk_family == 'sky130'
run: cat examples/sky130_cace_ip__ota5t/runs/*/summary.md >> $GITHUB_STEP_SUMMARY
# Upload artifacts
- name: Upload Artifacts
if: matrix.pdk_family == 'ihp-sg13g2'
uses: actions/upload-artifact@v4
with:
name: runs_ihp-sg13g2
path: |
examples/sg13g2_cace_ip__ota5t/runs/
# Add summary
- name: Add Markdown to Step Summary
if: matrix.pdk_family == 'ihp-sg13g2'
run: cat examples/sg13g2_cace_ip__ota5t/runs/*/summary.md >> $GITHUB_STEP_SUMMARY
2 changes: 1 addition & 1 deletion cace/__version__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
__version__ = "2.10.0"
__version__ = "2.11.0"

if __name__ == "__main__":
print(__version__, end="")
4 changes: 3 additions & 1 deletion cace/cace_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,9 @@ def cli():
)

# Run the simulations
parameter_manager.run_parameters_async()
if parameter_manager.run_parameters_async():
err(f"CACE failed to dispatch parameters.")
sys.exit(1)

# Wait for completion
parameter_manager.join_parameters()
Expand Down
9 changes: 0 additions & 9 deletions cace/common/cace_read.py
Original file line number Diff line number Diff line change
Expand Up @@ -627,10 +627,6 @@ def validate_datasheet(datasheet):
# Find tool via old name or new ID
if cls := find_tool(toolname):

print("-----------")
print(toolname)
print(variables)

for config_var in cls.config_vars:
if config_var.name in variables:
value = variables[config_var.name]
Expand All @@ -641,11 +637,6 @@ def validate_datasheet(datasheet):

key_path = f"{param_name}.{cls.id}.{config_var.name}"

print(key_path)
print(value)
print(config_var.default)
print(config_var.type)

# Validate the types
config_var._Variable__process(
key_path=key_path,
Expand Down
54 changes: 21 additions & 33 deletions cace/parameter/parameter_klayout_drc.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,15 +141,15 @@ def implementation(self):
"drc",
f'{self.datasheet["PDK"]}_mr.drc',
)
if self.datasheet["PDK"].startswith("ihp-sg13g2"):
if self.datasheet["PDK"].startswith("ihp-sg13"):
drc_script_path = os.path.join(
get_pdk_root(),
self.datasheet["PDK"],
"libs.tech",
"klayout",
"tech",
"drc",
"run_drc.py",
f'{self.datasheet["PDK"]}.drc',
)

if not os.path.exists(drc_script_path):
Expand All @@ -158,7 +158,7 @@ def implementation(self):
self.jobs_sem.release(jobs)
return

report_file_path = os.path.join(self.param_dir, "report.xml")
report_file_path = os.path.join(self.param_dir, "drc_report.lyrdb")

arguments = []

Expand All @@ -178,41 +178,29 @@ def implementation(self):
f"thr={jobs}",
]

if self.datasheet["PDK"].startswith("ihp-sg13g2"):
if self.datasheet["PDK"].startswith("ihp-sg13"):
arguments = [
"-b",
"-r",
drc_script_path,
f"--topcell={projname}",
f"--path={os.path.abspath(layout_filepath)}",
f"--run_dir={self.param_dir}",
f"--mp={jobs}",
"-rd",
f"input={os.path.abspath(layout_filepath)}",
"-rd",
f"topcell={projname}",
"-rd",
f"report={report_file_path}",
"-rd",
f"threads={jobs}",
]

if self.config["args"]:
arguments.extend(self.config["args"])

# IHP has a python wrapper for running the DRC
returncode = self.run_subprocess(
"python3",
arguments,
cwd=self.param_dir,
)
if self.config["args"]:
arguments.extend(self.config["args"])

# The report is placed in a .lyrdb file
# - The name of this file depends on which rulesets were checked...
# - Only one report should remain after merging by run_drc.py
report_files = glob.glob(f"{self.param_dir}/*.lyrdb")
if len(report_files) > 0:
report_file_path = report_files[0]

else:
if self.config["args"]:
arguments.extend(self.config["args"])

returncode = self.run_subprocess(
"klayout",
arguments,
cwd=self.param_dir,
)
returncode = self.run_subprocess(
"klayout",
arguments,
cwd=self.param_dir,
)

# Free job(s) from the global jobs semaphore
self.jobs_sem.release(jobs)
Expand Down
20 changes: 7 additions & 13 deletions cace/parameter/parameter_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
generate_documentation,
)
from ..common.cace_regenerate import regenerate_netlists, regenerate_gds
from ..common.common import get_pdk_root

from ..logging import (
dbg,
Expand Down Expand Up @@ -487,10 +488,6 @@ def queue_parameter(

if cls := find_tool(toolname):

print("-----------")
print(toolname)
print(variables)

processed_variables = {}

for config_var in cls.config_vars:
Expand All @@ -503,11 +500,6 @@ def queue_parameter(

key_path = f"{pname}.{cls.id}.{config_var.name}"

print(key_path)
print(value)
print(config_var.default)
print(config_var.type)

# Validate the types
val = config_var._Variable__process(
key_path=key_path,
Expand All @@ -519,8 +511,6 @@ def queue_parameter(

processed_variables[config_var.name] = val

print(processed_variables)

new_sim_param = cls(
pname,
processed_variables,
Expand Down Expand Up @@ -644,6 +634,8 @@ def prepare_run_dir(self):
for run in remove:
shutil.rmtree(run)

info(f"PDK root is '{get_pdk_root()}'.")

def run_parameters_async(self):
"""Start a worker thread to start parameter threads"""

Expand All @@ -656,13 +648,13 @@ def run_parameters_async(self):
if not fullnetlistpath:
err("Failed to regenerate project netlist, aborting.")
self.cancel_parameters(True)
return
return 1

# If mag files are given as layout, regenerate the gds if needed
if regenerate_gds(self.datasheet, self.runtime_options):
err("Failed to regenerate GDSII layout from magic layout, aborting.")
self.cancel_parameters(True)
return
return 1

# Only start a new worker thread, if
# the previous one hasn't completed yet
Expand All @@ -671,6 +663,8 @@ def run_parameters_async(self):
self.worker_thread = threading.Thread(target=self.run_parameters_thread)
self.worker_thread.start()

return 0

def run_parameters_thread(self):
"""Called as a thread, starts the threads of queued parameters"""

Expand Down
7 changes: 4 additions & 3 deletions docs/source/examples/index.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# Examples

The following repositories contain example circuit designs, each having a `cace/` subdirectory with a specification input (the datasheet), and a set of testbench schematics which are used by CACE to measure all specified parameters, generate results, and analyze them to determine circuit performance over corners.
You can find examples using CACE in the `examples/` directory of the repository.

Example circuit repositories:
Each has a `cace/` subdirectory with a specification input (the datasheet), and a set of testbench schematics which are used by CACE to measure all specified parameters, generate results, and analyze them to determine circuit performance over corners.

### Community IP

| Design | Description | PDK |
|----------------------------|----------------------------|-----|
| [ota-5t](https://github.com/mole99/ota-5t/) | A simple 5-transistor OTA | Sky130A |
| [sky130_ef_ip__opamp](https://github.com/RTimothyEdwards/sky130_ef_ip__opamp) | Operational Amplifier | Sky130A |
| ... | ... |

Expand Down
7 changes: 7 additions & 0 deletions examples/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
netlist/
xschem/sim/
xschem/simulations/
runs/
cace/templates/*.spice
cace/templates/*.sym
docs/
6 changes: 6 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Examples

These are simple examples for using CACE for sky130 and ihp-sg13g2.

Please note that for ihp-sg13g2 you need to compile the simulation models first.
See `ihp-sg13g2/libs.tech/verilog-a/` for more information.
Loading
Loading