Adding Verilator and a basic Verilator unit test (#179)

This commit is contained in:
John Demme 2020-10-30 13:12:15 -07:00 committed by GitHub
parent 422eb0ab58
commit dc3b57de7e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 156 additions and 5 deletions

View File

@ -9,9 +9,6 @@ jobs:
name: Build LLVM
runs-on: ubuntu-latest
steps:
- name: Configure Environment
run: echo "::add-path::$GITHUB_WORKSPACE/llvm/install/bin"
# Clone the CIRCT repo and its submodules. Do shallow clone to save clone
# time.
- name: Get CIRCT
@ -86,6 +83,10 @@ jobs:
sudo update-alternatives --install /usr/bin/clang-tidy clang-tidy \
/usr/bin/clang-tidy-9 100
# --------
# Restore LLVM from cache and build if it's not in there.
# --------
# Extract the LLVM submodule hash for use in the cache key.
- name: Get LLVM Hash
id: get-llvm-hash
@ -125,6 +126,10 @@ jobs:
-DLLVM_ENABLE_ASSERTIONS=ON
cmake --build . --target install -- -j$(nproc)
# --------
# Build and test CIRCT in both debug and release mode.
# --------
# Build the CIRCT test target in debug mode to build and test.
- name: Build and Test CIRCT (Assert)
run: |
@ -158,6 +163,10 @@ jobs:
-DLLVM_EXTERNAL_LIT=`pwd`/../llvm/build/bin/llvm-lit
make check-circt -j$(nproc)
# --------
# Lint the CIRCT C++ code.
# -------
# Choose the git commit to diff against for the purposes of linting.
# Since this workflow is triggered on both pushes and pull requests, we
# have to determine if the pull request target branch is set (which it

3
.gitignore vendored
View File

@ -2,3 +2,6 @@ build
.vscode
#*
*~
# External software
/ext

View File

@ -64,6 +64,16 @@ include_directories(${MLIR_INCLUDE_DIRS})
include_directories(${PROJECT_SOURCE_DIR}/include)
include_directories(${PROJECT_BINARY_DIR}/include)
# Detect if Verilator is present
find_program(VERILATOR_PATH "verilator" PATHS "${CMAKE_CURRENT_SOURCE_DIR}/ext/bin" NO_DEFAULT_PATH)
find_program(VERILATOR_PATH "verilator")
if(${VERILATOR_PATH} STREQUAL "VERILATOR_PATH-NOTFOUND")
set(VERILATOR_PATH "")
message(STATUS "Did not find Verilator.")
else()
message(STATUS "Found Verilator at ${VERILATOR_PATH}.")
endif()
add_subdirectory(include/circt)
add_subdirectory(lib)
add_subdirectory(tools)

View File

@ -136,6 +136,27 @@ build() {
This allows you to invoke `build check-circt` from any directory and have it do
the right thing.
6) **Run the Verilator tests:** (optional)
[Verilator](https://github.com/verilator/verilator) is can be used to check
SystemVerilog code. To run the tests, build or install a **recent** version
of Verilator (at least v4.034). (Some Linux distributions have *ancient*
versions.) If Verilator is in your PATH, `build check-circt` should run the
tests which require Verilator.
We provide a script `utils/get-verilator.sh` to automate the download and
compilation of Verilator into a known location. The testing script will check
this location first. This script assumes that all the Verilator package
dependencies are installed on your system. They are:
- make
- autoconf
- g++
- flex
- bison
- libfl2 # Ubuntu only (ignore if gives error)
- libfl-dev # Ubuntu only (ignore if gives error)
## Submitting changes to CIRCT
The project is small so there are few formal process yet. We generally follow

View File

@ -3,6 +3,7 @@
import os
import platform
import re
import shutil
import subprocess
import tempfile
@ -21,7 +22,7 @@ config.name = 'CIRCT'
config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell)
# suffixes: A list of file extensions to treat as test files.
config.suffixes = ['.td', '.mlir', '.ll', '.fir']
config.suffixes = ['.td', '.mlir', '.ll', '.fir', '.sv']
# test_source_root: The root path where tests are located.
config.test_source_root = os.path.dirname(__file__)
@ -51,7 +52,8 @@ config.test_exec_root = os.path.join(config.circt_obj_root, 'test')
# Tweak the PATH to include the tools dir.
llvm_config.with_environment('PATH', config.llvm_tools_dir, append_path=True)
tool_dirs = [config.circt_tools_dir, config.mlir_tools_dir, config.llvm_tools_dir]
tool_dirs = [config.circt_tools_dir,
config.mlir_tools_dir, config.llvm_tools_dir]
tools = [
'firtool',
'handshake-runner',
@ -60,4 +62,10 @@ tools = [
'llhd-sim'
]
# Enable Verilator if it has been detected.
if config.verilator_path != "":
tool_dirs.append(os.path.dirname(config.verilator_path))
tools.append('verilator')
config.available_features.add('verilator')
llvm_config.add_tool_substitutions(tools, tool_dirs)

View File

@ -34,6 +34,7 @@ config.mlir_tools_dir = "@MLIR_TOOLS_DIR@"
config.circt_src_root = "@CIRCT_SOURCE_DIR@"
config.circt_obj_root = "@CIRCT_BINARY_DIR@"
config.circt_tools_dir = "@CIRCT_TOOLS_DIR@"
config.verilator_path = "@VERILATOR_PATH@"
# Support substitution of the tools_dir with user parameters. This is
# used when we can't determine the tool dir at configuration time.

21
test/verilator/errors1.sv Normal file
View File

@ -0,0 +1,21 @@
// REQUIRES: verilator
// RUN: (verilator --cc --top-module main -Wall -Wpedantic %s || true) 2>&1 | FileCheck %s
// Tell Verilator not to complain about multiple modules in same file.
/* verilator lint_off DECLFILENAME */
module main(
input logic clk,
input wire rst_n,
// CHECK: %Warning-UNUSED: {{.*}}:9:14: Signal is not used: 'rst_n'
output logic [15:0] x
);
reg [15:0] x_int;
assign x = (x_int << 2);
always@(posedge clk) begin
x_int = x_int + 1;
// CHECK: %Warning-BLKSEQ: {{.*}}:18:11: Blocking assignments (=) in sequential (flop or latch) block
end
endmodule

60
test/verilator/main.sv Normal file
View File

@ -0,0 +1,60 @@
// REQUIRES: verilator
// RUN: verilator --cc --top-module main -Wall -Wpedantic %s
// Tell Verilator not to complain about multiple modules in same file.
/* verilator lint_off DECLFILENAME */
module main(
input logic clk,
input wire rst_n,
output logic [15:0] x
);
reg [15:0] x_int;
assign x = (x_int << 2) ^ {fooOut, barOut};
always@(posedge clk) begin
if (~rst_n) begin
x_int <= 16'h0;
end else begin
x_int <= x_int + 1;
end
end
logic [3:0] fooIn = x[5:2];
logic [7:0] fooOut;
ParameterizedModule #(.INWIDTH(4), .OUTWIDTH(8)) foo (.a(fooIn), .x(fooOut));
logic [9:0] barIn = x[11:2];
logic [7:0] barOut;
ParameterizedModule #(.INWIDTH(10), .OUTWIDTH(8)) bar (.a(barIn), .x(barOut));
endmodule
module ParameterizedModule # (
parameter INWIDTH = 4,
parameter OUTWIDTH = 4
) (
input logic [INWIDTH-1:0] a,
output logic [OUTWIDTH-1:0] x
);
generate
if (OUTWIDTH > INWIDTH) begin
localparam DIFF = OUTWIDTH - INWIDTH;
assign x = {a, {DIFF{1'b0}}};
end else begin
if (OUTWIDTH != INWIDTH) begin
reg [63:0] leftOver;
always@(a) begin
leftOver = leftOver + {{(63 - INWIDTH + OUTWIDTH){1'b0}},
a[INWIDTH - 1: OUTWIDTH]};
end
end
assign x = a[OUTWIDTH-1:0];
end
endgenerate
endmodule

18
utils/get-verilator.sh Executable file
View File

@ -0,0 +1,18 @@
#!/bin/bash
# Downloads, compiles, and installs Verilator into $/ext
EXT_DIR=$(cd "$(dirname "$BASH_SOURCE[0]")/../ext" && pwd)
VERILATOR_VER=4.102
echo $EXT_DIR
cd $EXT_DIR
wget https://github.com/verilator/verilator/archive/v$VERILATOR_VER.tar.gz
tar -zxf v$VERILATOR_VER.tar.gz
cd verilator-$VERILATOR_VER
autoconf
./configure --prefix=`pwd`/..
make -j$(nproc)
make install
cd ..
rm -r verilator-$VERILATOR_VER v$VERILATOR_VER.tar.gz