Skip to content

Add GitHub actions CI [internal branch] #31

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
name: risc-v CI

on:
pull_request:

permissions:
contents: read
packages: write

jobs:
build_ci_image:
runs-on: ubuntu-latest
outputs:
image-tag: ${{ steps.meta.outputs.tags }}
image-digest: ${{ steps.build.outputs.digest }}

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/utoss/risc-v
tags: |
type=ref,event=branch,prefix=ci-branch-
type=ref,event=pr,prefix=ci-pr-
type=raw,value=latest,prefix=ci-,enable={{is_default_branch}}

- name: Build and push Docker image
id: build
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile.ci
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64
cache-from: |
type=gha
type=registry,ref=ghcr.io/utoss/risc-v:buildcache
cache-to: |
type=gha,mode=max
type=registry,ref=ghcr.io/utoss/risc-v:buildcache,mode=max

build_and_test:
needs: build_ci_image
runs-on: ubuntu-latest
container:
image: ${{ needs.build_ci_image.outputs.image-tag }}

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Build top
id: build-top
run: make build_top

- name: Build testbench
id: build-testbench
run: make build_tb

- name: Run testbench
run: make run_tb

- name: Upload VCD files
uses: actions/upload-artifact@v4
if: steps.build-testbench.outcome == 'success'
with:
name: vcd-files
path: test/vcd/*.vcd
retention-days: 7

- name: Upload VVP files
uses: actions/upload-artifact@v4
if: steps.build-top.outcome == 'success'
with:
name: vvp-files
path: out/*.vvp
retention-days: 7
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
*.vvp
*.vcd

!test/fetch_tb.vcd
!test/beq_tb.vcd

.devcontainer/
36 changes: 36 additions & 0 deletions Dockerfile.ci
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
FROM public.ecr.aws/lts/ubuntu:22.04_stable

ARG DEBIAN_FRONTEND=noninteractive
ARG KEYRING_PATH=/usr/share/keyrings
ARG APT_SOURCES_PATH=/etc/apt/sources.list.d

# update and upgrade
RUN apt update && apt upgrade -y

# install essentialls
RUN apt update && \
apt install -y \
man make build-essential git zsh vim curl wget procps gnupg gnupg2 ca-certificates zip \
software-properties-common

# create dev sudo user
RUN useradd --create-home dev && \
usermod --append --groups sudo dev && \
apt update && apt install -y sudo && \
echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

# build and install icarus verilog
USER dev
ARG ICARUS_SRC_TAR=v12_0.tar.gz
ARG ICARUS_SRC_URL=https://github.com/steveicarus/iverilog/archive/refs/tags/${ICARUS_SRC_TAR}
ARG ICARUS_SRC_HASH="a68cb1ef7c017ef090ebedb2bc3e39ef90ecc70a3400afb4aa94303bc3beaa7d ${ICARUS_SRC_TAR}"
RUN sudo apt update && sudo apt install -y autoconf gperf make gcc g++ bison flex && \
cd /tmp && \
wget ${ICARUS_SRC_URL} && \
echo ${ICARUS_SRC_HASH} | sha256sum -c && \
tar -xzf ${ICARUS_SRC_TAR} && \
cd iverilog-* && sh autoconf.sh && ./configure && make && make check && sudo make install && \
cd .. && rm ${ICARUS_SRC_TAR} && rm -rf ./iverilog-*

# CI needs priviledged access
USER root
55 changes: 45 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,54 @@ OUTPUT := out/top.vvp
IVERILOG := iverilog
VVP := vvp

all: $(OUTPUT)
SRCS := $(shell find $(SRC_DIR) -name "*.sv" -o -name "*.v")

$(OUTPUT): $(SRCS)
$(IVERILOG) -g2012 -o $(OUTPUT) -c src/top.cf
TB_SRC_PATTERN := test/%_tb.sv
TB_OUT_PATTERN := out/%_tb.vvp

TB_SRCS := $(wildcard $(subst %,*,$(TB_SRC_PATTERN)))
TB_VVPS := $(patsubst $(TB_SRC_PATTERN),$(TB_OUT_PATTERN),$(TB_SRCS))
TB_UTILS := test/utils.svh

TB_VCD_BASE_PATH := test/vcd

build_top: $(OUTPUT)

run: $(OUTPUT)
run_top: $(OUTPUT)
$(VVP) $(OUTPUT)

# tmp
fetch_tb:
$(IVERILOG) -g2012 -o $(OUTPUT) $(SRCS) -c src/top.cf test/fetch_tb.sv
$(OUTPUT): $(SRCS)
$(IVERILOG) -g2012 -o $(OUTPUT) $(SRCS)

$(TB_OUT_PATTERN): $(TB_SRC_PATTERN) $(TB_UTILS) $(SRCS)
$(IVERILOG) -g2012 -o $@ $(SRCS) $<

new_tb:
@if [ -z "$(name)" ]; then \
echo "Usage: make new_tb name=<testbench_name>"; \
exit 1; \
fi
m4 -D M4__TB_NAME="$(name)_tb" test/tb_template.sv.m4 > test/$(name)_tb.sv

build_tb: $(TB_VVPS)

beq_tb:
$(IVERILOG) -g2012 -o $(OUTPUT) $(SRCS) -c src/top.cf test/beq_tb.sv
run_tb: $(TB_VVPS)
@failed=0; \
for tb in $(TB_VVPS); do \
echo "Running $$tb..."; \
if ! $(VVP) -N $$tb +VCD_PATH=$(TB_VCD_BASE_PATH); then \
echo "\033[31mFAILED: $$tb\033[0m"; \
failed=1; \
else \
echo "\033[32mPASSED: $$tb\033[0m"; \
fi; \
echo ""; \
done; \
if [ $$failed -eq 1 ]; then \
echo "\033[31mSome testbenches failed!\033[0m"; \
exit 1; \
else \
echo "\033[32mAll testbenches passed!\033[0m"; \
fi

.PHONY: all run
.PHONY: all run testbenches run-tests
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,21 @@
# risc-v
UTOSS' starter multicycle RISC-V core.

## Development

Put new modules into `src/` folder.

### Testbenches

It is important that new functionality is tested to a reasonable extent by using test benches. To
run all existing testbenches use `make run_tb`

To create a new test bench, if you are on Linux use the following command:
```
$ make new_tb name="something"
```

If you are on Windows, create a new testbench file in `test/` folder named `something_tb.sv` (the
`_tb.sv` suffix and extension are necessary for the test suite to recognize this file as a
testbench). Copy the content of `test/tb_template.sv.m4` into your newly-created testbench file and
start writing the test bench.
File renamed without changes.
File renamed without changes.
22 changes: 0 additions & 22 deletions src/MA.v

This file was deleted.

9 changes: 0 additions & 9 deletions src/top.cf

This file was deleted.

38 changes: 21 additions & 17 deletions src/ALU&ALUdecoder/branchifeq_tb.sv → test/alu_branchifeq_tb.sv
Original file line number Diff line number Diff line change
@@ -1,57 +1,61 @@
`timescale 1ns / 1ps

module branchifeq_tb;
`include "test/utils.svh"

module alu_branchifeq_tb;

logic [2:0] funct3;
logic [6:0] funct7;
logic [1:0] alu_op;
logic [3:0] alu_control;
logic [31:0] A;
logic [31:0] B;
logic [31:0] B;
logic [31:0] out;
logic zeroE;

ALUdecoder ALU_decoder (
.funct3(funct3),
.funct7(funct7),
.alu_op(alu_op),
.alu_control(alu_control)
);

ALU alu (.a(A), .b(B), .alu_control(alu_control), .out(out), .zeroE(zeroE));

initial begin
// Test decode
// Test decode
//set old PC = 0x0; (A=0) set branching is to add 16 (B = 16);
alu_op = 2'b00; funct3 = 3'bxxx; funct7 = 7'bxxxxxxx;
A = 32'h0; B = 32'h10;
/* DECODE: begin

ALUSrcA <= 2'b01;
ALUSrcB <= 2'b01;
ALUOp <= 2'b00;

end
*/

// Test branch (SUB operation)
alu_op = 2'b01; funct3 = 3'b000; funct7 = 7'b0000000;
A = 32'h0010; B = 32'h0010;
#10;
assert(alu_control == 4'b0001) else $error("Unexpected zero output for funct3=%b", funct3);
assert(out == 32'b0) else $error("not branching when equal for funct3=%b", funct3);
assert(alu_control == 4'b0001) else $fatal(1,"Unexpected zero output for funct3=%b", funct3);
assert(out == 32'b0) else $fatal(1,"not branching when equal for funct3=%b", funct3);
$display("finish testing");
/*
/*
BRANCHIFEQ: begin

ALUSrcA <= 2'b10;
ALUSrcB <= 2'b00;
ALUOp <= 2'b01;
ResultSrc <= 2'b00;
Branch <= 1'b1;

end
*/
*/
end

endmodule

`SETUP_VCD_DUMP(alu_branchifeq_tb)

endmodule
Loading