Simulate saved RTL and keep the result
Save a bounded RTL simulation request, admit and preflight it, run it, then store, list and reopen the result in your project.
Use Altifigence CLI 0.1.9 on Linux to simulate saved SystemVerilog with the bundled RTL engine. The admit, preflight and run simulation commands each read one request file inside your project and print JSON. To read the four-state multi-clock simulation contract, run alti rtl simulate-v2 capabilities.
Save a simulation request
Create the project folder and save this request in it as sim.json. Use exactly these four top-level keys. The request holds the SystemVerilog source, the clock port and period, an optional reset, the initial register values and one input vector per cycle.
mkdir -p "$HOME/alti-projects/demo-project"
PROJECT="$(cd "$HOME/alti-projects/demo-project" && pwd -P)"{
"schema": "altifigence.rtl.operation-request.v1",
"version": 1,
"operationId": "altifigence.rtl.simulate.v1",
"request": {
"top": "top",
"sources": [
{
"path": "workspace/top.sv",
"source": "module top(\n input logic clk,\n input logic rst,\n input logic d,\n output logic q\n);\n always_ff @(posedge clk or posedge rst)\n if (rst) q <= 1'b0;\n else q <= d;\nendmodule\n"
}
],
"clock": {
"port": "clk",
"periodPs": 1000
},
"initialRegisterValues": [
false
],
"cycles": [
{
"inputs": {
"d": [
false
]
}
},
{
"inputs": {
"d": [
true
]
}
},
{
"inputs": {
"d": [
true
]
}
},
{
"inputs": {
"d": [
false
]
}
}
],
"limits": {
"maxCycles": 4,
"maxTimePs": 4000
},
"reset": {
"port": "rst",
"activeLevel": "active_high",
"assertCycles": 1
}
}
}Give every top-level input except the clock and reset in each cycle, least-significant bit first. The engine drives the clock and asserts the reset for the first assertCycles cycles. Keep clock.periodPs from 2 to 1000000000. Set limits.maxCycles from the number of cycles up to 32768, and limits.maxTimePs from cycles × periodPs up to 1000000000000. The request file can be up to 272629760 bytes.
Check the request before running
alti rtl simulate admit --project "$PROJECT" sim.json
alti rtl simulate preflight --project "$PROJECT" sim.json > "$PROJECT/preflight.json"
jq -c '[.outputPorts[].name]' "$PROJECT/preflight.json"Require exit status 0 for each command. Admit checks the request shape and limits and returns altifigence.rtl.simulation-admission.v1 with admitted true; for this request it reports cycleCount 4, transitionStepCount 8 and simulatedTimePs 4000. Preflight also synthesizes the source to a logic netlist and returns altifigence.rtl.simulation-preflight.v1 with the input ports, output ports and registers. The jq line prints:
["q"]Admit and preflight are pre-checks. The simulation runs only with run.
Run the simulation
alti rtl simulate run --project "$PROJECT" sim.json > "$PROJECT/result.json"
jq -c '.artifact.payload.summaryArtifact.payload.finalOutputsLsb0' "$PROJECT/result.json"
jq -r '.artifact.payload.waveformArtifact.payload' "$PROJECT/result.json" > "$PROJECT/wave.vcd"Require exit status 0. The result has schema altifigence.rtl.operation-result.v1 and operationId altifigence.rtl.simulate.v1. Its artifact is an altifigence.rtl.simulation-receipt.v1 receipt with the preflight, an event-step trace, a VCD waveform, a summary and provenance. For this request the final output is:
{"q":[false]}The bundled engine synthesizes the design and runs it with its own two-state event-step simulator. wave.vcd uses a 1ps timescale.
Inspect and synthesize the source
Save the same module as a project file, then emit its schematic and synthesize it. Source paths are relative to the project.
mkdir -p "$PROJECT/rtl"
jq -r '.request.sources[0].source' "$PROJECT/sim.json" > "$PROJECT/rtl/top.sv"
alti rtl schematic --project "$PROJECT" --top top rtl/top.sv > "$PROJECT/schematic.json"
jq -c '{schema, source}' "$PROJECT/schematic.json"Require exit status 0. The jq line prints:
{"schema":"alti-rtl-schematic.v1","source":"saved-files"}The document also contains topModule, modules, instances, nets, connections, diagnostics and unsupported. Its status is complete or partial; a failed document exits with status 1.
alti rtl synth --project "$PROJECT" --top top rtl/top.sv > "$PROJECT/synth.json"
jq -c '{report: .report.schema, netlist: .netlist.schema, cells: .report.stats.cells_by_kind}' "$PROJECT/synth.json"Require exit status 0. Synth prints the logic netlist and its synthesis report. For this module the jq line prints:
{"report":"rtl-synth-report-2","netlist":"logic-netlist-2","cells":{"dff_posedge_async_reset":1}}If synth stops with alti-rtl: synth requires at least one SystemVerilog file, add the source path, such as rtl/top.sv, after the options.
Keep and reopen the result
alti rtl artifact store --project "$PROJECT" result.json > "$PROJECT/manifest.json"
ENTRY_ID="$(jq -r '.entryId' "$PROJECT/manifest.json")"
alti rtl artifact list --project "$PROJECT"
alti rtl artifact show --project "$PROJECT" "$ENTRY_ID" > "$PROJECT/reopened.json"Store validates the complete result and writes it under .altifigence/artifacts/rtl/ in the project. Its altifigence.rtl.artifact-manifest.v1 manifest contains entryId, the SHA-256 of the stored result, and relativePath results/<entryId>.json. List prints every manifest; show prints the stored result JSON. A result can be up to 67108864 bytes.
Recover from errors
For RTL simulation request must be the exact altifigence.rtl.simulate.v1 envelope, give the file exactly the keys schema, version, operationId and request with the values shown above.
For RTL simulation request must be a normalized project-relative path, pass the path relative to the project, such as sim.json, without a leading ./ or /.
The engine prints request errors after alti-rtl: and exits with status 2. For RTL simulation resource limit exceeded for stimulus cycles: observed 5, maximum 4, raise limits.maxCycles to the number of cycles and run admit again.
For RTL simulation resource limit exceeded for simulated time ps: observed 5000, maximum 4000, raise limits.maxTimePs to at least the number of cycles × clock.periodPs.
For RTL artifact entry does not exist: followed by an id, copy an entryId from alti rtl artifact list and run show again.
Check and analyze saved sources
Use the saved rtl/top.sv from the preceding section. Check its diagnostics, inspect the checker coverage and hierarchy, then read the native symbol analysis. Keep execution options after the compiler subcommand.
alti rtl compile check --runner local --project "$PROJECT" -- rtl/top.sv --format json
alti rtl compile coverage --runner local --project "$PROJECT" -- rtl/top.sv --format json
alti rtl compile hierarchy --runner local --project "$PROJECT" -- rtl/top.sv --top top --format json
alti rtl analysis --project "$PROJECT" rtl/top.sv > "$PROJECT/analysis.json"
jq -c '{schemaVersion}' "$PROJECT/analysis.json"{"schemaVersion":"sv-symbols.v2"}The compatibility spelling synthesize also runs the local synthesizer. Pass its engine arguments after --:
alti rtl synthesize --runner local --project "$PROJECT" -- --top top rtl/top.sv > "$PROJECT/synth-compat.json"For RTL compiler execution options must follow the explicit subcommand, place --runner local and --project after check, coverage or hierarchy, as shown above.
Map a combinational netlist to cells
Save a separate combinational example and a small Liberty library. Synthesize its netlist, then map each logic cell to a function-equivalent library cell.
cat > "$PROJECT/rtl/map-example.sv" <<'SV'
module top(input logic a, input logic b, output logic y);
logic n;
assign n = a & b;
assign y = ~n;
endmodule
SV
cat > "$PROJECT/map-example.lib" <<'LIB'
library (neutral) {
cell (AND2) {
area : 2.0;
pin (A) { direction : input; }
pin (B) { direction : input; }
pin (Y) { direction : output; function : "A & B"; }
}
cell (INV) {
area : 1.0;
pin (A) { direction : input; }
pin (Y) { direction : output; function : "!A"; }
}
}
LIB
alti rtl synth --project "$PROJECT" --top top --netlist-only rtl/map-example.sv > "$PROJECT/map-netlist.json"
alti rtl map --project "$PROJECT" --netlist map-netlist.json --liberty map-example.lib > "$PROJECT/map-report.json"
jq -c '{schema, mapped_cell_count, total_area}' "$PROJECT/map-report.json"{"schema":"rtl-liberty-direct-map-report-0","mapped_cell_count":2,"total_area":"3.0"}For no direct Liberty cell covers generic kind followed by a cell kind, supply a library with the matching Boolean function and a positive area, then rerun the map command.
Check a target selection and its sources
Read the target-analysis contract and readiness record, then check a source bundle. The admission records your selections and source digest. Structural preflight returns diagnostics, coverage and hierarchy products.
alti rtl target-analysis capabilities
alti rtl target-analysis readiness
jq '{schema:"rtl-source-bundle.v1",sources:[.request.sources[] | {path,text:.source}],roots:[.request.sources[].path],include_dirs:[],defines:[],tops:[.request.top]}' "$PROJECT/sim.json" > "$PROJECT/target-sources.json"
DEADLINE_MS="$(( $(date +%s) * 1000 + 60000 ))"
TARGET_ARGS=(--module top --top top --targets generic-asic --primary-target generic-asic
--tools schematic,evidence --report-detail standard --profile local-example
--cpu-slots 1 --memory-bytes 536870912 --max-wall-time-ms 5000
--deadline-unix-ms "$DEADLINE_MS")
alti rtl target-analysis admit "${TARGET_ARGS[@]}" < "$PROJECT/target-sources.json" > "$PROJECT/target-admission.json"
jq -c '{schema, structuralPreflightAvailable}' "$PROJECT/target-admission.json"
alti rtl target-analysis preflight "${TARGET_ARGS[@]}" < "$PROJECT/target-sources.json" > "$PROJECT/target-preflight.json"
jq -r '.schema' "$PROJECT/target-preflight.json"{"schema":"altifigence.rtl.target-analysis-direct-admission.v1","structuralPreflightAvailable":true}
altifigence.rtl.target-analysis-direct-result.v1local-example is the profile selection recorded by this example. Keep tops equal to the requested --top. For target Analysis source bundle is invalid: source/root/include/define/top cardinality is invalid, check that sources and roots contain the source and tops contains that one top name.
Run the four-state simulation contract
Reuse the source in sim.json with a timed four-state request. Values are the strings 0, 1, X and Z, least-significant bit first. This example uses one clock, one reset and a timed input schedule.
jq '{schema:.schema,version:1,operationId:"altifigence.rtl.simulate.v2",request:{
top:.request.top,sources:.request.sources,
clocks:[{port:"clk",periodPs:1000,phasePs:500}],
resets:[{port:"rst",activeLevel:"active_high",changes:[
{timePs:0,valueLsb0:["1"]},{timePs:1000,valueLsb0:["0"]}]}],
inputSchedules:[{port:"d",changes:[
{timePs:0,valueLsb0:["0"]},{timePs:1000,valueLsb0:["1"]}]}],
initialRegisterValues:["0"],
limits:{maxCyclesPerClock:4,maxTimePs:4000,maxEvents:64}
}}' "$PROJECT/sim.json" > "$PROJECT/sim-v2.json"
alti rtl simulate-v2 admit --project "$PROJECT" sim-v2.json > "$PROJECT/v2-admission.json"
alti rtl simulate-v2 preflight --project "$PROJECT" sim-v2.json > "$PROJECT/v2-preflight.json"
alti rtl simulate-v2 run --project "$PROJECT" sim-v2.json > "$PROJECT/v2-result.json"
jq -r '.schema' "$PROJECT/v2-admission.json" "$PROJECT/v2-preflight.json"
jq -r '.artifact.payload.schema' "$PROJECT/v2-result.json"altifigence.rtl.simulation-admission.v2
altifigence.rtl.simulation-preflight.v2
altifigence.rtl.simulation-receipt.v2Require exit status 0 at each step. Admission checks the timed request; preflight prepares its synthesized netlist; run produces the trace, waveform, summary and provenance. Use an even periodPs and a phasePs smaller than the period.