Upload folder using huggingface_hub
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .gitattributes +3 -0
- Dockerfile +110 -0
- README.md +163 -6
- __init__.py +16 -0
- client.py +122 -0
- inference.py +504 -0
- models.py +164 -0
- obj_dir/Vsim +3 -0
- obj_dir/Vsim.cpp +137 -0
- obj_dir/Vsim.h +89 -0
- obj_dir/Vsim.mk +66 -0
- obj_dir/Vsim__ALL.a +0 -0
- obj_dir/Vsim__ALL.cpp +11 -0
- obj_dir/Vsim__ALL.d +15 -0
- obj_dir/Vsim__ALL.o +0 -0
- obj_dir/Vsim__Syms.h +40 -0
- obj_dir/Vsim__Syms__Slow.cpp +28 -0
- obj_dir/Vsim__TraceDecls__0__Slow.cpp +12 -0
- obj_dir/Vsim__Trace__0.cpp +52 -0
- obj_dir/Vsim__Trace__0__Slow.cpp +95 -0
- obj_dir/Vsim___024root.h +52 -0
- obj_dir/Vsim___024root__0.cpp +323 -0
- obj_dir/Vsim___024root__0__Slow.cpp +166 -0
- obj_dir/Vsim___024root__Slow.cpp +24 -0
- obj_dir/Vsim__main.cpp +40 -0
- obj_dir/Vsim__pch.h +27 -0
- obj_dir/Vsim__ver.d +1 -0
- obj_dir/Vsim__verFiles.dat +24 -0
- obj_dir/Vsim_classes.mk +57 -0
- obj_dir/verilated.d +12 -0
- obj_dir/verilated.o +3 -0
- obj_dir/verilated_threads.d +8 -0
- obj_dir/verilated_threads.o +0 -0
- obj_dir/verilated_timing.d +8 -0
- obj_dir/verilated_timing.o +0 -0
- obj_dir/verilated_vcd_c.d +12 -0
- obj_dir/verilated_vcd_c.o +3 -0
- openenv.yaml +7 -0
- openenv_chipforge.egg-info/PKG-INFO +12 -0
- openenv_chipforge.egg-info/SOURCES.txt +19 -0
- openenv_chipforge.egg-info/dependency_links.txt +1 -0
- openenv_chipforge.egg-info/entry_points.txt +2 -0
- openenv_chipforge.egg-info/requires.txt +8 -0
- openenv_chipforge.egg-info/top_level.txt +1 -0
- pyproject.toml +42 -0
- server/__init__.py +11 -0
- server/app.py +84 -0
- server/chipforge_environment.py +789 -0
- server/tasks/easy/01_inverter_semicolon/design_buggy.v +30 -0
- server/tasks/easy/01_inverter_semicolon/design_golden.v +30 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,6 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
obj_dir/Vsim filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
obj_dir/verilated.o filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
obj_dir/verilated_vcd_c.o filter=lfs diff=lfs merge=lfs -text
|
Dockerfile
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# This source code is licensed under the BSD-style license found in the
|
| 5 |
+
# LICENSE file in the root directory of this source tree.
|
| 6 |
+
|
| 7 |
+
# Multi-stage build using openenv-base
|
| 8 |
+
# This Dockerfile is flexible and works for both:
|
| 9 |
+
# - In-repo environments (with local OpenEnv sources)
|
| 10 |
+
# - Standalone environments (with openenv from PyPI/Git)
|
| 11 |
+
# The build script (openenv build) handles context detection and sets appropriate build args.
|
| 12 |
+
|
| 13 |
+
ARG BASE_IMAGE=ghcr.io/meta-pytorch/openenv-base:latest
|
| 14 |
+
FROM ${BASE_IMAGE} AS builder
|
| 15 |
+
|
| 16 |
+
WORKDIR /app
|
| 17 |
+
|
| 18 |
+
# OSS CAD Suite release to install into the image.
|
| 19 |
+
ARG OSS_CAD_SUITE_VERSION=20260407
|
| 20 |
+
ARG TARGETARCH
|
| 21 |
+
|
| 22 |
+
# Ensure git and perl are available (required for installing dependencies from VCS and running Verilator)
|
| 23 |
+
RUN apt-get update && \
|
| 24 |
+
apt-get install -y --no-install-recommends git perl perl-modules-5.40 && \
|
| 25 |
+
rm -rf /var/lib/apt/lists/*
|
| 26 |
+
|
| 27 |
+
# Install OSS CAD Suite so tools like yosys are available in the container.
|
| 28 |
+
RUN set -eux; \
|
| 29 |
+
case "${TARGETARCH}" in \
|
| 30 |
+
arm64) asset_arch=arm64 ;; \
|
| 31 |
+
amd64) asset_arch=x64 ;; \
|
| 32 |
+
*) echo "Unsupported target architecture: ${TARGETARCH}" && exit 1 ;; \
|
| 33 |
+
esac; \
|
| 34 |
+
archive="/tmp/oss-cad-suite.tgz"; \
|
| 35 |
+
curl -fsSL -o "${archive}" \
|
| 36 |
+
"https://github.com/YosysHQ/oss-cad-suite-build/releases/download/2026-04-07/oss-cad-suite-linux-${asset_arch}-${OSS_CAD_SUITE_VERSION}.tgz"; \
|
| 37 |
+
top_level_dir="$(tar -tzf "${archive}" | head -n 1 | cut -d/ -f1)"; \
|
| 38 |
+
tar -xzf "${archive}" -C /opt; \
|
| 39 |
+
if [ "${top_level_dir}" != "oss-cad-suite" ]; then \
|
| 40 |
+
mv "/opt/${top_level_dir}" /opt/oss-cad-suite; \
|
| 41 |
+
fi; \
|
| 42 |
+
rm -f "${archive}"
|
| 43 |
+
|
| 44 |
+
# Build argument to control whether we're building standalone or in-repo
|
| 45 |
+
ARG BUILD_MODE=in-repo
|
| 46 |
+
ARG ENV_NAME=chipforge
|
| 47 |
+
|
| 48 |
+
# Copy environment code (always at root of build context)
|
| 49 |
+
COPY . /app/env
|
| 50 |
+
|
| 51 |
+
# For in-repo builds, openenv is already vendored in the build context
|
| 52 |
+
# For standalone builds, openenv will be installed via pyproject.toml
|
| 53 |
+
WORKDIR /app/env
|
| 54 |
+
|
| 55 |
+
# Ensure uv is available (for local builds where base image lacks it)
|
| 56 |
+
RUN if ! command -v uv >/dev/null 2>&1; then \
|
| 57 |
+
curl -LsSf https://astral.sh/uv/install.sh | sh && \
|
| 58 |
+
mv /root/.local/bin/uv /usr/local/bin/uv && \
|
| 59 |
+
mv /root/.local/bin/uvx /usr/local/bin/uvx; \
|
| 60 |
+
fi
|
| 61 |
+
|
| 62 |
+
# Install dependencies using uv sync
|
| 63 |
+
# If uv.lock exists, use it; otherwise resolve on the fly
|
| 64 |
+
RUN --mount=type=cache,target=/root/.cache/uv \
|
| 65 |
+
if [ -f uv.lock ]; then \
|
| 66 |
+
uv sync --frozen --no-install-project --no-editable; \
|
| 67 |
+
else \
|
| 68 |
+
uv sync --no-install-project --no-editable; \
|
| 69 |
+
fi
|
| 70 |
+
|
| 71 |
+
RUN --mount=type=cache,target=/root/.cache/uv \
|
| 72 |
+
if [ -f uv.lock ]; then \
|
| 73 |
+
uv sync --frozen --no-editable; \
|
| 74 |
+
else \
|
| 75 |
+
uv sync --no-editable; \
|
| 76 |
+
fi
|
| 77 |
+
|
| 78 |
+
# Final runtime stage
|
| 79 |
+
FROM ${BASE_IMAGE}
|
| 80 |
+
|
| 81 |
+
WORKDIR /app
|
| 82 |
+
|
| 83 |
+
# Install runtime Perl support for Verilator's wrapper script.
|
| 84 |
+
RUN apt-get update && \
|
| 85 |
+
apt-get install -y --no-install-recommends g++ make perl perl-modules-5.40 && \
|
| 86 |
+
rm -rf /var/lib/apt/lists/*
|
| 87 |
+
|
| 88 |
+
# Copy OSS CAD Suite into the runtime image.
|
| 89 |
+
COPY --from=builder /opt/oss-cad-suite /opt/oss-cad-suite
|
| 90 |
+
|
| 91 |
+
# Copy the virtual environment from builder
|
| 92 |
+
COPY --from=builder /app/env/.venv /app/.venv
|
| 93 |
+
|
| 94 |
+
# Copy the environment code
|
| 95 |
+
COPY --from=builder /app/env /app/env
|
| 96 |
+
|
| 97 |
+
# Set PATH to use the virtual environment
|
| 98 |
+
ENV PATH="/opt/oss-cad-suite/bin:/app/.venv/bin:$PATH"
|
| 99 |
+
|
| 100 |
+
# Set PYTHONPATH so imports work correctly
|
| 101 |
+
ENV PYTHONPATH="/app/env:$PYTHONPATH"
|
| 102 |
+
|
| 103 |
+
# Health check
|
| 104 |
+
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
| 105 |
+
CMD curl -f http://localhost:8000/health || exit 1
|
| 106 |
+
|
| 107 |
+
# Run the FastAPI server
|
| 108 |
+
# Use the package-qualified module path so relative imports resolve correctly.
|
| 109 |
+
ENV ENABLE_WEB_INTERFACE=true
|
| 110 |
+
CMD ["sh", "-c", "cd /app/env && uvicorn chipforge.server.app:app --host 0.0.0.0 --port 8000"]
|
README.md
CHANGED
|
@@ -1,10 +1,167 @@
|
|
| 1 |
---
|
| 2 |
-
title:
|
| 3 |
-
emoji:
|
| 4 |
-
colorFrom:
|
| 5 |
-
colorTo:
|
| 6 |
-
sdk:
|
| 7 |
pinned: false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
title: ChipForge RTL Debugging Environment
|
| 3 |
+
emoji: 🔧
|
| 4 |
+
colorFrom: purple
|
| 5 |
+
colorTo: green
|
| 6 |
+
sdk: docker
|
| 7 |
pinned: false
|
| 8 |
+
app_port: 8000
|
| 9 |
+
base_path: /web
|
| 10 |
+
tags:
|
| 11 |
+
- openenv
|
| 12 |
+
- verilog
|
| 13 |
+
- rtl
|
| 14 |
+
- semiconductor
|
| 15 |
---
|
| 16 |
|
| 17 |
+
# ChipForge — RTL Debugging Environment
|
| 18 |
+
|
| 19 |
+
An OpenEnv environment where an AI agent debugs buggy Verilog RTL code using real EDA tools (**Verilator** for simulation/lint, **Yosys** for synthesis).
|
| 20 |
+
|
| 21 |
+
The agent receives buggy Verilog, inspects code, runs tools, reads error logs, edits lines to fix bugs, and submits the corrected design for grading.
|
| 22 |
+
|
| 23 |
+
## Quick Start
|
| 24 |
+
|
| 25 |
+
```python
|
| 26 |
+
from chipforge import ChipforgeAction, ChipforgeEnv
|
| 27 |
+
|
| 28 |
+
try:
|
| 29 |
+
env = ChipforgeEnv.from_docker_image("chipforge-env:latest")
|
| 30 |
+
|
| 31 |
+
# Start a new episode (loads a random buggy RTL task)
|
| 32 |
+
result = env.reset()
|
| 33 |
+
print(f"Task: {result.observation.task_description}")
|
| 34 |
+
|
| 35 |
+
# View the buggy RTL
|
| 36 |
+
result = env.step(ChipforgeAction(action_type="view_rtl"))
|
| 37 |
+
print(result.observation.rtl_code)
|
| 38 |
+
|
| 39 |
+
# Run simulation to see errors
|
| 40 |
+
result = env.step(ChipforgeAction(action_type="run_simulation"))
|
| 41 |
+
print(f"Status: {result.observation.sim_status}")
|
| 42 |
+
print(f"Error: {result.observation.error_summary}")
|
| 43 |
+
|
| 44 |
+
# Fix the bug
|
| 45 |
+
result = env.step(ChipforgeAction(
|
| 46 |
+
action_type="edit_line",
|
| 47 |
+
line_number=13,
|
| 48 |
+
new_content="assign sum = x1 ^ cin;"
|
| 49 |
+
))
|
| 50 |
+
|
| 51 |
+
# Verify the fix
|
| 52 |
+
result = env.step(ChipforgeAction(action_type="run_simulation"))
|
| 53 |
+
print(f"Status: {result.observation.sim_status}")
|
| 54 |
+
|
| 55 |
+
# Submit solution
|
| 56 |
+
result = env.step(ChipforgeAction(action_type="submit"))
|
| 57 |
+
print(f"Reward: {result.observation.reward}")
|
| 58 |
+
|
| 59 |
+
finally:
|
| 60 |
+
env.close()
|
| 61 |
+
```
|
| 62 |
+
|
| 63 |
+
## Action Space
|
| 64 |
+
|
| 65 |
+
| Action | Parameters | Description |
|
| 66 |
+
|--------|-----------|-------------|
|
| 67 |
+
| `view_rtl` | — | View current RTL code with line numbers |
|
| 68 |
+
| `view_testbench` | — | View the testbench code |
|
| 69 |
+
| `view_logs` | `log_type`: sim/synth/lint | View output from last tool run |
|
| 70 |
+
| `run_simulation` | — | Compile + simulate with Verilator |
|
| 71 |
+
| `run_synthesis` | — | Synthesize with Yosys |
|
| 72 |
+
| `run_lint` | — | Run Verilator lint checks |
|
| 73 |
+
| `edit_line` | `line_number`, `new_content` | Replace a single line of RTL |
|
| 74 |
+
| `submit` | — | Submit fix and get final reward |
|
| 75 |
+
|
| 76 |
+
## Observation Space
|
| 77 |
+
|
| 78 |
+
| Field | Type | Description |
|
| 79 |
+
|-------|------|-------------|
|
| 80 |
+
| `rtl_code` | str | Current RTL (populated by `view_rtl`) |
|
| 81 |
+
| `testbench_code` | str | Testbench (populated by `view_testbench`) |
|
| 82 |
+
| `log_output` | str | Tool output (populated by `view_logs`) |
|
| 83 |
+
| `sim_status` | str | `not_run` / `pass` / `fail` / `error` |
|
| 84 |
+
| `synth_status` | str | `not_run` / `pass` / `warning` / `error` |
|
| 85 |
+
| `lint_status` | str | `not_run` / `clean` / `warning` / `error` |
|
| 86 |
+
| `error_summary` | str | One-line error hint |
|
| 87 |
+
| `task_description` | str | Description of the current task |
|
| 88 |
+
| `step_count` | int | Steps taken so far |
|
| 89 |
+
| `max_steps` | int | Maximum allowed steps (20) |
|
| 90 |
+
|
| 91 |
+
## Reward
|
| 92 |
+
|
| 93 |
+
| Component | Value | Condition |
|
| 94 |
+
|-----------|-------|-----------|
|
| 95 |
+
| Compiles | +0.2 | No syntax errors |
|
| 96 |
+
| Simulation passes | +0.3 | Output matches expected truth table |
|
| 97 |
+
| Synthesis clean | +0.3 | No warnings (e.g., no latches) |
|
| 98 |
+
| Lint clean | +0.2 | No lint warnings |
|
| 99 |
+
| Step penalty | -0.01/step | Encourages efficiency |
|
| 100 |
+
|
| 101 |
+
Maximum reward: **1.0** (all checks pass, minimal steps).
|
| 102 |
+
|
| 103 |
+
## Tasks
|
| 104 |
+
|
| 105 |
+
| # | Name | Difficulty | Bug Type |
|
| 106 |
+
|---|------|-----------|----------|
|
| 107 |
+
| 1 | `task_easy_syntax` | Easy | Incomplete XOR expression |
|
| 108 |
+
| 2 | `task_easy_missing_semicolon` | Easy | Missing semicolon on wire declaration |
|
| 109 |
+
| 3 | `task_medium_logic_bug` | Medium | Wrong operator in sum computation |
|
| 110 |
+
| 4 | `task_medium_wrong_operator` | Medium | XOR instead of AND in carry logic |
|
| 111 |
+
| 5 | `task_hard_latch_inference` | Hard | Missing else branch → latch inferred |
|
| 112 |
+
|
| 113 |
+
## Tools Used
|
| 114 |
+
|
| 115 |
+
| Tool | Role | Installed via |
|
| 116 |
+
|------|------|--------------|
|
| 117 |
+
| **Verilator** | Simulation + Linting | OSS CAD Suite |
|
| 118 |
+
| **Yosys** | Synthesis | OSS CAD Suite |
|
| 119 |
+
|
| 120 |
+
Both tools are bundled in the Docker image via [OSS CAD Suite](https://github.com/YosysHQ/oss-cad-suite-build).
|
| 121 |
+
|
| 122 |
+
## Building & Running
|
| 123 |
+
|
| 124 |
+
```bash
|
| 125 |
+
# Build Docker image
|
| 126 |
+
docker build -t chipforge-env:latest -f server/Dockerfile .
|
| 127 |
+
|
| 128 |
+
# Run locally (for development)
|
| 129 |
+
uvicorn chipforge.server.app:app --reload
|
| 130 |
+
|
| 131 |
+
# Deploy to Hugging Face Spaces
|
| 132 |
+
openenv push
|
| 133 |
+
```
|
| 134 |
+
|
| 135 |
+
## Project Structure
|
| 136 |
+
|
| 137 |
+
```
|
| 138 |
+
chipforge/
|
| 139 |
+
├── __init__.py # Module exports
|
| 140 |
+
├── models.py # Action + Observation models
|
| 141 |
+
├── client.py # ChipforgeEnv client
|
| 142 |
+
├── openenv.yaml # OpenEnv manifest
|
| 143 |
+
├── pyproject.toml # Dependencies
|
| 144 |
+
└── server/
|
| 145 |
+
├── app.py # FastAPI application
|
| 146 |
+
├── chipforge_environment.py # Core environment logic
|
| 147 |
+
├── Dockerfile # Container with Verilator + Yosys
|
| 148 |
+
└── tasks/ # RTL debugging tasks
|
| 149 |
+
├── task_easy_syntax/
|
| 150 |
+
├── task_easy_missing_semicolon/
|
| 151 |
+
├── task_medium_logic_bug/
|
| 152 |
+
├── task_medium_wrong_operator/
|
| 153 |
+
└── task_hard_latch_inference/
|
| 154 |
+
```
|
| 155 |
+
|
| 156 |
+
## Example Agent Episode
|
| 157 |
+
|
| 158 |
+
```
|
| 159 |
+
reset() → Task: "Fix the syntax error in the full adder RTL"
|
| 160 |
+
|
| 161 |
+
view_rtl → see buggy code with line numbers
|
| 162 |
+
run_simulation → sim_status="error", error_summary="syntax error near '^'"
|
| 163 |
+
edit_line(13, "assign sum = x1 ^ cin;") → "Line 13 updated"
|
| 164 |
+
run_simulation → sim_status="pass"
|
| 165 |
+
run_synthesis → synth_status="pass"
|
| 166 |
+
submit → reward=0.93
|
| 167 |
+
```
|
__init__.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# This source code is licensed under the BSD-style license found in the
|
| 5 |
+
# LICENSE file in the root directory of this source tree.
|
| 6 |
+
|
| 7 |
+
"""Chipforge Environment."""
|
| 8 |
+
|
| 9 |
+
from .client import ChipforgeEnv
|
| 10 |
+
from .models import ChipforgeAction, ChipforgeObservation
|
| 11 |
+
|
| 12 |
+
__all__ = [
|
| 13 |
+
"ChipforgeAction",
|
| 14 |
+
"ChipforgeObservation",
|
| 15 |
+
"ChipforgeEnv",
|
| 16 |
+
]
|
client.py
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# This source code is licensed under the BSD-style license found in the
|
| 5 |
+
# LICENSE file in the root directory of this source tree.
|
| 6 |
+
|
| 7 |
+
"""ChipForge Environment Client."""
|
| 8 |
+
|
| 9 |
+
from typing import Dict
|
| 10 |
+
|
| 11 |
+
from openenv.core import EnvClient
|
| 12 |
+
from openenv.core.client_types import StepResult
|
| 13 |
+
from openenv.core.env_server.types import State
|
| 14 |
+
|
| 15 |
+
from .models import ChipforgeAction, ChipforgeObservation
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
class ChipforgeEnv(
|
| 19 |
+
EnvClient[ChipforgeAction, ChipforgeObservation, State]
|
| 20 |
+
):
|
| 21 |
+
"""
|
| 22 |
+
Client for the ChipForge RTL Debugging Environment.
|
| 23 |
+
|
| 24 |
+
This client maintains a persistent WebSocket connection to the environment
|
| 25 |
+
server, enabling efficient multi-step interactions with lower latency.
|
| 26 |
+
|
| 27 |
+
Example:
|
| 28 |
+
>>> with ChipforgeEnv(base_url="http://localhost:8000") as client:
|
| 29 |
+
... result = client.reset()
|
| 30 |
+
... print(result.observation.rtl_code) # RTL is always in observation
|
| 31 |
+
...
|
| 32 |
+
... # View the testbench code
|
| 33 |
+
... result = client.step(ChipforgeAction(action_type="view_testbench"))
|
| 34 |
+
... print(result.observation.testbench_code)
|
| 35 |
+
...
|
| 36 |
+
... # Run simulation and view the results
|
| 37 |
+
... result = client.step(ChipforgeAction(action_type="run_simulation"))
|
| 38 |
+
... result = client.step(ChipforgeAction(action_type="view_simulation_log"))
|
| 39 |
+
... print(result.observation.log_output)
|
| 40 |
+
...
|
| 41 |
+
... # Edit a line
|
| 42 |
+
... result = client.step(ChipforgeAction(
|
| 43 |
+
... action_type="edit_line",
|
| 44 |
+
... line_number=13,
|
| 45 |
+
... new_content="assign sum = x1 ^ cin;"
|
| 46 |
+
... ))
|
| 47 |
+
|
| 48 |
+
Example with Docker:
|
| 49 |
+
>>> client = ChipforgeEnv.from_docker_image("chipforge-env:latest")
|
| 50 |
+
>>> try:
|
| 51 |
+
... result = client.reset()
|
| 52 |
+
... print(result.observation.rtl_code) # RTL is always present
|
| 53 |
+
... result = client.step(ChipforgeAction(action_type="run_simulation"))
|
| 54 |
+
... finally:
|
| 55 |
+
... client.close()
|
| 56 |
+
"""
|
| 57 |
+
|
| 58 |
+
def _step_payload(self, action: ChipforgeAction) -> Dict:
|
| 59 |
+
"""
|
| 60 |
+
Convert ChipforgeAction to JSON payload for step message.
|
| 61 |
+
|
| 62 |
+
Args:
|
| 63 |
+
action: ChipforgeAction instance
|
| 64 |
+
|
| 65 |
+
Returns:
|
| 66 |
+
Dictionary representation suitable for JSON encoding
|
| 67 |
+
"""
|
| 68 |
+
payload = {"action_type": action.action_type}
|
| 69 |
+
|
| 70 |
+
if action.line_number is not None:
|
| 71 |
+
payload["line_number"] = action.line_number
|
| 72 |
+
if action.new_content is not None:
|
| 73 |
+
payload["new_content"] = action.new_content
|
| 74 |
+
return payload
|
| 75 |
+
|
| 76 |
+
def _parse_result(self, payload: Dict) -> StepResult[ChipforgeObservation]:
|
| 77 |
+
"""
|
| 78 |
+
Parse server response into StepResult[ChipforgeObservation].
|
| 79 |
+
|
| 80 |
+
Args:
|
| 81 |
+
payload: JSON response data from server
|
| 82 |
+
|
| 83 |
+
Returns:
|
| 84 |
+
StepResult with ChipforgeObservation
|
| 85 |
+
"""
|
| 86 |
+
obs_data = payload.get("observation", {})
|
| 87 |
+
observation = ChipforgeObservation(
|
| 88 |
+
rtl_code=obs_data.get("rtl_code", ""),
|
| 89 |
+
testbench_code=obs_data.get("testbench_code", ""),
|
| 90 |
+
log_output=obs_data.get("log_output", ""),
|
| 91 |
+
sim_status=obs_data.get("sim_status", "not_run"),
|
| 92 |
+
synth_status=obs_data.get("synth_status", "not_run"),
|
| 93 |
+
lint_status=obs_data.get("lint_status", "not_run"),
|
| 94 |
+
error_summary=obs_data.get("error_summary", ""),
|
| 95 |
+
task_description=obs_data.get("task_description", ""),
|
| 96 |
+
step_count=obs_data.get("step_count", 0),
|
| 97 |
+
max_steps=obs_data.get("max_steps", 20),
|
| 98 |
+
done=payload.get("done", False),
|
| 99 |
+
reward=payload.get("reward"),
|
| 100 |
+
metadata=obs_data.get("metadata", {}),
|
| 101 |
+
)
|
| 102 |
+
|
| 103 |
+
return StepResult(
|
| 104 |
+
observation=observation,
|
| 105 |
+
reward=payload.get("reward"),
|
| 106 |
+
done=payload.get("done", False),
|
| 107 |
+
)
|
| 108 |
+
|
| 109 |
+
def _parse_state(self, payload: Dict) -> State:
|
| 110 |
+
"""
|
| 111 |
+
Parse server response into State object.
|
| 112 |
+
|
| 113 |
+
Args:
|
| 114 |
+
payload: JSON response from state request
|
| 115 |
+
|
| 116 |
+
Returns:
|
| 117 |
+
State object with episode_id and step_count
|
| 118 |
+
"""
|
| 119 |
+
return State(
|
| 120 |
+
episode_id=payload.get("episode_id"),
|
| 121 |
+
step_count=payload.get("step_count", 0),
|
| 122 |
+
)
|
inference.py
ADDED
|
@@ -0,0 +1,504 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
LLM inference runner for ChipForge RTL Debugging Environment.
|
| 4 |
+
|
| 5 |
+
This script lets a chat model debug buggy Verilog RTL by choosing actions
|
| 6 |
+
(view code, run simulation/synthesis, edit lines, submit) against the
|
| 7 |
+
ChipForge HTTP server.
|
| 8 |
+
|
| 9 |
+
Examples:
|
| 10 |
+
# HTTP mode against running server
|
| 11 |
+
python inference.py --mode http --env-url http://localhost:8000
|
| 12 |
+
|
| 13 |
+
# Local mode (requires Verilator + Yosys on PATH)
|
| 14 |
+
python inference.py --mode local --episodes 1
|
| 15 |
+
"""
|
| 16 |
+
from __future__ import annotations
|
| 17 |
+
|
| 18 |
+
import argparse
|
| 19 |
+
import json
|
| 20 |
+
import os
|
| 21 |
+
import re
|
| 22 |
+
import urllib.error
|
| 23 |
+
import urllib.request
|
| 24 |
+
from typing import Any, Optional
|
| 25 |
+
|
| 26 |
+
from dotenv import load_dotenv
|
| 27 |
+
|
| 28 |
+
load_dotenv()
|
| 29 |
+
|
| 30 |
+
# ---------------------------------------------------------------------------
|
| 31 |
+
# Action definitions
|
| 32 |
+
# ---------------------------------------------------------------------------
|
| 33 |
+
|
| 34 |
+
VALID_ACTIONS = [
|
| 35 |
+
"view_testbench",
|
| 36 |
+
"view_synthesis_log",
|
| 37 |
+
"view_lint_log",
|
| 38 |
+
"view_simulation_log",
|
| 39 |
+
"run_simulation",
|
| 40 |
+
"run_synthesis",
|
| 41 |
+
"run_lint",
|
| 42 |
+
"edit_line",
|
| 43 |
+
"append_line",
|
| 44 |
+
"edit_testbench_line",
|
| 45 |
+
"append_testbench_line",
|
| 46 |
+
"submit",
|
| 47 |
+
]
|
| 48 |
+
|
| 49 |
+
DEFAULT_LLM_MODEL = os.environ.get("LLM_MODEL", "mistral-medium-2505")
|
| 50 |
+
|
| 51 |
+
# ---------------------------------------------------------------------------
|
| 52 |
+
# System prompt
|
| 53 |
+
# ---------------------------------------------------------------------------
|
| 54 |
+
|
| 55 |
+
SYSTEM_PROMPT = """You are an expert Verilog/RTL debugging agent controlling the ChipForge environment.
|
| 56 |
+
Your goal is to fix buggy Verilog RTL code so it passes simulation, synthesis, and lint checks.
|
| 57 |
+
|
| 58 |
+
Available actions (return exactly ONE JSON action per turn):
|
| 59 |
+
|
| 60 |
+
1. view_testbench — View the testbench code
|
| 61 |
+
2. view_synthesis_log — View synthesis tool logs from last run
|
| 62 |
+
3. view_lint_log — View lint tool logs from last run
|
| 63 |
+
4. view_simulation_log — View simulation tool logs from last run
|
| 64 |
+
5. run_simulation — Compile and simulate with Verilator
|
| 65 |
+
6. run_synthesis — Synthesize with Yosys
|
| 66 |
+
7. run_lint — Run Verilator lint checks
|
| 67 |
+
8. edit_line — Replace a single line. Requires line_number (1-indexed) and new_content
|
| 68 |
+
9. append_line — Append one RTL line. Requires new_content
|
| 69 |
+
10. edit_testbench_line — Replace a single testbench line. Requires line_number and new_content
|
| 70 |
+
11. append_testbench_line — Append one testbench line. Requires new_content
|
| 71 |
+
12. submit — Submit current RTL as final solution (triggers grading)
|
| 72 |
+
|
| 73 |
+
Response format — return ONLY valid JSON:
|
| 74 |
+
{"action_type": "...", "line_number": null, "new_content": null, "reasoning": "..."}
|
| 75 |
+
|
| 76 |
+
Strategy:
|
| 77 |
+
1. The observation always includes the current RTL code — you don't need to view it separately
|
| 78 |
+
2. Run run_simulation to see compilation/output errors
|
| 79 |
+
3. If there are errors, use view_simulation_log to read error details
|
| 80 |
+
4. Use edit_line to fix the bug (one line at a time)
|
| 81 |
+
5. Use append_line / append_testbench_line if a task starts with missing files
|
| 82 |
+
6. Re-run simulation to verify the fix
|
| 83 |
+
6. Run synthesis and lint to ensure clean results
|
| 84 |
+
7. Use view_synthesis_log and view_lint_log to check for warnings/errors
|
| 85 |
+
9. Submit when everything passes
|
| 86 |
+
|
| 87 |
+
Rules:
|
| 88 |
+
- Return valid JSON only, no markdown
|
| 89 |
+
- Use null for fields that don't apply to the chosen action
|
| 90 |
+
- Fix bugs methodically — read error logs before editing
|
| 91 |
+
- Minimize steps for a higher reward (step penalty of -0.02/step)
|
| 92 |
+
- Optimize cumulative_reward across the full episode, not only the immediate step reward
|
| 93 |
+
"""
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
# ---------------------------------------------------------------------------
|
| 97 |
+
# LLM helpers
|
| 98 |
+
# ---------------------------------------------------------------------------
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
def build_prompt(observation: dict[str, Any]) -> str:
|
| 102 |
+
"""Build user prompt from the current observation."""
|
| 103 |
+
parts = ["Fix the RTL bug."]
|
| 104 |
+
|
| 105 |
+
# Always show step information
|
| 106 |
+
parts.append(
|
| 107 |
+
f"Step: {observation.get('step_count', '?')}/{observation.get('max_steps', 20)}"
|
| 108 |
+
)
|
| 109 |
+
|
| 110 |
+
if observation.get("error_summary"):
|
| 111 |
+
parts.append(f"Error: {observation['error_summary']}")
|
| 112 |
+
if observation.get("last_action"):
|
| 113 |
+
parts.append(f"Last action: {observation['last_action']}")
|
| 114 |
+
if observation.get("action_result"):
|
| 115 |
+
parts.append(f"Action result: {observation['action_result']}")
|
| 116 |
+
|
| 117 |
+
status_line = (
|
| 118 |
+
f"Status: sim={observation.get('sim_status', 'not_run')}, "
|
| 119 |
+
f"synth={observation.get('synth_status', 'not_run')}, "
|
| 120 |
+
f"lint={observation.get('lint_status', 'not_run')}"
|
| 121 |
+
)
|
| 122 |
+
parts.append(status_line)
|
| 123 |
+
|
| 124 |
+
metadata = observation.get("metadata", {}) or {}
|
| 125 |
+
if "code_dirty" in metadata:
|
| 126 |
+
parts.append(f"Code dirty since last validation: {metadata.get('code_dirty')}")
|
| 127 |
+
tool_freshness = metadata.get("tool_freshness", {})
|
| 128 |
+
if tool_freshness:
|
| 129 |
+
parts.append(
|
| 130 |
+
"Tool freshness: "
|
| 131 |
+
f"sim={tool_freshness.get('simulation')}, "
|
| 132 |
+
f"synth={tool_freshness.get('synthesis')}, "
|
| 133 |
+
f"lint={tool_freshness.get('lint')}"
|
| 134 |
+
)
|
| 135 |
+
|
| 136 |
+
# Include content fields if populated
|
| 137 |
+
if observation.get("rtl_code"):
|
| 138 |
+
parts.append(f"\n--- RTL Code ---\n{observation['rtl_code']}")
|
| 139 |
+
|
| 140 |
+
if observation.get("testbench_code"):
|
| 141 |
+
parts.append(f"\n--- Testbench ---\n{observation['testbench_code']}")
|
| 142 |
+
|
| 143 |
+
if observation.get("log_output"):
|
| 144 |
+
# Truncate very long logs
|
| 145 |
+
log = observation["log_output"][:1500]
|
| 146 |
+
parts.append(f"\n--- Log Output ---\n{log}")
|
| 147 |
+
|
| 148 |
+
parts.append("\nReturn your next action as JSON:")
|
| 149 |
+
return "\n".join(parts)
|
| 150 |
+
|
| 151 |
+
|
| 152 |
+
def parse_action(text: str) -> Optional[dict[str, Any]]:
|
| 153 |
+
"""Try to extract a JSON action from the LLM response."""
|
| 154 |
+
text = text.strip()
|
| 155 |
+
|
| 156 |
+
# Direct JSON
|
| 157 |
+
try:
|
| 158 |
+
return json.loads(text)
|
| 159 |
+
except Exception:
|
| 160 |
+
pass
|
| 161 |
+
|
| 162 |
+
# Fenced code block
|
| 163 |
+
match = re.search(r"```(?:json)?\s*(\{.*?\})\s*```", text, re.DOTALL)
|
| 164 |
+
if match:
|
| 165 |
+
try:
|
| 166 |
+
return json.loads(match.group(1))
|
| 167 |
+
except Exception:
|
| 168 |
+
pass
|
| 169 |
+
|
| 170 |
+
# Any JSON object
|
| 171 |
+
match = re.search(r"\{.*\}", text, re.DOTALL)
|
| 172 |
+
if match:
|
| 173 |
+
try:
|
| 174 |
+
return json.loads(match.group(0))
|
| 175 |
+
except Exception:
|
| 176 |
+
pass
|
| 177 |
+
|
| 178 |
+
return None
|
| 179 |
+
|
| 180 |
+
|
| 181 |
+
def validate_action(action: dict[str, Any]) -> dict[str, Any]:
|
| 182 |
+
"""Validate and normalize the parsed action."""
|
| 183 |
+
action_type = action.get("action_type", "run_simulation")
|
| 184 |
+
if action_type not in VALID_ACTIONS:
|
| 185 |
+
action_type = "run_simulation"
|
| 186 |
+
|
| 187 |
+
payload: dict[str, Any] = {"action_type": action_type}
|
| 188 |
+
|
| 189 |
+
if action_type in ("edit_line", "edit_testbench_line"):
|
| 190 |
+
payload["line_number"] = action.get("line_number")
|
| 191 |
+
payload["new_content"] = action.get("new_content")
|
| 192 |
+
elif action_type in ("append_line", "append_testbench_line"):
|
| 193 |
+
payload["new_content"] = action.get("new_content")
|
| 194 |
+
|
| 195 |
+
return payload
|
| 196 |
+
|
| 197 |
+
|
| 198 |
+
# ---------------------------------------------------------------------------
|
| 199 |
+
# LLM client (Mistral)
|
| 200 |
+
# ---------------------------------------------------------------------------
|
| 201 |
+
|
| 202 |
+
|
| 203 |
+
def make_mistral_client(api_key: Optional[str] = None):
|
| 204 |
+
from mistralai.client import Mistral
|
| 205 |
+
|
| 206 |
+
return Mistral(
|
| 207 |
+
api_key=api_key or os.environ.get("MISTRAL_API_KEY"),
|
| 208 |
+
timeout_ms=120_000, # 120s — magistral is a reasoning model
|
| 209 |
+
)
|
| 210 |
+
|
| 211 |
+
|
| 212 |
+
def call_llm(client, model: str, prompt: str, temperature: float, max_retries: int = 3) -> str:
|
| 213 |
+
"""Call the LLM with retry on timeout."""
|
| 214 |
+
import time as _time
|
| 215 |
+
|
| 216 |
+
for attempt in range(max_retries):
|
| 217 |
+
try:
|
| 218 |
+
response = client.chat.complete(
|
| 219 |
+
model=model,
|
| 220 |
+
messages=[
|
| 221 |
+
{"role": "system", "content": SYSTEM_PROMPT},
|
| 222 |
+
{"role": "user", "content": prompt},
|
| 223 |
+
],
|
| 224 |
+
temperature=temperature,
|
| 225 |
+
)
|
| 226 |
+
content = response.choices[0].message.content
|
| 227 |
+
if not content:
|
| 228 |
+
raise RuntimeError("LLM response missing content")
|
| 229 |
+
|
| 230 |
+
# Some models (e.g. magistral) return content as a list of blocks
|
| 231 |
+
if isinstance(content, list):
|
| 232 |
+
parts = []
|
| 233 |
+
for block in content:
|
| 234 |
+
if isinstance(block, str):
|
| 235 |
+
parts.append(block)
|
| 236 |
+
elif hasattr(block, "text"):
|
| 237 |
+
parts.append(block.text)
|
| 238 |
+
elif isinstance(block, dict) and "text" in block:
|
| 239 |
+
parts.append(block["text"])
|
| 240 |
+
else:
|
| 241 |
+
parts.append(str(block))
|
| 242 |
+
content = "\n".join(parts)
|
| 243 |
+
|
| 244 |
+
return content
|
| 245 |
+
|
| 246 |
+
except Exception as e:
|
| 247 |
+
if attempt < max_retries - 1:
|
| 248 |
+
wait = 5 * (attempt + 1)
|
| 249 |
+
print(f" ⚠️ LLM call failed ({e.__class__.__name__}), retrying in {wait}s...")
|
| 250 |
+
_time.sleep(wait)
|
| 251 |
+
else:
|
| 252 |
+
raise
|
| 253 |
+
|
| 254 |
+
|
| 255 |
+
# ---------------------------------------------------------------------------
|
| 256 |
+
# HTTP helpers
|
| 257 |
+
# ---------------------------------------------------------------------------
|
| 258 |
+
|
| 259 |
+
|
| 260 |
+
def request_json(
|
| 261 |
+
url: str,
|
| 262 |
+
method: str = "GET",
|
| 263 |
+
payload: Optional[dict[str, Any]] = None,
|
| 264 |
+
) -> dict[str, Any]:
|
| 265 |
+
"""Make an HTTP request and return parsed JSON."""
|
| 266 |
+
data = None
|
| 267 |
+
headers = {}
|
| 268 |
+
if payload is not None:
|
| 269 |
+
data = json.dumps(payload).encode("utf-8")
|
| 270 |
+
headers["Content-Type"] = "application/json"
|
| 271 |
+
req = urllib.request.Request(url, data=data, headers=headers, method=method)
|
| 272 |
+
with urllib.request.urlopen(req, timeout=120) as resp:
|
| 273 |
+
return json.loads(resp.read().decode("utf-8"))
|
| 274 |
+
|
| 275 |
+
|
| 276 |
+
# ---------------------------------------------------------------------------
|
| 277 |
+
# Episode runners
|
| 278 |
+
# ---------------------------------------------------------------------------
|
| 279 |
+
|
| 280 |
+
|
| 281 |
+
def run_http_episode(args: argparse.Namespace) -> float:
|
| 282 |
+
"""Run one episode against the server using WebSocket (persistent session)."""
|
| 283 |
+
import time
|
| 284 |
+
import websocket # pip install websocket-client
|
| 285 |
+
|
| 286 |
+
llm_client = make_mistral_client(args.api_key)
|
| 287 |
+
|
| 288 |
+
# Connect via WebSocket for persistent session state
|
| 289 |
+
ws_url = args.env_url.replace("http://", "ws://").replace("https://", "wss://") + "/ws"
|
| 290 |
+
ws = websocket.create_connection(ws_url, timeout=120)
|
| 291 |
+
|
| 292 |
+
def ws_send(msg_type: str, data: dict = None) -> dict:
|
| 293 |
+
"""Send a WebSocket message and return the response."""
|
| 294 |
+
payload = {"type": msg_type}
|
| 295 |
+
if data is not None:
|
| 296 |
+
payload["data"] = data
|
| 297 |
+
ws.send(json.dumps(payload))
|
| 298 |
+
return json.loads(ws.recv())
|
| 299 |
+
|
| 300 |
+
# Reset
|
| 301 |
+
reset_payload: dict[str, Any] = {}
|
| 302 |
+
if args.seed is not None:
|
| 303 |
+
reset_payload["seed"] = args.seed
|
| 304 |
+
if args.task_name:
|
| 305 |
+
reset_payload["task_name"] = args.task_name
|
| 306 |
+
reset_resp = ws_send("reset", reset_payload if reset_payload else None)
|
| 307 |
+
obs = reset_resp.get("data", {})
|
| 308 |
+
total_reward = 0.0
|
| 309 |
+
|
| 310 |
+
print(f" Starting episode...")
|
| 311 |
+
print()
|
| 312 |
+
|
| 313 |
+
for step in range(args.max_steps):
|
| 314 |
+
# Build prompt and query LLM
|
| 315 |
+
prompt = build_prompt(obs)
|
| 316 |
+
raw_response = call_llm(
|
| 317 |
+
client=llm_client,
|
| 318 |
+
model=args.model,
|
| 319 |
+
prompt=prompt,
|
| 320 |
+
temperature=args.temperature,
|
| 321 |
+
)
|
| 322 |
+
|
| 323 |
+
# Parse and validate
|
| 324 |
+
parsed = parse_action(raw_response)
|
| 325 |
+
if parsed is None:
|
| 326 |
+
parsed = {"action_type": "run_simulation", "reasoning": "Failed to parse LLM response"}
|
| 327 |
+
|
| 328 |
+
action_dict = validate_action(parsed)
|
| 329 |
+
|
| 330 |
+
reasoning = parsed.get("reasoning", "")
|
| 331 |
+
|
| 332 |
+
# Step via WebSocket
|
| 333 |
+
step_resp = ws_send("step", action_dict)
|
| 334 |
+
obs = step_resp.get("data", {}).get("observation", step_resp.get("data", {}))
|
| 335 |
+
reward = float(step_resp.get("data", {}).get("reward", 0.0))
|
| 336 |
+
done = step_resp.get("data", {}).get("done", False)
|
| 337 |
+
total_reward += reward
|
| 338 |
+
obs_cumulative_reward = obs.get("cumulative_reward")
|
| 339 |
+
|
| 340 |
+
# Print step header
|
| 341 |
+
print(f"\n {'─'*56}")
|
| 342 |
+
print(f" STEP {step + 1}/{args.max_steps}")
|
| 343 |
+
print(f" {'─'*56}")
|
| 344 |
+
|
| 345 |
+
# Print full action object
|
| 346 |
+
print(f"\n ▶ ACTION:")
|
| 347 |
+
print(f" {json.dumps(action_dict, indent=4)}")
|
| 348 |
+
if reasoning:
|
| 349 |
+
print(f" reasoning: {reasoning}")
|
| 350 |
+
|
| 351 |
+
# Print observation
|
| 352 |
+
print(f"\n ◀ OBSERVATION:")
|
| 353 |
+
print(f" {json.dumps(obs, indent=4)}")
|
| 354 |
+
|
| 355 |
+
print(
|
| 356 |
+
f"\n Reward: step={reward:+.3f} episode_return={total_reward:+.3f} "
|
| 357 |
+
f"obs_cumulative={obs_cumulative_reward}"
|
| 358 |
+
)
|
| 359 |
+
|
| 360 |
+
if done:
|
| 361 |
+
print(f"\n 🏁 EPISODE DONE — Episode return: {total_reward:+.3f}")
|
| 362 |
+
break
|
| 363 |
+
|
| 364 |
+
# 10 second delay between steps
|
| 365 |
+
print(f"\n ⏳ Waiting 10 seconds...")
|
| 366 |
+
time.sleep(10)
|
| 367 |
+
|
| 368 |
+
ws.close()
|
| 369 |
+
print(f"\n Final episode return: {total_reward:+.3f}")
|
| 370 |
+
return total_reward
|
| 371 |
+
|
| 372 |
+
|
| 373 |
+
def run_local_episode(args: argparse.Namespace) -> float:
|
| 374 |
+
"""Run one episode using the local environment (needs Verilator+Yosys)."""
|
| 375 |
+
import sys
|
| 376 |
+
|
| 377 |
+
sys.path.insert(0, os.path.dirname(__file__))
|
| 378 |
+
|
| 379 |
+
from models import ChipforgeAction
|
| 380 |
+
from server.chipforge_environment import ChipforgeEnvironment
|
| 381 |
+
|
| 382 |
+
client = make_mistral_client(args.api_key)
|
| 383 |
+
env = ChipforgeEnvironment()
|
| 384 |
+
|
| 385 |
+
reset_kwargs: dict[str, Any] = {}
|
| 386 |
+
if args.seed is not None:
|
| 387 |
+
reset_kwargs["seed"] = args.seed
|
| 388 |
+
if args.task_name:
|
| 389 |
+
reset_kwargs["task_name"] = args.task_name
|
| 390 |
+
obs = env.reset(**reset_kwargs)
|
| 391 |
+
total_reward = 0.0
|
| 392 |
+
|
| 393 |
+
print(f" Starting episode...")
|
| 394 |
+
print()
|
| 395 |
+
|
| 396 |
+
for step in range(args.max_steps):
|
| 397 |
+
# Build observation dict for prompt
|
| 398 |
+
obs_dict = {
|
| 399 |
+
"rtl_code": obs.rtl_code,
|
| 400 |
+
"testbench_code": obs.testbench_code,
|
| 401 |
+
"log_output": obs.log_output,
|
| 402 |
+
"sim_status": obs.sim_status,
|
| 403 |
+
"synth_status": obs.synth_status,
|
| 404 |
+
"lint_status": obs.lint_status,
|
| 405 |
+
"last_action": obs.last_action,
|
| 406 |
+
"action_result": obs.action_result,
|
| 407 |
+
"error_summary": obs.error_summary,
|
| 408 |
+
"metadata": obs.metadata,
|
| 409 |
+
"step_count": obs.step_count,
|
| 410 |
+
"max_steps": obs.max_steps,
|
| 411 |
+
}
|
| 412 |
+
|
| 413 |
+
prompt = build_prompt(obs_dict)
|
| 414 |
+
raw_response = call_llm(
|
| 415 |
+
client=client,
|
| 416 |
+
model=args.model,
|
| 417 |
+
prompt=prompt,
|
| 418 |
+
temperature=args.temperature,
|
| 419 |
+
)
|
| 420 |
+
|
| 421 |
+
parsed = parse_action(raw_response)
|
| 422 |
+
if parsed is None:
|
| 423 |
+
parsed = {"action_type": "run_simulation", "reasoning": "Failed to parse"}
|
| 424 |
+
|
| 425 |
+
action_dict = validate_action(parsed)
|
| 426 |
+
reasoning = parsed.get("reasoning", "")
|
| 427 |
+
|
| 428 |
+
action = ChipforgeAction(**action_dict)
|
| 429 |
+
obs = env.step(action)
|
| 430 |
+
step_reward = float(obs.reward or 0.0)
|
| 431 |
+
total_reward += step_reward
|
| 432 |
+
|
| 433 |
+
action_str = action_dict["action_type"]
|
| 434 |
+
if action_dict["action_type"] == "edit_line":
|
| 435 |
+
action_str += f"({action_dict.get('line_number', '?')})"
|
| 436 |
+
|
| 437 |
+
print(
|
| 438 |
+
f" step={step + 1:02d} action={action_str:25s} "
|
| 439 |
+
f"reward={step_reward:+.3f} return={total_reward:+.3f} done={obs.done}"
|
| 440 |
+
)
|
| 441 |
+
if reasoning:
|
| 442 |
+
print(f" reasoning: {reasoning[:80]}")
|
| 443 |
+
|
| 444 |
+
if obs.done:
|
| 445 |
+
break
|
| 446 |
+
|
| 447 |
+
env.close()
|
| 448 |
+
print(f"\n Final episode return: {total_reward:+.3f}")
|
| 449 |
+
return total_reward
|
| 450 |
+
|
| 451 |
+
|
| 452 |
+
# ---------------------------------------------------------------------------
|
| 453 |
+
# CLI
|
| 454 |
+
# ---------------------------------------------------------------------------
|
| 455 |
+
|
| 456 |
+
|
| 457 |
+
def build_arg_parser() -> argparse.ArgumentParser:
|
| 458 |
+
parser = argparse.ArgumentParser(
|
| 459 |
+
description="Run an LLM agent against ChipForge RTL Debugging Environment."
|
| 460 |
+
)
|
| 461 |
+
parser.add_argument("--mode", choices=["local", "http"], default="http")
|
| 462 |
+
parser.add_argument("--env-url", default="http://localhost:8000")
|
| 463 |
+
parser.add_argument("--model", default=DEFAULT_LLM_MODEL)
|
| 464 |
+
parser.add_argument("--api-key", default=os.environ.get("MISTRAL_API_KEY"))
|
| 465 |
+
parser.add_argument("--episodes", type=int, default=1)
|
| 466 |
+
parser.add_argument("--max-steps", type=int, default=20)
|
| 467 |
+
parser.add_argument("--seed", type=int, default=None)
|
| 468 |
+
parser.add_argument(
|
| 469 |
+
"--task-name",
|
| 470 |
+
default=None,
|
| 471 |
+
help="Optional task directory name under server/tasks (e.g. easy/03_write_testbench_from_prompt).",
|
| 472 |
+
)
|
| 473 |
+
parser.add_argument("--temperature", type=float, default=0.2)
|
| 474 |
+
return parser
|
| 475 |
+
|
| 476 |
+
|
| 477 |
+
def main() -> int:
|
| 478 |
+
args = build_arg_parser().parse_args()
|
| 479 |
+
|
| 480 |
+
total_rewards = []
|
| 481 |
+
for episode in range(args.episodes):
|
| 482 |
+
print(f"\n{'='*60}")
|
| 483 |
+
print(f" Episode {episode + 1}/{args.episodes}")
|
| 484 |
+
print(f"{'='*60}")
|
| 485 |
+
|
| 486 |
+
if args.mode == "local":
|
| 487 |
+
reward = run_local_episode(args)
|
| 488 |
+
else:
|
| 489 |
+
reward = run_http_episode(args)
|
| 490 |
+
|
| 491 |
+
total_rewards.append(reward)
|
| 492 |
+
|
| 493 |
+
# Summary
|
| 494 |
+
avg = sum(total_rewards) / len(total_rewards)
|
| 495 |
+
print(f"\n{'='*60}")
|
| 496 |
+
print(f" Summary: {len(total_rewards)} episodes, avg reward: {avg:+.3f}")
|
| 497 |
+
print(f" Rewards: {[f'{r:+.3f}' for r in total_rewards]}")
|
| 498 |
+
print(f"{'='*60}")
|
| 499 |
+
|
| 500 |
+
return 0
|
| 501 |
+
|
| 502 |
+
|
| 503 |
+
if __name__ == "__main__":
|
| 504 |
+
raise SystemExit(main())
|
models.py
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# This source code is licensed under the BSD-style license found in the
|
| 5 |
+
# LICENSE file in the root directory of this source tree.
|
| 6 |
+
|
| 7 |
+
"""
|
| 8 |
+
Data models for the ChipForge RTL Debugging Environment.
|
| 9 |
+
|
| 10 |
+
Designed for RL training of LLMs:
|
| 11 |
+
- Observation is a self-contained Markov state (always includes RTL code)
|
| 12 |
+
- Reward uses potential-based shaping for dense per-step signal
|
| 13 |
+
- Action result feedback at every step
|
| 14 |
+
"""
|
| 15 |
+
|
| 16 |
+
from typing import Any, Dict, Literal, Optional
|
| 17 |
+
|
| 18 |
+
from openenv.core.env_server.types import Action, Observation
|
| 19 |
+
from pydantic import Field, model_validator
|
| 20 |
+
|
| 21 |
+
ActionType = Literal[
|
| 22 |
+
"view_testbench",
|
| 23 |
+
"view_synthesis_log",
|
| 24 |
+
"view_lint_log",
|
| 25 |
+
"view_simulation_log",
|
| 26 |
+
"run_simulation",
|
| 27 |
+
"run_synthesis",
|
| 28 |
+
"run_lint",
|
| 29 |
+
"edit_line",
|
| 30 |
+
"append_line",
|
| 31 |
+
"edit_testbench_line",
|
| 32 |
+
"append_testbench_line",
|
| 33 |
+
"submit",
|
| 34 |
+
]
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
class ChipforgeAction(Action):
|
| 38 |
+
"""Action for the ChipForge environment.
|
| 39 |
+
|
| 40 |
+
Supported action_types:
|
| 41 |
+
- view_testbench: View the testbench code
|
| 42 |
+
- view_synthesis_log: View synthesis log (only if run_synthesis was executed)
|
| 43 |
+
- view_lint_log: View lint log (only if run_lint was executed)
|
| 44 |
+
- view_simulation_log: View simulation log (only if run_simulation was executed)
|
| 45 |
+
- run_simulation: Compile and simulate with Verilator
|
| 46 |
+
- run_synthesis: Synthesize with Yosys
|
| 47 |
+
- run_lint: Run Verilator lint checks
|
| 48 |
+
- edit_line: Replace a single line (requires line_number + new_content)
|
| 49 |
+
- append_line: Append one new RTL line (requires new_content)
|
| 50 |
+
- edit_testbench_line: Replace a single testbench line (requires line_number + new_content)
|
| 51 |
+
- append_testbench_line: Append one new testbench line (requires new_content)
|
| 52 |
+
- submit: Submit current RTL as the final solution
|
| 53 |
+
"""
|
| 54 |
+
|
| 55 |
+
action_type: ActionType = Field(..., description="Type of action to execute")
|
| 56 |
+
line_number: Optional[int] = Field(
|
| 57 |
+
default=None,
|
| 58 |
+
description="Line number to edit (1-indexed). Required for edit_line.",
|
| 59 |
+
)
|
| 60 |
+
new_content: Optional[str] = Field(
|
| 61 |
+
default=None,
|
| 62 |
+
description="New content for the line. Required for edit_line.",
|
| 63 |
+
)
|
| 64 |
+
log_type: Optional[str] = Field(
|
| 65 |
+
default=None,
|
| 66 |
+
description="Deprecated. Use view_synthesis_log, view_lint_log, or view_simulation_log instead.",
|
| 67 |
+
)
|
| 68 |
+
|
| 69 |
+
@model_validator(mode="after")
|
| 70 |
+
def validate_action_payload(self) -> "ChipforgeAction":
|
| 71 |
+
is_edit = self.action_type == "edit_line"
|
| 72 |
+
is_append = self.action_type == "append_line"
|
| 73 |
+
is_tb_edit = self.action_type == "edit_testbench_line"
|
| 74 |
+
is_tb_append = self.action_type == "append_testbench_line"
|
| 75 |
+
has_line = self.line_number is not None
|
| 76 |
+
has_content = self.new_content is not None
|
| 77 |
+
|
| 78 |
+
if is_edit and (not has_line or not has_content):
|
| 79 |
+
raise ValueError("edit_line requires both line_number and new_content")
|
| 80 |
+
|
| 81 |
+
if is_tb_edit and (not has_line or not has_content):
|
| 82 |
+
raise ValueError("edit_testbench_line requires both line_number and new_content")
|
| 83 |
+
|
| 84 |
+
if (is_append or is_tb_append) and (not has_content or has_line):
|
| 85 |
+
raise ValueError(
|
| 86 |
+
"append_line/append_testbench_line require new_content only"
|
| 87 |
+
)
|
| 88 |
+
|
| 89 |
+
if (not is_edit and not is_tb_edit and not is_append and not is_tb_append) and (
|
| 90 |
+
has_line or has_content
|
| 91 |
+
):
|
| 92 |
+
raise ValueError(
|
| 93 |
+
"line_number/new_content are only valid for edit_line, append_line, "
|
| 94 |
+
"edit_testbench_line, append_testbench_line"
|
| 95 |
+
)
|
| 96 |
+
return self
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
class ChipforgeObservation(Observation):
|
| 100 |
+
"""Observation returned by the ChipForge environment.
|
| 101 |
+
|
| 102 |
+
Designed as a self-contained Markov state for RL training.
|
| 103 |
+
Always includes the current RTL code.
|
| 104 |
+
Tool logs are only populated when explicitly requested via:
|
| 105 |
+
- view_synthesis_log: Shows synthesis logs from last run
|
| 106 |
+
- view_lint_log: Shows lint logs from last run
|
| 107 |
+
- view_simulation_log: Shows simulation logs from last run
|
| 108 |
+
"""
|
| 109 |
+
|
| 110 |
+
# ── Always populated (Markov state core) ─────────────────────────────
|
| 111 |
+
rtl_code: str = Field(
|
| 112 |
+
default="",
|
| 113 |
+
description="Current RTL design code with line numbers (always present)",
|
| 114 |
+
)
|
| 115 |
+
sim_status: Literal["not_run", "pass", "fail", "error"] = Field(
|
| 116 |
+
default="not_run",
|
| 117 |
+
description="Latest simulation status for current RTL snapshot",
|
| 118 |
+
)
|
| 119 |
+
synth_status: Literal["not_run", "pass", "warning", "error"] = Field(
|
| 120 |
+
default="not_run",
|
| 121 |
+
description="Latest synthesis status for current RTL snapshot",
|
| 122 |
+
)
|
| 123 |
+
lint_status: Literal["not_run", "clean", "warning", "error"] = Field(
|
| 124 |
+
default="not_run",
|
| 125 |
+
description="Latest lint status for current RTL snapshot",
|
| 126 |
+
)
|
| 127 |
+
error_summary: str = Field(
|
| 128 |
+
default="",
|
| 129 |
+
description="One-line summary of the most relevant diagnostic",
|
| 130 |
+
)
|
| 131 |
+
task_description: str = Field(
|
| 132 |
+
default="",
|
| 133 |
+
description="Natural language description of the loaded RTL debug task",
|
| 134 |
+
)
|
| 135 |
+
|
| 136 |
+
# Action feedback (what just happened)
|
| 137 |
+
last_action: str = Field(
|
| 138 |
+
default="reset", description="The action that produced this observation"
|
| 139 |
+
)
|
| 140 |
+
action_result: str = Field(
|
| 141 |
+
default="",
|
| 142 |
+
description="Human-readable result of the last action taken",
|
| 143 |
+
)
|
| 144 |
+
|
| 145 |
+
# ── Conditionally populated (verbose action-specific payload) ─────────
|
| 146 |
+
testbench_code: str = Field(
|
| 147 |
+
default="", description="Testbench code (populated by view_testbench)"
|
| 148 |
+
)
|
| 149 |
+
log_output: str = Field(
|
| 150 |
+
default="",
|
| 151 |
+
description="Tool output log, truncated to 2000 chars (populated by view_synthesis_log, view_lint_log, view_simulation_log, or tool runs)",
|
| 152 |
+
)
|
| 153 |
+
metadata: Dict[str, Any] = Field(
|
| 154 |
+
default_factory=dict,
|
| 155 |
+
description="Optional extra machine-readable fields for clients/prompts",
|
| 156 |
+
)
|
| 157 |
+
|
| 158 |
+
# ── RL signals ──────────────────────────────────────────────────────
|
| 159 |
+
step_count: int = Field(default=0, description="Steps taken so far")
|
| 160 |
+
max_steps: int = Field(default=20, description="Maximum allowed steps")
|
| 161 |
+
cumulative_reward: float = Field(
|
| 162 |
+
default=0.0,
|
| 163 |
+
description="Total quality score so far (0.0 to 1.0)",
|
| 164 |
+
)
|
obj_dir/Vsim
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e178e8ea680df686c13f65b6251df05731d0476c78554ebd1cb0bd52f28d0ef4
|
| 3 |
+
size 295160
|
obj_dir/Vsim.cpp
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Verilated -*- C++ -*-
|
| 2 |
+
// DESCRIPTION: Verilator output: Model implementation (design independent parts)
|
| 3 |
+
|
| 4 |
+
#include "Vsim__pch.h"
|
| 5 |
+
#include "verilated_vcd_c.h"
|
| 6 |
+
|
| 7 |
+
//============================================================
|
| 8 |
+
// Constructors
|
| 9 |
+
|
| 10 |
+
Vsim::Vsim(VerilatedContext* _vcontextp__, const char* _vcname__)
|
| 11 |
+
: VerilatedModel{*_vcontextp__}
|
| 12 |
+
, vlSymsp{new Vsim__Syms(contextp(), _vcname__, this)}
|
| 13 |
+
, rootp{&(vlSymsp->TOP)}
|
| 14 |
+
{
|
| 15 |
+
// Register model with the context
|
| 16 |
+
contextp()->addModel(this);
|
| 17 |
+
contextp()->traceBaseModelCbAdd(
|
| 18 |
+
[this](VerilatedTraceBaseC* tfp, int levels, int options) { traceBaseModel(tfp, levels, options); });
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
Vsim::Vsim(const char* _vcname__)
|
| 22 |
+
: Vsim(Verilated::threadContextp(), _vcname__)
|
| 23 |
+
{
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
//============================================================
|
| 27 |
+
// Destructor
|
| 28 |
+
|
| 29 |
+
Vsim::~Vsim() {
|
| 30 |
+
delete vlSymsp;
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
//============================================================
|
| 34 |
+
// Evaluation function
|
| 35 |
+
|
| 36 |
+
#ifdef VL_DEBUG
|
| 37 |
+
void Vsim___024root___eval_debug_assertions(Vsim___024root* vlSelf);
|
| 38 |
+
#endif // VL_DEBUG
|
| 39 |
+
void Vsim___024root___eval_static(Vsim___024root* vlSelf);
|
| 40 |
+
void Vsim___024root___eval_initial(Vsim___024root* vlSelf);
|
| 41 |
+
void Vsim___024root___eval_settle(Vsim___024root* vlSelf);
|
| 42 |
+
void Vsim___024root___eval(Vsim___024root* vlSelf);
|
| 43 |
+
|
| 44 |
+
void Vsim::eval_step() {
|
| 45 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+++++TOP Evaluate Vsim::eval_step\n"); );
|
| 46 |
+
#ifdef VL_DEBUG
|
| 47 |
+
// Debug assertions
|
| 48 |
+
Vsim___024root___eval_debug_assertions(&(vlSymsp->TOP));
|
| 49 |
+
#endif // VL_DEBUG
|
| 50 |
+
vlSymsp->__Vm_activity = true;
|
| 51 |
+
vlSymsp->__Vm_deleter.deleteAll();
|
| 52 |
+
if (VL_UNLIKELY(!vlSymsp->__Vm_didInit)) {
|
| 53 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Initial\n"););
|
| 54 |
+
Vsim___024root___eval_static(&(vlSymsp->TOP));
|
| 55 |
+
Vsim___024root___eval_initial(&(vlSymsp->TOP));
|
| 56 |
+
Vsim___024root___eval_settle(&(vlSymsp->TOP));
|
| 57 |
+
vlSymsp->__Vm_didInit = true;
|
| 58 |
+
}
|
| 59 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Eval\n"););
|
| 60 |
+
Vsim___024root___eval(&(vlSymsp->TOP));
|
| 61 |
+
// Evaluate cleanup
|
| 62 |
+
Verilated::endOfEval(vlSymsp->__Vm_evalMsgQp);
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
//============================================================
|
| 66 |
+
// Events and timing
|
| 67 |
+
bool Vsim::eventsPending() { return !vlSymsp->TOP.__VdlySched.empty() && !contextp()->gotFinish(); }
|
| 68 |
+
|
| 69 |
+
uint64_t Vsim::nextTimeSlot() { return vlSymsp->TOP.__VdlySched.nextTimeSlot(); }
|
| 70 |
+
|
| 71 |
+
//============================================================
|
| 72 |
+
// Utilities
|
| 73 |
+
|
| 74 |
+
const char* Vsim::name() const {
|
| 75 |
+
return vlSymsp->name();
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
//============================================================
|
| 79 |
+
// Invoke final blocks
|
| 80 |
+
|
| 81 |
+
void Vsim___024root___eval_final(Vsim___024root* vlSelf);
|
| 82 |
+
|
| 83 |
+
VL_ATTR_COLD void Vsim::final() {
|
| 84 |
+
contextp()->executingFinal(true);
|
| 85 |
+
Vsim___024root___eval_final(&(vlSymsp->TOP));
|
| 86 |
+
contextp()->executingFinal(false);
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
//============================================================
|
| 90 |
+
// Implementations of abstract methods from VerilatedModel
|
| 91 |
+
|
| 92 |
+
const char* Vsim::hierName() const { return vlSymsp->name(); }
|
| 93 |
+
const char* Vsim::modelName() const { return "Vsim"; }
|
| 94 |
+
unsigned Vsim::threads() const { return 1; }
|
| 95 |
+
void Vsim::prepareClone() const { contextp()->prepareClone(); }
|
| 96 |
+
void Vsim::atClone() const {
|
| 97 |
+
contextp()->threadPoolpOnClone();
|
| 98 |
+
}
|
| 99 |
+
std::unique_ptr<VerilatedTraceConfig> Vsim::traceConfig() const {
|
| 100 |
+
return std::unique_ptr<VerilatedTraceConfig>{new VerilatedTraceConfig{false, false, false}};
|
| 101 |
+
};
|
| 102 |
+
|
| 103 |
+
//============================================================
|
| 104 |
+
// Trace configuration
|
| 105 |
+
|
| 106 |
+
void Vsim___024root__trace_decl_types(VerilatedVcd* tracep);
|
| 107 |
+
|
| 108 |
+
void Vsim___024root__trace_init_top(Vsim___024root* vlSelf, VerilatedVcd* tracep);
|
| 109 |
+
|
| 110 |
+
VL_ATTR_COLD static void trace_init(void* voidSelf, VerilatedVcd* tracep, uint32_t code) {
|
| 111 |
+
// Callback from tracep->open()
|
| 112 |
+
Vsim___024root* const __restrict vlSelf VL_ATTR_UNUSED = static_cast<Vsim___024root*>(voidSelf);
|
| 113 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 114 |
+
if (!vlSymsp->_vm_contextp__->calcUnusedSigs()) {
|
| 115 |
+
VL_FATAL_MT(__FILE__, __LINE__, __FILE__,
|
| 116 |
+
"Turning on wave traces requires Verilated::traceEverOn(true) call before time 0.");
|
| 117 |
+
}
|
| 118 |
+
vlSymsp->__Vm_baseCode = code;
|
| 119 |
+
tracep->pushPrefix(vlSymsp->name(), VerilatedTracePrefixType::SCOPE_MODULE);
|
| 120 |
+
Vsim___024root__trace_decl_types(tracep);
|
| 121 |
+
Vsim___024root__trace_init_top(vlSelf, tracep);
|
| 122 |
+
tracep->popPrefix();
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
VL_ATTR_COLD void Vsim___024root__trace_register(Vsim___024root* vlSelf, VerilatedVcd* tracep);
|
| 126 |
+
|
| 127 |
+
VL_ATTR_COLD void Vsim::traceBaseModel(VerilatedTraceBaseC* tfp, int levels, int options) {
|
| 128 |
+
(void)levels; (void)options;
|
| 129 |
+
VerilatedVcdC* const stfp = dynamic_cast<VerilatedVcdC*>(tfp);
|
| 130 |
+
if (VL_UNLIKELY(!stfp)) {
|
| 131 |
+
vl_fatal(__FILE__, __LINE__, __FILE__,"'Vsim::trace()' called on non-VerilatedVcdC object;"
|
| 132 |
+
" use --trace-fst with VerilatedFst object, and --trace-vcd with VerilatedVcd object");
|
| 133 |
+
}
|
| 134 |
+
stfp->spTrace()->addModel(this);
|
| 135 |
+
stfp->spTrace()->addInitCb(&trace_init, &(vlSymsp->TOP), name(), false, 6);
|
| 136 |
+
Vsim___024root__trace_register(&(vlSymsp->TOP), stfp->spTrace());
|
| 137 |
+
}
|
obj_dir/Vsim.h
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Verilated -*- C++ -*-
|
| 2 |
+
// DESCRIPTION: Verilator output: Primary model header
|
| 3 |
+
//
|
| 4 |
+
// This header should be included by all source files instantiating the design.
|
| 5 |
+
// The class here is then constructed to instantiate the design.
|
| 6 |
+
// See the Verilator manual for examples.
|
| 7 |
+
|
| 8 |
+
#ifndef VERILATED_VSIM_H_
|
| 9 |
+
#define VERILATED_VSIM_H_ // guard
|
| 10 |
+
|
| 11 |
+
#include "verilated.h"
|
| 12 |
+
|
| 13 |
+
class Vsim__Syms;
|
| 14 |
+
class Vsim___024root;
|
| 15 |
+
class VerilatedVcdC;
|
| 16 |
+
|
| 17 |
+
// This class is the main interface to the Verilated model
|
| 18 |
+
class alignas(VL_CACHE_LINE_BYTES) Vsim VL_NOT_FINAL : public VerilatedModel {
|
| 19 |
+
private:
|
| 20 |
+
// Symbol table holding complete model state (owned by this class)
|
| 21 |
+
Vsim__Syms* const vlSymsp;
|
| 22 |
+
|
| 23 |
+
public:
|
| 24 |
+
|
| 25 |
+
// CONSTEXPR CAPABILITIES
|
| 26 |
+
// Verilated with --trace?
|
| 27 |
+
static constexpr bool traceCapable = true;
|
| 28 |
+
|
| 29 |
+
// PORTS
|
| 30 |
+
// The application code writes and reads these signals to
|
| 31 |
+
// propagate new values into/out from the Verilated model.
|
| 32 |
+
|
| 33 |
+
// CELLS
|
| 34 |
+
// Public to allow access to /* verilator public */ items.
|
| 35 |
+
// Otherwise the application code can consider these internals.
|
| 36 |
+
|
| 37 |
+
// Root instance pointer to allow access to model internals,
|
| 38 |
+
// including inlined /* verilator public_flat_* */ items.
|
| 39 |
+
Vsim___024root* const rootp;
|
| 40 |
+
|
| 41 |
+
// CONSTRUCTORS
|
| 42 |
+
/// Construct the model; called by application code
|
| 43 |
+
/// If contextp is null, then the model will use the default global context
|
| 44 |
+
/// If name is "", then makes a wrapper with a
|
| 45 |
+
/// single model invisible with respect to DPI scope names.
|
| 46 |
+
explicit Vsim(VerilatedContext* contextp, const char* name = "TOP");
|
| 47 |
+
explicit Vsim(const char* name = "TOP");
|
| 48 |
+
/// Destroy the model; called (often implicitly) by application code
|
| 49 |
+
virtual ~Vsim();
|
| 50 |
+
private:
|
| 51 |
+
VL_UNCOPYABLE(Vsim); ///< Copying not allowed
|
| 52 |
+
|
| 53 |
+
public:
|
| 54 |
+
// API METHODS
|
| 55 |
+
/// Evaluate the model. Application must call when inputs change.
|
| 56 |
+
void eval() { eval_step(); }
|
| 57 |
+
/// Evaluate when calling multiple units/models per time step.
|
| 58 |
+
void eval_step();
|
| 59 |
+
/// Evaluate at end of a timestep for tracing, when using eval_step().
|
| 60 |
+
/// Application must call after all eval() and before time changes.
|
| 61 |
+
void eval_end_step() {}
|
| 62 |
+
/// Simulation complete, run final blocks. Application must call on completion.
|
| 63 |
+
void final();
|
| 64 |
+
/// Are there scheduled events to handle?
|
| 65 |
+
bool eventsPending();
|
| 66 |
+
/// Returns time at next time slot. Aborts if !eventsPending()
|
| 67 |
+
uint64_t nextTimeSlot();
|
| 68 |
+
/// Trace signals in the model; called by application code
|
| 69 |
+
void trace(VerilatedTraceBaseC* tfp, int levels, int options = 0) { contextp()->trace(tfp, levels, options); }
|
| 70 |
+
/// Retrieve name of this model instance (as passed to constructor).
|
| 71 |
+
const char* name() const;
|
| 72 |
+
|
| 73 |
+
// Abstract methods from VerilatedModel
|
| 74 |
+
const char* hierName() const override final;
|
| 75 |
+
const char* modelName() const override final;
|
| 76 |
+
unsigned threads() const override final;
|
| 77 |
+
/// Prepare for cloning the model at the process level (e.g. fork in Linux)
|
| 78 |
+
/// Release necessary resources. Called before cloning.
|
| 79 |
+
void prepareClone() const;
|
| 80 |
+
/// Re-init after cloning the model at the process level (e.g. fork in Linux)
|
| 81 |
+
/// Re-allocate necessary resources. Called after cloning.
|
| 82 |
+
void atClone() const;
|
| 83 |
+
std::unique_ptr<VerilatedTraceConfig> traceConfig() const override final;
|
| 84 |
+
private:
|
| 85 |
+
// Internal functions - trace registration
|
| 86 |
+
void traceBaseModel(VerilatedTraceBaseC* tfp, int levels, int options);
|
| 87 |
+
};
|
| 88 |
+
|
| 89 |
+
#endif // guard
|
obj_dir/Vsim.mk
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Verilated -*- Makefile -*-
|
| 2 |
+
# DESCRIPTION: Verilator output: Makefile for building Verilated archive or executable
|
| 3 |
+
#
|
| 4 |
+
# Execute this makefile from the object directory:
|
| 5 |
+
# make -f Vsim.mk
|
| 6 |
+
|
| 7 |
+
default: Vsim
|
| 8 |
+
|
| 9 |
+
### Constants...
|
| 10 |
+
# Perl executable (from $PERL, defaults to 'perl' if not set)
|
| 11 |
+
PERL = perl
|
| 12 |
+
# Python3 executable (from $PYTHON3, defaults to 'python3' if not set)
|
| 13 |
+
PYTHON3 = python3
|
| 14 |
+
# Path to Verilator kit (from $VERILATOR_ROOT)
|
| 15 |
+
VERILATOR_ROOT = /opt/oss-cad-suite/share/verilator
|
| 16 |
+
# SystemC include directory with systemc.h (from $SYSTEMC_INCLUDE)
|
| 17 |
+
SYSTEMC_INCLUDE ?=
|
| 18 |
+
# SystemC library directory with libsystemc.a (from $SYSTEMC_LIBDIR)
|
| 19 |
+
SYSTEMC_LIBDIR ?=
|
| 20 |
+
|
| 21 |
+
### Switches...
|
| 22 |
+
# C++ code coverage 0/1 (from --prof-c)
|
| 23 |
+
VM_PROFC = 0
|
| 24 |
+
# SystemC output mode? 0/1 (from --sc)
|
| 25 |
+
VM_SC = 0
|
| 26 |
+
# Legacy or SystemC output mode? 0/1 (from --sc)
|
| 27 |
+
VM_SP_OR_SC = $(VM_SC)
|
| 28 |
+
# Deprecated
|
| 29 |
+
VM_PCLI = 1
|
| 30 |
+
# Deprecated: SystemC architecture to find link library path (from $SYSTEMC_ARCH)
|
| 31 |
+
VM_SC_TARGET_ARCH = linux
|
| 32 |
+
|
| 33 |
+
### Vars...
|
| 34 |
+
# Design prefix (from --prefix)
|
| 35 |
+
VM_PREFIX = Vsim
|
| 36 |
+
# Module prefix (from --prefix)
|
| 37 |
+
VM_MODPREFIX = Vsim
|
| 38 |
+
# User CFLAGS (from -CFLAGS on Verilator command line)
|
| 39 |
+
VM_USER_CFLAGS = \
|
| 40 |
+
-DVL_TIME_CONTEXT \
|
| 41 |
+
|
| 42 |
+
# User LDLIBS (from -LDFLAGS on Verilator command line)
|
| 43 |
+
VM_USER_LDLIBS = \
|
| 44 |
+
|
| 45 |
+
# User .cpp files (from .cpp's on Verilator command line)
|
| 46 |
+
VM_USER_CLASSES = \
|
| 47 |
+
|
| 48 |
+
# User .cpp directories (from .cpp's on Verilator command line)
|
| 49 |
+
VM_USER_DIR = \
|
| 50 |
+
.. \
|
| 51 |
+
|
| 52 |
+
### Default rules...
|
| 53 |
+
# Include list of all generated classes
|
| 54 |
+
include Vsim_classes.mk
|
| 55 |
+
# Include global rules
|
| 56 |
+
include $(VERILATOR_ROOT)/include/verilated.mk
|
| 57 |
+
|
| 58 |
+
### Executable rules... (from --exe)
|
| 59 |
+
VPATH += $(VM_USER_DIR)
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
### Link rules... (from --exe)
|
| 63 |
+
Vsim: $(VK_USER_OBJS) $(VK_GLOBAL_OBJS) $(VM_PREFIX)__ALL.a
|
| 64 |
+
$(LINK) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) $(LIBS) $(SC_LIBS) -o $@
|
| 65 |
+
|
| 66 |
+
# Verilated -*- Makefile -*-
|
obj_dir/Vsim__ALL.a
ADDED
|
Binary file (59.4 kB). View file
|
|
|
obj_dir/Vsim__ALL.cpp
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// DESCRIPTION: Generated by verilator_includer via makefile
|
| 2 |
+
#define VL_INCLUDE_OPT include
|
| 3 |
+
#include "Vsim.cpp"
|
| 4 |
+
#include "Vsim___024root__0.cpp"
|
| 5 |
+
#include "Vsim__main.cpp"
|
| 6 |
+
#include "Vsim__Trace__0.cpp"
|
| 7 |
+
#include "Vsim___024root__Slow.cpp"
|
| 8 |
+
#include "Vsim___024root__0__Slow.cpp"
|
| 9 |
+
#include "Vsim__Syms__Slow.cpp"
|
| 10 |
+
#include "Vsim__Trace__0__Slow.cpp"
|
| 11 |
+
#include "Vsim__TraceDecls__0__Slow.cpp"
|
obj_dir/Vsim__ALL.d
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Vsim__ALL.o: Vsim__ALL.cpp Vsim.cpp Vsim__pch.h \
|
| 2 |
+
/opt/oss-cad-suite/share/verilator/include/verilated.h \
|
| 3 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_config.h \
|
| 4 |
+
/opt/oss-cad-suite/share/verilator/include/verilatedos.h \
|
| 5 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_types.h \
|
| 6 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_funcs.h \
|
| 7 |
+
Vsim__Syms.h Vsim.h Vsim___024root.h \
|
| 8 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_timing.h \
|
| 9 |
+
/opt/oss-cad-suite/share/verilator/include/verilated.h \
|
| 10 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_vcd_c.h \
|
| 11 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_trace.h \
|
| 12 |
+
Vsim___024root__0.cpp Vsim__main.cpp Vsim__Trace__0.cpp \
|
| 13 |
+
Vsim___024root__Slow.cpp Vsim___024root__0__Slow.cpp \
|
| 14 |
+
Vsim__Syms__Slow.cpp Vsim__Trace__0__Slow.cpp \
|
| 15 |
+
Vsim__TraceDecls__0__Slow.cpp
|
obj_dir/Vsim__ALL.o
ADDED
|
Binary file (54.2 kB). View file
|
|
|
obj_dir/Vsim__Syms.h
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Verilated -*- C++ -*-
|
| 2 |
+
// DESCRIPTION: Verilator output: Symbol table internal header
|
| 3 |
+
//
|
| 4 |
+
// Internal details; most calling programs do not need this header,
|
| 5 |
+
// unless using verilator public meta comments.
|
| 6 |
+
|
| 7 |
+
#ifndef VERILATED_VSIM__SYMS_H_
|
| 8 |
+
#define VERILATED_VSIM__SYMS_H_ // guard
|
| 9 |
+
|
| 10 |
+
#include "verilated.h"
|
| 11 |
+
|
| 12 |
+
// INCLUDE MODEL CLASS
|
| 13 |
+
|
| 14 |
+
#include "Vsim.h"
|
| 15 |
+
|
| 16 |
+
// INCLUDE MODULE CLASSES
|
| 17 |
+
#include "Vsim___024root.h"
|
| 18 |
+
|
| 19 |
+
// SYMS CLASS (contains all model state)
|
| 20 |
+
class alignas(VL_CACHE_LINE_BYTES) Vsim__Syms final : public VerilatedSyms {
|
| 21 |
+
public:
|
| 22 |
+
// INTERNAL STATE
|
| 23 |
+
Vsim* const __Vm_modelp;
|
| 24 |
+
bool __Vm_activity = false; ///< Used by trace routines to determine change occurred
|
| 25 |
+
uint32_t __Vm_baseCode = 0; ///< Used by trace routines when tracing multiple models
|
| 26 |
+
VlDeleter __Vm_deleter;
|
| 27 |
+
bool __Vm_didInit = false;
|
| 28 |
+
|
| 29 |
+
// MODULE INSTANCE STATE
|
| 30 |
+
Vsim___024root TOP;
|
| 31 |
+
|
| 32 |
+
// CONSTRUCTORS
|
| 33 |
+
Vsim__Syms(VerilatedContext* contextp, const char* namep, Vsim* modelp);
|
| 34 |
+
~Vsim__Syms();
|
| 35 |
+
|
| 36 |
+
// METHODS
|
| 37 |
+
const char* name() const { return TOP.vlNamep; }
|
| 38 |
+
};
|
| 39 |
+
|
| 40 |
+
#endif // guard
|
obj_dir/Vsim__Syms__Slow.cpp
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Verilated -*- C++ -*-
|
| 2 |
+
// DESCRIPTION: Verilator output: Symbol table implementation internals
|
| 3 |
+
|
| 4 |
+
#include "Vsim__pch.h"
|
| 5 |
+
|
| 6 |
+
Vsim__Syms::Vsim__Syms(VerilatedContext* contextp, const char* namep, Vsim* modelp)
|
| 7 |
+
: VerilatedSyms{contextp}
|
| 8 |
+
// Setup internal state of the Syms class
|
| 9 |
+
, __Vm_modelp{modelp}
|
| 10 |
+
// Setup top module instance
|
| 11 |
+
, TOP{this, namep}
|
| 12 |
+
{
|
| 13 |
+
// Check resources
|
| 14 |
+
Verilated::stackCheck(256);
|
| 15 |
+
// Setup sub module instances
|
| 16 |
+
// Configure time unit / time precision
|
| 17 |
+
_vm_contextp__->timeunit(-9);
|
| 18 |
+
_vm_contextp__->timeprecision(-12);
|
| 19 |
+
// Setup each module's pointers to their submodules
|
| 20 |
+
// Setup each module's pointer back to symbol table (for public functions)
|
| 21 |
+
TOP.__Vconfigure(true);
|
| 22 |
+
// Setup scopes
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
Vsim__Syms::~Vsim__Syms() {
|
| 26 |
+
// Tear down scopes
|
| 27 |
+
// Tear down sub module instances
|
| 28 |
+
}
|
obj_dir/Vsim__TraceDecls__0__Slow.cpp
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Verilated -*- C++ -*-
|
| 2 |
+
// DESCRIPTION: Verilator output: Tracing declarations
|
| 3 |
+
|
| 4 |
+
#include "verilated_vcd_c.h"
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
void Vsim___024root__traceDeclTypesSub0(VerilatedVcd* tracep) {
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
void Vsim___024root__trace_decl_types(VerilatedVcd* tracep) {
|
| 11 |
+
Vsim___024root__traceDeclTypesSub0(tracep);
|
| 12 |
+
}
|
obj_dir/Vsim__Trace__0.cpp
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Verilated -*- C++ -*-
|
| 2 |
+
// DESCRIPTION: Verilator output: Tracing implementation internals
|
| 3 |
+
|
| 4 |
+
#include "verilated_vcd_c.h"
|
| 5 |
+
#include "Vsim__Syms.h"
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
void Vsim___024root__trace_chg_0_sub_0(Vsim___024root* vlSelf, VerilatedVcd::Buffer* bufp);
|
| 9 |
+
|
| 10 |
+
void Vsim___024root__trace_chg_0(void* voidSelf, VerilatedVcd::Buffer* bufp) {
|
| 11 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root__trace_chg_0\n"); );
|
| 12 |
+
// Body
|
| 13 |
+
Vsim___024root* const __restrict vlSelf VL_ATTR_UNUSED = static_cast<Vsim___024root*>(voidSelf);
|
| 14 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 15 |
+
if (VL_UNLIKELY(!vlSymsp->__Vm_activity)) return;
|
| 16 |
+
Vsim___024root__trace_chg_0_sub_0((&vlSymsp->TOP), bufp);
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
void Vsim___024root__trace_chg_0_sub_0(Vsim___024root* vlSelf, VerilatedVcd::Buffer* bufp) {
|
| 20 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root__trace_chg_0_sub_0\n"); );
|
| 21 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 22 |
+
auto& vlSelfRef = std::ref(*vlSelf).get();
|
| 23 |
+
// Body
|
| 24 |
+
uint32_t* const oldp VL_ATTR_UNUSED = bufp->oldp(vlSymsp->__Vm_baseCode + 0);
|
| 25 |
+
if (VL_UNLIKELY(((vlSelfRef.__Vm_traceActivity[1U]
|
| 26 |
+
| vlSelfRef.__Vm_traceActivity[2U])))) {
|
| 27 |
+
bufp->chgBit(oldp+0,(vlSelfRef.tb_full_adder__DOT__a));
|
| 28 |
+
bufp->chgBit(oldp+1,(vlSelfRef.tb_full_adder__DOT__b));
|
| 29 |
+
bufp->chgBit(oldp+2,(vlSelfRef.tb_full_adder__DOT__cin));
|
| 30 |
+
bufp->chgBit(oldp+3,(((IData)(vlSelfRef.tb_full_adder__DOT__cin)
|
| 31 |
+
^ ((IData)(vlSelfRef.tb_full_adder__DOT__a)
|
| 32 |
+
^ (IData)(vlSelfRef.tb_full_adder__DOT__b)))));
|
| 33 |
+
bufp->chgBit(oldp+4,((((IData)(vlSelfRef.tb_full_adder__DOT__a)
|
| 34 |
+
& (IData)(vlSelfRef.tb_full_adder__DOT__b))
|
| 35 |
+
| ((IData)(vlSelfRef.tb_full_adder__DOT__cin)
|
| 36 |
+
& ((IData)(vlSelfRef.tb_full_adder__DOT__a)
|
| 37 |
+
| (IData)(vlSelfRef.tb_full_adder__DOT__b))))));
|
| 38 |
+
bufp->chgBit(oldp+5,(((IData)(vlSelfRef.tb_full_adder__DOT__a)
|
| 39 |
+
^ (IData)(vlSelfRef.tb_full_adder__DOT__b))));
|
| 40 |
+
}
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
void Vsim___024root__trace_cleanup(void* voidSelf, VerilatedVcd* /*unused*/) {
|
| 44 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root__trace_cleanup\n"); );
|
| 45 |
+
// Body
|
| 46 |
+
Vsim___024root* const __restrict vlSelf VL_ATTR_UNUSED = static_cast<Vsim___024root*>(voidSelf);
|
| 47 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 48 |
+
vlSymsp->__Vm_activity = false;
|
| 49 |
+
vlSymsp->TOP.__Vm_traceActivity[0U] = 0U;
|
| 50 |
+
vlSymsp->TOP.__Vm_traceActivity[1U] = 0U;
|
| 51 |
+
vlSymsp->TOP.__Vm_traceActivity[2U] = 0U;
|
| 52 |
+
}
|
obj_dir/Vsim__Trace__0__Slow.cpp
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Verilated -*- C++ -*-
|
| 2 |
+
// DESCRIPTION: Verilator output: Tracing implementation internals
|
| 3 |
+
|
| 4 |
+
#include "verilated_vcd_c.h"
|
| 5 |
+
#include "Vsim__Syms.h"
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
VL_ATTR_COLD void Vsim___024root__trace_init_sub__TOP__0(Vsim___024root* vlSelf, VerilatedVcd* tracep) {
|
| 9 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root__trace_init_sub__TOP__0\n"); );
|
| 10 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 11 |
+
auto& vlSelfRef = std::ref(*vlSelf).get();
|
| 12 |
+
// Body
|
| 13 |
+
const int c = vlSymsp->__Vm_baseCode;
|
| 14 |
+
VL_TRACE_PUSH_PREFIX(tracep, "tb_full_adder", VerilatedTracePrefixType::SCOPE_MODULE, 0, 0);
|
| 15 |
+
VL_TRACE_DECL_BIT(tracep,c+0,0,"a",-1, VerilatedTraceSigDirection::NONE, VerilatedTraceSigKind::VAR, VerilatedTraceSigType::LOGIC);
|
| 16 |
+
VL_TRACE_DECL_BIT(tracep,c+1,0,"b",-1, VerilatedTraceSigDirection::NONE, VerilatedTraceSigKind::VAR, VerilatedTraceSigType::LOGIC);
|
| 17 |
+
VL_TRACE_DECL_BIT(tracep,c+2,0,"cin",-1, VerilatedTraceSigDirection::NONE, VerilatedTraceSigKind::VAR, VerilatedTraceSigType::LOGIC);
|
| 18 |
+
VL_TRACE_DECL_BIT(tracep,c+3,0,"sum",-1, VerilatedTraceSigDirection::NONE, VerilatedTraceSigKind::WIRE, VerilatedTraceSigType::LOGIC);
|
| 19 |
+
VL_TRACE_DECL_BIT(tracep,c+4,0,"cout",-1, VerilatedTraceSigDirection::NONE, VerilatedTraceSigKind::WIRE, VerilatedTraceSigType::LOGIC);
|
| 20 |
+
VL_TRACE_PUSH_PREFIX(tracep, "uut", VerilatedTracePrefixType::SCOPE_MODULE, 0, 0);
|
| 21 |
+
VL_TRACE_DECL_BIT(tracep,c+0,0,"a",-1, VerilatedTraceSigDirection::INPUT, VerilatedTraceSigKind::WIRE, VerilatedTraceSigType::LOGIC);
|
| 22 |
+
VL_TRACE_DECL_BIT(tracep,c+1,0,"b",-1, VerilatedTraceSigDirection::INPUT, VerilatedTraceSigKind::WIRE, VerilatedTraceSigType::LOGIC);
|
| 23 |
+
VL_TRACE_DECL_BIT(tracep,c+2,0,"cin",-1, VerilatedTraceSigDirection::INPUT, VerilatedTraceSigKind::WIRE, VerilatedTraceSigType::LOGIC);
|
| 24 |
+
VL_TRACE_DECL_BIT(tracep,c+3,0,"sum",-1, VerilatedTraceSigDirection::OUTPUT, VerilatedTraceSigKind::WIRE, VerilatedTraceSigType::LOGIC);
|
| 25 |
+
VL_TRACE_DECL_BIT(tracep,c+4,0,"cout",-1, VerilatedTraceSigDirection::OUTPUT, VerilatedTraceSigKind::WIRE, VerilatedTraceSigType::LOGIC);
|
| 26 |
+
VL_TRACE_DECL_BIT(tracep,c+5,0,"x1",-1, VerilatedTraceSigDirection::NONE, VerilatedTraceSigKind::WIRE, VerilatedTraceSigType::LOGIC);
|
| 27 |
+
VL_TRACE_DECL_BIT(tracep,c+5,0,"x2",-1, VerilatedTraceSigDirection::NONE, VerilatedTraceSigKind::WIRE, VerilatedTraceSigType::LOGIC);
|
| 28 |
+
VL_TRACE_DECL_BIT(tracep,c+3,0,"x3",-1, VerilatedTraceSigDirection::NONE, VerilatedTraceSigKind::WIRE, VerilatedTraceSigType::LOGIC);
|
| 29 |
+
VL_TRACE_DECL_BIT(tracep,c+4,0,"x4",-1, VerilatedTraceSigDirection::NONE, VerilatedTraceSigKind::WIRE, VerilatedTraceSigType::LOGIC);
|
| 30 |
+
VL_TRACE_DECL_BIT(tracep,c+3,0,"temp",-1, VerilatedTraceSigDirection::NONE, VerilatedTraceSigKind::WIRE, VerilatedTraceSigType::LOGIC);
|
| 31 |
+
VL_TRACE_POP_PREFIX(tracep);
|
| 32 |
+
VL_TRACE_POP_PREFIX(tracep);
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
VL_ATTR_COLD void Vsim___024root__trace_init_top(Vsim___024root* vlSelf, VerilatedVcd* tracep) {
|
| 36 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root__trace_init_top\n"); );
|
| 37 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 38 |
+
auto& vlSelfRef = std::ref(*vlSelf).get();
|
| 39 |
+
// Body
|
| 40 |
+
Vsim___024root__trace_init_sub__TOP__0(vlSelf, tracep);
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
VL_ATTR_COLD void Vsim___024root__trace_const_0(void* voidSelf, VerilatedVcd::Buffer* bufp);
|
| 44 |
+
VL_ATTR_COLD void Vsim___024root__trace_full_0(void* voidSelf, VerilatedVcd::Buffer* bufp);
|
| 45 |
+
void Vsim___024root__trace_chg_0(void* voidSelf, VerilatedVcd::Buffer* bufp);
|
| 46 |
+
void Vsim___024root__trace_cleanup(void* voidSelf, VerilatedVcd* /*unused*/);
|
| 47 |
+
|
| 48 |
+
VL_ATTR_COLD void Vsim___024root__trace_register(Vsim___024root* vlSelf, VerilatedVcd* tracep) {
|
| 49 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root__trace_register\n"); );
|
| 50 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 51 |
+
auto& vlSelfRef = std::ref(*vlSelf).get();
|
| 52 |
+
// Body
|
| 53 |
+
tracep->addConstCb(&Vsim___024root__trace_const_0, 0, vlSelf);
|
| 54 |
+
tracep->addFullCb(&Vsim___024root__trace_full_0, 0, vlSelf);
|
| 55 |
+
tracep->addChgCb(&Vsim___024root__trace_chg_0, 0, vlSelf);
|
| 56 |
+
tracep->addCleanupCb(&Vsim___024root__trace_cleanup, vlSelf);
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
VL_ATTR_COLD void Vsim___024root__trace_const_0(void* voidSelf, VerilatedVcd::Buffer* bufp) {
|
| 60 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root__trace_const_0\n"); );
|
| 61 |
+
// Body
|
| 62 |
+
Vsim___024root* const __restrict vlSelf VL_ATTR_UNUSED = static_cast<Vsim___024root*>(voidSelf);
|
| 63 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
VL_ATTR_COLD void Vsim___024root__trace_full_0_sub_0(Vsim___024root* vlSelf, VerilatedVcd::Buffer* bufp);
|
| 67 |
+
|
| 68 |
+
VL_ATTR_COLD void Vsim___024root__trace_full_0(void* voidSelf, VerilatedVcd::Buffer* bufp) {
|
| 69 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root__trace_full_0\n"); );
|
| 70 |
+
// Body
|
| 71 |
+
Vsim___024root* const __restrict vlSelf VL_ATTR_UNUSED = static_cast<Vsim___024root*>(voidSelf);
|
| 72 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 73 |
+
Vsim___024root__trace_full_0_sub_0((&vlSymsp->TOP), bufp);
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
VL_ATTR_COLD void Vsim___024root__trace_full_0_sub_0(Vsim___024root* vlSelf, VerilatedVcd::Buffer* bufp) {
|
| 77 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root__trace_full_0_sub_0\n"); );
|
| 78 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 79 |
+
auto& vlSelfRef = std::ref(*vlSelf).get();
|
| 80 |
+
// Body
|
| 81 |
+
uint32_t* const oldp VL_ATTR_UNUSED = bufp->oldp(vlSymsp->__Vm_baseCode);
|
| 82 |
+
bufp->fullBit(oldp+0,(vlSelfRef.tb_full_adder__DOT__a));
|
| 83 |
+
bufp->fullBit(oldp+1,(vlSelfRef.tb_full_adder__DOT__b));
|
| 84 |
+
bufp->fullBit(oldp+2,(vlSelfRef.tb_full_adder__DOT__cin));
|
| 85 |
+
bufp->fullBit(oldp+3,(((IData)(vlSelfRef.tb_full_adder__DOT__cin)
|
| 86 |
+
^ ((IData)(vlSelfRef.tb_full_adder__DOT__a)
|
| 87 |
+
^ (IData)(vlSelfRef.tb_full_adder__DOT__b)))));
|
| 88 |
+
bufp->fullBit(oldp+4,((((IData)(vlSelfRef.tb_full_adder__DOT__a)
|
| 89 |
+
& (IData)(vlSelfRef.tb_full_adder__DOT__b))
|
| 90 |
+
| ((IData)(vlSelfRef.tb_full_adder__DOT__cin)
|
| 91 |
+
& ((IData)(vlSelfRef.tb_full_adder__DOT__a)
|
| 92 |
+
| (IData)(vlSelfRef.tb_full_adder__DOT__b))))));
|
| 93 |
+
bufp->fullBit(oldp+5,(((IData)(vlSelfRef.tb_full_adder__DOT__a)
|
| 94 |
+
^ (IData)(vlSelfRef.tb_full_adder__DOT__b))));
|
| 95 |
+
}
|
obj_dir/Vsim___024root.h
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Verilated -*- C++ -*-
|
| 2 |
+
// DESCRIPTION: Verilator output: Design internal header
|
| 3 |
+
// See Vsim.h for the primary calling header
|
| 4 |
+
|
| 5 |
+
#ifndef VERILATED_VSIM___024ROOT_H_
|
| 6 |
+
#define VERILATED_VSIM___024ROOT_H_ // guard
|
| 7 |
+
|
| 8 |
+
#include "verilated.h"
|
| 9 |
+
#include "verilated_timing.h"
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
class Vsim__Syms;
|
| 13 |
+
|
| 14 |
+
class alignas(VL_CACHE_LINE_BYTES) Vsim___024root final {
|
| 15 |
+
public:
|
| 16 |
+
|
| 17 |
+
// DESIGN SPECIFIC STATE
|
| 18 |
+
CData/*0:0*/ tb_full_adder__DOT__a;
|
| 19 |
+
CData/*0:0*/ tb_full_adder__DOT__b;
|
| 20 |
+
CData/*0:0*/ tb_full_adder__DOT__cin;
|
| 21 |
+
CData/*0:0*/ tb_full_adder__DOT__uut__DOT__sum;
|
| 22 |
+
CData/*0:0*/ tb_full_adder__DOT__uut__DOT__cout;
|
| 23 |
+
CData/*0:0*/ __VstlFirstIteration;
|
| 24 |
+
CData/*0:0*/ __VstlPhaseResult;
|
| 25 |
+
CData/*0:0*/ __VactPhaseResult;
|
| 26 |
+
CData/*0:0*/ __VinactPhaseResult;
|
| 27 |
+
CData/*0:0*/ __VnbaPhaseResult;
|
| 28 |
+
IData/*31:0*/ __VactIterCount;
|
| 29 |
+
IData/*31:0*/ __VinactIterCount;
|
| 30 |
+
IData/*31:0*/ __Vi;
|
| 31 |
+
VlUnpacked<QData/*63:0*/, 1> __VstlTriggered;
|
| 32 |
+
VlUnpacked<QData/*63:0*/, 1> __VactTriggered;
|
| 33 |
+
VlUnpacked<QData/*63:0*/, 1> __VactTriggeredAcc;
|
| 34 |
+
VlUnpacked<QData/*63:0*/, 1> __VnbaTriggered;
|
| 35 |
+
VlUnpacked<CData/*0:0*/, 3> __Vm_traceActivity;
|
| 36 |
+
VlDelayScheduler __VdlySched;
|
| 37 |
+
|
| 38 |
+
// INTERNAL VARIABLES
|
| 39 |
+
Vsim__Syms* vlSymsp;
|
| 40 |
+
const char* vlNamep;
|
| 41 |
+
|
| 42 |
+
// CONSTRUCTORS
|
| 43 |
+
Vsim___024root(Vsim__Syms* symsp, const char* namep);
|
| 44 |
+
~Vsim___024root();
|
| 45 |
+
VL_UNCOPYABLE(Vsim___024root);
|
| 46 |
+
|
| 47 |
+
// INTERNAL METHODS
|
| 48 |
+
void __Vconfigure(bool first);
|
| 49 |
+
};
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
#endif // guard
|
obj_dir/Vsim___024root__0.cpp
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Verilated -*- C++ -*-
|
| 2 |
+
// DESCRIPTION: Verilator output: Design implementation internals
|
| 3 |
+
// See Vsim.h for the primary calling header
|
| 4 |
+
|
| 5 |
+
#include "Vsim__pch.h"
|
| 6 |
+
|
| 7 |
+
VlCoroutine Vsim___024root___eval_initial__TOP__Vtiming__0(Vsim___024root* vlSelf);
|
| 8 |
+
|
| 9 |
+
void Vsim___024root___eval_initial(Vsim___024root* vlSelf) {
|
| 10 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___eval_initial\n"); );
|
| 11 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 12 |
+
auto& vlSelfRef = std::ref(*vlSelf).get();
|
| 13 |
+
// Body
|
| 14 |
+
Vsim___024root___eval_initial__TOP__Vtiming__0(vlSelf);
|
| 15 |
+
vlSelfRef.__Vm_traceActivity[1U] = 1U;
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
VlCoroutine Vsim___024root___eval_initial__TOP__Vtiming__0(Vsim___024root* vlSelf) {
|
| 19 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___eval_initial__TOP__Vtiming__0\n"); );
|
| 20 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 21 |
+
auto& vlSelfRef = std::ref(*vlSelf).get();
|
| 22 |
+
// Body
|
| 23 |
+
VL_WRITEF_NX("a b cin | sum cout\n-------------------\n",0);
|
| 24 |
+
vlSelfRef.tb_full_adder__DOT__a = 0U;
|
| 25 |
+
vlSelfRef.tb_full_adder__DOT__b = 0U;
|
| 26 |
+
vlSelfRef.tb_full_adder__DOT__cin = 0U;
|
| 27 |
+
co_await vlSelfRef.__VdlySched.delay(0x0000000000002710ULL,
|
| 28 |
+
nullptr, "/workspace/.tmp_verilator/testbench.sv",
|
| 29 |
+
26);
|
| 30 |
+
vlSelfRef.__Vm_traceActivity[2U] = 1U;
|
| 31 |
+
VL_WRITEF_NX("%b %b %b | %b %b\n",5, '#',1,vlSelfRef.tb_full_adder__DOT__a
|
| 32 |
+
, '#',1,(IData)(vlSelfRef.tb_full_adder__DOT__b)
|
| 33 |
+
, '#',1,vlSelfRef.tb_full_adder__DOT__cin
|
| 34 |
+
, '#',1,(IData)(vlSelfRef.tb_full_adder__DOT__uut__DOT__sum)
|
| 35 |
+
, '#',1,vlSelfRef.tb_full_adder__DOT__uut__DOT__cout);
|
| 36 |
+
vlSelfRef.tb_full_adder__DOT__a = 0U;
|
| 37 |
+
vlSelfRef.tb_full_adder__DOT__b = 0U;
|
| 38 |
+
vlSelfRef.tb_full_adder__DOT__cin = 1U;
|
| 39 |
+
co_await vlSelfRef.__VdlySched.delay(0x0000000000002710ULL,
|
| 40 |
+
nullptr, "/workspace/.tmp_verilator/testbench.sv",
|
| 41 |
+
29);
|
| 42 |
+
vlSelfRef.__Vm_traceActivity[2U] = 1U;
|
| 43 |
+
VL_WRITEF_NX("%b %b %b | %b %b\n",5, '#',1,vlSelfRef.tb_full_adder__DOT__a
|
| 44 |
+
, '#',1,(IData)(vlSelfRef.tb_full_adder__DOT__b)
|
| 45 |
+
, '#',1,vlSelfRef.tb_full_adder__DOT__cin
|
| 46 |
+
, '#',1,(IData)(vlSelfRef.tb_full_adder__DOT__uut__DOT__sum)
|
| 47 |
+
, '#',1,vlSelfRef.tb_full_adder__DOT__uut__DOT__cout);
|
| 48 |
+
vlSelfRef.tb_full_adder__DOT__a = 0U;
|
| 49 |
+
vlSelfRef.tb_full_adder__DOT__b = 1U;
|
| 50 |
+
vlSelfRef.tb_full_adder__DOT__cin = 0U;
|
| 51 |
+
co_await vlSelfRef.__VdlySched.delay(0x0000000000002710ULL,
|
| 52 |
+
nullptr, "/workspace/.tmp_verilator/testbench.sv",
|
| 53 |
+
32);
|
| 54 |
+
vlSelfRef.__Vm_traceActivity[2U] = 1U;
|
| 55 |
+
VL_WRITEF_NX("%b %b %b | %b %b\n",5, '#',1,vlSelfRef.tb_full_adder__DOT__a
|
| 56 |
+
, '#',1,(IData)(vlSelfRef.tb_full_adder__DOT__b)
|
| 57 |
+
, '#',1,vlSelfRef.tb_full_adder__DOT__cin
|
| 58 |
+
, '#',1,(IData)(vlSelfRef.tb_full_adder__DOT__uut__DOT__sum)
|
| 59 |
+
, '#',1,vlSelfRef.tb_full_adder__DOT__uut__DOT__cout);
|
| 60 |
+
vlSelfRef.tb_full_adder__DOT__a = 0U;
|
| 61 |
+
vlSelfRef.tb_full_adder__DOT__b = 1U;
|
| 62 |
+
vlSelfRef.tb_full_adder__DOT__cin = 1U;
|
| 63 |
+
co_await vlSelfRef.__VdlySched.delay(0x0000000000002710ULL,
|
| 64 |
+
nullptr, "/workspace/.tmp_verilator/testbench.sv",
|
| 65 |
+
35);
|
| 66 |
+
vlSelfRef.__Vm_traceActivity[2U] = 1U;
|
| 67 |
+
VL_WRITEF_NX("%b %b %b | %b %b\n",5, '#',1,vlSelfRef.tb_full_adder__DOT__a
|
| 68 |
+
, '#',1,(IData)(vlSelfRef.tb_full_adder__DOT__b)
|
| 69 |
+
, '#',1,vlSelfRef.tb_full_adder__DOT__cin
|
| 70 |
+
, '#',1,(IData)(vlSelfRef.tb_full_adder__DOT__uut__DOT__sum)
|
| 71 |
+
, '#',1,vlSelfRef.tb_full_adder__DOT__uut__DOT__cout);
|
| 72 |
+
vlSelfRef.tb_full_adder__DOT__a = 1U;
|
| 73 |
+
vlSelfRef.tb_full_adder__DOT__b = 0U;
|
| 74 |
+
vlSelfRef.tb_full_adder__DOT__cin = 0U;
|
| 75 |
+
co_await vlSelfRef.__VdlySched.delay(0x0000000000002710ULL,
|
| 76 |
+
nullptr, "/workspace/.tmp_verilator/testbench.sv",
|
| 77 |
+
38);
|
| 78 |
+
vlSelfRef.__Vm_traceActivity[2U] = 1U;
|
| 79 |
+
VL_WRITEF_NX("%b %b %b | %b %b\n",5, '#',1,vlSelfRef.tb_full_adder__DOT__a
|
| 80 |
+
, '#',1,(IData)(vlSelfRef.tb_full_adder__DOT__b)
|
| 81 |
+
, '#',1,vlSelfRef.tb_full_adder__DOT__cin
|
| 82 |
+
, '#',1,(IData)(vlSelfRef.tb_full_adder__DOT__uut__DOT__sum)
|
| 83 |
+
, '#',1,vlSelfRef.tb_full_adder__DOT__uut__DOT__cout);
|
| 84 |
+
vlSelfRef.tb_full_adder__DOT__a = 1U;
|
| 85 |
+
vlSelfRef.tb_full_adder__DOT__b = 0U;
|
| 86 |
+
vlSelfRef.tb_full_adder__DOT__cin = 1U;
|
| 87 |
+
co_await vlSelfRef.__VdlySched.delay(0x0000000000002710ULL,
|
| 88 |
+
nullptr, "/workspace/.tmp_verilator/testbench.sv",
|
| 89 |
+
41);
|
| 90 |
+
vlSelfRef.__Vm_traceActivity[2U] = 1U;
|
| 91 |
+
VL_WRITEF_NX("%b %b %b | %b %b\n",5, '#',1,vlSelfRef.tb_full_adder__DOT__a
|
| 92 |
+
, '#',1,(IData)(vlSelfRef.tb_full_adder__DOT__b)
|
| 93 |
+
, '#',1,vlSelfRef.tb_full_adder__DOT__cin
|
| 94 |
+
, '#',1,(IData)(vlSelfRef.tb_full_adder__DOT__uut__DOT__sum)
|
| 95 |
+
, '#',1,vlSelfRef.tb_full_adder__DOT__uut__DOT__cout);
|
| 96 |
+
vlSelfRef.tb_full_adder__DOT__a = 1U;
|
| 97 |
+
vlSelfRef.tb_full_adder__DOT__b = 1U;
|
| 98 |
+
vlSelfRef.tb_full_adder__DOT__cin = 0U;
|
| 99 |
+
co_await vlSelfRef.__VdlySched.delay(0x0000000000002710ULL,
|
| 100 |
+
nullptr, "/workspace/.tmp_verilator/testbench.sv",
|
| 101 |
+
44);
|
| 102 |
+
vlSelfRef.__Vm_traceActivity[2U] = 1U;
|
| 103 |
+
VL_WRITEF_NX("%b %b %b | %b %b\n",5, '#',1,vlSelfRef.tb_full_adder__DOT__a
|
| 104 |
+
, '#',1,(IData)(vlSelfRef.tb_full_adder__DOT__b)
|
| 105 |
+
, '#',1,vlSelfRef.tb_full_adder__DOT__cin
|
| 106 |
+
, '#',1,(IData)(vlSelfRef.tb_full_adder__DOT__uut__DOT__sum)
|
| 107 |
+
, '#',1,vlSelfRef.tb_full_adder__DOT__uut__DOT__cout);
|
| 108 |
+
vlSelfRef.tb_full_adder__DOT__a = 1U;
|
| 109 |
+
vlSelfRef.tb_full_adder__DOT__b = 1U;
|
| 110 |
+
vlSelfRef.tb_full_adder__DOT__cin = 1U;
|
| 111 |
+
co_await vlSelfRef.__VdlySched.delay(0x0000000000002710ULL,
|
| 112 |
+
nullptr, "/workspace/.tmp_verilator/testbench.sv",
|
| 113 |
+
47);
|
| 114 |
+
vlSelfRef.__Vm_traceActivity[2U] = 1U;
|
| 115 |
+
VL_WRITEF_NX("%b %b %b | %b %b\n",5, '#',1,vlSelfRef.tb_full_adder__DOT__a
|
| 116 |
+
, '#',1,(IData)(vlSelfRef.tb_full_adder__DOT__b)
|
| 117 |
+
, '#',1,vlSelfRef.tb_full_adder__DOT__cin
|
| 118 |
+
, '#',1,(IData)(vlSelfRef.tb_full_adder__DOT__uut__DOT__sum)
|
| 119 |
+
, '#',1,vlSelfRef.tb_full_adder__DOT__uut__DOT__cout);
|
| 120 |
+
VL_FINISH_MT("/workspace/.tmp_verilator/testbench.sv", 50, "");
|
| 121 |
+
vlSelfRef.__Vm_traceActivity[2U] = 1U;
|
| 122 |
+
co_return;
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
void Vsim___024root___eval_triggers_vec__act(Vsim___024root* vlSelf) {
|
| 126 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___eval_triggers_vec__act\n"); );
|
| 127 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 128 |
+
auto& vlSelfRef = std::ref(*vlSelf).get();
|
| 129 |
+
// Body
|
| 130 |
+
vlSelfRef.__VactTriggered[0U] = (QData)((IData)(vlSelfRef.__VdlySched.awaitingCurrentTime()));
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
bool Vsim___024root___trigger_anySet__act(const VlUnpacked<QData/*63:0*/, 1> &in) {
|
| 134 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___trigger_anySet__act\n"); );
|
| 135 |
+
// Locals
|
| 136 |
+
IData/*31:0*/ n;
|
| 137 |
+
// Body
|
| 138 |
+
n = 0U;
|
| 139 |
+
do {
|
| 140 |
+
if (in[n]) {
|
| 141 |
+
return (1U);
|
| 142 |
+
}
|
| 143 |
+
n = ((IData)(1U) + n);
|
| 144 |
+
} while ((1U > n));
|
| 145 |
+
return (0U);
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
void Vsim___024root___act_sequent__TOP__0(Vsim___024root* vlSelf) {
|
| 149 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___act_sequent__TOP__0\n"); );
|
| 150 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 151 |
+
auto& vlSelfRef = std::ref(*vlSelf).get();
|
| 152 |
+
// Body
|
| 153 |
+
vlSelfRef.tb_full_adder__DOT__uut__DOT__sum = ((IData)(vlSelfRef.tb_full_adder__DOT__cin)
|
| 154 |
+
^
|
| 155 |
+
((IData)(vlSelfRef.tb_full_adder__DOT__a)
|
| 156 |
+
^ (IData)(vlSelfRef.tb_full_adder__DOT__b)));
|
| 157 |
+
vlSelfRef.tb_full_adder__DOT__uut__DOT__cout =
|
| 158 |
+
(((IData)(vlSelfRef.tb_full_adder__DOT__a)
|
| 159 |
+
& (IData)(vlSelfRef.tb_full_adder__DOT__b))
|
| 160 |
+
| ((IData)(vlSelfRef.tb_full_adder__DOT__cin)
|
| 161 |
+
& ((IData)(vlSelfRef.tb_full_adder__DOT__a)
|
| 162 |
+
| (IData)(vlSelfRef.tb_full_adder__DOT__b))));
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
void Vsim___024root___eval_act(Vsim___024root* vlSelf) {
|
| 166 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___eval_act\n"); );
|
| 167 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 168 |
+
auto& vlSelfRef = std::ref(*vlSelf).get();
|
| 169 |
+
// Body
|
| 170 |
+
if ((1ULL & vlSelfRef.__VactTriggered[0U])) {
|
| 171 |
+
Vsim___024root___act_sequent__TOP__0(vlSelf);
|
| 172 |
+
}
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
void Vsim___024root___eval_nba(Vsim___024root* vlSelf) {
|
| 176 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___eval_nba\n"); );
|
| 177 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 178 |
+
auto& vlSelfRef = std::ref(*vlSelf).get();
|
| 179 |
+
// Body
|
| 180 |
+
if ((1ULL & vlSelfRef.__VnbaTriggered[0U])) {
|
| 181 |
+
Vsim___024root___act_sequent__TOP__0(vlSelf);
|
| 182 |
+
}
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
void Vsim___024root___timing_resume(Vsim___024root* vlSelf) {
|
| 186 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___timing_resume\n"); );
|
| 187 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 188 |
+
auto& vlSelfRef = std::ref(*vlSelf).get();
|
| 189 |
+
// Body
|
| 190 |
+
if ((1ULL & vlSelfRef.__VactTriggered[0U])) {
|
| 191 |
+
vlSelfRef.__VdlySched.resume();
|
| 192 |
+
}
|
| 193 |
+
}
|
| 194 |
+
|
| 195 |
+
void Vsim___024root___trigger_orInto__act_vec_vec(VlUnpacked<QData/*63:0*/, 1> &out, const VlUnpacked<QData/*63:0*/, 1> &in) {
|
| 196 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___trigger_orInto__act_vec_vec\n"); );
|
| 197 |
+
// Locals
|
| 198 |
+
IData/*31:0*/ n;
|
| 199 |
+
// Body
|
| 200 |
+
n = 0U;
|
| 201 |
+
do {
|
| 202 |
+
out[n] = (out[n] | in[n]);
|
| 203 |
+
n = ((IData)(1U) + n);
|
| 204 |
+
} while ((0U >= n));
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
+
#ifdef VL_DEBUG
|
| 208 |
+
VL_ATTR_COLD void Vsim___024root___dump_triggers__act(const VlUnpacked<QData/*63:0*/, 1> &triggers, const std::string &tag);
|
| 209 |
+
#endif // VL_DEBUG
|
| 210 |
+
|
| 211 |
+
bool Vsim___024root___eval_phase__act(Vsim___024root* vlSelf) {
|
| 212 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___eval_phase__act\n"); );
|
| 213 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 214 |
+
auto& vlSelfRef = std::ref(*vlSelf).get();
|
| 215 |
+
// Locals
|
| 216 |
+
CData/*0:0*/ __VactExecute;
|
| 217 |
+
// Body
|
| 218 |
+
Vsim___024root___eval_triggers_vec__act(vlSelf);
|
| 219 |
+
Vsim___024root___trigger_orInto__act_vec_vec(vlSelfRef.__VactTriggered, vlSelfRef.__VactTriggeredAcc);
|
| 220 |
+
#ifdef VL_DEBUG
|
| 221 |
+
if (VL_UNLIKELY(vlSymsp->_vm_contextp__->debug())) {
|
| 222 |
+
Vsim___024root___dump_triggers__act(vlSelfRef.__VactTriggered, "act"s);
|
| 223 |
+
}
|
| 224 |
+
#endif
|
| 225 |
+
Vsim___024root___trigger_orInto__act_vec_vec(vlSelfRef.__VnbaTriggered, vlSelfRef.__VactTriggered);
|
| 226 |
+
__VactExecute = Vsim___024root___trigger_anySet__act(vlSelfRef.__VactTriggered);
|
| 227 |
+
if (__VactExecute) {
|
| 228 |
+
vlSelfRef.__VactTriggeredAcc.fill(0ULL);
|
| 229 |
+
Vsim___024root___timing_resume(vlSelf);
|
| 230 |
+
Vsim___024root___eval_act(vlSelf);
|
| 231 |
+
}
|
| 232 |
+
return (__VactExecute);
|
| 233 |
+
}
|
| 234 |
+
|
| 235 |
+
bool Vsim___024root___eval_phase__inact(Vsim___024root* vlSelf) {
|
| 236 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___eval_phase__inact\n"); );
|
| 237 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 238 |
+
auto& vlSelfRef = std::ref(*vlSelf).get();
|
| 239 |
+
// Locals
|
| 240 |
+
CData/*0:0*/ __VinactExecute;
|
| 241 |
+
// Body
|
| 242 |
+
__VinactExecute = vlSelfRef.__VdlySched.awaitingZeroDelay();
|
| 243 |
+
if (__VinactExecute) {
|
| 244 |
+
VL_FATAL_MT("/workspace/.tmp_verilator/testbench.sv", 3, "", "ZERODLY: Design Verilated with '--no-sched-zero-delay', but #0 delay executed at runtime");
|
| 245 |
+
}
|
| 246 |
+
return (__VinactExecute);
|
| 247 |
+
}
|
| 248 |
+
|
| 249 |
+
void Vsim___024root___trigger_clear__act(VlUnpacked<QData/*63:0*/, 1> &out) {
|
| 250 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___trigger_clear__act\n"); );
|
| 251 |
+
// Locals
|
| 252 |
+
IData/*31:0*/ n;
|
| 253 |
+
// Body
|
| 254 |
+
n = 0U;
|
| 255 |
+
do {
|
| 256 |
+
out[n] = 0ULL;
|
| 257 |
+
n = ((IData)(1U) + n);
|
| 258 |
+
} while ((1U > n));
|
| 259 |
+
}
|
| 260 |
+
|
| 261 |
+
bool Vsim___024root___eval_phase__nba(Vsim___024root* vlSelf) {
|
| 262 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___eval_phase__nba\n"); );
|
| 263 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 264 |
+
auto& vlSelfRef = std::ref(*vlSelf).get();
|
| 265 |
+
// Locals
|
| 266 |
+
CData/*0:0*/ __VnbaExecute;
|
| 267 |
+
// Body
|
| 268 |
+
__VnbaExecute = Vsim___024root___trigger_anySet__act(vlSelfRef.__VnbaTriggered);
|
| 269 |
+
if (__VnbaExecute) {
|
| 270 |
+
Vsim___024root___eval_nba(vlSelf);
|
| 271 |
+
Vsim___024root___trigger_clear__act(vlSelfRef.__VnbaTriggered);
|
| 272 |
+
}
|
| 273 |
+
return (__VnbaExecute);
|
| 274 |
+
}
|
| 275 |
+
|
| 276 |
+
void Vsim___024root___eval(Vsim___024root* vlSelf) {
|
| 277 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___eval\n"); );
|
| 278 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 279 |
+
auto& vlSelfRef = std::ref(*vlSelf).get();
|
| 280 |
+
// Locals
|
| 281 |
+
IData/*31:0*/ __VnbaIterCount;
|
| 282 |
+
// Body
|
| 283 |
+
__VnbaIterCount = 0U;
|
| 284 |
+
do {
|
| 285 |
+
if (VL_UNLIKELY(((0x00002710U < __VnbaIterCount)))) {
|
| 286 |
+
#ifdef VL_DEBUG
|
| 287 |
+
Vsim___024root___dump_triggers__act(vlSelfRef.__VnbaTriggered, "nba"s);
|
| 288 |
+
#endif
|
| 289 |
+
VL_FATAL_MT("/workspace/.tmp_verilator/testbench.sv", 3, "", "DIDNOTCONVERGE: NBA region did not converge after '--converge-limit' of 10000 tries");
|
| 290 |
+
}
|
| 291 |
+
__VnbaIterCount = ((IData)(1U) + __VnbaIterCount);
|
| 292 |
+
vlSelfRef.__VinactIterCount = 0U;
|
| 293 |
+
do {
|
| 294 |
+
if (VL_UNLIKELY(((0x00002710U < vlSelfRef.__VinactIterCount)))) {
|
| 295 |
+
VL_FATAL_MT("/workspace/.tmp_verilator/testbench.sv", 3, "", "DIDNOTCONVERGE: Inactive region did not converge after '--converge-limit' of 10000 tries");
|
| 296 |
+
}
|
| 297 |
+
vlSelfRef.__VinactIterCount = ((IData)(1U)
|
| 298 |
+
+ vlSelfRef.__VinactIterCount);
|
| 299 |
+
vlSelfRef.__VactIterCount = 0U;
|
| 300 |
+
do {
|
| 301 |
+
if (VL_UNLIKELY(((0x00002710U < vlSelfRef.__VactIterCount)))) {
|
| 302 |
+
#ifdef VL_DEBUG
|
| 303 |
+
Vsim___024root___dump_triggers__act(vlSelfRef.__VactTriggered, "act"s);
|
| 304 |
+
#endif
|
| 305 |
+
VL_FATAL_MT("/workspace/.tmp_verilator/testbench.sv", 3, "", "DIDNOTCONVERGE: Active region did not converge after '--converge-limit' of 10000 tries");
|
| 306 |
+
}
|
| 307 |
+
vlSelfRef.__VactIterCount = ((IData)(1U)
|
| 308 |
+
+ vlSelfRef.__VactIterCount);
|
| 309 |
+
vlSelfRef.__VactPhaseResult = Vsim___024root___eval_phase__act(vlSelf);
|
| 310 |
+
} while (vlSelfRef.__VactPhaseResult);
|
| 311 |
+
vlSelfRef.__VinactPhaseResult = Vsim___024root___eval_phase__inact(vlSelf);
|
| 312 |
+
} while (vlSelfRef.__VinactPhaseResult);
|
| 313 |
+
vlSelfRef.__VnbaPhaseResult = Vsim___024root___eval_phase__nba(vlSelf);
|
| 314 |
+
} while (vlSelfRef.__VnbaPhaseResult);
|
| 315 |
+
}
|
| 316 |
+
|
| 317 |
+
#ifdef VL_DEBUG
|
| 318 |
+
void Vsim___024root___eval_debug_assertions(Vsim___024root* vlSelf) {
|
| 319 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___eval_debug_assertions\n"); );
|
| 320 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 321 |
+
auto& vlSelfRef = std::ref(*vlSelf).get();
|
| 322 |
+
}
|
| 323 |
+
#endif // VL_DEBUG
|
obj_dir/Vsim___024root__0__Slow.cpp
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Verilated -*- C++ -*-
|
| 2 |
+
// DESCRIPTION: Verilator output: Design implementation internals
|
| 3 |
+
// See Vsim.h for the primary calling header
|
| 4 |
+
|
| 5 |
+
#include "Vsim__pch.h"
|
| 6 |
+
|
| 7 |
+
VL_ATTR_COLD void Vsim___024root___eval_static(Vsim___024root* vlSelf) {
|
| 8 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___eval_static\n"); );
|
| 9 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 10 |
+
auto& vlSelfRef = std::ref(*vlSelf).get();
|
| 11 |
+
// Body
|
| 12 |
+
do {
|
| 13 |
+
vlSelfRef.__VactTriggeredAcc[vlSelfRef.__Vi]
|
| 14 |
+
= vlSelfRef.__VactTriggered[vlSelfRef.__Vi];
|
| 15 |
+
vlSelfRef.__Vi = ((IData)(1U) + vlSelfRef.__Vi);
|
| 16 |
+
} while ((0U >= vlSelfRef.__Vi));
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
VL_ATTR_COLD void Vsim___024root___eval_final(Vsim___024root* vlSelf) {
|
| 20 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___eval_final\n"); );
|
| 21 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 22 |
+
auto& vlSelfRef = std::ref(*vlSelf).get();
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
#ifdef VL_DEBUG
|
| 26 |
+
VL_ATTR_COLD void Vsim___024root___dump_triggers__stl(const VlUnpacked<QData/*63:0*/, 1> &triggers, const std::string &tag);
|
| 27 |
+
#endif // VL_DEBUG
|
| 28 |
+
VL_ATTR_COLD bool Vsim___024root___eval_phase__stl(Vsim___024root* vlSelf);
|
| 29 |
+
|
| 30 |
+
VL_ATTR_COLD void Vsim___024root___eval_settle(Vsim___024root* vlSelf) {
|
| 31 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___eval_settle\n"); );
|
| 32 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 33 |
+
auto& vlSelfRef = std::ref(*vlSelf).get();
|
| 34 |
+
// Locals
|
| 35 |
+
IData/*31:0*/ __VstlIterCount;
|
| 36 |
+
// Body
|
| 37 |
+
__VstlIterCount = 0U;
|
| 38 |
+
vlSelfRef.__VstlFirstIteration = 1U;
|
| 39 |
+
do {
|
| 40 |
+
if (VL_UNLIKELY(((0x00002710U < __VstlIterCount)))) {
|
| 41 |
+
#ifdef VL_DEBUG
|
| 42 |
+
Vsim___024root___dump_triggers__stl(vlSelfRef.__VstlTriggered, "stl"s);
|
| 43 |
+
#endif
|
| 44 |
+
VL_FATAL_MT("/workspace/.tmp_verilator/testbench.sv", 3, "", "DIDNOTCONVERGE: Settle region did not converge after '--converge-limit' of 10000 tries");
|
| 45 |
+
}
|
| 46 |
+
__VstlIterCount = ((IData)(1U) + __VstlIterCount);
|
| 47 |
+
vlSelfRef.__VstlPhaseResult = Vsim___024root___eval_phase__stl(vlSelf);
|
| 48 |
+
vlSelfRef.__VstlFirstIteration = 0U;
|
| 49 |
+
} while (vlSelfRef.__VstlPhaseResult);
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
VL_ATTR_COLD void Vsim___024root___eval_triggers_vec__stl(Vsim___024root* vlSelf) {
|
| 53 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___eval_triggers_vec__stl\n"); );
|
| 54 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 55 |
+
auto& vlSelfRef = std::ref(*vlSelf).get();
|
| 56 |
+
// Body
|
| 57 |
+
vlSelfRef.__VstlTriggered[0U] = ((0xfffffffffffffffeULL
|
| 58 |
+
& vlSelfRef.__VstlTriggered[0U])
|
| 59 |
+
| (IData)((IData)(vlSelfRef.__VstlFirstIteration)));
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
VL_ATTR_COLD bool Vsim___024root___trigger_anySet__stl(const VlUnpacked<QData/*63:0*/, 1> &in);
|
| 63 |
+
|
| 64 |
+
#ifdef VL_DEBUG
|
| 65 |
+
VL_ATTR_COLD void Vsim___024root___dump_triggers__stl(const VlUnpacked<QData/*63:0*/, 1> &triggers, const std::string &tag) {
|
| 66 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___dump_triggers__stl\n"); );
|
| 67 |
+
// Body
|
| 68 |
+
if ((1U & (~ (IData)(Vsim___024root___trigger_anySet__stl(triggers))))) {
|
| 69 |
+
VL_DBG_MSGS(" No '" + tag + "' region triggers active\n");
|
| 70 |
+
}
|
| 71 |
+
if ((1U & (IData)(triggers[0U]))) {
|
| 72 |
+
VL_DBG_MSGS(" '" + tag + "' region trigger index 0 is active: Internal 'stl' trigger - first iteration\n");
|
| 73 |
+
}
|
| 74 |
+
}
|
| 75 |
+
#endif // VL_DEBUG
|
| 76 |
+
|
| 77 |
+
VL_ATTR_COLD bool Vsim___024root___trigger_anySet__stl(const VlUnpacked<QData/*63:0*/, 1> &in) {
|
| 78 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___trigger_anySet__stl\n"); );
|
| 79 |
+
// Locals
|
| 80 |
+
IData/*31:0*/ n;
|
| 81 |
+
// Body
|
| 82 |
+
n = 0U;
|
| 83 |
+
do {
|
| 84 |
+
if (in[n]) {
|
| 85 |
+
return (1U);
|
| 86 |
+
}
|
| 87 |
+
n = ((IData)(1U) + n);
|
| 88 |
+
} while ((1U > n));
|
| 89 |
+
return (0U);
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
void Vsim___024root___act_sequent__TOP__0(Vsim___024root* vlSelf);
|
| 93 |
+
|
| 94 |
+
VL_ATTR_COLD void Vsim___024root___eval_stl(Vsim___024root* vlSelf) {
|
| 95 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___eval_stl\n"); );
|
| 96 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 97 |
+
auto& vlSelfRef = std::ref(*vlSelf).get();
|
| 98 |
+
// Body
|
| 99 |
+
if ((1ULL & vlSelfRef.__VstlTriggered[0U])) {
|
| 100 |
+
Vsim___024root___act_sequent__TOP__0(vlSelf);
|
| 101 |
+
}
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
VL_ATTR_COLD bool Vsim___024root___eval_phase__stl(Vsim___024root* vlSelf) {
|
| 105 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___eval_phase__stl\n"); );
|
| 106 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 107 |
+
auto& vlSelfRef = std::ref(*vlSelf).get();
|
| 108 |
+
// Locals
|
| 109 |
+
CData/*0:0*/ __VstlExecute;
|
| 110 |
+
// Body
|
| 111 |
+
Vsim___024root___eval_triggers_vec__stl(vlSelf);
|
| 112 |
+
#ifdef VL_DEBUG
|
| 113 |
+
if (VL_UNLIKELY(vlSymsp->_vm_contextp__->debug())) {
|
| 114 |
+
Vsim___024root___dump_triggers__stl(vlSelfRef.__VstlTriggered, "stl"s);
|
| 115 |
+
}
|
| 116 |
+
#endif
|
| 117 |
+
__VstlExecute = Vsim___024root___trigger_anySet__stl(vlSelfRef.__VstlTriggered);
|
| 118 |
+
if (__VstlExecute) {
|
| 119 |
+
Vsim___024root___eval_stl(vlSelf);
|
| 120 |
+
}
|
| 121 |
+
return (__VstlExecute);
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
bool Vsim___024root___trigger_anySet__act(const VlUnpacked<QData/*63:0*/, 1> &in);
|
| 125 |
+
|
| 126 |
+
#ifdef VL_DEBUG
|
| 127 |
+
VL_ATTR_COLD void Vsim___024root___dump_triggers__act(const VlUnpacked<QData/*63:0*/, 1> &triggers, const std::string &tag) {
|
| 128 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___dump_triggers__act\n"); );
|
| 129 |
+
// Body
|
| 130 |
+
if ((1U & (~ (IData)(Vsim___024root___trigger_anySet__act(triggers))))) {
|
| 131 |
+
VL_DBG_MSGS(" No '" + tag + "' region triggers active\n");
|
| 132 |
+
}
|
| 133 |
+
if ((1U & (IData)(triggers[0U]))) {
|
| 134 |
+
VL_DBG_MSGS(" '" + tag + "' region trigger index 0 is active: @([true] __VdlySched.awaitingCurrentTime())\n");
|
| 135 |
+
}
|
| 136 |
+
}
|
| 137 |
+
#endif // VL_DEBUG
|
| 138 |
+
|
| 139 |
+
VL_ATTR_COLD void Vsim___024root___ctor_var_reset(Vsim___024root* vlSelf) {
|
| 140 |
+
VL_DEBUG_IF(VL_DBG_MSGF("+ Vsim___024root___ctor_var_reset\n"); );
|
| 141 |
+
Vsim__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
|
| 142 |
+
auto& vlSelfRef = std::ref(*vlSelf).get();
|
| 143 |
+
// Body
|
| 144 |
+
const uint64_t __VscopeHash = VL_MURMUR64_HASH(vlSelf->vlNamep);
|
| 145 |
+
vlSelf->tb_full_adder__DOT__a = VL_SCOPED_RAND_RESET_I(1, __VscopeHash, 13747735994981389321ull);
|
| 146 |
+
vlSelf->tb_full_adder__DOT__b = VL_SCOPED_RAND_RESET_I(1, __VscopeHash, 686105649783556071ull);
|
| 147 |
+
vlSelf->tb_full_adder__DOT__cin = VL_SCOPED_RAND_RESET_I(1, __VscopeHash, 4012772730186193120ull);
|
| 148 |
+
vlSelf->tb_full_adder__DOT__uut__DOT__sum = VL_SCOPED_RAND_RESET_I(1, __VscopeHash, 13287595272639865983ull);
|
| 149 |
+
vlSelf->tb_full_adder__DOT__uut__DOT__cout = VL_SCOPED_RAND_RESET_I(1, __VscopeHash, 13664396158812022014ull);
|
| 150 |
+
for (int __Vi0 = 0; __Vi0 < 1; ++__Vi0) {
|
| 151 |
+
vlSelf->__VstlTriggered[__Vi0] = 0;
|
| 152 |
+
}
|
| 153 |
+
for (int __Vi0 = 0; __Vi0 < 1; ++__Vi0) {
|
| 154 |
+
vlSelf->__VactTriggered[__Vi0] = 0;
|
| 155 |
+
}
|
| 156 |
+
for (int __Vi0 = 0; __Vi0 < 1; ++__Vi0) {
|
| 157 |
+
vlSelf->__VactTriggeredAcc[__Vi0] = 0;
|
| 158 |
+
}
|
| 159 |
+
for (int __Vi0 = 0; __Vi0 < 1; ++__Vi0) {
|
| 160 |
+
vlSelf->__VnbaTriggered[__Vi0] = 0;
|
| 161 |
+
}
|
| 162 |
+
vlSelf->__Vi = 0;
|
| 163 |
+
for (int __Vi0 = 0; __Vi0 < 3; ++__Vi0) {
|
| 164 |
+
vlSelf->__Vm_traceActivity[__Vi0] = 0;
|
| 165 |
+
}
|
| 166 |
+
}
|
obj_dir/Vsim___024root__Slow.cpp
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Verilated -*- C++ -*-
|
| 2 |
+
// DESCRIPTION: Verilator output: Design implementation internals
|
| 3 |
+
// See Vsim.h for the primary calling header
|
| 4 |
+
|
| 5 |
+
#include "Vsim__pch.h"
|
| 6 |
+
|
| 7 |
+
void Vsim___024root___ctor_var_reset(Vsim___024root* vlSelf);
|
| 8 |
+
|
| 9 |
+
Vsim___024root::Vsim___024root(Vsim__Syms* symsp, const char* namep)
|
| 10 |
+
: __VdlySched{*symsp->_vm_contextp__}
|
| 11 |
+
{
|
| 12 |
+
vlSymsp = symsp;
|
| 13 |
+
vlNamep = strdup(namep);
|
| 14 |
+
// Reset structure values
|
| 15 |
+
Vsim___024root___ctor_var_reset(this);
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
void Vsim___024root::__Vconfigure(bool first) {
|
| 19 |
+
(void)first; // Prevent unused variable warning
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
Vsim___024root::~Vsim___024root() {
|
| 23 |
+
VL_DO_DANGLING(std::free(const_cast<char*>(vlNamep)), vlNamep);
|
| 24 |
+
}
|
obj_dir/Vsim__main.cpp
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Verilated -*- C++ -*-
|
| 2 |
+
// DESCRIPTION: Verilator output: main() simulation loop, created with --main
|
| 3 |
+
|
| 4 |
+
#include "verilated.h"
|
| 5 |
+
#include "Vsim.h"
|
| 6 |
+
|
| 7 |
+
//======================
|
| 8 |
+
|
| 9 |
+
int main(int argc, char** argv, char**) {
|
| 10 |
+
// Setup context, defaults, and parse command line
|
| 11 |
+
Verilated::debug(0);
|
| 12 |
+
const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};
|
| 13 |
+
contextp->traceEverOn(true);
|
| 14 |
+
contextp->threads(1);
|
| 15 |
+
contextp->commandArgs(argc, argv);
|
| 16 |
+
|
| 17 |
+
// Construct the Verilated model, from Vtop.h generated from Verilating
|
| 18 |
+
const std::unique_ptr<Vsim> topp{new Vsim{contextp.get(), ""}};
|
| 19 |
+
|
| 20 |
+
// Simulate until $finish
|
| 21 |
+
while (VL_LIKELY(!contextp->gotFinish())) {
|
| 22 |
+
// Evaluate model
|
| 23 |
+
topp->eval();
|
| 24 |
+
// Advance time
|
| 25 |
+
if (!topp->eventsPending()) break;
|
| 26 |
+
contextp->time(topp->nextTimeSlot());
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
if (VL_LIKELY(!contextp->gotFinish())) {
|
| 30 |
+
VL_DEBUG_IF(VL_PRINTF("+ Exiting without $finish; no events left\n"););
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
// Execute 'final' processes
|
| 34 |
+
topp->final();
|
| 35 |
+
|
| 36 |
+
// Print statistical summary report
|
| 37 |
+
contextp->statsPrintSummary();
|
| 38 |
+
|
| 39 |
+
return 0;
|
| 40 |
+
}
|
obj_dir/Vsim__pch.h
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Verilated -*- C++ -*-
|
| 2 |
+
// DESCRIPTION: Verilator output: Precompiled header
|
| 3 |
+
//
|
| 4 |
+
// Internal details; most user sources do not need this header,
|
| 5 |
+
// unless using verilator public meta comments.
|
| 6 |
+
// Suggest use Vsim.h instead.
|
| 7 |
+
|
| 8 |
+
#ifndef VERILATED_VSIM__PCH_H_
|
| 9 |
+
#define VERILATED_VSIM__PCH_H_ // guard
|
| 10 |
+
|
| 11 |
+
// GCC and Clang only will precompile headers (PCH) for the first header.
|
| 12 |
+
// So, make sure this is the one and only PCH.
|
| 13 |
+
// If multiple module's includes are needed, use individual includes.
|
| 14 |
+
#ifdef VL_PCH_INCLUDED
|
| 15 |
+
# error "Including multiple precompiled header files"
|
| 16 |
+
#endif
|
| 17 |
+
#define VL_PCH_INCLUDED
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
#include "verilated.h"
|
| 21 |
+
|
| 22 |
+
#include "Vsim__Syms.h"
|
| 23 |
+
#include "Vsim.h"
|
| 24 |
+
|
| 25 |
+
// Additional include files added using '--compiler-include'
|
| 26 |
+
|
| 27 |
+
#endif // guard
|
obj_dir/Vsim__ver.d
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
obj_dir/Vsim.cpp obj_dir/Vsim.h obj_dir/Vsim.mk obj_dir/Vsim__Syms.h obj_dir/Vsim__Syms__Slow.cpp obj_dir/Vsim__TraceDecls__0__Slow.cpp obj_dir/Vsim__Trace__0.cpp obj_dir/Vsim__Trace__0__Slow.cpp obj_dir/Vsim___024root.h obj_dir/Vsim___024root__0.cpp obj_dir/Vsim___024root__0__Slow.cpp obj_dir/Vsim___024root__Slow.cpp obj_dir/Vsim__main.cpp obj_dir/Vsim__pch.h obj_dir/Vsim__ver.d obj_dir/Vsim_classes.mk : /opt/oss-cad-suite/libexec/verilator_bin /opt/oss-cad-suite/libexec/verilator_bin /opt/oss-cad-suite/share/verilator/include/verilated_std.sv /opt/oss-cad-suite/share/verilator/include/verilated_std_waiver.vlt /workspace/.tmp_verilator/design.sv /workspace/.tmp_verilator/testbench.sv
|
obj_dir/Vsim__verFiles.dat
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# DESCRIPTION: Verilator output: Timestamp data for --skip-identical. Delete at will.
|
| 2 |
+
C "--prefix Vsim --binary --build-jobs 0 --build --trace-vcd --quiet-build -Wno-fatal --timescale 1ns/1ns /workspace/.tmp_verilator/design.sv /workspace/.tmp_verilator/testbench.sv"
|
| 3 |
+
S 15470064 408335 1775589273 781926010 1775535881 0 "unhashed" "/opt/oss-cad-suite/libexec/verilator_bin"
|
| 4 |
+
S 7905 417104 1775589275 228926010 1775535881 0 "vaoJo7Sb62R3p7xvCJKmh57f4Cpmx2GHt7zuj5gO" "/opt/oss-cad-suite/share/verilator/include/verilated_std.sv"
|
| 5 |
+
S 3224 417105 1775589275 228926010 1775535881 0 "Hydzkv9X77JH03JyZeFi7tBFnQaHV7yknXQxBZFr" "/opt/oss-cad-suite/share/verilator/include/verilated_std_waiver.vlt"
|
| 6 |
+
S 508 23 1775588927 379763036 1775588927 379763036 "RzP0e7y9BjAWuxPxEHd8sMbLhVMBBykyireN9BO5" "/workspace/.tmp_verilator/design.sv"
|
| 7 |
+
S 994 22 1775588850 546387233 1775588850 546387233 "MJHSal6XoThtIDgaccnyRos1QWroJuR0B5ti7XBh" "/workspace/.tmp_verilator/testbench.sv"
|
| 8 |
+
T 5052 28 1775589279 970070246 1775589279 970070246 "unhashed" "obj_dir/Vsim.cpp"
|
| 9 |
+
T 3496 27 1775589279 969891205 1775589279 969891205 "unhashed" "obj_dir/Vsim.h"
|
| 10 |
+
T 1850 39 1775589279 972469243 1775589279 972469243 "unhashed" "obj_dir/Vsim.mk"
|
| 11 |
+
T 1100 26 1775589279 969740413 1775589279 969740413 "unhashed" "obj_dir/Vsim__Syms.h"
|
| 12 |
+
T 851 25 1775589279 969551330 1775589279 969551330 "unhashed" "obj_dir/Vsim__Syms__Slow.cpp"
|
| 13 |
+
T 291 34 1775589279 971867244 1775589279 971867244 "unhashed" "obj_dir/Vsim__TraceDecls__0__Slow.cpp"
|
| 14 |
+
T 2687 36 1775589279 972046036 1775589279 972046036 "unhashed" "obj_dir/Vsim__Trace__0.cpp"
|
| 15 |
+
T 6323 35 1775589279 971777952 1775589279 971777952 "unhashed" "obj_dir/Vsim__Trace__0__Slow.cpp"
|
| 16 |
+
T 1476 30 1775589279 970559246 1775589279 970559246 "unhashed" "obj_dir/Vsim___024root.h"
|
| 17 |
+
T 15367 33 1775589279 971426953 1775589279 971426953 "unhashed" "obj_dir/Vsim___024root__0.cpp"
|
| 18 |
+
T 6982 32 1775589279 971074662 1775589279 971074662 "unhashed" "obj_dir/Vsim___024root__0__Slow.cpp"
|
| 19 |
+
T 674 31 1775589279 970776829 1775589279 970776829 "unhashed" "obj_dir/Vsim___024root__Slow.cpp"
|
| 20 |
+
T 1137 37 1775589279 972180619 1775589279 972180619 "unhashed" "obj_dir/Vsim__main.cpp"
|
| 21 |
+
T 745 29 1775589279 970367704 1775589279 970367704 "unhashed" "obj_dir/Vsim__pch.h"
|
| 22 |
+
T 696 40 1775589279 972557452 1775589279 972557452 "unhashed" "obj_dir/Vsim__ver.d"
|
| 23 |
+
T 0 0 1775589279 972619952 1775589279 972619952 "unhashed" "obj_dir/Vsim__verFiles.dat"
|
| 24 |
+
T 1745 38 1775589279 972333494 1775589279 972333494 "unhashed" "obj_dir/Vsim_classes.mk"
|
obj_dir/Vsim_classes.mk
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Verilated -*- Makefile -*-
|
| 2 |
+
# DESCRIPTION: Verilator output: Make include file with class lists
|
| 3 |
+
#
|
| 4 |
+
# This file lists generated Verilated files, for including in higher level makefiles.
|
| 5 |
+
# See Vsim.mk for the caller.
|
| 6 |
+
|
| 7 |
+
### Switches...
|
| 8 |
+
# C11 constructs required? 0/1 (always on now)
|
| 9 |
+
VM_C11 = 1
|
| 10 |
+
# Timing enabled? 0/1
|
| 11 |
+
VM_TIMING = 1
|
| 12 |
+
# Coverage output mode? 0/1 (from --coverage)
|
| 13 |
+
VM_COVERAGE = 0
|
| 14 |
+
# Parallel builds? 0/1 (from --output-split)
|
| 15 |
+
VM_PARALLEL_BUILDS = 0
|
| 16 |
+
# Tracing output mode? 0/1 (from --trace-fst/--trace-saif/--trace-vcd)
|
| 17 |
+
VM_TRACE = 1
|
| 18 |
+
# Tracing output mode in FST format? 0/1 (from --trace-fst)
|
| 19 |
+
VM_TRACE_FST = 0
|
| 20 |
+
# Tracing output mode in SAIF format? 0/1 (from --trace-saif)
|
| 21 |
+
VM_TRACE_SAIF = 0
|
| 22 |
+
# Tracing output mode in VCD format? 0/1 (from --trace-vcd)
|
| 23 |
+
VM_TRACE_VCD = 1
|
| 24 |
+
|
| 25 |
+
### Object file lists...
|
| 26 |
+
# Generated module classes, fast-path, compile with highest optimization
|
| 27 |
+
VM_CLASSES_FAST += \
|
| 28 |
+
Vsim \
|
| 29 |
+
Vsim___024root__0 \
|
| 30 |
+
Vsim__main \
|
| 31 |
+
|
| 32 |
+
# Generated module classes, non-fast-path, compile with low/medium optimization
|
| 33 |
+
VM_CLASSES_SLOW += \
|
| 34 |
+
Vsim___024root__Slow \
|
| 35 |
+
Vsim___024root__0__Slow \
|
| 36 |
+
|
| 37 |
+
# Generated support classes, fast-path, compile with highest optimization
|
| 38 |
+
VM_SUPPORT_FAST += \
|
| 39 |
+
Vsim__Trace__0 \
|
| 40 |
+
|
| 41 |
+
# Generated support classes, non-fast-path, compile with low/medium optimization
|
| 42 |
+
VM_SUPPORT_SLOW += \
|
| 43 |
+
Vsim__Syms__Slow \
|
| 44 |
+
Vsim__Trace__0__Slow \
|
| 45 |
+
Vsim__TraceDecls__0__Slow \
|
| 46 |
+
|
| 47 |
+
# Global classes, need linked once per executable, fast-path, compile with highest optimization
|
| 48 |
+
VM_GLOBAL_FAST += \
|
| 49 |
+
verilated \
|
| 50 |
+
verilated_vcd_c \
|
| 51 |
+
verilated_timing \
|
| 52 |
+
verilated_threads \
|
| 53 |
+
|
| 54 |
+
# Global classes, need linked once per executable, non-fast-path, compile with low/medium optimization
|
| 55 |
+
VM_GLOBAL_SLOW += \
|
| 56 |
+
|
| 57 |
+
# Verilated -*- Makefile -*-
|
obj_dir/verilated.d
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
verilated.o: /opt/oss-cad-suite/share/verilator/include/verilated.cpp \
|
| 2 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_config.h \
|
| 3 |
+
/opt/oss-cad-suite/share/verilator/include/verilatedos.h \
|
| 4 |
+
/opt/oss-cad-suite/share/verilator/include/verilated.h \
|
| 5 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_types.h \
|
| 6 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_funcs.h \
|
| 7 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_imp.h \
|
| 8 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_syms.h \
|
| 9 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_sym_props.h \
|
| 10 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_threads.h \
|
| 11 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_trace.h \
|
| 12 |
+
/opt/oss-cad-suite/share/verilator/include/verilatedos_c.h
|
obj_dir/verilated.o
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:c15e0086becf59dedb31cd5b4e20cfab3c618ecba86e0aeda2d5e8c2bf9c6177
|
| 3 |
+
size 254520
|
obj_dir/verilated_threads.d
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
verilated_threads.o: \
|
| 2 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_threads.cpp \
|
| 3 |
+
/opt/oss-cad-suite/share/verilator/include/verilatedos.h \
|
| 4 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_threads.h \
|
| 5 |
+
/opt/oss-cad-suite/share/verilator/include/verilated.h \
|
| 6 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_config.h \
|
| 7 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_types.h \
|
| 8 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_funcs.h
|
obj_dir/verilated_threads.o
ADDED
|
Binary file (64 kB). View file
|
|
|
obj_dir/verilated_timing.d
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
verilated_timing.o: \
|
| 2 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_timing.cpp \
|
| 3 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_timing.h \
|
| 4 |
+
/opt/oss-cad-suite/share/verilator/include/verilated.h \
|
| 5 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_config.h \
|
| 6 |
+
/opt/oss-cad-suite/share/verilator/include/verilatedos.h \
|
| 7 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_types.h \
|
| 8 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_funcs.h
|
obj_dir/verilated_timing.o
ADDED
|
Binary file (16.2 kB). View file
|
|
|
obj_dir/verilated_vcd_c.d
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
verilated_vcd_c.o: \
|
| 2 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_vcd_c.cpp \
|
| 3 |
+
/opt/oss-cad-suite/share/verilator/include/verilatedos.h \
|
| 4 |
+
/opt/oss-cad-suite/share/verilator/include/verilated.h \
|
| 5 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_config.h \
|
| 6 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_types.h \
|
| 7 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_funcs.h \
|
| 8 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_vcd_c.h \
|
| 9 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_trace.h \
|
| 10 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_trace_imp.h \
|
| 11 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_intrinsics.h \
|
| 12 |
+
/opt/oss-cad-suite/share/verilator/include/verilated_threads.h
|
obj_dir/verilated_vcd_c.o
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:2669196c2cea7409e4fab856394490d9fab4a106e07737af067725680845979f
|
| 3 |
+
size 132968
|
openenv.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
spec_version: 1
|
| 2 |
+
name: chipforge
|
| 3 |
+
type: space
|
| 4 |
+
runtime: fastapi
|
| 5 |
+
app: server.app:app
|
| 6 |
+
port: 8000
|
| 7 |
+
|
openenv_chipforge.egg-info/PKG-INFO
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Metadata-Version: 2.4
|
| 2 |
+
Name: openenv-chipforge
|
| 3 |
+
Version: 0.1.0
|
| 4 |
+
Summary: Chipforge environment for OpenEnv
|
| 5 |
+
Requires-Python: >=3.10
|
| 6 |
+
Requires-Dist: openenv-core[core]>=0.2.2
|
| 7 |
+
Requires-Dist: mistralai>=1.0.0
|
| 8 |
+
Requires-Dist: python-dotenv>=1.0.0
|
| 9 |
+
Requires-Dist: websocket-client>=1.9.0
|
| 10 |
+
Provides-Extra: dev
|
| 11 |
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
| 12 |
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
openenv_chipforge.egg-info/SOURCES.txt
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
README.md
|
| 2 |
+
__init__.py
|
| 3 |
+
client.py
|
| 4 |
+
inference.py
|
| 5 |
+
models.py
|
| 6 |
+
pyproject.toml
|
| 7 |
+
./__init__.py
|
| 8 |
+
./client.py
|
| 9 |
+
./inference.py
|
| 10 |
+
./models.py
|
| 11 |
+
openenv_chipforge.egg-info/PKG-INFO
|
| 12 |
+
openenv_chipforge.egg-info/SOURCES.txt
|
| 13 |
+
openenv_chipforge.egg-info/dependency_links.txt
|
| 14 |
+
openenv_chipforge.egg-info/entry_points.txt
|
| 15 |
+
openenv_chipforge.egg-info/requires.txt
|
| 16 |
+
openenv_chipforge.egg-info/top_level.txt
|
| 17 |
+
server/__init__.py
|
| 18 |
+
server/app.py
|
| 19 |
+
server/chipforge_environment.py
|
openenv_chipforge.egg-info/dependency_links.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
|
openenv_chipforge.egg-info/entry_points.txt
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[console_scripts]
|
| 2 |
+
server = chipforge.server.app:main
|
openenv_chipforge.egg-info/requires.txt
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
openenv-core[core]>=0.2.2
|
| 2 |
+
mistralai>=1.0.0
|
| 3 |
+
python-dotenv>=1.0.0
|
| 4 |
+
websocket-client>=1.9.0
|
| 5 |
+
|
| 6 |
+
[dev]
|
| 7 |
+
pytest>=8.0.0
|
| 8 |
+
pytest-cov>=4.0.0
|
openenv_chipforge.egg-info/top_level.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
chipforge
|
pyproject.toml
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# This source code is licensed under the BSD-style license found in the
|
| 5 |
+
# LICENSE file in the root directory of this source tree.
|
| 6 |
+
|
| 7 |
+
[build-system]
|
| 8 |
+
requires = ["setuptools>=45", "wheel"]
|
| 9 |
+
build-backend = "setuptools.build_meta"
|
| 10 |
+
|
| 11 |
+
[project]
|
| 12 |
+
name = "openenv-chipforge"
|
| 13 |
+
version = "0.1.0"
|
| 14 |
+
description = "Chipforge environment for OpenEnv"
|
| 15 |
+
requires-python = ">=3.10"
|
| 16 |
+
dependencies = [
|
| 17 |
+
# Core OpenEnv runtime (provides FastAPI server + HTTP client types)
|
| 18 |
+
# install from github
|
| 19 |
+
# "openenv-core[core] @ git+https://github.com/meta-pytorch/OpenEnv.git",
|
| 20 |
+
"openenv-core[core]>=0.2.2",
|
| 21 |
+
# Environment-specific dependencies
|
| 22 |
+
# (none needed — Verilator + Yosys are installed in the Docker image)
|
| 23 |
+
"mistralai>=1.0.0",
|
| 24 |
+
"python-dotenv>=1.0.0",
|
| 25 |
+
"websocket-client>=1.9.0",
|
| 26 |
+
]
|
| 27 |
+
|
| 28 |
+
[project.optional-dependencies]
|
| 29 |
+
dev = [
|
| 30 |
+
"pytest>=8.0.0",
|
| 31 |
+
"pytest-cov>=4.0.0",
|
| 32 |
+
]
|
| 33 |
+
|
| 34 |
+
[project.scripts]
|
| 35 |
+
# Server entry point - enables running via: uv run --project . server
|
| 36 |
+
# or: python -m chipforge.server.app
|
| 37 |
+
server = "chipforge.server.app:main"
|
| 38 |
+
|
| 39 |
+
[tool.setuptools]
|
| 40 |
+
include-package-data = true
|
| 41 |
+
packages = ["chipforge", "chipforge.server"]
|
| 42 |
+
package-dir = { "chipforge" = ".", "chipforge.server" = "server" }
|
server/__init__.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# This source code is licensed under the BSD-style license found in the
|
| 5 |
+
# LICENSE file in the root directory of this source tree.
|
| 6 |
+
|
| 7 |
+
"""Chipforge environment server components."""
|
| 8 |
+
|
| 9 |
+
from .chipforge_environment import ChipforgeEnvironment
|
| 10 |
+
|
| 11 |
+
__all__ = ["ChipforgeEnvironment"]
|
server/app.py
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# This source code is licensed under the BSD-style license found in the
|
| 5 |
+
# LICENSE file in the root directory of this source tree.
|
| 6 |
+
|
| 7 |
+
"""
|
| 8 |
+
FastAPI application for the Chipforge Environment.
|
| 9 |
+
|
| 10 |
+
This module creates an HTTP server that exposes the ChipforgeEnvironment
|
| 11 |
+
over HTTP and WebSocket endpoints, compatible with EnvClient.
|
| 12 |
+
|
| 13 |
+
Endpoints:
|
| 14 |
+
- POST /reset: Reset the environment
|
| 15 |
+
- POST /step: Execute an action
|
| 16 |
+
- GET /state: Get current environment state
|
| 17 |
+
- GET /schema: Get action/observation schemas
|
| 18 |
+
- WS /ws: WebSocket endpoint for persistent sessions
|
| 19 |
+
|
| 20 |
+
Usage:
|
| 21 |
+
# Development (with auto-reload):
|
| 22 |
+
uvicorn server.app:app --reload --host 0.0.0.0 --port 8000
|
| 23 |
+
|
| 24 |
+
# Production:
|
| 25 |
+
uvicorn server.app:app --host 0.0.0.0 --port 8000 --workers 4
|
| 26 |
+
|
| 27 |
+
# Or run directly:
|
| 28 |
+
python -m server.app
|
| 29 |
+
"""
|
| 30 |
+
|
| 31 |
+
try:
|
| 32 |
+
from openenv.core.env_server.http_server import create_app
|
| 33 |
+
except Exception as e: # pragma: no cover
|
| 34 |
+
raise ImportError(
|
| 35 |
+
"openenv is required for the web interface. Install dependencies with '\n uv sync\n'"
|
| 36 |
+
) from e
|
| 37 |
+
|
| 38 |
+
try:
|
| 39 |
+
from ..models import ChipforgeAction, ChipforgeObservation
|
| 40 |
+
from .chipforge_environment import ChipforgeEnvironment
|
| 41 |
+
except ImportError:
|
| 42 |
+
from models import ChipforgeAction, ChipforgeObservation
|
| 43 |
+
from server.chipforge_environment import ChipforgeEnvironment
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
# Create the app with web interface and README integration
|
| 47 |
+
app = create_app(
|
| 48 |
+
ChipforgeEnvironment,
|
| 49 |
+
ChipforgeAction,
|
| 50 |
+
ChipforgeObservation,
|
| 51 |
+
env_name="chipforge",
|
| 52 |
+
max_concurrent_envs=1, # increase this number to allow more concurrent WebSocket sessions
|
| 53 |
+
)
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
def main(host: str = "0.0.0.0", port: int = 8000):
|
| 57 |
+
"""
|
| 58 |
+
Entry point for direct execution via uv run or python -m.
|
| 59 |
+
|
| 60 |
+
This function enables running the server without Docker:
|
| 61 |
+
uv run --project . server
|
| 62 |
+
uv run --project . server --port 8001
|
| 63 |
+
python -m chipforge.server.app
|
| 64 |
+
|
| 65 |
+
Args:
|
| 66 |
+
host: Host address to bind to (default: "0.0.0.0")
|
| 67 |
+
port: Port number to listen on (default: 8000)
|
| 68 |
+
|
| 69 |
+
For production deployments, consider using uvicorn directly with
|
| 70 |
+
multiple workers:
|
| 71 |
+
uvicorn chipforge.server.app:app --workers 4
|
| 72 |
+
"""
|
| 73 |
+
import uvicorn
|
| 74 |
+
|
| 75 |
+
uvicorn.run(app, host=host, port=port)
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
if __name__ == "__main__":
|
| 79 |
+
import argparse
|
| 80 |
+
|
| 81 |
+
parser = argparse.ArgumentParser()
|
| 82 |
+
parser.add_argument("--port", type=int, default=8000)
|
| 83 |
+
args = parser.parse_args()
|
| 84 |
+
main(port=args.port)
|
server/chipforge_environment.py
ADDED
|
@@ -0,0 +1,789 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# This source code is licensed under the BSD-style license found in the
|
| 5 |
+
# LICENSE file in the root directory of this source tree.
|
| 6 |
+
|
| 7 |
+
"""
|
| 8 |
+
ChipForge RTL Debugging Environment — RL-optimized.
|
| 9 |
+
|
| 10 |
+
Key RL design decisions:
|
| 11 |
+
1. OBSERVATION is a self-contained Markov state:
|
| 12 |
+
- RTL code always included (agent never wastes steps viewing)
|
| 13 |
+
- All tool statuses always present
|
| 14 |
+
- Action result feedback at every step
|
| 15 |
+
|
| 16 |
+
2. REWARD uses potential-based shaping (Andrew Ng's theorem):
|
| 17 |
+
- per_step_reward = new_potential - old_potential - step_cost
|
| 18 |
+
- Potential = quality score based on tool statuses (0.0 to 1.0)
|
| 19 |
+
- Gives dense learning signal without changing optimal policy
|
| 20 |
+
- Terminal bonus on submit
|
| 21 |
+
|
| 22 |
+
3. STATUS is NOT reset on edit:
|
| 23 |
+
- Prevents reward hacking (edit → artificially drop potential → re-run → gain)
|
| 24 |
+
- Agent must re-run tools to confirm fix worked
|
| 25 |
+
- On submit, all stale tools are automatically re-run
|
| 26 |
+
"""
|
| 27 |
+
|
| 28 |
+
import json
|
| 29 |
+
import os
|
| 30 |
+
import random
|
| 31 |
+
import shutil
|
| 32 |
+
import subprocess
|
| 33 |
+
import tempfile
|
| 34 |
+
from pathlib import Path
|
| 35 |
+
from typing import Any, Dict, List, Optional
|
| 36 |
+
from uuid import uuid4
|
| 37 |
+
|
| 38 |
+
from openenv.core.env_server.interfaces import Environment
|
| 39 |
+
from openenv.core.env_server.types import State
|
| 40 |
+
|
| 41 |
+
try:
|
| 42 |
+
from ..models import ChipforgeAction, ChipforgeObservation
|
| 43 |
+
except ImportError:
|
| 44 |
+
from models import ChipforgeAction, ChipforgeObservation
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
# ---------------------------------------------------------------------------
|
| 48 |
+
# Constants
|
| 49 |
+
# ---------------------------------------------------------------------------
|
| 50 |
+
|
| 51 |
+
MAX_STEPS = 20
|
| 52 |
+
LOG_TRUNCATE = 2000 # max chars in observation logs
|
| 53 |
+
TOOL_TIMEOUT = 30 # seconds
|
| 54 |
+
STEP_COST = 0.02 # per-step penalty to encourage efficiency
|
| 55 |
+
|
| 56 |
+
# Tool paths — absolute for OSS CAD Suite in Docker
|
| 57 |
+
VERILATOR = os.environ.get("VERILATOR_PATH", "/opt/oss-cad-suite/bin/verilator")
|
| 58 |
+
YOSYS = os.environ.get("YOSYS_PATH", "/opt/oss-cad-suite/bin/yosys")
|
| 59 |
+
|
| 60 |
+
VALID_ACTIONS = {
|
| 61 |
+
"view_testbench",
|
| 62 |
+
"view_synthesis_log",
|
| 63 |
+
"view_lint_log",
|
| 64 |
+
"view_simulation_log",
|
| 65 |
+
"run_simulation",
|
| 66 |
+
"run_synthesis",
|
| 67 |
+
"run_lint",
|
| 68 |
+
"edit_line",
|
| 69 |
+
"append_line",
|
| 70 |
+
"edit_testbench_line",
|
| 71 |
+
"append_testbench_line",
|
| 72 |
+
"submit",
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
TASKS_DIR = Path(__file__).parent / "tasks"
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
# ---------------------------------------------------------------------------
|
| 79 |
+
# Helpers
|
| 80 |
+
# ---------------------------------------------------------------------------
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
def _discover_tasks() -> List[Path]:
|
| 84 |
+
"""Return sorted list of task directories under TASKS_DIR (recursive)."""
|
| 85 |
+
if not TASKS_DIR.is_dir():
|
| 86 |
+
return []
|
| 87 |
+
return sorted(
|
| 88 |
+
p.parent
|
| 89 |
+
for p in TASKS_DIR.rglob("task.json")
|
| 90 |
+
if p.is_file() and p.parent.is_dir()
|
| 91 |
+
)
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
def _run_tool(cmd: List[str], cwd: str, timeout: int = TOOL_TIMEOUT) -> Dict[str, Any]:
|
| 95 |
+
"""Run a shell command and return stdout, stderr, returncode."""
|
| 96 |
+
try:
|
| 97 |
+
result = subprocess.run(
|
| 98 |
+
cmd,
|
| 99 |
+
cwd=cwd,
|
| 100 |
+
capture_output=True,
|
| 101 |
+
text=True,
|
| 102 |
+
timeout=timeout,
|
| 103 |
+
)
|
| 104 |
+
return {
|
| 105 |
+
"stdout": result.stdout,
|
| 106 |
+
"stderr": result.stderr,
|
| 107 |
+
"returncode": result.returncode,
|
| 108 |
+
}
|
| 109 |
+
except subprocess.TimeoutExpired:
|
| 110 |
+
return {
|
| 111 |
+
"stdout": "",
|
| 112 |
+
"stderr": f"Command timed out after {timeout}s",
|
| 113 |
+
"returncode": -1,
|
| 114 |
+
}
|
| 115 |
+
except FileNotFoundError as e:
|
| 116 |
+
return {
|
| 117 |
+
"stdout": "",
|
| 118 |
+
"stderr": f"Tool not found: {e}",
|
| 119 |
+
"returncode": -1,
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
|
| 123 |
+
def _extract_error_summary(stderr: str, stdout: str = "") -> str:
|
| 124 |
+
"""Extract a one-line error summary from tool output."""
|
| 125 |
+
combined = stderr + "\n" + stdout
|
| 126 |
+
for line in combined.splitlines():
|
| 127 |
+
line = line.strip()
|
| 128 |
+
if not line:
|
| 129 |
+
continue
|
| 130 |
+
lower = line.lower()
|
| 131 |
+
if any(kw in lower for kw in ("error", "syntax", "warning", "latch", "fail")):
|
| 132 |
+
return line[:200]
|
| 133 |
+
for line in stderr.splitlines():
|
| 134 |
+
line = line.strip()
|
| 135 |
+
if line:
|
| 136 |
+
return line[:200]
|
| 137 |
+
return ""
|
| 138 |
+
|
| 139 |
+
|
| 140 |
+
# ---------------------------------------------------------------------------
|
| 141 |
+
# Environment
|
| 142 |
+
# ---------------------------------------------------------------------------
|
| 143 |
+
|
| 144 |
+
|
| 145 |
+
class ChipforgeEnvironment(Environment):
|
| 146 |
+
"""
|
| 147 |
+
RTL Debugging Environment for RL training.
|
| 148 |
+
|
| 149 |
+
Quality potential (φ) breakdown:
|
| 150 |
+
+0.2 code compiles (no syntax errors)
|
| 151 |
+
+0.3 simulation output matches expected
|
| 152 |
+
+0.3 synthesis clean (no warnings/errors)
|
| 153 |
+
+0.2 lint clean
|
| 154 |
+
|
| 155 |
+
Per-step reward = φ(s') - φ(s) - step_cost
|
| 156 |
+
Terminal bonus on submit = +0.1 if all pass, -0.2 if premature
|
| 157 |
+
"""
|
| 158 |
+
|
| 159 |
+
SUPPORTS_CONCURRENT_SESSIONS: bool = False
|
| 160 |
+
|
| 161 |
+
def __init__(self) -> None:
|
| 162 |
+
self._state = State(episode_id=str(uuid4()), step_count=0)
|
| 163 |
+
self._tasks = _discover_tasks()
|
| 164 |
+
self._rng = random.Random()
|
| 165 |
+
|
| 166 |
+
# Episode state
|
| 167 |
+
self._rtl_lines: List[str] = []
|
| 168 |
+
self._testbench_code: str = ""
|
| 169 |
+
self._task_meta: Dict[str, Any] = {}
|
| 170 |
+
self._golden_code: str = ""
|
| 171 |
+
self._expected_output: str = ""
|
| 172 |
+
|
| 173 |
+
# Tool statuses & logs
|
| 174 |
+
self._sim_status: str = "not_run"
|
| 175 |
+
self._synth_status: str = "not_run"
|
| 176 |
+
self._lint_status: str = "not_run"
|
| 177 |
+
self._sim_log: str = ""
|
| 178 |
+
self._synth_log: str = ""
|
| 179 |
+
self._lint_log: str = ""
|
| 180 |
+
self._error_summary: str = ""
|
| 181 |
+
|
| 182 |
+
# Track if code has been edited since last tool run
|
| 183 |
+
self._code_dirty: bool = False
|
| 184 |
+
self._code_hash: str = ""
|
| 185 |
+
self._sim_validated_hash: str = ""
|
| 186 |
+
self._synth_validated_hash: str = ""
|
| 187 |
+
self._lint_validated_hash: str = ""
|
| 188 |
+
|
| 189 |
+
# Working directory
|
| 190 |
+
self._workdir: Optional[str] = None
|
| 191 |
+
|
| 192 |
+
# Episode signals
|
| 193 |
+
self._done: bool = False
|
| 194 |
+
self._potential: float = 0.0 # current quality potential
|
| 195 |
+
self._cumulative_reward: float = 0.0 # sum of per-step rewards
|
| 196 |
+
|
| 197 |
+
# -----------------------------------------------------------------------
|
| 198 |
+
# Potential-based reward
|
| 199 |
+
# -----------------------------------------------------------------------
|
| 200 |
+
|
| 201 |
+
def _compute_potential(self) -> float:
|
| 202 |
+
"""
|
| 203 |
+
Quality potential φ(s) based on current tool statuses.
|
| 204 |
+
Range: [0.0, 1.0]. Only counts tools that have been run.
|
| 205 |
+
"""
|
| 206 |
+
phi = 0.0
|
| 207 |
+
|
| 208 |
+
sim_fresh = self._sim_validated_hash == self._code_hash
|
| 209 |
+
synth_fresh = self._synth_validated_hash == self._code_hash
|
| 210 |
+
lint_fresh = self._lint_validated_hash == self._code_hash
|
| 211 |
+
|
| 212 |
+
# +0.2 if code compiles (sim ran and didn't error) on current code
|
| 213 |
+
if sim_fresh and self._sim_status in ("pass", "fail"):
|
| 214 |
+
phi += 0.2
|
| 215 |
+
|
| 216 |
+
# +0.3 if simulation passes on current code
|
| 217 |
+
if sim_fresh and self._sim_status == "pass":
|
| 218 |
+
phi += 0.3
|
| 219 |
+
|
| 220 |
+
# +0.3 if synthesis is clean on current code
|
| 221 |
+
if synth_fresh and self._synth_status == "pass":
|
| 222 |
+
phi += 0.3
|
| 223 |
+
|
| 224 |
+
# +0.2 if lint is clean on current code
|
| 225 |
+
if lint_fresh and self._lint_status == "clean":
|
| 226 |
+
phi += 0.2
|
| 227 |
+
|
| 228 |
+
return phi
|
| 229 |
+
|
| 230 |
+
def _current_code_hash(self) -> str:
|
| 231 |
+
return str(hash("\n".join(self._rtl_lines)))
|
| 232 |
+
|
| 233 |
+
# -----------------------------------------------------------------------
|
| 234 |
+
# OpenEnv Interface
|
| 235 |
+
# -----------------------------------------------------------------------
|
| 236 |
+
|
| 237 |
+
def reset(
|
| 238 |
+
self,
|
| 239 |
+
seed: Optional[int] = None,
|
| 240 |
+
episode_id: Optional[str] = None,
|
| 241 |
+
**kwargs: Any,
|
| 242 |
+
) -> ChipforgeObservation:
|
| 243 |
+
"""Load a task and return initial observation with RTL code."""
|
| 244 |
+
|
| 245 |
+
# Clean up
|
| 246 |
+
if self._workdir and os.path.isdir(self._workdir):
|
| 247 |
+
shutil.rmtree(self._workdir, ignore_errors=True)
|
| 248 |
+
|
| 249 |
+
if seed is not None:
|
| 250 |
+
self._rng.seed(seed)
|
| 251 |
+
|
| 252 |
+
if not self._tasks:
|
| 253 |
+
raise RuntimeError(f"No tasks found in {TASKS_DIR}")
|
| 254 |
+
|
| 255 |
+
# Pick task
|
| 256 |
+
task_name = kwargs.get("task_name")
|
| 257 |
+
if task_name:
|
| 258 |
+
task_dir = TASKS_DIR / task_name
|
| 259 |
+
if not task_dir.is_dir():
|
| 260 |
+
raise ValueError(f"Task not found: {task_name}")
|
| 261 |
+
else:
|
| 262 |
+
task_dir = self._rng.choice(self._tasks)
|
| 263 |
+
|
| 264 |
+
# Load files
|
| 265 |
+
with open(task_dir / "task.json") as f:
|
| 266 |
+
self._task_meta = json.load(f)
|
| 267 |
+
|
| 268 |
+
design_buggy = task_dir / "design_buggy.v"
|
| 269 |
+
if design_buggy.is_file():
|
| 270 |
+
with open(design_buggy) as f:
|
| 271 |
+
self._rtl_lines = f.read().splitlines()
|
| 272 |
+
else:
|
| 273 |
+
self._rtl_lines = []
|
| 274 |
+
|
| 275 |
+
testbench = task_dir / "testbench.v"
|
| 276 |
+
if testbench.is_file():
|
| 277 |
+
with open(testbench) as f:
|
| 278 |
+
self._testbench_code = f.read()
|
| 279 |
+
else:
|
| 280 |
+
self._testbench_code = ""
|
| 281 |
+
|
| 282 |
+
design_golden = task_dir / "design_golden.v"
|
| 283 |
+
if design_golden.is_file():
|
| 284 |
+
with open(design_golden) as f:
|
| 285 |
+
self._golden_code = f.read()
|
| 286 |
+
else:
|
| 287 |
+
self._golden_code = ""
|
| 288 |
+
|
| 289 |
+
self._expected_output = self._task_meta.get("expected_sim_output", "")
|
| 290 |
+
|
| 291 |
+
# Reset state
|
| 292 |
+
eid = episode_id or str(uuid4())
|
| 293 |
+
self._state = State(episode_id=eid, step_count=0)
|
| 294 |
+
self._sim_status = "not_run"
|
| 295 |
+
self._synth_status = "not_run"
|
| 296 |
+
self._lint_status = "not_run"
|
| 297 |
+
self._sim_log = ""
|
| 298 |
+
self._synth_log = ""
|
| 299 |
+
self._lint_log = ""
|
| 300 |
+
self._error_summary = ""
|
| 301 |
+
self._code_dirty = False
|
| 302 |
+
self._code_hash = self._current_code_hash()
|
| 303 |
+
self._sim_validated_hash = ""
|
| 304 |
+
self._synth_validated_hash = ""
|
| 305 |
+
self._lint_validated_hash = ""
|
| 306 |
+
self._done = False
|
| 307 |
+
self._potential = 0.0
|
| 308 |
+
self._cumulative_reward = 0.0
|
| 309 |
+
|
| 310 |
+
# Fresh workdir
|
| 311 |
+
self._workdir = tempfile.mkdtemp(prefix="chipforge_")
|
| 312 |
+
|
| 313 |
+
return self._make_obs(
|
| 314 |
+
last_action="reset",
|
| 315 |
+
action_result=f"Loaded task: {self._task_meta.get('description', '')}",
|
| 316 |
+
step_reward=0.0,
|
| 317 |
+
)
|
| 318 |
+
|
| 319 |
+
def step( # type: ignore[override]
|
| 320 |
+
self,
|
| 321 |
+
action: ChipforgeAction,
|
| 322 |
+
timeout_s: Optional[float] = None,
|
| 323 |
+
**kwargs: Any,
|
| 324 |
+
) -> ChipforgeObservation:
|
| 325 |
+
"""Execute one action and return observation with per-step reward."""
|
| 326 |
+
|
| 327 |
+
if self._done:
|
| 328 |
+
return self._make_obs(
|
| 329 |
+
last_action="none",
|
| 330 |
+
action_result="Episode already finished. Call reset().",
|
| 331 |
+
step_reward=0.0,
|
| 332 |
+
)
|
| 333 |
+
|
| 334 |
+
self._state.step_count += 1
|
| 335 |
+
timeout = TOOL_TIMEOUT if timeout_s is None else max(1, int(timeout_s))
|
| 336 |
+
action_type = action.action_type.strip().lower()
|
| 337 |
+
|
| 338 |
+
if action_type not in VALID_ACTIONS:
|
| 339 |
+
return self._make_obs(
|
| 340 |
+
last_action=action_type,
|
| 341 |
+
action_result=f"Unknown action. Valid: {sorted(VALID_ACTIONS)}",
|
| 342 |
+
step_reward=-STEP_COST,
|
| 343 |
+
)
|
| 344 |
+
|
| 345 |
+
# Snapshot potential BEFORE action
|
| 346 |
+
old_potential = self._potential
|
| 347 |
+
|
| 348 |
+
# Dispatch action
|
| 349 |
+
obs_extras: Dict[str, Any] = {}
|
| 350 |
+
action_result = ""
|
| 351 |
+
|
| 352 |
+
if action_type == "view_testbench":
|
| 353 |
+
obs_extras["testbench_code"] = self._testbench_code
|
| 354 |
+
action_result = f"Testbench loaded ({self._testbench_code.count(chr(10))+1} lines)."
|
| 355 |
+
|
| 356 |
+
elif action_type == "view_synthesis_log":
|
| 357 |
+
obs_extras["log_output"] = self._synth_log[:LOG_TRUNCATE]
|
| 358 |
+
action_result = f"Viewing synthesis log ({len(self._synth_log)} chars)."
|
| 359 |
+
|
| 360 |
+
elif action_type == "view_lint_log":
|
| 361 |
+
obs_extras["log_output"] = self._lint_log[:LOG_TRUNCATE]
|
| 362 |
+
action_result = f"Viewing lint log ({len(self._lint_log)} chars)."
|
| 363 |
+
|
| 364 |
+
elif action_type == "view_simulation_log":
|
| 365 |
+
obs_extras["log_output"] = self._sim_log[:LOG_TRUNCATE]
|
| 366 |
+
action_result = f"Viewing simulation log ({len(self._sim_log)} chars)."
|
| 367 |
+
|
| 368 |
+
elif action_type == "run_simulation":
|
| 369 |
+
self._do_simulation(timeout=timeout)
|
| 370 |
+
obs_extras["log_output"] = self._sim_log[:LOG_TRUNCATE]
|
| 371 |
+
action_result = f"Simulation: {self._sim_status}. {self._error_summary}"
|
| 372 |
+
|
| 373 |
+
elif action_type == "run_synthesis":
|
| 374 |
+
self._do_synthesis(timeout=timeout)
|
| 375 |
+
obs_extras["log_output"] = self._synth_log[:LOG_TRUNCATE]
|
| 376 |
+
action_result = f"Synthesis: {self._synth_status}. {self._error_summary}"
|
| 377 |
+
|
| 378 |
+
elif action_type == "run_lint":
|
| 379 |
+
self._do_lint(timeout=timeout)
|
| 380 |
+
obs_extras["log_output"] = self._lint_log[:LOG_TRUNCATE]
|
| 381 |
+
action_result = f"Lint: {self._lint_status}. {self._error_summary}"
|
| 382 |
+
|
| 383 |
+
elif action_type == "edit_line":
|
| 384 |
+
action_result = self._do_edit(action.line_number, action.new_content)
|
| 385 |
+
|
| 386 |
+
elif action_type == "append_line":
|
| 387 |
+
action_result = self._do_append(action.new_content)
|
| 388 |
+
|
| 389 |
+
elif action_type == "edit_testbench_line":
|
| 390 |
+
action_result = self._do_edit_testbench(action.line_number, action.new_content)
|
| 391 |
+
|
| 392 |
+
elif action_type == "append_testbench_line":
|
| 393 |
+
action_result = self._do_append_testbench(action.new_content)
|
| 394 |
+
|
| 395 |
+
elif action_type == "submit":
|
| 396 |
+
action_result = self._do_submit(timeout=timeout)
|
| 397 |
+
|
| 398 |
+
# Compute new potential
|
| 399 |
+
new_potential = self._compute_potential()
|
| 400 |
+
self._potential = new_potential
|
| 401 |
+
|
| 402 |
+
# Per-step reward = potential delta - step cost + terminal bonus
|
| 403 |
+
step_reward = (new_potential - old_potential) - STEP_COST
|
| 404 |
+
|
| 405 |
+
# Terminal bonus/penalty on submit
|
| 406 |
+
if action_type == "submit":
|
| 407 |
+
if new_potential >= 1.0:
|
| 408 |
+
step_reward += 0.1 # bonus for perfect fix
|
| 409 |
+
elif new_potential >= 0.5:
|
| 410 |
+
step_reward += 0.0 # partial fix, no bonus
|
| 411 |
+
else:
|
| 412 |
+
step_reward -= 0.2 # premature submit penalty
|
| 413 |
+
|
| 414 |
+
self._cumulative_reward += step_reward
|
| 415 |
+
|
| 416 |
+
# Check step limit
|
| 417 |
+
if self._state.step_count >= MAX_STEPS and not self._done:
|
| 418 |
+
self._done = True
|
| 419 |
+
action_result += " Step limit reached."
|
| 420 |
+
|
| 421 |
+
return self._make_obs(
|
| 422 |
+
last_action=action_type,
|
| 423 |
+
action_result=action_result.strip(),
|
| 424 |
+
step_reward=step_reward,
|
| 425 |
+
**obs_extras,
|
| 426 |
+
)
|
| 427 |
+
|
| 428 |
+
@property
|
| 429 |
+
def state(self) -> State:
|
| 430 |
+
return self._state
|
| 431 |
+
|
| 432 |
+
# -----------------------------------------------------------------------
|
| 433 |
+
# Action Handlers
|
| 434 |
+
# -----------------------------------------------------------------------
|
| 435 |
+
|
| 436 |
+
def _do_simulation(self, timeout: int = TOOL_TIMEOUT) -> None:
|
| 437 |
+
"""Compile + run with Verilator."""
|
| 438 |
+
if not self._workdir:
|
| 439 |
+
self._error_summary = "No working directory."
|
| 440 |
+
return
|
| 441 |
+
|
| 442 |
+
if not self._rtl_lines:
|
| 443 |
+
self._sim_status = "error"
|
| 444 |
+
self._sim_log = "No RTL design present. Build design first."
|
| 445 |
+
self._error_summary = "No RTL design present. Add lines with append_line."
|
| 446 |
+
self._sim_validated_hash = self._code_hash
|
| 447 |
+
return
|
| 448 |
+
|
| 449 |
+
if not self._testbench_code.strip():
|
| 450 |
+
self._sim_status = "error"
|
| 451 |
+
self._sim_log = "No testbench present. Build testbench first."
|
| 452 |
+
self._error_summary = (
|
| 453 |
+
"No testbench present. Add lines with append_testbench_line."
|
| 454 |
+
)
|
| 455 |
+
self._sim_validated_hash = self._code_hash
|
| 456 |
+
return
|
| 457 |
+
|
| 458 |
+
# Write current files
|
| 459 |
+
design_path = os.path.join(self._workdir, "design.v")
|
| 460 |
+
tb_path = os.path.join(self._workdir, "testbench.v")
|
| 461 |
+
with open(design_path, "w") as f:
|
| 462 |
+
f.write("\n".join(self._rtl_lines) + "\n")
|
| 463 |
+
with open(tb_path, "w") as f:
|
| 464 |
+
f.write(self._testbench_code)
|
| 465 |
+
|
| 466 |
+
# Clean previous build
|
| 467 |
+
obj_dir = os.path.join(self._workdir, "obj_dir")
|
| 468 |
+
if os.path.isdir(obj_dir):
|
| 469 |
+
shutil.rmtree(obj_dir, ignore_errors=True)
|
| 470 |
+
|
| 471 |
+
# Compile
|
| 472 |
+
compile_result = _run_tool(
|
| 473 |
+
[
|
| 474 |
+
VERILATOR,
|
| 475 |
+
"--prefix", "Vsim",
|
| 476 |
+
"--binary",
|
| 477 |
+
"--build-jobs", "0",
|
| 478 |
+
"--build",
|
| 479 |
+
"--quiet-build",
|
| 480 |
+
"-Wno-fatal",
|
| 481 |
+
"--timescale", "1ns/1ns",
|
| 482 |
+
"design.v",
|
| 483 |
+
"testbench.v",
|
| 484 |
+
],
|
| 485 |
+
cwd=self._workdir,
|
| 486 |
+
timeout=timeout,
|
| 487 |
+
)
|
| 488 |
+
|
| 489 |
+
if compile_result["returncode"] != 0:
|
| 490 |
+
self._sim_status = "error"
|
| 491 |
+
self._sim_log = (
|
| 492 |
+
"=== COMPILATION FAILED ===\n"
|
| 493 |
+
+ compile_result["stderr"] + "\n"
|
| 494 |
+
+ compile_result["stdout"]
|
| 495 |
+
)
|
| 496 |
+
self._error_summary = _extract_error_summary(
|
| 497 |
+
compile_result["stderr"], compile_result["stdout"]
|
| 498 |
+
)
|
| 499 |
+
self._code_dirty = False
|
| 500 |
+
self._sim_validated_hash = self._code_hash
|
| 501 |
+
return
|
| 502 |
+
|
| 503 |
+
# Run simulation
|
| 504 |
+
sim_binary = os.path.join(self._workdir, "obj_dir", "Vsim")
|
| 505 |
+
if not os.path.isfile(sim_binary):
|
| 506 |
+
self._sim_status = "error"
|
| 507 |
+
self._sim_log = "Simulation binary not found."
|
| 508 |
+
self._error_summary = "Simulation binary not found."
|
| 509 |
+
return
|
| 510 |
+
|
| 511 |
+
run_result = _run_tool([sim_binary], cwd=self._workdir, timeout=timeout)
|
| 512 |
+
self._sim_log = run_result["stdout"] + run_result["stderr"]
|
| 513 |
+
self._code_dirty = False
|
| 514 |
+
self._sim_validated_hash = self._code_hash
|
| 515 |
+
|
| 516 |
+
# Compare output
|
| 517 |
+
if self._expected_output:
|
| 518 |
+
actual = [
|
| 519 |
+
l.strip() for l in run_result["stdout"].splitlines()
|
| 520 |
+
if l.strip() and not l.strip().startswith("-")
|
| 521 |
+
]
|
| 522 |
+
expected = [
|
| 523 |
+
l.strip() for l in self._expected_output.splitlines()
|
| 524 |
+
if l.strip() and not l.strip().startswith("-")
|
| 525 |
+
]
|
| 526 |
+
if actual == expected:
|
| 527 |
+
self._sim_status = "pass"
|
| 528 |
+
self._error_summary = "Simulation passed — output matches expected."
|
| 529 |
+
else:
|
| 530 |
+
self._sim_status = "fail"
|
| 531 |
+
self._error_summary = "Simulation output does not match expected."
|
| 532 |
+
else:
|
| 533 |
+
self._sim_status = "pass" if run_result["returncode"] == 0 else "fail"
|
| 534 |
+
self._error_summary = ""
|
| 535 |
+
|
| 536 |
+
def _do_synthesis(self, timeout: int = TOOL_TIMEOUT) -> None:
|
| 537 |
+
"""Run Yosys synthesis."""
|
| 538 |
+
if not self._workdir:
|
| 539 |
+
self._error_summary = "No working directory."
|
| 540 |
+
return
|
| 541 |
+
|
| 542 |
+
design_path = os.path.join(self._workdir, "design.v")
|
| 543 |
+
with open(design_path, "w") as f:
|
| 544 |
+
f.write("\n".join(self._rtl_lines) + "\n")
|
| 545 |
+
|
| 546 |
+
yosys_script = (
|
| 547 |
+
"read_verilog design.v; "
|
| 548 |
+
"hierarchy -auto-top; "
|
| 549 |
+
"proc; opt; memory; opt; fsm; opt; "
|
| 550 |
+
"write_verilog synth_out.v"
|
| 551 |
+
)
|
| 552 |
+
|
| 553 |
+
result = _run_tool(
|
| 554 |
+
[YOSYS, "-p", yosys_script],
|
| 555 |
+
cwd=self._workdir,
|
| 556 |
+
timeout=timeout,
|
| 557 |
+
)
|
| 558 |
+
|
| 559 |
+
full_log = result["stdout"] + "\n" + result["stderr"]
|
| 560 |
+
self._synth_log = full_log
|
| 561 |
+
self._code_dirty = False
|
| 562 |
+
|
| 563 |
+
if result["returncode"] != 0:
|
| 564 |
+
self._synth_status = "error"
|
| 565 |
+
self._error_summary = _extract_error_summary(
|
| 566 |
+
result["stderr"], result["stdout"]
|
| 567 |
+
)
|
| 568 |
+
self._synth_validated_hash = self._code_hash
|
| 569 |
+
else:
|
| 570 |
+
lower_log = full_log.lower()
|
| 571 |
+
warning_patterns = ["latch inferred", "found and reported", "warning:"]
|
| 572 |
+
has_warning = any(p in lower_log for p in warning_patterns)
|
| 573 |
+
|
| 574 |
+
if has_warning:
|
| 575 |
+
self._synth_status = "warning"
|
| 576 |
+
self._error_summary = _extract_error_summary(
|
| 577 |
+
result["stderr"], result["stdout"]
|
| 578 |
+
) or "Synthesis completed with warnings."
|
| 579 |
+
else:
|
| 580 |
+
self._synth_status = "pass"
|
| 581 |
+
self._error_summary = "Synthesis clean."
|
| 582 |
+
self._synth_validated_hash = self._code_hash
|
| 583 |
+
|
| 584 |
+
def _do_lint(self, timeout: int = TOOL_TIMEOUT) -> None:
|
| 585 |
+
"""Run Verilator lint."""
|
| 586 |
+
if not self._workdir:
|
| 587 |
+
self._error_summary = "No working directory."
|
| 588 |
+
return
|
| 589 |
+
|
| 590 |
+
design_path = os.path.join(self._workdir, "design.v")
|
| 591 |
+
with open(design_path, "w") as f:
|
| 592 |
+
f.write("\n".join(self._rtl_lines) + "\n")
|
| 593 |
+
|
| 594 |
+
result = _run_tool(
|
| 595 |
+
[VERILATOR, "--lint-only", "design.v"],
|
| 596 |
+
cwd=self._workdir,
|
| 597 |
+
timeout=timeout,
|
| 598 |
+
)
|
| 599 |
+
|
| 600 |
+
lint_output = result["stderr"] + "\n" + result["stdout"]
|
| 601 |
+
self._lint_log = lint_output
|
| 602 |
+
self._code_dirty = False
|
| 603 |
+
|
| 604 |
+
if result["returncode"] != 0:
|
| 605 |
+
lower = lint_output.lower()
|
| 606 |
+
self._lint_status = "error" if "error" in lower else "warning"
|
| 607 |
+
self._error_summary = _extract_error_summary(
|
| 608 |
+
result["stderr"], result["stdout"]
|
| 609 |
+
)
|
| 610 |
+
self._lint_validated_hash = self._code_hash
|
| 611 |
+
else:
|
| 612 |
+
if "warning" in lint_output.lower():
|
| 613 |
+
self._lint_status = "warning"
|
| 614 |
+
self._error_summary = _extract_error_summary(
|
| 615 |
+
result["stderr"], result["stdout"]
|
| 616 |
+
)
|
| 617 |
+
else:
|
| 618 |
+
self._lint_status = "clean"
|
| 619 |
+
self._error_summary = "Lint clean."
|
| 620 |
+
self._lint_validated_hash = self._code_hash
|
| 621 |
+
|
| 622 |
+
def _do_edit(self, line_number: Optional[int], new_content: Optional[str]) -> str:
|
| 623 |
+
"""Edit a single line. Returns action_result string."""
|
| 624 |
+
if line_number is None or new_content is None:
|
| 625 |
+
self._error_summary = "edit_line requires line_number and new_content."
|
| 626 |
+
return self._error_summary
|
| 627 |
+
|
| 628 |
+
if line_number < 1 or line_number > len(self._rtl_lines):
|
| 629 |
+
self._error_summary = (
|
| 630 |
+
f"Invalid line_number {line_number}. "
|
| 631 |
+
f"Valid range: 1–{len(self._rtl_lines)}."
|
| 632 |
+
)
|
| 633 |
+
return self._error_summary
|
| 634 |
+
|
| 635 |
+
old_line = self._rtl_lines[line_number - 1]
|
| 636 |
+
self._rtl_lines[line_number - 1] = new_content
|
| 637 |
+
self._code_dirty = True
|
| 638 |
+
self._code_hash = self._current_code_hash()
|
| 639 |
+
|
| 640 |
+
result = (
|
| 641 |
+
f"Line {line_number} updated. "
|
| 642 |
+
f"Old: '{old_line.strip()}' → New: '{new_content.strip()}'"
|
| 643 |
+
)
|
| 644 |
+
self._error_summary = result
|
| 645 |
+
|
| 646 |
+
# NOTE: We do NOT reset tool statuses here.
|
| 647 |
+
# This is intentional for RL — the potential stays the same
|
| 648 |
+
# after edit, so reward delta = -step_cost. The agent must
|
| 649 |
+
# re-run tools to measure the impact of the edit.
|
| 650 |
+
return result
|
| 651 |
+
|
| 652 |
+
def _do_append(self, new_content: Optional[str]) -> str:
|
| 653 |
+
"""Append a single RTL line."""
|
| 654 |
+
if new_content is None:
|
| 655 |
+
self._error_summary = "append_line requires new_content."
|
| 656 |
+
return self._error_summary
|
| 657 |
+
|
| 658 |
+
self._rtl_lines.append(new_content)
|
| 659 |
+
self._code_dirty = True
|
| 660 |
+
self._code_hash = self._current_code_hash()
|
| 661 |
+
result = f"RTL line appended at {len(self._rtl_lines)}."
|
| 662 |
+
self._error_summary = result
|
| 663 |
+
return result
|
| 664 |
+
|
| 665 |
+
def _do_edit_testbench(self, line_number: Optional[int], new_content: Optional[str]) -> str:
|
| 666 |
+
"""Edit a single line in testbench.v."""
|
| 667 |
+
if line_number is None or new_content is None:
|
| 668 |
+
self._error_summary = (
|
| 669 |
+
"edit_testbench_line requires line_number and new_content."
|
| 670 |
+
)
|
| 671 |
+
return self._error_summary
|
| 672 |
+
|
| 673 |
+
tb_lines = self._testbench_code.splitlines()
|
| 674 |
+
if line_number < 1 or line_number > len(tb_lines):
|
| 675 |
+
self._error_summary = (
|
| 676 |
+
f"Invalid testbench line_number {line_number}. "
|
| 677 |
+
f"Valid range: 1–{len(tb_lines)}."
|
| 678 |
+
)
|
| 679 |
+
return self._error_summary
|
| 680 |
+
|
| 681 |
+
old_line = tb_lines[line_number - 1]
|
| 682 |
+
tb_lines[line_number - 1] = new_content
|
| 683 |
+
self._testbench_code = "\n".join(tb_lines) + "\n"
|
| 684 |
+
self._code_dirty = True
|
| 685 |
+
self._code_hash = self._current_code_hash()
|
| 686 |
+
|
| 687 |
+
result = (
|
| 688 |
+
f"Testbench line {line_number} updated. "
|
| 689 |
+
f"Old: '{old_line.strip()}' → New: '{new_content.strip()}'"
|
| 690 |
+
)
|
| 691 |
+
self._error_summary = result
|
| 692 |
+
return result
|
| 693 |
+
|
| 694 |
+
def _do_append_testbench(self, new_content: Optional[str]) -> str:
|
| 695 |
+
"""Append one line to testbench.v."""
|
| 696 |
+
if new_content is None:
|
| 697 |
+
self._error_summary = "append_testbench_line requires new_content."
|
| 698 |
+
return self._error_summary
|
| 699 |
+
|
| 700 |
+
tb_lines = self._testbench_code.splitlines()
|
| 701 |
+
tb_lines.append(new_content)
|
| 702 |
+
self._testbench_code = "\n".join(tb_lines) + "\n"
|
| 703 |
+
self._code_dirty = True
|
| 704 |
+
self._code_hash = self._current_code_hash()
|
| 705 |
+
result = f"Testbench line appended at {len(tb_lines)}."
|
| 706 |
+
self._error_summary = result
|
| 707 |
+
return result
|
| 708 |
+
|
| 709 |
+
def _do_submit(self, timeout: int = TOOL_TIMEOUT) -> str:
|
| 710 |
+
"""Submit solution. Re-runs any stale tools, then marks done."""
|
| 711 |
+
self._done = True
|
| 712 |
+
|
| 713 |
+
# Force re-run all tools on the current (possibly edited) code
|
| 714 |
+
self._do_simulation(timeout=timeout)
|
| 715 |
+
self._do_synthesis(timeout=timeout)
|
| 716 |
+
self._do_lint(timeout=timeout)
|
| 717 |
+
|
| 718 |
+
return (
|
| 719 |
+
f"Submitted. sim={self._sim_status}, "
|
| 720 |
+
f"synth={self._synth_status}, lint={self._lint_status}."
|
| 721 |
+
)
|
| 722 |
+
|
| 723 |
+
# -----------------------------------------------------------------------
|
| 724 |
+
# Observation builder
|
| 725 |
+
# -----------------------------------------------------------------------
|
| 726 |
+
|
| 727 |
+
def _numbered_rtl(self) -> str:
|
| 728 |
+
"""Return RTL code with line numbers."""
|
| 729 |
+
if not self._rtl_lines:
|
| 730 |
+
return " 1: // RTL is currently empty. Use append_line to create it."
|
| 731 |
+
return "\n".join(f"{i:3d}: {line}" for i, line in enumerate(self._rtl_lines, 1))
|
| 732 |
+
|
| 733 |
+
def _make_obs(
|
| 734 |
+
self,
|
| 735 |
+
last_action: str,
|
| 736 |
+
action_result: str,
|
| 737 |
+
step_reward: float,
|
| 738 |
+
**extra: Any,
|
| 739 |
+
) -> ChipforgeObservation:
|
| 740 |
+
"""Build a self-contained observation."""
|
| 741 |
+
return ChipforgeObservation(
|
| 742 |
+
# Always included — the Markov state
|
| 743 |
+
rtl_code=self._numbered_rtl(),
|
| 744 |
+
sim_status=self._sim_status,
|
| 745 |
+
synth_status=self._synth_status,
|
| 746 |
+
lint_status=self._lint_status,
|
| 747 |
+
error_summary=self._error_summary,
|
| 748 |
+
task_description=self._task_meta.get("description", ""),
|
| 749 |
+
|
| 750 |
+
# Action feedback
|
| 751 |
+
last_action=last_action,
|
| 752 |
+
action_result=action_result,
|
| 753 |
+
|
| 754 |
+
# Conditionally populated
|
| 755 |
+
testbench_code=extra.get("testbench_code", ""),
|
| 756 |
+
log_output=extra.get("log_output", ""),
|
| 757 |
+
|
| 758 |
+
# RL signals
|
| 759 |
+
step_count=self._state.step_count,
|
| 760 |
+
max_steps=MAX_STEPS,
|
| 761 |
+
reward=step_reward,
|
| 762 |
+
cumulative_reward=self._cumulative_reward,
|
| 763 |
+
done=self._done,
|
| 764 |
+
metadata={
|
| 765 |
+
"task_mode": self._task_meta.get("task_type", "debug_rtl"),
|
| 766 |
+
"missing_files": {
|
| 767 |
+
"design_buggy.v": not bool(self._rtl_lines),
|
| 768 |
+
"testbench.v": not bool(self._testbench_code.strip()),
|
| 769 |
+
"design_golden.v": not bool(self._golden_code.strip()),
|
| 770 |
+
},
|
| 771 |
+
"code_dirty": self._code_dirty,
|
| 772 |
+
"tool_freshness": {
|
| 773 |
+
"simulation": self._sim_validated_hash == self._code_hash,
|
| 774 |
+
"synthesis": self._synth_validated_hash == self._code_hash,
|
| 775 |
+
"lint": self._lint_validated_hash == self._code_hash,
|
| 776 |
+
},
|
| 777 |
+
"logs_available": {
|
| 778 |
+
"simulation": bool(self._sim_log),
|
| 779 |
+
"synthesis": bool(self._synth_log),
|
| 780 |
+
"lint": bool(self._lint_log),
|
| 781 |
+
},
|
| 782 |
+
},
|
| 783 |
+
)
|
| 784 |
+
|
| 785 |
+
def close(self) -> None:
|
| 786 |
+
"""Clean up."""
|
| 787 |
+
if self._workdir and os.path.isdir(self._workdir):
|
| 788 |
+
shutil.rmtree(self._workdir, ignore_errors=True)
|
| 789 |
+
self._workdir = None
|
server/tasks/easy/01_inverter_semicolon/design_buggy.v
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
module inverter (
|
| 2 |
+
input a,
|
| 3 |
+
output y
|
| 4 |
+
);
|
| 5 |
+
|
| 6 |
+
wire stage0;
|
| 7 |
+
wire stage1;
|
| 8 |
+
wire stage2;
|
| 9 |
+
wire stage3;
|
| 10 |
+
wire stage4;
|
| 11 |
+
wire stage5;
|
| 12 |
+
wire stage6;
|
| 13 |
+
wire stage7;
|
| 14 |
+
wire stage8;
|
| 15 |
+
wire stage9;
|
| 16 |
+
|
| 17 |
+
assign stage0 = a;
|
| 18 |
+
assign stage1 = stage0;
|
| 19 |
+
assign stage2 = stage1;
|
| 20 |
+
assign stage3 = stage2;
|
| 21 |
+
assign stage4 = stage3;
|
| 22 |
+
assign stage5 = stage4;
|
| 23 |
+
assign stage6 = stage5;
|
| 24 |
+
assign stage7 = stage6;
|
| 25 |
+
assign stage8 = stage7;
|
| 26 |
+
assign stage9 = stage8;
|
| 27 |
+
|
| 28 |
+
assign y = ~stage9
|
| 29 |
+
|
| 30 |
+
endmodule
|
server/tasks/easy/01_inverter_semicolon/design_golden.v
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
module inverter (
|
| 2 |
+
input a,
|
| 3 |
+
output y
|
| 4 |
+
);
|
| 5 |
+
|
| 6 |
+
wire stage0;
|
| 7 |
+
wire stage1;
|
| 8 |
+
wire stage2;
|
| 9 |
+
wire stage3;
|
| 10 |
+
wire stage4;
|
| 11 |
+
wire stage5;
|
| 12 |
+
wire stage6;
|
| 13 |
+
wire stage7;
|
| 14 |
+
wire stage8;
|
| 15 |
+
wire stage9;
|
| 16 |
+
|
| 17 |
+
assign stage0 = a;
|
| 18 |
+
assign stage1 = stage0;
|
| 19 |
+
assign stage2 = stage1;
|
| 20 |
+
assign stage3 = stage2;
|
| 21 |
+
assign stage4 = stage3;
|
| 22 |
+
assign stage5 = stage4;
|
| 23 |
+
assign stage6 = stage5;
|
| 24 |
+
assign stage7 = stage6;
|
| 25 |
+
assign stage8 = stage7;
|
| 26 |
+
assign stage9 = stage8;
|
| 27 |
+
|
| 28 |
+
assign y = ~stage9;
|
| 29 |
+
|
| 30 |
+
endmodule
|