Skip to content

Commit

Permalink
Rename example folders and add verilator docker scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
magnmaeh committed Jan 27, 2024
1 parent 60a4c98 commit e1e4f07
Show file tree
Hide file tree
Showing 22 changed files with 82 additions and 30 deletions.
20 changes: 1 addition & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,11 @@

The main contribution of this project is the `verilator.mk` makefile. Include it in your own project in the same manner as seen in the examples.

# Usage

[Docker](https://www.docker.com/) should be used to run the examples. Run the command

`docker run -e CCACHE_DIR=/work/.ccache -ti -v $(pwd):/work --entrypoint bash --hostname verilator-env verilator/verilator:4.038`

or a similar one to enter the container. It should be run from the root of this repository. The first time this is run, it will download a docker image which gives information on which programs and their versions to use. After that, it will jump into the image.

The purpose of this is to ensure we always run the same programs for our code. In the case of `verilator`, it is not very backward-compatible between versions, so Docker is very useful here.

Inside the docker environment, run `make` to run the tests.

## The docker command explained

1. `-e CCACHE_DIR=/work/.ccache`: Verilator uses ccache which defaults to a location outside the container. We override it with an environment variable here.
2. `--entrypoint bash`: Stops Docker from running verilator once and exiting.
3. `verilator/verilator:4.038`: The Verilator version we want to use.

# Examples

The examples show how Verilator can be used to simualate a Verilog circuit. Feel free to add more examples and tests for them.

All examples can be run using the `makefile` at the top level of this repository.
All examples can be run using the `makefile` at the top level of this repository. Simply type `make` to run the makefile.

## And

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
`include "../doublesub/Sub.sv"
`include "delay/Delay.sv"
`include "../Doublesub/Sub.sv"
`include "Delay/Delay.sv"

module Hierarchy (
input clk,
Expand Down
File renamed without changes.
File renamed without changes.
32 changes: 32 additions & 0 deletions verilator-docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/bash
# DESCRIPTION: Wrap a verilator call to run a docker container
#
# Copyright 2020 by Stefan Wallentowitz. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0

# Pull newest image
docker pull verilator/verilator:4.038 > /dev/null

# Get id of container
id=$(docker ps -aqf "name=verilator")

# When no user is specified, the default user is root. This makes it so files
# created by docker are owned by root, which we do not want. The solution is to
# add a user identical to ourselves in the docker environment. The three following
# lines do this.
#
# Solution found here:
# https://stackoverflow.com/questions/67995208/docker-username-interactive-result-in-i-have-no-name-error

docker cp $id:/etc/passwd /tmp > /dev/null
echo "orbit:x:""$(id -u)"":""$(id -g)""orbit:/tmp:/bin/bash" >> /tmp/passwd
docker cp /tmp/passwd $id:/etc/passwd > /dev/null

# Get the directory this script is located
root_dir=$(realpath $3)

# Run the docker image with the user we "made" above
docker run -e CCACHE_DIR=/work/.ccache -ti -v ${root_dir}:/work -w /work/$2 --user $(id -u):$(id -g) verilator/verilator:$1 "${@:4}"
31 changes: 31 additions & 0 deletions verilator-wrap.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/bin/bash
# DESCRIPTION: Wrap a Verilator call and copy vlt includes
# (inside docker container)
#
# Copyright 2020 by Stefan Wallentowitz. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0

perl /usr/local/bin/verilator "$@"
status=$?
if [ $status -ne 0 ]; then
exit $status
fi

# Check if user set an obj_dir
obj_dir=$(echo " $@" | grep -oP '\s--Mdir\s*\K\S+')
if [ "$obj_dir" == "" ]; then
obj_dir="obj_dir"
fi

# If the run was successful: Copy required files to allow build without this container
if [ -e ${obj_dir} ]; then
# Copy files required for the build
mkdir -p ${obj_dir}/vlt
cp -r /usr/local/share/verilator/bin ${obj_dir}/vlt
cp -r /usr/local/share/verilator/include ${obj_dir}/vlt
# Point Makefile to that folder
sed -i 's/VERILATOR_ROOT = \/usr\/local\/share\/verilator/VERILATOR_ROOT = vlt/g' ${obj_dir}/*.mk
fi
25 changes: 16 additions & 9 deletions verilator.mk
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
MODULE_FOLDER ?= examples
PROJECT_ROOT ?= ${VERILATOR_ROOT}

VERILATOR_EXE := obj_dir/V$(PROJECT_NAME)
# Find the path between the top level folder and the source code folder
PATH_FROM_ROOT_TO_SRC = $(shell p=$(shell pwd); g=$${p\#\#*/${MODULE_FOLDER}}; echo $$g)

PARSER ?= $(VERILATOR_ROOT)/default_parser.sh
VERILATOR := $(VERILATOR_ROOT)/verilator-docker.sh
VERILATOR_ARGS := 4.038 ${MODULE_FOLDER}${PATH_FROM_ROOT_TO_SRC} ${PROJECT_ROOT}
VERILATOR_ARGS_LINT := --lint-only -Wall
VERILATOR_ARGS_EMULATOR := --cc --build --exe --trace

VERILATOR_ARGS += --cc --build --exe --trace
VERILATOR_EMULATOR := obj_dir/V$(PROJECT_NAME)
PARSER ?= $(VERILATOR_ROOT)/default_parser.sh

all: run

lint: $(SOURCES)
verilator --lint-only -Wall $^ --top-module $(PROJECT_NAME)
lint: $(SOURCES) $(GENERATED)
./$(VERILATOR) $(VERILATOR_ARGS) $(VERILATOR_ARGS_LINT) $(SOURCES) --top-module $(PROJECT_NAME)

$(VERILATOR_EXE): lint | $(SOURCES)
verilator $(VERILATOR_ARGS) $(SIMFILES) $(SOURCES) > /dev/null
$(VERILATOR_EMULATOR): lint | $(SOURCES) $(GENERATED)
./$(VERILATOR) $(VERILATOR_ARGS) $(VERILATOR_ARGS_EMULATOR) $(SIMFILES) $(SOURCES)

# https://stackoverflow.com/questions/17757039/equivalent-of-pipefail-in-dash-shell
run: $(VERILATOR_EXE)
run: $(VERILATOR_EMULATOR)
@mkfifo named_pipe
@tee output.txt < named_pipe &
@./$(VERILATOR_EXE) > named_pipe; ./$(PARSER) $(PROJECT_NAME) $$? output.txt
@./$(VERILATOR_EMULATOR) > named_pipe; ./$(PARSER) $(PROJECT_NAME) $$? output.txt
@rm named_pipe

clean:
Expand Down

0 comments on commit e1e4f07

Please sign in to comment.