diff --git a/csv_to_plot.m b/csv_to_plot.m index 7a9dceb687fc04cf41ba419b8450367a9372984d..792a43333da7b7237f9fb6c97da13bee62281a15 100644 --- a/csv_to_plot.m +++ b/csv_to_plot.m @@ -1,9 +1,9 @@ % -% Plot results from the +% Plot results from design sweep. % % Read input data. -in_data = readtable('../sweep_pe_float_2021-01-11_13:17:06/result.csv'); +in_data = readtable('../sweep_my_divider_2021-01-11_13:17:06/result.csv'); % Generic sweep? generic_sweep = width(in_data) > 3; diff --git a/sweep.bash b/sweep.bash index 13ea645e21e98cf135279b52e19959cb90ee01ed..5704574ffb2ce071453756c181bbc4e52f9aefda 100755 --- a/sweep.bash +++ b/sweep.bash @@ -1,14 +1,14 @@ #!/bin/bash # -# Parallel design sweeping tool for Design Compiler. It can be used to sweep -# both clock constraints and VHDL design generics. The tool is used by setting -# the global sweeping settings, found just bellow this note, and the results are -# put in a newly created directory named 'sweep_<design_name>_<date_of_sweep>'. -# Any library settings etc that is to be shared among sweeps are to be put in -# the local configuration file '.synopsys_dc.setup' which is sourced by all -# instances of Design Compiler. -# Use the script at your own risk or whatever... +# Parallel design sweeping script for Design Compiler. It can be used to sweep +# both clock constraints and VHDL design generics simultaneously. The tool is +# used by altering the global sweeping settings, found just bellow this note, and +# the sweep results are put in a newly created directory named +# 'sweep_<design_name>_<date_of_sweep>'. All library technology settings that +# are to be shared among sweeps are to be put in the local configuration file +# '.synopsys_dc.setup' which is sourced by all instances of Design Compiler. +# Use this script at your own risk or whatever... # # Author: Mikael Henriksson # @@ -21,8 +21,8 @@ # Top level design entity name. DESIGN_NAME="my_divider" -# BASH-style array with each design file to be analyzed by Design Compiler. -# Analisys happens from left to right. +# BASH-style array with design files to be analyzed by Design Compiler. Analisys +# of files are done from left (first element) to right (last element). DESIGN_FILES=("divider.vhdl") # BASH-style array with periods (in the technology time unit) to be sweept. @@ -32,21 +32,23 @@ PERIODS=(10.00 5.00 2.50 1.25) # should be set. Multiple generics can be assigned for one sweep by comma # separating each generic assignment in the BASH-array element. GENERICS=("pipeline=0" "pipeline=1" "pipeline=2") +#GENERICS=() -# Design clock name to be sweept. Must be set. +# Design clock name to be sweept. The design must have a clock signal. CLOCK_NAME="clk" # Enable Design Compiler adaptive retime through 'set_optimize_registers' for # current design and run 'compile_ultra -retime'. This option is applied to all -# designs sweept. Set to 'YES' or 'NO' (note the capital letters). +# designs sweept. Set to 'YES' or 'NO' (note the CAPITALIZATION). RETIME_ENABLE="YES" -# Maximum instances of Design Compiler that can run at a time. This should +# Maximum instances of Design Compiler that can run at a time. This should # idealy be set to min{ Computer Cores, Design Compiler Licenses }. MAX_CONCURRENCY=12 -# Extra info that should be appended to the top directory. Could be used for -# appending technology, corrner or other to directory. Leave blank if unused. +# String that will be appended to the top sweep directory name. Could, for +# example, be used to append technology, corrner or other vital info to the +# sweep directory name. Leave blank if unused. TOP_DIR_APPEND="" # Resulting units. These will be used for the generated CSV files. They should @@ -61,9 +63,9 @@ AREA_DIM="um^2" # -# Function for generating a CSV file from a sweep result. Only those sweep whose -# slack where non-violated are extracted. -sweep_to_csv() { +# Generate a CSV sweep result file from a sweep result. Only the sweeps whose +# slack where not violated are extracted. +function sweep_to_csv() { local data_dir="$1" local csv_out="$2" @@ -79,7 +81,7 @@ sweep_to_csv() { echo "Period ($PERIOD_DIM), Total cell area ($AREA_DIM)," \ "Total Power ($POWER_DIM)" > "$csv_out" - # Iterate over successful synthesised results, which had it's timing + # Iterate over successful synthesised results, which had it's timing # constraints met. while IFS='' read -r period; do # Extract data. @@ -93,15 +95,18 @@ sweep_to_csv() { done <<< "$periods" } -# Function for joining a BASH array or white space separated string, specified -# in $1, by the content of $2. -function join_by { - local d=$1; shift; local f=$1; shift; printf %s "$f" "${@/#/$d}"; +# Join elements of BASH array, or white space separated string, in $2 by the +# string in $1. Example usage: +#| > MY_ARRAY=('a' 'b' 'c') +#| > echo join_by '---' "${MY_ARRAY[@]}" +#| a---b---c +function join_by { + local d=$1; shift; local f=$1; shift; printf %s "$f" "${@/#/$d}"; } # Function for generating the synthesis script to be run by design compiler. The -# third option 'design_generics' is optional. -generate_synthesis_script() { +# third parameter to this function 'design_generics' is optional. +function generate_synthesis_script() { local period="$1" local sub_dir="$2" local design_generics="$3" @@ -118,11 +123,11 @@ generate_synthesis_script() { "$sub_dir/sim.tcl" } -# Function used for running design compiler with the different designs. The +# Function used for running Design Compiler with the different designs. The # design script will export this function, fork of new bash-instances with xargs -# and invoke this function. Note to programmer, this means that this function -# cannot access any unexported items (variables, functions, etc). -run_design_compiler() { +# and invoke this function. Note to programmer, that means this function cannot +# access any unexported items (variables, functions, etc). +function run_design_compiler() { # Change directory to design directory. local design_directory="$1" cd "$design_directory" || exit 1 @@ -130,10 +135,11 @@ run_design_compiler() { # Get time of sweep start. start_time="$(date +"%H:%M:%S")" - # Source design options. + # Source the automatically generated design options file. This file contains + # 'period' and 'design'generics'. # shellcheck disable=SC1091 source .design_options.sh - + if [ "$design_generics" = "" ]; then echo "[ PID: $$ ]: $start_time, starting synthesis: '$DESIGN_NAME'" \ "@ $period $PERIOD_DIM." @@ -143,14 +149,13 @@ run_design_compiler() { fi # - # Run design compiler with the auto generated build file. - # Custom design compiler exit codes: + # Run design compiler with the auto generated TCL build script. All logging + # is done in the local 'log.txt' file. Custom Design Compiler exit codes: # 0: Success # 1: Analyze failure # 2: Elaborate failure - # 3: Create clock + # 3: Create clock failure # 3: Compile failure - # dc_error_type=("Success" "analyze" "elaborate" "create_clock" "compile") dc_shell -f sim.tcl 1>log.txt 2>&1 dc_exit_code="$?" @@ -160,15 +165,15 @@ run_design_compiler() { "$dc_exit_code (abnormal '${dc_error_type[$dc_exit_code]}'-phase)." fi } -export -f run_design_compiler -# Here we export global variables that might be needed by run_design_compiler -# function. This because 'run_design_compiler' will run in another process. +# Export functions and variables needed by the forked instances of this script +# that run the run_design_compiler function. +export -f run_design_compiler export DESIGN_NAME export PERIOD_DIM # -# Sanity checks for the settings. +# Sanity checks for the global settings. # if [ -z "$CLOCK_NAME" ]; then echo "Error: No clock name (\$CLOCK_NAME) provided." @@ -214,11 +219,11 @@ fi # Make sure dc_shell is accessable through PATH. which dc_shell 1>/dev/null 2>&1 && HAS_DC=1 || HAS_DC=0 if [ "$HAS_DC" = "0" ]; then - echo "Error: Could not access Design Compiler (dc_shell) through PATH." + echo "Error: Design Compiler (dc_shell) not available through \$PATH." exit 1 fi -# If the '.synopsys_dc.setup' setup file, which usually contains technology +# If the '.synopsys_dc.setup' setup file, which should contain technology # settings, is missing, query the user and ask if they would like to continue. if [ ! -f ".synopsys_dc.setup" ]; then read -r -p "Could not locate file '.synopsys_dc.setup'. Are you sure you \ @@ -231,8 +236,10 @@ want to continure? [y/N] " response fi fi -# Create top directory. +# Get script launch date. SCRIPT_LAUNCH_DATE=$(date +"%F_%H:%M:%S") + +# Create sweep top directory. if [ -z "$TOP_DIR_APPEND" ]; then TOP_DIR="sweep_${DESIGN_NAME}_${SCRIPT_LAUNCH_DATE}" else @@ -245,16 +252,16 @@ fi echo "Created top directory: '$TOP_DIR'" echo "" -# Get the absolute path of design files, which is necessary for the sweep. +# Get absolute path of design files, which is necessary for the sweep. DESIGN_FILES_ABS=() for file in "${DESIGN_FILES[@]}"; do DESIGN_FILES_ABS+=("$(realpath "$file")") done -# Initialize designs. We create one sub directory from each design that is -# to be sweept. One design is one design file with one generic setting. Further -# we substitue design options into 'template.tcl' and copy the resulting -# synthesis script into the design directory. +# Initialize designs. We create one sub directory for each design that is +# to be sweept. A 'design' is exactly one setting from ${DESIGN_GENERICS[@]}. +# Further, we substitue design options into 'template.tcl' and copy the +# resulting synthesis script into the design directory. SYNTH_DIRS="" if [ "${#GENERICS[@]}" -gt 0 ]; then @@ -264,7 +271,7 @@ if [ "${#GENERICS[@]}" -gt 0 ]; then period_cnt=1 for period in "${PERIODS[@]}"; do - # Create design/period subdirectory. + # Create design and period subdirectory. sub_dir="$TOP_DIR/$design_generics/$period" mkdir -p "$sub_dir" if [ "$period_cnt" -ne "${#PERIODS[@]}" ]; then @@ -273,20 +280,20 @@ if [ "${#GENERICS[@]}" -gt 0 ]; then echo " └── Period: $period $PERIOD_DIM." fi - # Generate synthesis script from template. + # Generate current design and period synthesis script from template. generate_synthesis_script "$period" "$sub_dir" "$design_generics" - # Possibly copy the Design Compiler local setup file. + # Possibly copy the Design Compiler global settings/technology file. if [ -f ".synopsys_dc.setup" ]; then cp ".synopsys_dc.setup" "$sub_dir/" fi # Append new synthesis directory to sweep list. - SYNTH_DIRS="$sub_dir|$SYNTH_DIRS" + SYNTH_DIRS="${sub_dir}|${SYNTH_DIRS}" ((period_cnt=period_cnt+1)) - # Add data to be read by 'run_design_compiler'. - design_options="$sub_dir/.design_options.sh" + # Add period and design options to design option file. + design_options="${sub_dir}/.design_options.sh" touch "$design_options" echo "period=\"$period\"" >> "$design_options" echo "design_generics=\"$design_generics\"" >> "$design_options" @@ -309,20 +316,20 @@ else # "${GENERICS[@]}" is empty. echo " └── Period: $period $PERIOD_DIM." fi - # Generate synthesis script from template. + # Generate current design and period synthesis script from template. generate_synthesis_script "$period" "$sub_dir" - # Possibly copy the Design Compiler local setup file. + # Possibly copy the Design Compiler global settings/technology file. if [ -f ".synopsys_dc.setup" ]; then cp ".synopsys_dc.setup" "$sub_dir/" fi # Append new synthesis directory to sweep list. - SYNTH_DIRS="$sub_dir|$SYNTH_DIRS" + SYNTH_DIRS="${sub_dir}|${SYNTH_DIRS}" ((period_cnt=period_cnt+1)) - # Add data to be read by 'run_design_compiler'. - design_options="$sub_dir/.design_options.sh" + # Add period and design options to design option file. + design_options="${sub_dir}/.design_options.sh" touch "$design_options" echo "period=\"$period\"" >> "$design_options" done @@ -340,7 +347,7 @@ echo "End of parallel synthesis log." # -# Generate design CSV files from result. +# Generate CSV files from sweep result. # if [ "${#GENERICS[@]}" -eq 0 ]; then # Sweep without design generics.