diff --git a/.gitattributes b/.gitattributes index 3a838b4..e6844e8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,6 +3,17 @@ .png filter=lfs diff=lfs merge=lfs -text *.png filter=lfs diff=lfs merge=lfs -text *.sh text eol=lf +*.py text eol=lf *.bat text eol=crlf +<<<<<<< HEAD *.desktop text eol=lf -scripts/* text eol=lf \ No newline at end of file +scripts/* text eol=lf +======= +desktopinit text eol=lf +klayout text eol=lf +.bashrc text eol=lf +setwallpaper text eol=lf +startserver text eol=lf +*.desktop text eol=lf +xschemrc text eol=lf +>>>>>>> 9337a522bfce850a6848722c6ba4973ce31ea63b diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 5eadff6..d302c09 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -312,4 +312,43 @@ jobs: tags: git.1159.cl/mario1159/heavy-web platforms: linux/amd64 context: . - file: ./stacks/heavy.Dockerfile \ No newline at end of file + file: ./stacks/heavy.Dockerfile + + build-chipathon-tools: + needs: build-heavy + runs-on: [ubuntu-latest, amd64] + container: + image: catthehacker/ubuntu:act-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Set up Docker BuildX + uses: docker/setup-buildx-action@v2 + + - name: Authentication + uses: docker/login-action@v2 + with: + registry: git.1159.cl + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build chipathon-tools desktop + uses: docker/build-push-action@v4 + with: + push: true + build-args: BASE_IMG=git.1159.cl/mario1159/heavy-desktop + tags: git.1159.cl/mario1159/chipathon-tools-desktop + platforms: linux/amd64 + context: . + file: ./stacks/chipathon-tools/Dockerfile + + - name: Build chipathon-tools web + uses: docker/build-push-action@v4 + with: + push: true + build-args: BASE_IMG=git.1159.cl/mario1159/heavy-web + tags: git.1159.cl/mario1159/chipathon-tools-web + platforms: linux/amd64 + context: . + file: ./stacks/chipathon-tools/Dockerfile \ No newline at end of file diff --git a/README.md b/README.md index f646f74..c55bca2 100644 --- a/README.md +++ b/README.md @@ -50,9 +50,9 @@ These scripts automate the binding of graphics environment variables to the cont Execute the next script in powershell and follow the container initialization prompt. ```pwsh -& ([scriptblock]::Create((irm https://git.1159.cl/Mario1159/osic-stacks/raw/branch/main/run.ps1))) -remote +& ([scriptblock]::Create((irm https://git.1159.cl/Mario1159/osic-stacks/raw/branch/main/run.ps1))) -pull -download ``` - This script will run the container inside WSL and bind the enviroments variables for [WSLg](https://github.com/microsoft/wslg/blob/main/samples/container/Containers.md). + This script will run the container inside WSL and bind the enviroments variables for [WSLg](https://github.com/microsoft/wslg/blob/main/samples/container/Containers.md). Also, it will download itself so it will exists locally. ##### Linux Execute the next docker command in your terminal replacing `` by any name and `` by an stack from the previous [stack list](#stacks). diff --git a/compile.bat b/compile.bat new file mode 100644 index 0000000..48c6e1a --- /dev/null +++ b/compile.bat @@ -0,0 +1,43 @@ +@echo off +setlocal + +@REM SET BASE_IMG=git.1159.cl/mario1159/analog-xk-web:latest +SET BASE_IMG=git.1159.cl/mario1159/heavy-desktop:latest +SET RESULT_IMAGE=akilesalreadytaken/chipathon-tools:latest + +SET CALL=call +:parse + IF /I ""%1""=="""" GOTO run + IF /I ""%1""==""--help"" GOTO documentation + IF /I ""%1""==""-h"" GOTO documentation + IF /I ""%1""==""--dry"" ( SET "CALL=echo" ) + IF /I ""%1""==""-s"" ( SET "CALL=echo" ) + IF /I ""%1""==""--path"" ( SET "DESIGNS=%~2" && SHIFT ) + IF /I ""%1""==""-p"" ( SET "DESIGNS=%~2" && SHIFT ) + SHIFT + GOTO parse + + +:documentation + echo Usage: run.bat %~nx0 [-h^|--help] [-s^|--dry-run] + GOTO end + + +:run + %CALL% docker build --build-arg BASE_IMG=%BASE_IMG% -t %RESULT_IMAGE% -f stacks/chipathon-tools/Dockerfile stacks/chipathon-tools/ + GOTO end + +:end + endlocal + + +:normalizepath + SET DESIGNS=%~f1 + EXIT /B + + +:: Get DISPLAY from WSL +::wsl --exec bash --norc -c 'echo $DISPLAY' + +:: Get current path of batsh script +::SET BATCH_PATH=%~dpnx0 diff --git a/run.bat b/run.bat new file mode 100644 index 0000000..423e04d --- /dev/null +++ b/run.bat @@ -0,0 +1,166 @@ +@echo off +setlocal + +SET IMAGE=akilesalreadytaken/analog-xk:latest +SET IMAGE=akilesalreadytaken/chipathon-tools:latest +::SET IMAGE=git.1159.cl/mario1159/analog-xk-web:latest + +SET CALL=call +:parse + IF /I ""%~1""=="""" GOTO run + IF /I ""%~1""==""--help"" GOTO documentation + IF /I ""%~1""==""-h"" GOTO documentation + IF /I ""%~1""==""--dry"" ( SET "CALL=echo" ) + IF /I ""%~1""==""-s"" ( SET "CALL=echo" ) + IF /I ""%~1""==""-v"" ( SET "ENABLE_VNC=" ) + IF /I ""%~1""==""--vnc"" ( SET "ENABLE_VNC=" ) + IF /I ""%~1""==""--path"" ( SET "DESIGNS=%~2" && SHIFT ) + IF /I ""%~1""==""-p"" ( SET "DESIGNS=%~2" && SHIFT ) + IF /I ""%~1""==""-k"" ( SET "PDK=%~2" && SHIFT ) + IF /I ""%~1""==""--pdk"" ( SET "PDK=%~2" && SHIFT ) + SHIFT + GOTO parse + + +:documentation + echo Usage: run.bat %~nx0 [ OPTIONS ] + echo. + echo -h --help Show usage information + echo -s --dry See the commands to be executed + echo -p --path PATH Link to a directory + echo -v --vnc Enable the vnc in port "https:\\localhost:8444" + echo If vnc is not working, execute: + echo ^$ xfce4-session --display=:1 ^& + echo -k --pdk PDK Set the PDK to be used: gf180mcuC ^| sky130A + echo By default: gf180mcuC + GOTO end + + +:run + :: Set fixed parameters + ::::::::::::::::::::::::::: + IF NOT DEFINED DESIGNS SET DESIGNS=%CD% + CALL :NORMALIZEPATH %DESIGNS% + + IF NOT DEFINED PDK SET PDK=gf180mcuC + + IF NOT DEFINED DOCKER_USER SET DOCKER_USER=git.1159.cl/mario1159 + IF NOT DEFINED DOCKER_IMAGE SET DOCKER_IMAGE=analog-xk + IF NOT DEFINED DOCKER_TAG SET DOCKER_TAG=latest + + IF NOT DEFINED CONTAINER_USER SET CONTAINER_USER=1000 + IF NOT DEFINED CONTAINER_GROUP SET CONTAINER_GROUP=1000 + + IF NOT DEFINED CONTAINER_NAME SET CONTAINER_NAME=chipathon-tools + + IF NOT DEFINED JUPYTER_PORT SET JUPYTER_PORT=8888 + IF NOT DEFINED VNC_PORT SET VNC_PORT=8444 + + :: Get parameters from wsl + :::::::::::::::::::::::::: + SET WSL_GET_PARAMETER=wsl --exec bash --norc -c "echo $DISPLAY" + @REM SET WSL_GET_PARAMETER=wsl -d docker-desktop --exec ash -c "echo $DISPLAY" + FOR /F "USEBACKQ" %%i IN (`%WSL_GET_PARAMETER%`) DO ( SET "DISPLAY=%%i" ) + + SET WSL_GET_PARAMETER=wsl --exec bash --norc -c "echo $WAYLAND_DISPLAY" + @REM SET WSL_GET_PARAMETER=wsl -d docker-desktop --exec ash -c "echo $WAYLAND_DISPLAY" + FOR /F "USEBACKQ" %%i IN (`%WSL_GET_PARAMETER%`) DO ( SET "WAYLAND_DISPLAY=%%i" ) + + SET WSL_GET_PARAMETER=wsl --exec bash --norc -c "echo $XDG_RUNTIME_DIR" + @REM SET WSL_GET_PARAMETER=wsl -d docker-desktop --exec ash -c "echo $XDG_RUNTIME_DIR" + FOR /F "USEBACKQ" %%i IN (`%WSL_GET_PARAMETER%`) DO ( SET "XDG_RUNTIME_DIR=%%i" ) + + :: Validate parameters + :::::::::::::::::::::: + IF %CONTAINER_USER% NEQ 0 IF %CONTAINER_USER% LSS 1000 ( + echo WARNING: Selected User ID %CONTAINER_USER% is below 1000. This ID might interfere with User-IDs inside the container and cause undefined behaviour! + ) + IF %CONTAINER_GROUP% NEQ 0 IF %CONTAINER_GROUP% LSS 1000 ( + echo WARNING: Selected Group ID %CONTAINER_GROUP% is below 1000. This ID might interfere with Group-IDs inside the container and cause undefined behaviour! + ) + + :: Attach to existing container + ::::::::::::::::::::::::::::::: + docker container inspect %CONTAINER_NAME% 2>&1 | find "Status" | find /i "running" + IF NOT ERRORLEVEL 1 ( + ECHO Container %CONTAINER_NAME% is running! + ECHO Stop with "docker stop %CONTAINER_NAME%" + ECHO Remove with "docker rm %CONTAINER_NAME%" if required. + GOTO attach_shell + ) + docker container inspect %CONTAINER_NAME% 2>&1 | find "Status" | find /i "exited" + IF NOT ERRORLEVEL 1 ( + ECHO Container %CONTAINER_NAME% exists. + ECHO Restart with "docker start %CONTAINER_NAME%" + ECHO Or remove with "docker rm %CONTAINER_NAME%" if required. + GOTO restart_shell + ) + + :: Set environment, variables and run the container + ::::::::::::::::::::::::::::::::::::::::::::::::::: + echo Check requirements + %CALL% wsl --install Ubuntu --no-launch + %CALL% wsl --update + + echo Container does not exist, creating %CONTAINER_NAME% ... + + SET PARAMS=-d + SET PARAMS=%PARAMS% --name %CONTAINER_NAME% + ::SET PARAMS=%PARAMS% --user %CONTAINER_USER%:%CONTAINER_GROUP% + SET PARAMS=%PARAMS% --security-opt seccomp=unconfined + + SET PARAMS=%PARAMS% -p %JUPYTER_PORT%:8888 + SET PARAMS=%PARAMS% -p %VNC_PORT%:8444 + + SET PARAMS=%PARAMS% -v "%DESIGNS%":/home/designer/shared + SET PARAMS=%PARAMS% -v "\\wsl.localhost\Ubuntu\mnt\wslg":/tmp + SET PARAMS=%PARAMS% -v "\\wsl.localhost\Ubuntu\mnt\wslg\runtime-dir":%XDG_RUNTIME_DIR% + @REM SET PARAMS=%PARAMS% -v "\\wsl.localhost\docker-desktop\mnt\host\wslg":/tmp + @REM SET PARAMS=%PARAMS% -v "\\wsl.localhost\docker-desktop\mnt\host\wslg\runtime-dir":%XDG_RUNTIME_DIR% + + SET PARAMS=%PARAMS% -e PDK=%PDK% + SET PARAMS=%PARAMS% -e DISPLAY=%DISPLAY% + SET PARAMS=%PARAMS% -e WAYLAND_DISPLAY=%WAYLAND_DISPLAY% + SET PARAMS=%PARAMS% -e XDG_RUNTIME_DIR=%XDG_RUNTIME_DIR% + @REM IF NOT DEFINED ENABLE_VNC ( + @REM ) ELSE ( + @REM ) + + IF NOT DEFINED IMAGE ( + SET IMAGE=%DOCKER_USER%/%DOCKER_IMAGE% + IF DEFINED DOCKER_TAG SET IMAGE=%IMAGE%:%DOCKER_TAG% + ) + + @REM SET COMMAND=jupyter-lab --no-browser + @REM SET COMMAND=sleep infinity + + %CALL% docker run %PARAMS% %IMAGE% %COMMAND% + + GOTO attach_shell + + +:attach_shell + %CALL% docker exec -it %CONTAINER_NAME% bash + GOTO end + + +:restart_shell + %CALL% docker start %CONTAINER_NAME% + GOTO attach_shell + + +:end + endlocal + EXIT + + +:normalizepath + SET DESIGNS=%~f1 + EXIT /B + + +:: Get DISPLAY from WSL +::wsl --exec bash --norc -c 'echo $DISPLAY' + +:: Get current path of batsh script +::SET BATCH_PATH=%~dpnx0 diff --git a/run.ps1 b/run.ps1 index cc32f34..56cf012 100644 --- a/run.ps1 +++ b/run.ps1 @@ -1,89 +1,232 @@ -param([switch] $remote = $false) - -Write-Host "OSIC-Stacks Container Creation" -ForegroundColor Green -Write-Host "Checking requirements and WSL updates" -ForegroundColor DarkGray - -Write-Host "" -wsl --install Ubuntu --no-launch -wsl --update -Write-Host "" - -Write-Host "Please select an image index:" - -$stacks_options = @( - 'analog-xk' - 'analog-xm' - 'analog-heavy' - 'digital-ator' - 'digital-icarus' - 'digital-heavy' - 'heavy' +param( + [switch] $pull = $false, + [switch] $interactive = $false, + [switch] $silent = $false, + [switch] $attach = $false, + [switch] $download = $false ) -for($i = 0; $i -lt $stacks_options.Length; $i++) { - $stack_option = $stacks_options[$i] - Write-Host "[$($i+1)] - $stack_option" -ForegroundColor Cyan +$global:STACK_OPTIONS = [ordered]@{ + 1 = 'analog-xk' + 2 = 'analog-xm' + 3 = 'analog-heavy' + 4 = 'digital-ator' + 5 = 'digital-icarus' + 6 = 'digital-heavy' + 7 = 'heavy' + 8 = "chipathon-tools" } -$stack_index = Read-Host -Prompt "Container image to initialize [1-$($stacks_options.Length)]" -$selected_stack = $stacks_options[$stack_index-1] -$container_name = Read-Host -Prompt "Container instance name [default=$selected_stack]" -if (!$container_name) { $container_name = $selected_stack } +$global:SELECTED_STACK='chipathon-tools' +$global:CONTAINER_NAME=$global:SELECTED_STACK +$global:EXECMODE='desktop' +$global:PDK="gf180mcuC" +$global:DIRECTORY=Get-Location | Foreach-Object { $_.Path } -$execmode = '' -while(!$execmode) { - Write-Host "Please select an execution mode index" - Write-Host '[1] - desktop' -ForegroundColor Cyan - Write-Host '[2] - web' -ForegroundColor Cyan - $response = Read-Host "Execution mode [1-2]" - if ($response -eq '1') { - $execmode = 'desktop' - } elseif ($response -eq '2') { - $execmode = 'web' - } else { - Write-Host "Unexpected respose, please try again" -ForegroundColor Red +$global:PARAMS = "" + +New-Alias Call Invoke-Expression + +function validate-environment() { + Write-Host "Checking requirements and WSL updates" -ForegroundColor DarkGray + + Write-Host "" + Call "wsl --install Ubuntu --no-launch" + Call "wsl --update" + Write-Host "" +} + +function select-stack() { + Write-Host "Please select an stack index:" + + $STACK_OPTIONS.GetEnumerator() | ForEach-Object { + Write-Host "[$($_.Key)] - $($_.Value)" -ForegroundColor Cyan + } + + $response = Read-Host -Prompt "Container stack to initialize [1-$($STACK_OPTIONS.Count)]" + if ($response) { + $global:SELECTED_STACK = $STACK_OPTIONS[$response-1] + } + + $response = Read-Host -Prompt "Container instance name [default=$global:CONTAINER_NAME]" + if ($response) { + $global:CONTAINER_NAME = $response } } -$additional_options = '' -if($remote) { - $image = "git.1159.cl/mario1159/$selected_stack-$execmode" - $additional_options = '--pull always ' -} else { - $image = "$selected_stack-$execmode" +function select-execmode() { + Write-Host "Please select an execution mode index" + Write-Host '[1] - desktop' -ForegroundColor Cyan + Write-Host '[2] - web' -ForegroundColor Cyan + $response = Read-Host "Execution mode [1-2] [default=$global:EXECMODE]" + + if ($response -eq '1') { + $global:EXECMODE = 'desktop' + } elseif ($response -eq '2') { + $global:EXECMODE = 'web' + } else { + Write-Host "Using default mode ($global:EXECMODE)" + } } -$response = Read-Host "Do you want to bind the container home directory into a windows directory? [N/y]" +function bind-to-directory() { + $response = Read-Host "Do you want to bind the container home directory into a windows directory? [N/y]" -if ($response -eq 'y') { - $directory = Read-Host "Write the windows directory destination relative to WSL, for example `"/mnt/c/Users/Username/Desktop/ExampleFolder`"`n" - $additionaloptions = -join($additionaloptions, "-v ${directory}:/home/designer/shared ") + if ($response -eq 'y') { + $global:DIRECTORY = Read-Host "Write the windows directory destination , for example `"C:\Users\Username\Desktop\ExampleFolder`"`n" + } } -$response = Read-Host -Prompt "Do you want to set additional arguments for the container instantiation? [N/y]" +function set-aditional-parameters() { + $response = Read-Host -Prompt "Do you want to set additional arguments for the container instantiation? [N/y]" -if ($response -eq 'y') { - $response = Read-Host -Prompt "Write the additional arguments, for example -v :." - $additionaloptions = -join($additionaloptions, $response) + if ($response -eq 'y') { + $response = Read-Host -Prompt "Write the additional arguments, for example -v :." + $global:PARAMS += " $response" + } } -Write-Host "" +function force-pull() { + $response = Read-Host -Prompt "Do you want to pull latest image? [N/y] [default=N]" -$dockercommand = ("docker run -d " + - "--name $container_name " + - "-v /tmp/.X11-unix:/tmp/.X11-unix " + - "-v /mnt/wslg:/mnt/wsl " + - "-e WAYLAND_DISPLAY=`$WAYLAND_DISPLAY " + - "-e DISPLAY=`$DISPLAY " + - "-e XDG_RUNTIME_DIR=/mnt/wslg " + - "$additional_options "+ - $image) + if ($response -eq 'y') { + $global:PARAMS += " --pull always" + } +} -wsl -d Ubuntu bash -ic $dockercommand +function select-pdk() { + Write-Host "Please select a pdk" + Write-Host '[1] - gf180mcuC' -ForegroundColor Cyan + Write-Host '[2] - sky130A' -ForegroundColor Cyan + $response = Read-Host "Execution mode [1-2] [default=$global:PDK]" -if ($?) { - Write-Host "Container created successfully!" -ForegroundColor Green - Write-Host "Enter the container with `"docker exec -it $container_name bash`"" -ForegroundColor DarkGray -} else { - Write-Host "Container creation failed, see logs above" -ForegroundColor Red -} \ No newline at end of file + if ($response -eq '1') { + $global:PDK = 'gf180mcuC' + } elseif ($response -eq '2') { + $global:PDK = 'sky130A' + } else { + Write-Host "Using default pdk ($global:PDK)" + } +} + +function attach-shell () { + Call "docker exec -it $global:CONTAINER_NAME bash" +} + +function path-conversion() { + $directory, $other = $args + $drive, $path = $directory.split(":") + + echo "/mnt/$($drive.tolower())$($path.replace("\","/"))" +} + +function get-value-from-wsl () { + $variable, $other = $args + return "$(wsl -d Ubuntu bash -c "echo `$$variable")" +} + +function set-common-parameters () { + $global:IMAGE = "git.1159.cl/mario1159/$SELECTED_STACK-$EXECMODE" + + if ($attach) { + $global:PARAMS += " -it --rm" + $global:COMMAND = "bash" + } else { + $global:PARAMS += " -d" + $global:COMMAND = "" + } + + if ($pull) { + $global:PARAMS += " --pull always" + } + + $global:PARAMS += " --name $global:CONTAINER_NAME" + $global:PARAMS += " --security-opt seccomp=unconfined" + + # $global:PARAMS += " -p '8888:8888'" + # $global:PARAMS += " -p '8082:8082'" + + $global:PARAMS += " -e PDK=$global:PDK" + + $global:PARAMS += " -e DISPLAY=$(get-value-from-wsl "DISPLAY")" + $global:PARAMS += " -e WAYLAND_DISPLAY=$(get-value-from-wsl "WAYLAND_DISPLAY")" + $global:PARAMS += " -e XDG_RUNTIME_DIR=$(get-value-from-wsl "XDG_RUNTIME_DIR")" +} + +function run-docker-wsl() { + $global:DIRECTORY = path-conversion $global:DIRECTORY + + $global:PARAMS += " -v /tmp/.X11-unix:/tmp/.X11-unix" + $global:PARAMS += " -v /mnt/wslg:/mnt/wsl" + $global:PARAMS += " -v ${global:DIRECTORY}:/home/designer/shared " + + Call "wsl -d Ubuntu bash --noprofile --norc -ic `"docker run $global:PARAMS $global:IMAGE $global:COMMAND`"" + + if ($?) { + Write-Host "Container created successfully!" -ForegroundColor Green + Write-Host "Enter the container with `"docker exec -it $global:CONTAINER_NAME bash`"" -ForegroundColor DarkGray + + attach-shell + } else { + Write-Host "Container creation failed, see logs above" -ForegroundColor Red + } +} + +function run-docker-win() { + $global:PARAMS += " -v '\\wsl.localhost\Ubuntu\mnt\wslg:/tmp'" + $global:PARAMS += " -v ${global:DIRECTORY}:/home/designer/shared" + #$global:PARAMS += " -v '\\wsl.localhost\Ubuntu\mnt\wslg\runtime-dir'%XDG_RUNTIME_DIR%" + + Call "docker run $global:PARAMS $global:IMAGE $global:COMMAND" + + if ($?) { + Write-Host "Container created successfully!" -ForegroundColor Green + Write-Host "Enter the container with `"docker exec -it $global:CONTAINER_NAME bash`"" -ForegroundColor DarkGray + + attach-shell + } else { + Write-Host "Container creation failed, see logs above" -ForegroundColor Red + } +} + +function download-run-bat () { + if (!$download) { return } + + try { + $response = Call "Invoke-WebRequest -URI https://git.1159.cl/Mario1159/osic-stacks/src/branch/main/run.ps1" + } catch { + $StatusCode = $_.Exception.Response.StatusCode.value__ + Write-Host "Error downloading file :( ($($StatusCode))" -ForegroundColor Red + return + } + + Write-Host "run.bat updated successfully" -ForegroundColor Green +} + +function run(){ + if ($silent) { + Write-Host "[Silent Mode]" -ForegroundColor Yellow + Remove-Alias Call + New-Alias Call Write-Host + } + + Write-Host "OSIC-Stacks Container Creation" -ForegroundColor Green + + download-run-bat + validate-environment + + if ($interactive) { + select-stack + select-execmode + bind-to-directory + set-aditional-parameters + force-pull + } + + set-common-parameters + + #run-docker-win + run-docker-wsl +} + +run diff --git a/run.sh b/run.sh new file mode 100644 index 0000000..5ab132e --- /dev/null +++ b/run.sh @@ -0,0 +1,155 @@ +#!/bin/bash +set -e + +# IMAGE=akilesalreadytaken/analog-xk:latest +IMAGE=akilesalreadytaken/chipathon-tools:latest +# IMAGE=git.1159.cl/mario1159/analog-xk-web:latest + +CALL= +function parse () { + while getopts ":hsvp:k:" option; do + case $option in + h) documentation ;; + s) CALL="echo [CMD] " ;; + #v) ENABLE_VNC=1 ;; # VNC not working rigth now + p) DESIGNS=$OPTARG ;; + k) PDK=$OPTARG ;; + \?) echo "Error: Invalid option"; documentation ;; + esac + done +} + +function documentation () { + echo "Usage: run.bat [ OPTIONS ]" + echo "" + echo " -h Show usage information" + echo " -s See the commands to be executed" + echo " -p PATH Link to a directory" + # echo " -v Enable the vnc in port "https:\\localhost:8444"" + # echo " If vnc is not working, execute:" + # echo " $ xfce4-session --display=:1 &" + echo " -k PDK Set the PDK to be used (gf180mcuC | sky130A)" + echo " By default: gf180mcuC" + exit +} + +function run () { + # Set fixed parameters + #################### + [ -z "${DESIGNS+x}" ] && DESIGNS=$PWD + DESIGNS=$( realpath $DESIGNS ) + + [ -z "${PDK+x}" ] && PDK=gf180mcuC + + [ -z "${DOCKER_USER+x}" ] && DOCKER_USER=git.1159.cl/mario1159 + [ -z "${DOCKER_IMAGE+x}" ] && DOCKER_IMAGE=analog-xk + [ -z "${DOCKER_TAG+x}" ] && DOCKER_TAG=latest + + [ -z "${CONTAINER_USER+x}" ] && CONTAINER_USER=$(id -u) + [ -z "${CONTAINER_GROUP+x}" ] && CONTAINER_GROUP=$(id -g) + + [ -z "${CONTAINER_NAME+x}" ] && CONTAINER_NAME=chipathon-tools + + [ -z "${JUPYTER_PORT+x}" ] && JUPYTER_PORT=8888 + [ -z "${VNC_PORT+x}" ] && VNC_PORT=8444 + + # Validate parameters + ##################### + if [[ ${CONTAINER_USER} -ne 0 ]] && [[ ${CONTAINER_USER} -lt 1000 ]]; then + prt_str="# [WARNING] Selected User ID ${CONTAINER_USER} is below 1000. This ID might interfere with User-IDs inside the container and cause undefined behavior! #" + printf -- '#%.0s' $(seq 1 ${#prt_str}) + echo + echo "${prt_str}" + printf -- '#%.0s' $(seq 1 ${#prt_str}) + echo + fi + + if [[ ${CONTAINER_GROUP} -ne 0 ]] && [[ ${CONTAINER_GROUP} -lt 1000 ]]; then + prt_str="# [WARNING] Selected Group ID ${CONTAINER_GROUP} is below 1000. This ID might interfere with Group-IDs inside the container and cause undefined behavior! #" + printf -- '#%.0s' $(seq 1 ${#prt_str}) + echo + echo "${prt_str}" + printf -- '#%.0s' $(seq 1 ${#prt_str}) + echo + fi + + # Check if the container exists and if it is running. + if [ "$(docker ps -q -f name="${CONTAINER_NAME}")" ]; then + echo "[WARNING] Container is running!" + echo "[HINT] It can also be stopped with \"docker stop ${CONTAINER_NAME}\" and removed with \"docker rm ${CONTAINER_NAME}\" if required." + echo + echo -n "Press \"s\" to stop, and \"r\" to stop & remove: " + read -r -n 1 k <&1 + echo + if [[ $k = s ]] ; then + $CALL docker stop "${CONTAINER_NAME}" + elif [[ $k = r ]] ; then + $CALL docker stop "${CONTAINER_NAME}" + $CALL docker rm "${CONTAINER_NAME}" + fi + exit + fi + + # If the container exists but is exited, it is restarted. + if [ "$(docker ps -aq -f name="${CONTAINER_NAME}")" ]; then + echo "[WARNING] Container ${CONTAINER_NAME} exists." + echo "[HINT] It can also be restarted with \"docker start ${CONTAINER_NAME}\" or removed with \"docker rm ${CONTAINER_NAME}\" if required." + echo + echo -n "Press \"s\" to start, and \"r\" to remove: " + read -r -n 1 k <&1 + echo + if [[ $k = s ]] ; then + $CALL docker start "${CONTAINER_NAME}" + elif [[ $k = r ]] ; then + $CALL docker rm "${CONTAINER_NAME}" + fi + exit + fi + + # Set environment, variables and run the container + ################################################## + + echo "[INFO] Container does not exist, creating ${CONTAINER_NAME} ..." + + PARAMS="-d" + PARAMS="$PARAMS --name $CONTAINER_NAME" + PARAMS="$PARAMS -e PDK=$PDK" + PARAMS="$PARAMS --user ${CONTAINER_USER}:${CONTAINER_GROUP}" + PARAMS="$PARAMS --security-opt seccomp=unconfined" + PARAMS="$PARAMS -p $JUPYTER_PORT:8888" + PARAMS="$PARAMS -v $DESIGNS:/home/designer/shared" + PARAMS="$PARAMS -v /tmp/.X11-unix:/tmp/.X11-unix" + + if [ -z "${ENABLE_VNC+x}" ]; then + PARAMS="$PARAMS -e DISPLAY=$DISPLAY" + PARAMS="$PARAMS -e WAYLAND_DISPLAY=$WAYLAND_DISPLAY" + PARAMS="$PARAMS -e XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR" + else + PARAMS="$PARAMS -p $VNC_PORT:8444" + # Should use WSL_DISTRO_NAME ? + PARAMS="$PARAMS -v /mnt/wslg:/mnt/wsl" + fi + + if [ -z "${IMAGE+x}" ]; then + IMAGE=$DOCKER_USER/$DOCKER_IMAGE:$DOCKER_TAG + fi + + echo "[INFO] Container based on $IMAGE" + + $CALL docker run $PARAMS $IMAGE $COMMAND + + attach_shell +} + +function attach_shell () { + $CALL docker exec -it $CONTAINER_NAME bash +} + + +function restart_shell () { + $CALL docker start $CONTAINER_NAME + attach_shell +} + +parse $@ +run \ No newline at end of file diff --git a/stacks/analog-xk.Dockerfile b/stacks/analog-xk.Dockerfile index da3ec95..0c25038 100644 --- a/stacks/analog-xk.Dockerfile +++ b/stacks/analog-xk.Dockerfile @@ -12,9 +12,6 @@ RUN sudo aur-install \ klayout \ netgen-lvs-git -RUN pip install gdsfactory --break-system-packages -RUN pip install gf180 --upgrade --break-system-packages - # Clean cache RUN sudo pacman -Scc diff --git a/stacks/chipathon-tools/Dockerfile b/stacks/chipathon-tools/Dockerfile new file mode 100644 index 0000000..12bac9b --- /dev/null +++ b/stacks/chipathon-tools/Dockerfile @@ -0,0 +1,15 @@ +ARG BASE_IMG=heavy-desktop +FROM $BASE_IMG as chipathon-tools + +# Add scripts +COPY --chown=designer:designer --chmod=755 stacks/chipathon-tools/scripts/install-open-pdks.sh . +RUN ./install-open-pdks.sh + +COPY --chown=designer:designer --chmod=755 stacks/chipathon-tools/scripts/* . +RUN ./patch-open-pdks-gf180.sh +RUN ./patch-open-pdks-sky130.sh + +RUN rm *.sh + +# Initialize the enviroment keeping container alive +CMD ["sleep", "infinity"] \ No newline at end of file diff --git a/stacks/chipathon-tools/scripts/.bashrc b/stacks/chipathon-tools/scripts/.bashrc new file mode 100644 index 0000000..511b22f --- /dev/null +++ b/stacks/chipathon-tools/scripts/.bashrc @@ -0,0 +1,49 @@ +[[ $- != *i* ]] && return + +case "$PDK" in +gf180mcuC) + export PDKPATH=$PDK_ROOT/$PDK + export STD_CELL_LIBRARY=gf180mcu_fd_sc_mcu7t5v0 + ;; +sky130A) + export PDKPATH=$PDK_ROOT/$PDK + export STD_CELL_LIBRARY=sky130_fd_sc_hd + ;; +*) + echo "PDK not defined, using default one (gf180mcuC)" + export PDK=gf180mcuC + export PDKPATH=$PDK_ROOT/$PDK + export STD_CELL_LIBRARY=gf180mcu_fd_sc_mcu7t5v0 + ;; +esac + +function git_branch { + branch=$(git symbolic-ref --short HEAD 2>/dev/null) + if [ "$branch" != "" ]; then + echo "[$branch]" + fi +} + +c_res='\[\033[00m\]' # Reset +c_bla='\[\033[01;30m\]' # Black +c_red='\[\033[01;31m\]' # Red +c_gre='\[\033[01;32m\]' # Green +c_yel='\[\033[01;33m\]' # Yellow +c_blu='\[\033[01;34m\]' # Blue +c_pur='\[\033[01;35m\]' # Purple +c_cya='\[\033[01;36m\]' # Cyan +c_whi='\[\033[01;37m\]' # White + +# export PS1="${c_pur}\w $(git_branch)\n${c_res}\$ " ## This dont work :( +PS1="${c_pur}\w \n${c_res}\$ " ## This dont work :( + +export KLAYOUT_HOME=$PDK_ROOT/$PDK/libs.tech/klayout +export DESIGNS="/home/designer/shared" + +alias ls="ls --color=auto -XF" +alias grep="grep --color=auto" + +alias xschem='xschem -b --rcfile $PDK_ROOT/$PDK/libs.tech/xschem/xschemrc' +alias xschemtcl='xschem --rcfile $PDK_ROOT/$PDK/libs.tech/xschem/xschemrc' + +git config --global --add safe.directory $DESIGNS \ No newline at end of file diff --git a/stacks/chipathon-tools/scripts/.vimrc b/stacks/chipathon-tools/scripts/.vimrc new file mode 100644 index 0000000..bc9b26a --- /dev/null +++ b/stacks/chipathon-tools/scripts/.vimrc @@ -0,0 +1,26 @@ +set nocompatible +filetype plugin on +filetype indent on +syntax on + +set number relativenumber +set autoindent expandtab tabstop=4 shiftwidth=4 +set cursorline +set mouse=a +set showcmd +set showmatch +set lazyredraw +set ttyfast + + +set clipboard="unnamedplus" +set showmatch +set wildmenu +set backspace=indent,eol,start + + +let &t_SI="\e[6 q" +let &t_EI="\e[2 q" +let &t_ut='' + + diff --git a/stacks/chipathon-tools/scripts/iic-spice-model-red.py b/stacks/chipathon-tools/scripts/iic-spice-model-red.py new file mode 100644 index 0000000..544b4e0 --- /dev/null +++ b/stacks/chipathon-tools/scripts/iic-spice-model-red.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python3 +# ======================================================================== +# SPDX-FileCopyrightText: 2021-2022 Harald Pretl +# Johannes Kepler University, Institute for Integrated Circuits +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# SPDX-License-Identifier: Apache-2.0 +# +# This script traverses SPICE model files (e.g. from SKY130) and +# extracts only the wanted model section, removes all comments and +# empty lines, and resolves all includes so that a flat model file +# results. This should speed up ngspice starts. +# ======================================================================== + +import sys,re,os + +def process_file(file_in_name, top_file): + global is_warning + try: + f_in = open(file_in_name, 'r') + except FileNotFoundError: + print('Warning! File ' + file_in_name + ' not found.') + is_warning = True + return; + + # process_file can be called recursively, so that nested include + # files can be traversed + + # write_active indicates whether we are in the right model section; in + # include files, it is always true + + if top_file == True: + write_active = False + else: + write_active = True + + for line in f_in: + line_trim = (line.lower()).strip() + + if top_file == True: + # we assume that .lib statements are only used in the main file + if '.lib' in line_trim: + if model_section in line_trim: + write_active = True + else: + write_active = False + + if '.endl' == line_trim: + write_active = False + f_out.write(line) + + if len(line_trim) > 0: # write no empty lines + if (line_trim[0] != '*'): # write no comments + if (write_active == True): + if '.include' in line_trim: + # need to save and restore working dir so that nested + # includes work + current_wd = os.getcwd() + newfile = re.findall(r'"(.*?)(? 0: + try: + os.chdir(new_wd) + except OSError: + print('Warning: Could not enter directory ' + new_wd) + is_warning = True + + # traverse into new include file + new_file_name = os.path.basename(newfile[0]) + process_file(new_file_name, False) + + # restore old working dir after return + os.chdir(current_wd) + else: + f_out.write(line) + + f_in.close() + return; + +# main routine + +if len(sys.argv) == 3: + model_section = sys.argv[2] +else: + model_section = 'tt' + +if (len(sys.argv) == 2) or (len(sys.argv) == 3): + infile_name = sys.argv[1] + outfile_name = infile_name + '.' + model_section + '.red' + + try: + f_out = open(outfile_name, 'w') + except OSError: + print('Error: Cannot write file ' + outfile_name + '.') + sys.exit(1) + + is_warning = False + process_file(infile_name, True) + f_out.close() + + print() + print('Model file ' + outfile_name + ' written.') + if is_warning == True: + print('There have been warnings! Please check output log.') + sys.exit(0) + else: + sys.exit(0) +else: + print() + print('iic-spice-model-red.py SPICE model file reducer') + print(' (c) 2021 Harald Pretl, JKU') + print() + print('Usage: iic-spice-model-red [corner] (default corner = tt)') + print() + print('Return codes for script automation:') + print(' 0 = all OK or warnings') + print(' 1 = errors') + print(' 2 = call of script w/o parameters (= showing this message)') + print() + sys.exit(2) diff --git a/stacks/chipathon-tools/scripts/install-open-pdks.sh b/stacks/chipathon-tools/scripts/install-open-pdks.sh new file mode 100644 index 0000000..c482f6e --- /dev/null +++ b/stacks/chipathon-tools/scripts/install-open-pdks.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +set -e + +export OPEN_PDKS_VERSION="dd7771c384ed36b91a25e9f8b314355fc26561be" +export SCRIPT_DIR=$PWD + +#pip install git+https://github.com/gdsfactory/skywater130.git git+https://github.com/gdsfactory/gf180.git --upgrade --break-system-packages +pip install gf180 --upgrade --break-system-packages +pip install sky130 --upgrade --break-system-packages + +###################### +# INSTALL GF180MCU PDK +###################### + +volare enable "${OPEN_PDKS_VERSION}" --pdk gf180mcu + +rm -rf $PDK_ROOT/volare/gf180mcu/versions/*/gf180mcuA +rm -rf $PDK_ROOT/volare/gf180mcu/versions/*/gf180mcuB +rm -rf $PDK_ROOT/volare/gf180mcu/versions/*/gf180mcuD +rm -rf $PDK_ROOT/gf180mcuA +rm -rf $PDK_ROOT/gf180mcuB +rm -rf $PDK_ROOT/gf180mcuD + +#################### +# INSTALL SKY130 PDK +#################### + +volare enable "${OPEN_PDKS_VERSION}" --pdk sky130 + +# ADD PCELL SUPPORT + +# remove version sky130B to save space (efabless TO use mostly sky130A) +rm -rf "$PDK_ROOT"/volare/sky130/versions/*/sky130B +rm -rf "$PDK_ROOT"/sky130B diff --git a/stacks/chipathon-tools/scripts/patch-open-pdks-gf180.sh b/stacks/chipathon-tools/scripts/patch-open-pdks-gf180.sh new file mode 100644 index 0000000..c535a9c --- /dev/null +++ b/stacks/chipathon-tools/scripts/patch-open-pdks-gf180.sh @@ -0,0 +1,82 @@ +#!/bin/bash +set -ex + +SCRIPT_DIR=$PWD + +# This files can be downloaded directly +# - sky130A_mr.drc +# - gf180mcuC_mr.drc +PRECHECK_REPO=https://raw.githubusercontent.com/efabless/mpw_precheck/main/checks/tech-files/ +PRECHECK_GF_FILE=gf180mcuC_mr.drc +PRECHECK_SKY_FILE=sky130A_mr.drc + +sudo aur-install wget +pip install docopt --upgrade --break-system-packages + + +function gf180_patch_xschemrc() { + FILEPATH=$PDK_ROOT/gf180mcuC/libs.tech/xschem/xschemrc + + ORIGINAL='append XSCHEM_LIBRARY_PATH :$env(PWD)' + REPLACE='append XSCHEM_LIBRARY_PATH :$env(PDK_ROOT)/$env(PDK)/libs.tech/xschem' + sed -i "s\\$ORIGINAL\\$REPLACE\g" $FILEPATH + + ORIGINAL='set 180MCU_MODELS ${PDK_ROOT}/models/ngspice' + REPLACE='set 180MCU_MODELS $env(PDK_ROOT)/$env(PDK)/libs.tech/ngspice' + sed -i "s\\$ORIGINAL\\$REPLACE\g" $FILEPATH +} + +function gf180_patch_klayout_pcells() { + mv $KLAYOUT_HOME/pymacros $KLAYOUT_HOME/cells + mkdir $KLAYOUT_HOME/pymacros + mv $KLAYOUT_HOME/cells $KLAYOUT_HOME/pymacros + mv $KLAYOUT_HOME/tech/gf180mcu.lym $KLAYOUT_HOME/pymacros + + rm -rf .scripts/klayout +} + +function gf180_patch_klayout_dropdown() { + # 27:00 & 36:40 + DROPDOWN_REPO="https://github.com/mabrains/globalfoundries-pdk-libs-gf180mcu_fd_pr" + DROPDOWN_DIRECTORY="gf_dropdown" + + git clone $DROPDOWN_REPO $DROPDOWN_DIRECTORY + + cp -r $DROPDOWN_DIRECTORY/rules/klayout/macros $KLAYOUT_HOME + + rm -rf $DROPDOWN_DIRECTORY +} + +function gf180_patch_klayout_gf_drc() { + # 27:00 & 36:40 + GF_VERIFICATION_REPO=https://github.com/efabless/globalfoundries-pdk-libs-gf180mcu_fd_pv + VERIFICATION_DIR="gf_verification" + + git clone $GF_VERIFICATION_REPO $VERIFICATION_DIR + + # rm -rf $KLAYOUT_HOME/drc + # rm -rf $KLAYOUT_HOME/lvs + + cp -r $VERIFICATION_DIR/klayout/drc/* $KLAYOUT_HOME/drc + cp -r $VERIFICATION_DIR/klayout/lvs/* $KLAYOUT_HOME/lvs + + rm -rf $VERIFICATION_DIR +} + +function gf180_patch_klayout_precheck_drc() { + #curl -o $KLAYOUT_HOME/drc/rule_decks/$PRECHECK_GF_FILE $PRECHECK_REPO/$PRECHECK_GF_FILE + wget -O $KLAYOUT_HOME/drc/rule_decks/$PRECHECK_GF_FILE $PRECHECK_REPO/$PRECHECK_GF_FILE +} + +function gf180_patch() { + export KLAYOUT_HOME="$PDK_ROOT/gf180mcuC/libs.tech/klayout" + gf180_patch_xschemrc + gf180_patch_klayout_pcells + gf180_patch_klayout_precheck_drc + gf180_patch_klayout_dropdown + gf180_patch_klayout_gf_drc +} + +gf180_patch + +sudo aur-install gedit xterm gvim \ No newline at end of file diff --git a/stacks/chipathon-tools/scripts/patch-open-pdks-sky130.sh b/stacks/chipathon-tools/scripts/patch-open-pdks-sky130.sh new file mode 100644 index 0000000..b816aa7 --- /dev/null +++ b/stacks/chipathon-tools/scripts/patch-open-pdks-sky130.sh @@ -0,0 +1,74 @@ +#!/bin/bash +set -ex + +SCRIPT_DIR=$PWD + +# This files can be downloaded directly +# - sky130A_mr.drc +# - gf180mcuC_mr.drc +PRECHECK_REPO=https://raw.githubusercontent.com/efabless/mpw_precheck/main/checks/tech-files/ +PRECHECK_GF_FILE=gf180mcuC_mr.drc +PRECHECK_SKY_FILE=sky130A_mr.drc + +# TODO: DOWNLOAD WITH WGET, DONT HAVE IT STATIC +if [ -d $SCRIPT_DIR/iic-spice-model-red.py ]; then + echo File iic-spice-model.red.py not found + return -1 +fi + +sudo aur-install wget + +function sky130_patch_reduced_models() { + cd "$PDK_ROOT/sky130A/libs.tech/ngspice" || exit 1 + "$SCRIPT_DIR/iic-spice-model-red.py" sky130.lib.spice tt + "$SCRIPT_DIR/iic-spice-model-red.py" sky130.lib.spice ss + "$SCRIPT_DIR/iic-spice-model-red.py" sky130.lib.spice ff + + cd "$SCRIPT_DIR" + rm -rf "iic-spice-model-red.py" +} + +function sky130_patch_klayout_lyt() { + FILEPATH="$KLAYOUT_HOME/tech/sky130A.lyt" + + sed -i 's/>sky130sky130A/c\ ' $FILEPATH + sed -i '//c\ $PDK_ROOT/$PDK/libs.tech/klayout' $FILEPATH +} + +function sky130_patch_klayout_lym () { + # ERROR: Reading /home/designer/.volare/sky130A/libs.tech/klayout/pymacros/sky130.lym: XML parser error: invalid name for processing instruction in line 17, column 6 + # ERROR: Reading /home/designer/.volare/sky130A/libs.tech/klayout/pymacros/sky130.lym: XML parser error: invalid name for processing instruction in line 17, column 6 + # ERROR: Reading /home/designer/.volare/sky130A/libs.tech/klayout/pymacros/sky130.lym: XML parser error: invalid name for processing instruction in line 17, column 6 + FILENAME="$KLAYOUT_HOME/pymacros/sky130.lym" + LINE=17 + ( sed -n ${LINE}' {p;q}' $FILENAME ; sed "${LINE}d" $FILENAME ) > $FILENAME +} + +function sky130_patch_klayout_pcells() { + # Fixing the above, the cells indicates the following: + # ERROR: /home/designer/.volare/sky130A/libs.tech/klayout/pymacros/cells/via_generator.py:23: ModuleNotFoundError: No module named 'gdsfactory.types' + # /home/designer/.volare/sky130A/libs.tech/klayout/pymacros/cells/via_generator.py:23 + # /home/designer/.volare/sky130A/libs.tech/klayout/pymacros/cells/vias.py:20 + # /home/designer/.volare/sky130A/libs.tech/klayout/pymacros/cells/__init__.py:21 + # /home/designer/.volare/sky130A/libs.tech/klayout/pymacros/sky130.lym:9 (class ModuleNotFoundError) + echo hola +} + +function sky130_patch_klayout_precheck_drc() { + wget -O $KLAYOUT_HOME/drc/$PRECHECK_SKY_FILE $PRECHECK_REPO/$PRECHECK_SKY_FILE +} + +function sky130_patch() { + export KLAYOUT_HOME="$PDK_ROOT/sky130A/libs.tech/klayout" + sky130_patch_reduced_models + sky130_patch_klayout_lyt + # sky130_patch_klayout_lym # TODO: The file disappears + # sky130_patch_klayout_pcells # TODO: Before fixing lym, this explodes + sky130_patch_klayout_precheck_drc +} + +sky130_patch + +sudo aur-install gedit xterm gvim \ No newline at end of file