Add miner testbench
diff --git a/build b/build new file mode 100755 index 0000000..d3b2ee9 --- /dev/null +++ b/build
@@ -0,0 +1,6 @@ +#!/bin/bash +cd openlane +make user_proj_example | tee ../user_proj_example.log +make user_project_wrapper | tee ../user_project_wrapper.log +cd .. +make ship | tee ../ship.log
diff --git a/verilog/dv/caravel/user_proj_example/miner_test/Makefile b/verilog/dv/caravel/user_proj_example/miner_test/Makefile new file mode 100644 index 0000000..f6bf3f8 --- /dev/null +++ b/verilog/dv/caravel/user_proj_example/miner_test/Makefile
@@ -0,0 +1,54 @@ +FIRMWARE_PATH = ../.. +RTL_PATH = ../../../../rtl +IP_PATH = ../../../../ip +BEHAVIOURAL_MODELS = ../../ + +GCC_PATH?=/opt/riscv32imc/bin +GCC_PREFIX?=riscv32-unknown-elf +PDK_PATH?=~/openlane/pdks/sky130A +GCC_OPTS=-fverbose-asm -Wa,-adhlns="$@.lst" -Wl,-Map=$@.map +GCC_OPTS+=-march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug +GCC_OPTS+=-ffreestanding -nostdlib +GCC_OPTS+=-O3 + +SIM?=RTL + +.SUFFIXES: + +PATTERN = miner_test + +all: ${PATTERN:=.vcd} + +hex: ${PATTERN:=.hex} + +%.vvp: %_tb.v %.hex +ifeq ($(SIM),RTL) + iverilog -DFUNCTIONAL -DSIM -I $(BEHAVIOURAL_MODELS) \ + -I $(PDK_PATH) -I $(IP_PATH) -I $(RTL_PATH) \ + $< -o $@ +else + iverilog -DFUNCTIONAL -DSIM -DGL -I $(BEHAVIOURAL_MODELS) \ + -I $(PDK_PATH) -I $(IP_PATH) -I $(RTL_PATH) \ + $< -o $@ +endif + +%.vcd: %.vvp + vvp $< + +%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s + ${GCC_PATH}/${GCC_PREFIX}-gcc ${GCC_OPTS} -o $@ $(FIRMWARE_PATH)/start.s $< + +%.hex: %.elf + ${GCC_PATH}/${GCC_PREFIX}-objcopy -O verilog $< $@ + # to fix flash base address + sed -i 's/@10000000/@00000000/g' $@ + +%.bin: %.elf + ${GCC_PATH}/${GCC_PREFIX}-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@ + +# ---- Clean ---- + +clean: + rm -f *.elf *.hex *.bin *.vvp *.vcd *.log *.lst *.map + +.PHONY: clean hex all
diff --git a/verilog/dv/caravel/user_proj_example/miner_test/miner_test.c b/verilog/dv/caravel/user_proj_example/miner_test/miner_test.c new file mode 100644 index 0000000..b1b8a5c --- /dev/null +++ b/verilog/dv/caravel/user_proj_example/miner_test/miner_test.c
@@ -0,0 +1,86 @@ +#include "../../defs.h" +#include "../../stub.c" + +static volatile unsigned *regs = (unsigned*)0x30000000U; + +static const unsigned soln_b = 0; +static const unsigned stat_b = 2; +static const unsigned hdr_b = 4; +static const unsigned diff_b = 12; +static const unsigned start_b = 20; +static const unsigned ctl_b = 22; + +// header: 644a7f32 cc155134 2997512a df12ab67 b94e7a63 2a26a07e d4615959 dd8d5b09 +// nonce: 1883832e 85da0f7a +// hash: a4b44b86 80040878 f767b763 c46bbca6 19c1e1af 1c5c37da 42e11e05 8cb09ca0 + +static inline void write_reg(unsigned r, unsigned v) { + regs[r] = v; +} + +static inline unsigned read_reg(unsigned r) { + return regs[r]; +} + + +void main() +{ + unsigned long long start, s, solution; + unsigned status; + + // Set UART clock to 64 kbaud (enable before I/O configuration) + reg_uart_clkdiv = 625; + reg_uart_enable = 1; + + /* Apply configuration */ + reg_mprj_xfer = 1; + while (reg_mprj_xfer == 1); + + for (int i = 0; i < 32; i++) { + write_reg(ctl_b, 0); + // header + write_reg(hdr_b + 0, (0x644a7f32)); + write_reg(hdr_b + 1, (0xcc155134)); + write_reg(hdr_b + 2, (0x2997512a)); + write_reg(hdr_b + 3, (0xdf12ab67)); + write_reg(hdr_b + 4, (0xb94e7a63)); + write_reg(hdr_b + 5, (0x2a26a07e)); + write_reg(hdr_b + 6, (0xd4615959)); + write_reg(hdr_b + 7, (0xdd8d5b09)); + // start nonce + start = 0x1883832e85da0f7aULL; + s = start - i; + write_reg(start_b + 1, (unsigned)s); + write_reg(start_b + 0, s >> 32); + // diff + write_reg(diff_b + 0, (0xa4b44b86)); + write_reg(diff_b + 1, (0x80040878)); + write_reg(diff_b + 2, (0xf767b763)); + write_reg(diff_b + 3, (0xc46bbca6)); + write_reg(diff_b + 4, (0x19c1e1af)); + write_reg(diff_b + 5, (0x1c5c37da)); + write_reg(diff_b + 6, (0x42e11e05)); + write_reg(diff_b + 7, (0x8cb09ca0)); + + // control + write_reg(ctl_b, 0x01800003); + + for (int j = 0; j < 5000000; j = j + 1) { + status = read_reg(stat_b); + if ((status & 7) == 7) + break; + } + status = read_reg(ctl_b); + solution = read_reg(soln_b + 0) + + ((unsigned long long)read_reg(soln_b + 1) << 32); + write_reg(ctl_b, 0); + if ((solution != start) || ((status & 7) != 7)) { + print("\nFailed\n"); // Makes simulation very long! + reg_mprj_datal = 0xAB510000; + return; + } + } + print("\nPassed\n"); // Makes simulation very long! + reg_mprj_datal = 0xAB510000; +} +
diff --git a/verilog/dv/caravel/user_proj_example/miner_test/miner_test_tb.v b/verilog/dv/caravel/user_proj_example/miner_test/miner_test_tb.v new file mode 100644 index 0000000..31f6d34 --- /dev/null +++ b/verilog/dv/caravel/user_proj_example/miner_test/miner_test_tb.v
@@ -0,0 +1,138 @@ +// SPDX-FileCopyrightText: 2020 Efabless Corporation +// +// Licensed 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. +// SPDX-License-Identifier: Apache-2.0 + +`default_nettype none + +`timescale 1 ns / 1 ps + +`include "caravel.v" +`include "spiflash.v" +`include "tbuart.v" + +module miner_test_tb; + reg clock; + reg RSTB; + reg power1, power2; + + wire gpio; + wire uart_tx; + wire [37:0] mprj_io; + wire [15:0] checkbits; + + assign checkbits = mprj_io[31:16]; + assign uart_tx = mprj_io[6]; + + always #12.5 clock <= (clock === 1'b0); + + initial begin + clock = 0; + end + + initial begin + $dumpfile("miner_test.vcd"); + $dumpvars(0, miner_test_tb); + + // Repeat cycles of 1000 clock edges as needed to complete testbench + repeat (200) begin + repeat (1000) @(posedge clock); + $display("+1000 cycles"); + end + $display("%c[1;31m",27); + $display ("Monitor: Timeout, Test Mega-Project IO (RTL) Failed"); + $display("%c[0m",27); + $finish; + end + + initial begin + wait(checkbits == 16'hAB40); + $display("Miner test started"); + wait(checkbits == 16'hAB41); + wait(checkbits == 16'hAB51); + #10000; + $finish; + end + + initial begin + RSTB <= 1'b0; + #1000; + RSTB <= 1'b1; // Release reset + #2000; + end + + initial begin // Power-up sequence + power1 <= 1'b0; + power2 <= 1'b0; + #200; + power1 <= 1'b1; + #200; + power2 <= 1'b1; + end + + wire flash_csb; + wire flash_clk; + wire flash_io0; + wire flash_io1; + + wire VDD1V8; + wire VDD3V3; + wire VSS; + + assign VDD3V3 = power1; + assign VDD1V8 = power2; + assign VSS = 1'b0; + + caravel uut ( + .vddio (VDD3V3), + .vssio (VSS), + .vdda (VDD3V3), + .vssa (VSS), + .vccd (VDD1V8), + .vssd (VSS), + .vdda1 (VDD3V3), + .vdda2 (VDD3V3), + .vssa1 (VSS), + .vssa2 (VSS), + .vccd1 (VDD1V8), + .vccd2 (VDD1V8), + .vssd1 (VSS), + .vssd2 (VSS), + .clock (clock), + .gpio (gpio), + .mprj_io (mprj_io), + .flash_csb(flash_csb), + .flash_clk(flash_clk), + .flash_io0(flash_io0), + .flash_io1(flash_io1), + .resetb (RSTB) + ); + + spiflash #( + .FILENAME("miner_test.hex") + ) spiflash ( + .csb(flash_csb), + .clk(flash_clk), + .io0(flash_io0), + .io1(flash_io1), + .io2(), // not used + .io3() // not used + ); + + // Testbench UART + tbuart tbuart ( + .ser_rx(uart_tx) + ); + +endmodule +`default_nettype wire