Skip to content

Commit 96ea7a5

Browse files
committed
variables: demonstrate migration path from make to bash
Signed-off-by: Øyvind Harboe <[email protected]>
1 parent 8aab92b commit 96ea7a5

File tree

11 files changed

+149
-82
lines changed

11 files changed

+149
-82
lines changed

flow/Makefile

Lines changed: 32 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -113,61 +113,36 @@ MAKEFLAGS += --no-builtin-rules
113113
SHELL := /usr/bin/env bash
114114
.SHELLFLAGS := -o pipefail -c
115115

116-
#-------------------------------------------------------------------------------
117-
# Setup variables to point to root / head of the OpenROAD directory
118-
# - the following settings allowed user to point OpenROAD binaries to different
119-
# location
120-
# - default is current install / clone directory
121116
ifeq ($(origin FLOW_HOME), undefined)
122117
FLOW_HOME := $(abspath $(dir $(firstword $(MAKEFILE_LIST))))
123118
endif
124119
export FLOW_HOME
125120

126-
#-------------------------------------------------------------------------------
127-
# Setup variables to point to other location for the following sub directory
128-
# - designs - default is under current directory
129-
# - platforms - default is under current directory
130-
# - work home - default is current directory
131-
# - utils, scripts, test - default is under current directory
132-
export DESIGN_HOME ?= $(FLOW_HOME)/designs
133-
export PLATFORM_HOME ?= $(FLOW_HOME)/platforms
134-
export WORK_HOME ?= .
135-
136-
export UTILS_DIR ?= $(FLOW_HOME)/util
137-
export SCRIPTS_DIR ?= $(FLOW_HOME)/scripts
138-
export TEST_DIR ?= $(FLOW_HOME)/test
139-
140-
PUBLIC=nangate45 sky130hd sky130hs asap7 ihp-sg13g2 gf180
141-
142-
ifneq ($(wildcard $(PLATFORM_HOME)/$(PLATFORM)),)
143-
export PLATFORM_DIR = $(PLATFORM_HOME)/$(PLATFORM)
144-
else ifneq ($(findstring $(PLATFORM),$(PUBLIC)),)
145-
export PLATFORM_DIR = ./platforms/$(PLATFORM)
146-
else ifneq ($(wildcard ../../$(PLATFORM)),)
147-
export PLATFORM_DIR = ../../$(PLATFORM)
148-
else
149-
$(error [ERROR][FLOW] Platform '$(PLATFORM)' not found.)
150-
endif
151-
152-
include $(PLATFORM_DIR)/config.mk
153-
121+
# The plan is to migrate all variables to .sh so that
122+
# ORFS is no longer dependent on make.
123+
#
124+
# Explicitly enumerate the environment variables we need $SCRIPTS/config.sh
125+
# to see since make doesn't pass its environment to subshells.
126+
#
154127
# __SPACE__ is a workaround for whitespace hell in "foreach"; there
155128
# is no way to escape space in defaults.py and get "foreach" to work.
156-
$(foreach line,$(shell $(SCRIPTS_DIR)/defaults.py),$(eval export $(subst __SPACE__, ,$(line))))
157-
158-
# Not normally adjusted by user
159-
export SYNTH_OPERATIONS_ARGS ?= -extra-map $(FLOW_HOME)/platforms/common/lcu_kogge_stone.v
160-
export SYNTH_FULL_ARGS ?= $(SYNTH_ARGS) $(SYNTH_OPERATIONS_ARGS)
161-
162-
# Setup working directories
163-
export DESIGN_NICKNAME ?= $(DESIGN_NAME)
164-
165-
export DESIGN_CONFIG
166-
export DESIGN_DIR = $(dir $(DESIGN_CONFIG))
167-
export LOG_DIR = $(WORK_HOME)/logs/$(PLATFORM)/$(DESIGN_NICKNAME)/$(FLOW_VARIANT)
168-
export OBJECTS_DIR = $(WORK_HOME)/objects/$(PLATFORM)/$(DESIGN_NICKNAME)/$(FLOW_VARIANT)
169-
export REPORTS_DIR = $(WORK_HOME)/reports/$(PLATFORM)/$(DESIGN_NICKNAME)/$(FLOW_VARIANT)
170-
export RESULTS_DIR = $(WORK_HOME)/results/$(PLATFORM)/$(DESIGN_NICKNAME)/$(FLOW_VARIANT)
129+
$(foreach line,$(shell \
130+
DESIGN_NAME=$(DESIGN_NAME) \
131+
FLOW_HOME=$(FLOW_HOME) \
132+
DESIGN_CONFIG=$(DESIGN_CONFIG) \
133+
PLATFORM=$(PLATFORM) \
134+
FLOW_VARIANT=$(FLOW_VARIANT) \
135+
$(FLOW_HOME)/scripts/env.sh $(FLOW_HOME)/scripts/config.sh),$(eval $(subst __SPACE__, ,$(line))))
136+
137+
# check some critical variables in a loop
138+
$(foreach var,DESIGN_NAME DESIGN_NICKNAME PLATFORM,\
139+
$(if $(strip $($(var))),,$(error $(var) is not set)))
140+
141+
# The plan is to move all config.mk variables into $(PLATFORM_DIR)/config.sh and
142+
# delete this include below
143+
ifneq ($(wildcard $(PLATFORM_DIR)/config.mk),)
144+
include $(PLATFORM_DIR)/config.mk
145+
endif
171146

172147
ifneq ($(BLOCKS),)
173148
$(foreach block,$(BLOCKS),$(eval BLOCK_LEFS += ./results/$(PLATFORM)/$(DESIGN_NICKNAME)_$(block)/$(FLOW_VARIANT)/${block}.lef))
@@ -208,16 +183,7 @@ ifeq (,$(strip $(NUM_CORES)))
208183
endif
209184
export NUM_CORES
210185

211-
YOSYS_FLAGS += -v 3
212-
213-
#-------------------------------------------------------------------------------
214-
# setup all commands used within this flow
215-
export TIME_BIN ?= env time
216-
TIME_CMD = $(TIME_BIN) -f 'Elapsed time: %E[h:]min:sec. CPU time: user %U sys %S (%P). Peak memory: %MKB.'
217-
TIME_TEST = $(shell $(TIME_CMD) echo foo 2>/dev/null)
218-
ifeq (,$(strip $(TIME_TEST)))
219-
TIME_CMD = $(TIME_BIN)
220-
endif
186+
export YOSYS_FLAGS += -v 3
221187

222188
# The following determine the executable location for each tool used by this flow.
223189
# Priority is given to
@@ -226,12 +192,12 @@ endif
226192
export OPENROAD_EXE ?= $(abspath $(FLOW_HOME)/../tools/install/OpenROAD/bin/openroad)
227193
export OPENSTA_EXE ?= $(abspath $(FLOW_HOME)/../tools/install/OpenROAD/bin/sta)
228194

229-
OPENROAD_ARGS = -no_init -threads $(NUM_CORES) $(OR_ARGS)
230-
OPENROAD_CMD = $(OPENROAD_EXE) -exit $(OPENROAD_ARGS)
231-
OPENROAD_NO_EXIT_CMD = $(OPENROAD_EXE) $(OPENROAD_ARGS)
232-
OPENROAD_GUI_CMD = $(OPENROAD_EXE) -gui $(OR_ARGS)
195+
export OPENROAD_ARGS = -no_init -threads $(NUM_CORES) $(OR_ARGS)
196+
export OPENROAD_CMD = $(OPENROAD_EXE) -exit $(OPENROAD_ARGS)
197+
export OPENROAD_NO_EXIT_CMD = $(OPENROAD_EXE) $(OPENROAD_ARGS)
198+
export OPENROAD_GUI_CMD = $(OPENROAD_EXE) -gui $(OR_ARGS)
233199

234-
YOSYS_EXE ?= $(abspath $(FLOW_HOME)/../tools/install/yosys/bin/yosys)
200+
export YOSYS_EXE ?= $(abspath $(FLOW_HOME)/../tools/install/yosys/bin/yosys)
235201

236202
# Use locally installed and built klayout if it exists, otherwise use klayout in path
237203
KLAYOUT_DIR = $(abspath $(FLOW_HOME)/../tools/install/klayout/)
@@ -435,14 +401,11 @@ yosys-dependencies: $(YOSYS_DEPENDENCIES)
435401

436402
.PHONY: do-yosys
437403
do-yosys: $(DONT_USE_SC_LIB)
438-
mkdir -p $(RESULTS_DIR) $(LOG_DIR) $(REPORTS_DIR) $(OBJECTS_DIR)
439-
(export VERILOG_FILES=$(RESULTS_DIR)/1_synth.rtlil; \
440-
$(TIME_CMD) $(YOSYS_EXE) $(YOSYS_FLAGS) -c $(SYNTH_SCRIPT)) 2>&1 | tee $(abspath $(LOG_DIR)/1_1_yosys.log)
404+
$(SCRIPTS_DIR)/synth.sh $(SYNTH_SCRIPT) $(LOG_DIR)/1_1_yosys.log
441405

442406
.PHONY: do-yosys-canonicalize
443407
do-yosys-canonicalize: yosys-dependencies $(DONT_USE_SC_LIB)
444-
mkdir -p $(RESULTS_DIR) $(LOG_DIR) $(REPORTS_DIR) $(OBJECTS_DIR)
445-
($(TIME_CMD) $(YOSYS_EXE) $(YOSYS_FLAGS) -c $(SCRIPTS_DIR)/synth_canonicalize.tcl) 2>&1 | tee $(abspath $(LOG_DIR)/1_1_yosys_canonicalize.log)
408+
$(SCRIPTS_DIR)/synth.sh $(SCRIPTS_DIR)/synth_canonicalize.tcl $(LOG_DIR)/1_1_yosys_canonicalize.log
446409

447410
$(RESULTS_DIR)/1_synth.rtlil: $(YOSYS_DEPENDENCIES)
448411
$(UNSET_AND_MAKE) do-yosys-canonicalize
@@ -555,13 +518,7 @@ endif
555518

556519
.PHONY: do-$(1)
557520
do-$(1): $(OBJECTS_DIR)/copyright.txt
558-
@mkdir -p $(RESULTS_DIR) $(LOG_DIR) $(REPORTS_DIR) $(OBJECTS_DIR)
559-
@echo Running $(3).tcl, stage $(1)
560-
@(set -eo pipefail; \
561-
trap 'mv $(LOG_DIR)/$(1).tmp.log $(LOG_DIR)/$(1).log' EXIT; \
562-
$(OPENROAD_EXE) $(OPENROAD_ARGS) -exit $(SCRIPTS_DIR)/noop.tcl 2>&1 >$(LOG_DIR)/$(1).tmp.log; \
563-
$(TIME_CMD) $(OPENROAD_CMD) -no_splash $(SCRIPTS_DIR)/$(3).tcl -metrics $(LOG_DIR)/$(1).json 2>&1 | \
564-
tee -a $(abspath $(LOG_DIR)/$(1).tmp.log))
521+
$(SCRIPTS_DIR)/flow.sh $(1) $(3)
565522
endef
566523

567524
# generate make rules to copy a file, if a dependency change and

flow/platforms/asap7/config.mk

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
export PLATFORM = asap7
2-
export PROCESS = 7
3-
41
ifeq ($(LIB_MODEL),)
52
export LIB_MODEL = NLDM
63
endif

flow/platforms/asap7/config.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export PROCESS=7

flow/platforms/nangate45/config.mk

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
# Process node
2-
export PROCESS = 45
3-
41
#-----------------------------------------------------
52
# Tech/Libs
63
# ----------------------------------------------------

flow/platforms/nangate45/config.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Process node
2+
export PROCESS=45

flow/scripts/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

33
Various scripts to support flow as well as utilities.
44

5+
## flow.sh/synth.sh - WORK IN PROGRESS
6+
7+
This script is a low level script used to invoke a flow step. ORFS make or bazel-orfs will set up all the project specific variables before invoking this script where the rest of the variables are set up before invoking OpenROAD.
8+
9+
scripts/flow.sh 2_1_floorplan floorplan
10+
11+
scripts/synth.sh $SYNTH_SCRIPT $LOG_DIR/1_1_yosys.log
12+
513
## make run-yosys
614

715
Sets up all the ORFS environment variables and launches Yosys.

flow/scripts/config.sh

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/bin/bash
2+
set -u
3+
4+
# Set default paths
5+
export PLATFORM_HOME="${PLATFORM_HOME:-${FLOW_HOME}/platforms}"
6+
export WORK_HOME="${WORK_HOME:-.}"
7+
export SCRIPTS_DIR="${SCRIPTS_DIR:-${FLOW_HOME}/scripts}"
8+
9+
# Define public platforms
10+
PUBLIC="nangate45 sky130hd sky130hs asap7 ihp-sg13g2 gf180"
11+
12+
# Determine PLATFORM_DIR based on PLATFORM
13+
if [[ -d "${PLATFORM_HOME}/${PLATFORM}" ]]; then
14+
export PLATFORM_DIR="${PLATFORM_HOME}/${PLATFORM}"
15+
elif [[ " ${PUBLIC} " == *" ${PLATFORM} "* ]]; then
16+
export PLATFORM_DIR="./platforms/${PLATFORM}"
17+
elif [[ -d "../../${PLATFORM}" ]]; then
18+
export PLATFORM_DIR="../../${PLATFORM}"
19+
fi
20+
21+
export DESIGN_HOME="${DESIGN_HOME:-${FLOW_HOME}/designs}"
22+
export UTILS_DIR="${UTILS_DIR:-${FLOW_HOME}/util}"
23+
export SCRIPTS_DIR="${SCRIPTS_DIR:-${FLOW_HOME}/scripts}"
24+
export TEST_DIR="${TEST_DIR:-${FLOW_HOME}/test}"
25+
26+
# if $PLATFORM_DIR/config.sh exists, source it
27+
if [ -f "${PLATFORM_DIR}/config.sh" ]; then
28+
source "${PLATFORM_DIR}/config.sh"
29+
fi
30+
31+
export TIME_BIN="${TIME_BIN:-env time}"
32+
TIME_CMD="$TIME_BIN -f 'Elapsed time: %E[h:]min:sec. CPU time: user %U sys %S (%P). Peak memory: %MKB.'"
33+
if ! TIME_TEST=$(eval "$TIME_CMD echo foo" 2>/dev/null); then
34+
TIME_CMD="$TIME_BIN"
35+
fi
36+
export TIME_CMD
37+
38+
# Setup working directories
39+
export DESIGN_NICKNAME="${DESIGN_NICKNAME:=${DESIGN_NAME}}"
40+
41+
export DESIGN_DIR="$(dirname "${DESIGN_CONFIG}")"
42+
export LOG_DIR="${WORK_HOME}/logs/${PLATFORM}/${DESIGN_NICKNAME}/${FLOW_VARIANT}"
43+
export OBJECTS_DIR="${WORK_HOME}/objects/${PLATFORM}/${DESIGN_NICKNAME}/${FLOW_VARIANT}"
44+
export REPORTS_DIR="${WORK_HOME}/reports/${PLATFORM}/${DESIGN_NICKNAME}/${FLOW_VARIANT}"
45+
export RESULTS_DIR="${WORK_HOME}/results/${PLATFORM}/${DESIGN_NICKNAME}/${FLOW_VARIANT}"
46+
47+
# Run the defaults.py script and process its output
48+
while IFS= read -r line; do
49+
# Replace "__SPACE__" with an actual space in the line
50+
eval "${line//__SPACE__/ }"
51+
done < <("${FLOW_HOME}/scripts/defaults.py")

flow/scripts/defaults.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@
1212
for key, value in data.items():
1313
if value.get("default", None) is None:
1414
continue
15-
print(f'export {key}?={str(value["default"]).replace(" ", "__SPACE__")}')
15+
print(
16+
f'export {key}="${{{key}:-{str(value["default"]).replace(" ", "__SPACE__")}}}"'
17+
)

flow/scripts/env.sh

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/bin/bash
2+
# Print out make variables that have changed so that
3+
# make can set them up in "make". This vile script has to
4+
# be in bash, because we're sourcing the script that we're
5+
# checking for changes to environment variables.
6+
set -e
7+
# Get the environment file from the first argument
8+
envfile="$1"
9+
10+
# Save the current environment variables
11+
declare -A env_vars
12+
13+
while IFS= read -r -d '' entry; do
14+
var="${entry%%=*}" # Extract the variable name
15+
val="${entry#*=}" # Extract the variable value
16+
env_vars["$var"]="$val"
17+
done < <(env -0)
18+
19+
# Source the environment file to load new variables
20+
if [[ -f "$envfile" ]]; then
21+
source "$envfile"
22+
else
23+
echo "Error: Environment file '$envfile' not found."
24+
exit 1
25+
fi
26+
27+
# Compare the new environment variables with the original ones
28+
while IFS= read -r -d '' entry; do
29+
var="${entry%%=*}" # Extract the variable name
30+
val="${entry#*=}" # Extract the variable value
31+
if [[ "${env_vars[$var]+_}" && "${env_vars[$var]}" != "$val" ]] || [[ ! "${env_vars[$var]+_}" ]]; then
32+
val=$(echo "$val" | sed 's/ /__SPACE__/g')
33+
echo "export $var:=$val"
34+
fi
35+
done < <(env -0)

flow/scripts/flow.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/bin/bash
2+
set -u -eo pipefail
3+
mkdir -p $RESULTS_DIR $LOG_DIR $REPORTS_DIR $OBJECTS_DIR
4+
echo Running $2.tcl, stage $1
5+
(trap 'mv $LOG_DIR/$1.tmp.log $LOG_DIR/$1.log' EXIT; \
6+
$OPENROAD_EXE $OPENROAD_ARGS -exit $SCRIPTS_DIR/noop.tcl 2>&1 >$LOG_DIR/$1.tmp.log; \
7+
eval "$TIME_CMD $OPENROAD_CMD -no_splash $SCRIPTS_DIR/$2.tcl -metrics $LOG_DIR/$1.json" 2>&1 | \
8+
tee -a $(realpath $LOG_DIR/$1.tmp.log))

0 commit comments

Comments
 (0)