Skip to content

Commit 7851af2

Browse files
committed
ci: add initial short and full flows
Short: (runs on each commit) - Synthesis - Simulation (with check) Full: (runs on PRs and releases) - Synthesis - Backend - KLayout export
1 parent 49b929b commit 7851af2

File tree

6 files changed

+317
-0
lines changed

6 files changed

+317
-0
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Copyright (c) 2025 ETH Zurich and University of Bologna.
2+
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
# Author: Philippe Sauter <[email protected]>
6+
7+
name: 'OSEDA Caching'
8+
description: 'Cache OSEDA Docker Images'
9+
10+
runs:
11+
using: 'composite'
12+
steps:
13+
- name: Get image name from docker-compose
14+
id: get-image
15+
shell: bash
16+
run: |
17+
echo "UID=$(id -u)" >> $GITHUB_ENV
18+
echo "GID=$(id -g)" >> $GITHUB_ENV
19+
IMAGE=$(docker compose config | awk '/image:/{print $2}' | head -n1)
20+
echo "IMAGE_NAME=$IMAGE" >> $GITHUB_ENV
21+
22+
- name: Restore Docker image cache
23+
id: restore-cache
24+
uses: actions/cache@v4
25+
with:
26+
path: /tmp/oseda.tar.gz
27+
key: oseda-${{ env.IMAGE_NAME }}
28+
29+
- name: Check disk usage
30+
shell: bash
31+
run: df -h
32+
33+
- name: Load cached Docker image
34+
shell: bash
35+
if: steps.restore-cache.outputs.cache-hit == 'true'
36+
run: docker import /tmp/oseda.tar.gz
37+
38+
- name: Prepare Docker image for caching
39+
shell: bash
40+
if: steps.restore-cache.outputs.cache-hit != 'true'
41+
run: |
42+
docker system prune -af
43+
docker compose pull
44+
df -h
45+
docker save $IMAGE_NAME | pigz -9 -f > /tmp/oseda.tar.gz
46+
df -h
47+
48+
- name: Check disk usage
49+
shell: bash
50+
run: df -h
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Copyright (c) 2025 ETH Zurich and University of Bologna.
2+
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
# Author: Philippe Sauter <[email protected]>
6+
7+
name: 'OSEDA Command Action'
8+
description: 'Sets up OSEDA environment and runs commands in a Docker container'
9+
10+
inputs:
11+
cmd:
12+
description: 'Command to run in the OSEDA container'
13+
required: true
14+
image_file_name:
15+
description: 'Name of the artifact to download (default: oseda-image)'
16+
required: false
17+
default: 'oseda-image'
18+
service_name:
19+
description: 'Name of the Docker service (default: from ./docker-compose.yml)'
20+
required: false
21+
default: ''
22+
23+
runs:
24+
using: 'composite'
25+
steps:
26+
- name: Set up Docker environment
27+
shell: bash
28+
run: |
29+
echo "UID=$(id -u)" >> $GITHUB_ENV
30+
echo "GID=$(id -g)" >> $GITHUB_ENV
31+
32+
- name: Get image name from docker-compose
33+
id: get-image
34+
shell: bash
35+
run: |
36+
IMAGE=$(docker compose config | awk '/image:/{print $2}' | head -n 1)
37+
if [ -z "$IMAGE" ]; then
38+
echo "ERROR: No image found in docker-compose.yml"
39+
exit 1
40+
fi
41+
echo "IMAGE_NAME=$IMAGE" >> $GITHUB_ENV
42+
43+
- name: Download Docker image from cache
44+
continue-on-error: true
45+
uses: actions/cache/restore@v4
46+
with:
47+
key: oseda-${{ env.IMAGE_NAME }}
48+
path: /tmp/oseda.tar.gz
49+
50+
- name: Load or pull Docker image
51+
shell: bash
52+
run: |
53+
if [ -f "/tmp/oseda.tar.gz" ]; then
54+
docker import /tmp/oseda.tar.gz
55+
echo "Loaded image $IMAGE_NAME from artifacts/cache"
56+
else
57+
docker compose pull
58+
fi
59+
60+
- name: Determine service name if not provided
61+
shell: bash
62+
run: |
63+
if [ -z "${{ inputs.service_name }}" ]; then
64+
SERVICE_NAME=$(docker compose config --services | head -n 1)
65+
echo "service_name=$SERVICE_NAME" >> $GITHUB_ENV
66+
else
67+
echo "service_name=${{ inputs.service_name }}" >> $GITHUB_ENV
68+
fi
69+
70+
- name: Run commands in OSEDA container
71+
shell: bash
72+
run: |
73+
docker compose up -d
74+
docker compose exec ${{ env.service_name }} bash -c "source ~/.bashrc; ${{ inputs.cmd }}" | tee result.log
75+
echo "result_log=$(pwd)/result.log" >> $GITHUB_ENV

.github/scripts/check_sim.sh

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/bin/bash
2+
# Copyright (c) 2025 ETH Zurich and University of Bologna.
3+
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
# Author: Philippe Sauter <[email protected]>
7+
8+
LOG_FILE=$1
9+
10+
expected_lines=(
11+
"\[CORE\] Start fetching instructions"
12+
"\[JTAG\] Halting hart 0"
13+
"\[JTAG\] Resumed hart 0"
14+
"\[UART\] Hello World!"
15+
"\[UART\] Result: 0x8940, Cycles: 0xBD"
16+
"\[UART\] Tick"
17+
"\[UART\] Tock"
18+
)
19+
20+
for line in "${expected_lines[@]}"; do
21+
if ! grep -q "$line" "$LOG_FILE"; then
22+
echo "Error: Expected line not found in the log: '$line'"
23+
exit 1
24+
fi
25+
done
26+
27+
tick=$(awk '/\[UART\] Tick/ {print $2+0}' "$LOG_FILE")
28+
tock=$(awk '/\[UART\] Tock/ {print $2+0}' "$LOG_FILE")
29+
30+
echo "Tick time: ${tick}"
31+
echo "Tock time: ${tock}"
32+
33+
time_diff=$(echo "scale=2; ($tock - $tick) / 1000000" | bc)
34+
time_diff_ms=$(printf "%.0f" $time_diff)
35+
36+
# 1.5ms tolerance
37+
if ((time_diff_ms >= 9 && time_diff_ms <= 11)); then
38+
echo "Timer correct: The gap between Tick and Tock is approximately 10ms: ${time_diff}ms."
39+
else
40+
echo "Timer Error: The gap between Tick and Tock is not approximately 10ms: ${time_diff}ms."
41+
exit 1
42+
fi
43+
44+
echo "Hello world simulation passed."
45+
exit 0

.github/workflows/full-flow.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Copyright (c) 2025 ETH Zurich and University of Bologna.
2+
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
# Author: Philippe Sauter <[email protected]>
6+
7+
name: Full-flow
8+
9+
on:
10+
workflow_dispatch:
11+
pull_request:
12+
branches:
13+
- main
14+
release:
15+
types:
16+
- created
17+
18+
jobs:
19+
backend:
20+
runs-on: ubuntu-latest
21+
timeout-minutes: 180
22+
steps:
23+
- name: Checkout repository (with submodules)
24+
uses: actions/checkout@v4
25+
with:
26+
submodules: true
27+
28+
- name: Run Yosys, OpenROAD and KLayout
29+
uses: ./.github/actions/oseda-cmd
30+
with:
31+
cmd: "make yosys && make openroad && make klayout"
32+
- name: Upload openroad output
33+
uses: actions/upload-artifact@v4
34+
with:
35+
name: croc-openroad
36+
path: openroad/out
37+
continue-on-error: true
38+
- name: Upload openroad reports
39+
uses: actions/upload-artifact@v4
40+
with:
41+
name: croc-openroad
42+
path: openroad/reports
43+
continue-on-error: true
44+
- name: Upload gds
45+
uses: actions/upload-artifact@v4
46+
with:
47+
name: croc-gds
48+
path: klayout/croc_chip.gds
49+
continue-on-error: true

.github/workflows/license.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Copyright (c) 2022 ETH Zurich and University of Bologna.
2+
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
# Author: Jannis Schönleber <[email protected]>
6+
7+
name: lint-license
8+
9+
on: [push, pull_request, workflow_dispatch]
10+
11+
jobs:
12+
lint-license:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: lint license
16+
uses: pulp-platform/pulp-actions/lint-license@v2
17+
with:
18+
license: |
19+
Copyright \(c\) (\d{4}(-\d{4})?\s)?(ETH Zurich and University of Bologna|lowRISC contributors).
20+
(Solderpad Hardware License, Version 0.51|Licensed under the Apache License, Version 2.0), see LICENSE for details.
21+
SPDX-License-Identifier: (SHL-0.51|Apache-2.0)
22+
exclude_paths: |
23+
deps
24+
include/version.h

.github/workflows/short-flow.yml

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Copyright (c) 2025 ETH Zurich and University of Bologna.
2+
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
# Author: Philippe Sauter <[email protected]>
6+
7+
name: Short Flow
8+
9+
on:
10+
push:
11+
branches:
12+
- '**'
13+
14+
jobs:
15+
simulation:
16+
runs-on: ubuntu-latest
17+
timeout-minutes: 30
18+
steps:
19+
- name: Checkout repository (with submodules)
20+
uses: actions/checkout@v4
21+
with:
22+
submodules: true
23+
24+
- name: Run simulation commands in OSEDA
25+
uses: ./.github/actions/oseda-cmd
26+
with:
27+
cmd: "make sw && make verilator"
28+
- name: Upload built software
29+
uses: actions/upload-artifact@v4
30+
with:
31+
name: croc-sw
32+
path: sw/bin
33+
continue-on-error: true
34+
- name: Upload waveform
35+
uses: actions/upload-artifact@v4
36+
with:
37+
name: croc-waveform
38+
path: croc.vcd
39+
continue-on-error: true
40+
41+
- name: Upload simulation output
42+
uses: actions/upload-artifact@v4
43+
with:
44+
name: simulation-output
45+
path: ${{ env.result_log }}
46+
- name: Check simulation output
47+
shell: bash
48+
run: ./.github/scripts/check_sim.sh ${{ env.result_log }}
49+
50+
synthesis:
51+
runs-on: ubuntu-latest
52+
timeout-minutes: 30
53+
steps:
54+
- name: Checkout repository (with submodules)
55+
uses: actions/checkout@v4
56+
with:
57+
submodules: true
58+
59+
- name: Setup OSEDA container
60+
uses: ./.github/actions/oseda-cmd
61+
with:
62+
cmd: "make yosys && tail -n 40 yosys/reports/*area.rpt"
63+
- name: Upload synthesis reports
64+
uses: actions/upload-artifact@v4
65+
with:
66+
name: croc-synth-reports
67+
path: yosys/reports
68+
continue-on-error: true
69+
- name: Upload netlist
70+
uses: actions/upload-artifact@v4
71+
with:
72+
name: croc-netlist
73+
path: yosys/out
74+
continue-on-error: true

0 commit comments

Comments
 (0)