You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tvm.apache.org by mo...@apache.org on 2020/11/27 19:31:43 UTC

[tvm-vta] branch main updated: [Hardware][Verilator] Integrating and simulating hardware accelerators in TVM (#18)

This is an automated email from the ASF dual-hosted git repository.

moreau pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm-vta.git


The following commit(s) were added to refs/heads/main by this push:
     new 12fb486  [Hardware][Verilator] Integrating and simulating hardware accelerators in TVM (#18)
12fb486 is described below

commit 12fb486a491b75d70ec4c5e0a0cd112ab49a95bc
Author: Luis Vega <ve...@users.noreply.github.com>
AuthorDate: Fri Nov 27 11:31:04 2020 -0800

    [Hardware][Verilator] Integrating and simulating hardware accelerators in TVM (#18)
    
    * add files
    
    * fix paths
    
    * add apache header to readme
---
 apps/verilator/Makefile                    |  22 ++++++
 apps/verilator/README.md                   |  34 ++++++++
 apps/verilator/scalar_add/Makefile         |  59 ++++++++++++++
 apps/verilator/scalar_add/src/driver.cc    |  93 ++++++++++++++++++++++
 apps/verilator/scalar_add/src/kernel.cc    |  43 ++++++++++
 apps/verilator/scalar_add/verilog/adder.v  |  37 +++++++++
 apps/verilator/scalar_add/verilog/driver.v | 121 +++++++++++++++++++++++++++++
 7 files changed, 409 insertions(+)

diff --git a/apps/verilator/Makefile b/apps/verilator/Makefile
new file mode 100644
index 0000000..b957abe
--- /dev/null
+++ b/apps/verilator/Makefile
@@ -0,0 +1,22 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+
+default: scalar_add
+
+.PHONY:scalar_add
+scalar_add:
+	make -C scalar_add
diff --git a/apps/verilator/README.md b/apps/verilator/README.md
new file mode 100644
index 0000000..f4b0f69
--- /dev/null
+++ b/apps/verilator/README.md
@@ -0,0 +1,34 @@
+<!--- Licensed to the Apache Software Foundation (ASF) under one -->
+<!--- or more contributor license agreements.  See the NOTICE file -->
+<!--- distributed with this work for additional information -->
+<!--- regarding copyright ownership.  The ASF licenses this file -->
+<!--- to you 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. -->
+
+# Verilator examples
+
+These are examples of hardware designs for testing Verilator backend integration to TVM
+
+## Requirements
+
+This repository is meant to be used together with TVM (3rdparty folder) and not standalone,
+because it depends on certain headers (device and runtime) available in TVM.
+
+Install Verilator (4.100 or above)
+
+## Build
+
+1. Build Verilator hardware library by running `make`
+2. Enable Verilator backend by setting `USE_VERILATOR_HW ON` in TVM cmake configuration file (`config.cmake`)
+3. Build and install TVM
+
diff --git a/apps/verilator/scalar_add/Makefile b/apps/verilator/scalar_add/Makefile
new file mode 100644
index 0000000..05513f6
--- /dev/null
+++ b/apps/verilator/scalar_add/Makefile
@@ -0,0 +1,59 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+
+VERILATOR_BIN := $(shell which verilator)
+VERILATOR_INC_DIR := $(abspath $(dir $(VERILATOR_BIN))/../share/verilator/include)
+TOP_NAME = "Top"
+VERILOG_DIR = $(abspath .)/verilog
+SRC_DIR = $(abspath .)/src
+ROOT_DIR = $(abspath ..)
+TVM_DIR = $(abspath ../../../../..)
+OUT_DIR = $(abspath .)/out
+
+default: $(ROOT_DIR)/libverilator.so
+
+$(ROOT_DIR)/libverilator.so: $(OUT_DIR)/$(TOP_NAME).cpp
+	g++ \
+	-std=c++14 \
+	-O2 \
+	-shared \
+	-fPIC \
+	-I$(TVM_DIR)/src/runtime/contrib/verilator \
+	-I$(TVM_DIR)/include \
+	-I$(TVM_DIR)/3rdparty/dlpack/include \
+	-I$(VERILATOR_INC_DIR) \
+	-I$(OUT_DIR) \
+	$(VERILATOR_INC_DIR)/verilated.cpp \
+	$(SRC_DIR)/*.cc \
+	$(OUT_DIR)/*.cpp \
+	-o $@
+
+$(OUT_DIR)/$(TOP_NAME).cpp: $(VERILOG_DIR)/*.v
+	$(VERILATOR_BIN) \
+	-Wno-BLKANDNBLK \
+	-Wno-PINMISSING \
+	-Wno-STMTDLY \
+	-Wno-WIDTH \
+	-Wno-UNOPTFLAT \
+	--cc \
+	--prefix $(TOP_NAME) \
+	--top-module "driver" \
+	--Mdir $(OUT_DIR) \
+	$^
+
+clean:
+	-rm -rf $(OUT_DIR)
diff --git a/apps/verilator/scalar_add/src/driver.cc b/apps/verilator/scalar_add/src/driver.cc
new file mode 100644
index 0000000..8d2c0f1
--- /dev/null
+++ b/apps/verilator/scalar_add/src/driver.cc
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+#include "Top.h"
+#include "verilator_device.h"
+
+vluint64_t main_time = 0;
+double sc_time_stamp() { return main_time; }
+
+namespace tvm {
+namespace runtime {
+namespace contrib {
+
+extern "C" VerilatorHandle VerilatorAlloc() {
+  Top *top = new Top;
+  return static_cast<VerilatorHandle>(top);
+}
+
+extern "C" void VerilatorDealloc(VerilatorHandle handle) { delete static_cast<Top *>(handle); }
+
+extern "C" int VerilatorRead(VerilatorHandle handle, int id, int addr) {
+  Top *top = static_cast<Top *>(handle);
+  top->opcode = 2;
+  top->id = id;
+  top->addr = addr;
+  top->eval();
+  return top->out;
+}
+
+extern "C" void VerilatorWrite(VerilatorHandle handle, int id, int addr, int value) {
+  Top *top = static_cast<Top *>(handle);
+  top->opcode = 1;
+  top->id = id;
+  top->addr = addr;
+  top->in = value;
+  top->eval();
+}
+
+extern "C" void VerilatorReset(VerilatorHandle handle, int n) {
+  Top *top = static_cast<Top *>(handle);
+  top->clock = 0;
+  top->reset = 1;
+  main_time = 0;
+  while (!Verilated::gotFinish() &&
+         main_time < static_cast<vluint64_t>(n * 10)) {
+    if ((main_time % 10) == 1) {
+      top->clock = 1;
+    }
+    if ((main_time % 10) == 6) {
+      top->reset = 0;
+    }
+    top->eval();
+    main_time++;
+  }
+  top->reset = 0;
+}
+
+extern "C" void VerilatorRun(VerilatorHandle handle, int n) {
+  Top *top = static_cast<Top *>(handle);
+  top->clock = 0;
+  main_time = 0;
+  while (!Verilated::gotFinish() &&
+         main_time < static_cast<vluint64_t>(n * 10)) {
+    if ((main_time % 10) == 1) {
+      top->clock = 1;
+    }
+    if ((main_time % 10) == 6) {
+      top->clock = 0;
+    }
+    top->eval();
+    main_time++;
+  }
+}
+
+}  // namespace contrib
+}  // namespace runtime
+}  // namespace tvm
diff --git a/apps/verilator/scalar_add/src/kernel.cc b/apps/verilator/scalar_add/src/kernel.cc
new file mode 100644
index 0000000..e4ed9dd
--- /dev/null
+++ b/apps/verilator/scalar_add/src/kernel.cc
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+#include <stdint.h>
+
+#include "verilator_device.h"
+#include "verilator_kernel.h"
+
+namespace tvm {
+namespace runtime {
+namespace contrib {
+
+extern "C" void verilator_add(VerilatorHandle handle, int *data, int *weight, int *out, int p_h_, int p_w_) {
+  for (int64_t i = 0; i < p_h_; ++i) {
+    for (int64_t j = 0; j < p_w_; ++j) {
+      int64_t k = i * p_w_ + j;
+      VerilatorWrite(handle, 0, 0, data[k]);
+      VerilatorWrite(handle, 1, 0, weight[k]);
+      VerilatorRun(handle, 1);
+      out[k] = VerilatorRead(handle, 2, 0);
+    }
+  }
+}
+
+}  // namespace contrib
+}  // namespace runtime
+}  // namespace tvm
diff --git a/apps/verilator/scalar_add/verilog/adder.v b/apps/verilator/scalar_add/verilog/adder.v
new file mode 100644
index 0000000..6497e78
--- /dev/null
+++ b/apps/verilator/scalar_add/verilog/adder.v
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+module scalar_add(input clock, input reset);
+
+    reg [32-1:0] ra;
+    reg [32-1:0] rb;
+    reg [32-1:0] ry;
+
+    always @(posedge clock) begin
+        if (reset) begin
+            ra <= 0;
+            rb <= 0;
+            ry <= 0;
+        end
+        else begin
+            ry <= ra + rb;
+        end
+    end
+
+endmodule
diff --git a/apps/verilator/scalar_add/verilog/driver.v b/apps/verilator/scalar_add/verilog/driver.v
new file mode 100644
index 0000000..c3674d3
--- /dev/null
+++ b/apps/verilator/scalar_add/verilog/driver.v
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+module driver (
+    input  logic          clock,
+    input  logic          reset,
+    input  logic [32-1:0] opcode,
+    input  logic [32-1:0] id,
+    input  logic [32-1:0] in,
+    input  logic [32-1:0] addr,
+    output logic [32-1:0] out
+);
+
+    function void write_reg_a;
+        input int value;
+        input int addr;
+        logic [31:0] tmp;
+        begin
+            tmp[0+:32] = 0;
+            tmp[0+:32] = driver.dut.ra;
+            tmp[addr*32+:32] = value;
+            driver.dut.ra = tmp[0+:32];
+        end
+    endfunction
+
+    function int read_reg_a;
+        input int addr;
+        logic [32-1:0] tmp;
+        begin
+            tmp[0+:32] = 0;
+            tmp[0+:32] = driver.dut.ra;
+            return tmp[addr*32+:32];
+        end
+    endfunction
+
+    function void write_reg_b;
+        input int value;
+        input int addr;
+        logic [31:0] tmp;
+        begin
+            tmp[0+:32] = 0;
+            tmp[0+:32] = driver.dut.rb;
+            tmp[addr*32+:32] = value;
+            driver.dut.rb = tmp[0+:32];
+        end
+    endfunction
+
+    function int read_reg_b;
+        input int addr;
+        logic [32-1:0] tmp;
+        begin
+            tmp[0+:32] = 0;
+            tmp[0+:32] = driver.dut.rb;
+            return tmp[addr*32+:32];
+        end
+    endfunction
+
+    function void write_reg_y;
+        input int value;
+        input int addr;
+        logic [31:0] tmp;
+        begin
+            tmp[0+:32] = 0;
+            tmp[0+:32] = driver.dut.ry;
+            tmp[addr*32+:32] = value;
+            driver.dut.ry = tmp[0+:32];
+        end
+    endfunction
+
+    function int read_reg_y;
+        input int addr;
+        logic [32-1:0] tmp;
+        begin
+            tmp[0+:32] = 0;
+            tmp[0+:32] = driver.dut.ry;
+            return tmp[addr*32+:32];
+        end
+    endfunction
+
+    always_comb begin
+        case(opcode)
+            32'd0 : out = 32'hdeadbeef;
+            32'd1 : begin
+                case(id)
+                    32'd0 : write_reg_a(in, addr);
+                    32'd1 : write_reg_b(in, addr);
+                    32'd2 : write_reg_y(in, addr);
+                    default : $error("invalid id");
+                endcase
+            end
+            32'd2 : begin
+                case(id)
+                    32'd0 : out = read_reg_a(addr);
+                    32'd1 : out = read_reg_b(addr);
+                    32'd2 : out = read_reg_y(addr);
+                    default : $error("invalid id");
+                endcase
+            end
+            default : $error("invalid opcode");
+        endcase
+    end
+
+    scalar_add dut (.clock(clock), .reset(reset));
+
+endmodule