Script ↔ Dataflow I/O¶
Shell tasks (shell: bash and friends) exchange data with the dataflow
graph through a GitHub-Actions-style contract: environment variables carry
inputs into the script, and append-only files carry outputs back to the
graph. The files are located by DFM_* environment variables that the
runner sets, so a script just appends to $DFM_OUTPUT (etc.) and the runner
parses the file after the process exits.
This is fully backward compatible: ${{ }} parameter substitution still
works, and a script that ignores all of the channels below behaves exactly as
before.
Inputs the runner provides¶
Env var |
Kind |
Contents |
|---|---|---|
|
path |
Task run directory (alias: |
|
path |
Task source directory (alias: |
|
string |
Fully-qualified task name |
|
string |
Each declared param. Scalars verbatim; |
|
path |
JSON file: |
|
path |
JSON file: |
|
path |
JSON file of the prior memento (absent on the first run) |
DFM_INPUTS is a path to a file rather than inline JSON so that large
filesets cannot blow the environment-size limit. Scalar params are also
inlined as DFM_PARAM_* for the common, ergonomic case.
Outputs the script provides¶
All output files are pre-created empty, so a script can blindly >> to them.
Env var |
Format |
Becomes |
|---|---|---|
|
JSONL — one data-item object per line |
|
|
|
a |
|
one directory per line |
a |
|
JSONL of |
|
|
JSON object (write) |
|
exit code |
integer |
|
File formats¶
DFM_OUTPUT — typed data items (JSONL). Each line is one item; type is
required. A std.FileSet with basedir: "." is rewritten to the rundir:
echo '{"type":"std.FileSet","filetype":"verilogSource","basedir":".","files":["gen.sv"]}' >> "$DFM_OUTPUT"
DFM_ENV — GHA-compatible key/value, including the multiline heredoc form:
echo "SIM_SEED=42" >> "$DFM_ENV"
{ echo "BANNER<<EOF"; cat banner.txt; echo "EOF"; } >> "$DFM_ENV"
The runner folds the accumulated keys (and DFM_PATH directories) into a
single std.Env item, so they flow downstream through the same
env-merging path that std.Env inputs already use.
The dfm-out helper¶
Hand-writing JSON in bash is the rough edge of this design. The bundled
dfm-out console script writes the files for you (it reads the DFM_*
paths from its own environment, and is placed on PATH for shell tasks):
dfm-out fileset --filetype verilogSource gen.sv pkg.sv # → $DFM_OUTPUT
dfm-out env SIM_SEED=42 # → $DFM_ENV
dfm-out path /opt/tools/bin # → $DFM_PATH
dfm-out error "synthesis failed" --file top.sv --line 10 # → $DFM_MARKERS
dfm-out item --type my_pkg.Report key=val n:=3 # n:= ⇒ JSON-typed value
python -m dv_flow.mgr.out is an equivalent fallback. Scripts may always
fall back to raw echo >> "$DFM_OUTPUT".
Worked example¶
- name: GenRtl
shell: bash
consumes: [{type: std.FileSet}]
produces: [{type: std.FileSet}]
with:
top: {type: str, value: "soc_top"}
seeds: {type: list, value: [1, 2, 3]}
run: |
echo "Generating for $DFM_PARAM_TOP" # scalar param, inline
echo "seeds JSON: $DFM_PARAM_SEEDS" # list param as JSON
# Read upstream filesets structurally
jq -r '.[] | select(.type=="std.FileSet") | .files[]' "$DFM_INPUTS" > srclist.txt
python gen.py --top "$DFM_PARAM_TOP" --srcs srclist.txt --out gen.sv
# Hand results back to the graph
dfm-out fileset --filetype verilogSource gen.sv
dfm-out env GEN_OK=1
[ -s gen.sv ] || dfm-out error "generator produced empty output"
Downstream tasks that consumes: std.FileSet automatically see gen.sv;
downstream shell tasks see GEN_OK in their environment.
Coming from GitHub Actions¶
GitHub Actions |
DV Flow |
|---|---|
|
|
|
|
|
|
|
|
|
|
Note
TASK_SRCDIR / TASK_RUNDIR remain as aliases for one release and are
then removed in favor of DFM_SRCDIR / DFM_RUNDIR.