external test
diff --git a/verilog/dv/scan_controller_ext/Makefile b/verilog/dv/scan_controller_ext/Makefile new file mode 100644 index 0000000..eb95226 --- /dev/null +++ b/verilog/dv/scan_controller_ext/Makefile
@@ -0,0 +1,31 @@ +PWDD := $(shell pwd) +BLOCKS := $(shell basename $(PWDD)) + +# ---- Include Partitioned Makefiles ---- + +CONFIG = caravel_user_project + +export COCOTB_REDUCED_LOG_FMT=1 +# Change this line if you want to use existing cocotb test modules: +#export PYTHONPATH := $(DESIGNS)/verilog/rtl/<your design python tests> +export LIBPYTHON_LOC=$(shell cocotb-config --libpython) + + +include $(MCW_ROOT)/verilog/dv/make/env.makefile +include $(MCW_ROOT)/verilog/dv/make/var.makefile +include $(MCW_ROOT)/verilog/dv/make/cpu.makefile +include $(MCW_ROOT)/verilog/dv/make/sim.makefile + +# change the project.hex to your projects firmware file +coco_test: scan_controller.hex + rm -rf sim_build/ + mkdir sim_build/ + + # change project_tb.v to match your testbench name + iverilog -Ttyp -DFUNCTIONAL -DSIM -DUSE_POWER_PINS -DUNIT_DELAY=#1 \ + -f$(VERILOG_PATH)/includes/includes.rtl.caravel \ + -f$(USER_PROJECT_VERILOG)/includes/includes.rtl.$(CONFIG) -o sim_build/sim.vvp scan_controller_tb.v + + # change this line to choose the comma separated test cases and the name of your python test module + TESTCASE=test_start MODULE=test_scan_controller vvp -M $$(cocotb-config --prefix)/cocotb/libs -m libcocotbvpi_icarus sim_build/sim.vvp + ! grep failure results.xml
diff --git a/verilog/dv/scan_controller_ext/README.md b/verilog/dv/scan_controller_ext/README.md new file mode 100644 index 0000000..aa489e9 --- /dev/null +++ b/verilog/dv/scan_controller_ext/README.md
@@ -0,0 +1,7 @@ +# external controller test + +run + + ./configure.py --update-caravel --limit 1 + +before starting test
diff --git a/verilog/dv/scan_controller_ext/scan_controller.c b/verilog/dv/scan_controller_ext/scan_controller.c new file mode 100644 index 0000000..6edea7e --- /dev/null +++ b/verilog/dv/scan_controller_ext/scan_controller.c
@@ -0,0 +1,74 @@ +/* + * 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 + */ + +#include <defs.h> +#include <stub.c> + +#define SET(PIN,N) (PIN |= (1<<N)) +#define CLR(PIN,N) (PIN &= ~(1<<N)) +#define GET(PIN,N) (PIN & (1<<N)) + +#define FW_READY 12 + +void main() +{ + /* + IO Control Registers + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 3-bits | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | + + Output: 0000_0110_0000_1110 (0x1808) = GPIO_MODE_USER_STD_OUTPUT + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 110 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | + + + Input: 0000_0001_0000_1111 (0x0402) = GPIO_MODE_USER_STD_INPUT_NOPULL + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | + + */ + + // 2 inputs for enable logic analyser control + reg_mprj_io_8 = GPIO_MODE_USER_STD_INPUT_NOPULL; + reg_mprj_io_9 = GPIO_MODE_USER_STD_INPUT_NOPULL; + + /* + inputs (io_in[28:21]), + outputs (io_out[36:29]), + ext_scan_clk = inputs[0]; + ext_scan_data_in = inputs[1]; + ext_scan_data_out = outputs[0] + ext_scan_select = inputs[2]; + ext_scan_latch_en = inputs[3]; + */ + + reg_mprj_io_21 = GPIO_MODE_USER_STD_INPUT_NOPULL; // clk + reg_mprj_io_22 = GPIO_MODE_USER_STD_INPUT_NOPULL; // data in + reg_mprj_io_23 = GPIO_MODE_USER_STD_INPUT_NOPULL; // scan + reg_mprj_io_24 = GPIO_MODE_USER_STD_INPUT_NOPULL; // latch + + reg_mprj_io_29 = GPIO_MODE_USER_STD_OUTPUT; // data out + + // outputs for testbench control + reg_mprj_io_12 = GPIO_MODE_MGMT_STD_OUTPUT; // fw ready + + /* Apply configuration */ + reg_mprj_xfer = 1; + while (reg_mprj_xfer == 1); + + reg_mprj_datal |= 1 << FW_READY; +}
diff --git a/verilog/dv/scan_controller_ext/scan_controller.hex b/verilog/dv/scan_controller_ext/scan_controller.hex new file mode 100755 index 0000000..4dd92e8 --- /dev/null +++ b/verilog/dv/scan_controller_ext/scan_controller.hex
@@ -0,0 +1,59 @@ +@00000000 +6F 00 00 0B 13 00 00 00 13 00 00 00 13 00 00 00 +13 00 00 00 13 00 00 00 13 00 00 00 13 00 00 00 +23 2E 11 FE 23 2C 51 FE 23 2A 61 FE 23 28 71 FE +23 26 A1 FE 23 24 B1 FE 23 22 C1 FE 23 20 D1 FE +23 2E E1 FC 23 2C F1 FC 23 2A 01 FD 23 28 11 FD +23 26 C1 FD 23 24 D1 FD 23 22 E1 FD 23 20 F1 FD +13 01 01 FC EF 00 40 11 83 20 C1 03 83 22 81 03 +03 23 41 03 83 23 01 03 03 25 C1 02 83 25 81 02 +03 26 41 02 83 26 01 02 03 27 C1 01 83 27 81 01 +03 28 41 01 83 28 01 01 03 2E C1 00 83 2E 81 00 +03 2F 41 00 83 2F 01 00 13 01 01 04 73 00 20 30 +17 01 00 F1 13 01 01 75 17 05 00 00 13 05 85 F6 +73 10 55 30 13 05 00 00 93 05 00 00 17 06 00 00 +13 06 46 2D 63 0C B5 00 83 26 06 00 23 20 D5 00 +13 05 45 00 13 06 46 00 6F F0 DF FE 13 05 00 00 +93 05 80 00 63 08 B5 00 23 20 05 00 13 05 45 00 +6F F0 5F FF 37 15 00 00 13 05 05 88 73 10 45 30 +EF 00 C0 1A 6F 00 00 00 13 01 01 FF 23 26 81 00 +13 04 01 01 13 00 00 00 03 24 C1 00 13 01 01 01 +67 80 00 00 13 01 01 FF 23 26 81 00 13 04 01 01 +13 00 00 00 03 24 C1 00 13 01 01 01 67 80 00 00 +13 01 01 FE 23 2E 81 00 13 04 01 02 23 26 A4 FE +83 27 C4 FE 73 90 07 BC 13 00 00 00 03 24 C1 01 +13 01 01 02 67 80 00 00 13 01 01 FF 23 26 11 00 +23 24 81 00 13 04 01 01 13 05 00 00 EF F0 5F FC +B7 37 00 F0 93 87 87 03 13 07 A0 00 23 A0 E7 00 +B7 37 00 F0 93 87 C7 03 37 07 02 00 23 A0 E7 00 +13 07 10 00 23 10 E0 00 13 00 00 00 83 20 C1 00 +03 24 81 00 13 01 01 01 67 80 00 00 13 01 01 FF +23 26 81 00 13 04 01 01 13 00 00 00 03 24 C1 00 +13 01 01 01 67 80 00 00 13 01 01 FF 23 26 81 00 +13 04 01 01 13 00 00 00 03 24 C1 00 13 01 01 01 +67 80 00 00 13 01 01 FE 23 2E 11 00 23 2C 81 00 +13 04 01 02 93 07 05 00 A3 07 F4 FE 03 47 F4 FE +93 07 A0 00 63 16 F7 00 13 05 D0 00 EF F0 9F FD +13 00 00 00 B7 67 00 F0 93 87 47 80 03 A7 07 00 +93 07 10 00 E3 08 F7 FE B7 67 00 F0 93 87 07 80 +03 47 F4 FE 23 A0 E7 00 13 00 00 00 83 20 C1 01 +03 24 81 01 13 01 01 02 67 80 00 00 13 01 01 FE +23 2E 11 00 23 2C 81 00 13 04 01 02 23 26 A4 FE +6F 00 C0 01 83 27 C4 FE 13 87 17 00 23 26 E4 FE +83 C7 07 00 13 85 07 00 EF F0 DF F6 83 27 C4 FE +83 C7 07 00 E3 90 07 FE 13 00 00 00 83 20 C1 01 +03 24 81 01 13 01 01 02 67 80 00 00 13 01 01 FF +23 26 81 00 13 04 01 01 B7 07 00 26 93 87 47 04 +13 07 20 40 23 A0 E7 00 B7 07 00 26 93 87 87 04 +13 07 20 40 23 A0 E7 00 B7 07 00 26 93 87 87 07 +13 07 20 40 23 A0 E7 00 B7 07 00 26 93 87 C7 07 +13 07 20 40 23 A0 E7 00 B7 07 00 26 93 87 07 08 +13 07 20 40 23 A0 E7 00 B7 07 00 26 93 87 47 08 +13 07 20 40 23 A0 E7 00 B7 07 00 26 93 87 87 09 +37 27 00 00 13 07 87 80 23 A0 E7 00 B7 07 00 26 +93 87 47 05 37 27 00 00 13 07 97 80 23 A0 E7 00 +B7 07 00 26 13 07 10 00 23 A0 E7 00 13 00 00 00 +B7 07 00 26 03 A7 07 00 93 07 10 00 E3 0A F7 FE +B7 07 00 26 93 87 C7 00 83 A6 07 00 B7 07 00 26 +93 87 C7 00 37 17 00 00 33 E7 E6 00 23 A0 E7 00 +13 00 00 00 03 24 C1 00 13 01 01 01 67 80 00 00
diff --git a/verilog/dv/scan_controller_ext/scan_controller_ext.gtkw b/verilog/dv/scan_controller_ext/scan_controller_ext.gtkw new file mode 100644 index 0000000..c4a3411 --- /dev/null +++ b/verilog/dv/scan_controller_ext/scan_controller_ext.gtkw
@@ -0,0 +1,46 @@ +[*] +[*] GTKWave Analyzer v3.3.103 (w)1999-2019 BSI +[*] Sun Aug 28 03:59:31 2022 +[*] +[dumpfile] "/home/matt/work/asic-workshop/shuttle7/tinytapeout-mpw7/verilog/dv/scan_controller_ext/scan_controller_tb.vcd" +[dumpfile_mtime] "Sun Aug 28 03:59:25 2022" +[dumpfile_size] 357948 +[savefile] "/home/matt/work/asic-workshop/shuttle7/tinytapeout-mpw7/verilog/dv/scan_controller_ext/scan_controller_ext.gtkw" +[timestart] 365159000 +[size] 1848 1016 +[pos] -1 -1 +*-18.000000 366175000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] scan_controller_tb. +[treeopen] scan_controller_tb.uut. +[treeopen] scan_controller_tb.uut.mprj. +[sst_width] 423 +[signals_width] 261 +[sst_expanded] 1 +[sst_vpaned_height] 254 +@28 +scan_controller_tb.clk +scan_controller_tb.driver_sel[1:0] +scan_controller_tb.fw_ready +scan_controller_tb.uut.mprj.scan_controller.driver_sel[1:0] +@800200 +-scan chain +@28 +scan_controller_tb.uut.mprj.scan_controller.scan_clk +scan_controller_tb.uut.mprj.scan_controller.scan_data_in +scan_controller_tb.uut.mprj.scan_controller.scan_data_out +scan_controller_tb.uut.mprj.scan_controller.scan_latch_en +scan_controller_tb.uut.mprj.scan_controller.scan_select +@1000200 +-scan chain +@800200 +-ext scan chain +@29 +scan_controller_tb.ext_clk +scan_controller_tb.ext_data_in +scan_controller_tb.ext_data_out +scan_controller_tb.ext_latch +scan_controller_tb.ext_scan +@1000200 +-ext scan chain +[pattern_trace] 1 +[pattern_trace] 0
diff --git a/verilog/dv/scan_controller_ext/scan_controller_tb.v b/verilog/dv/scan_controller_ext/scan_controller_tb.v new file mode 100644 index 0000000..9b02c87 --- /dev/null +++ b/verilog/dv/scan_controller_ext/scan_controller_tb.v
@@ -0,0 +1,101 @@ +// 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 + +// change module name to something that suits your project +module scan_controller_tb; + initial begin + // change to suit your project + $dumpfile ("scan_controller_tb.vcd"); + $dumpvars (0, scan_controller_tb); + #1; + end + + reg clk; + reg RSTB; + reg power1, power2; + reg power3, power4; + + wire gpio; + wire [37:0] mprj_io; + + ///// convenience signals that match what the cocotb test modules are looking for + // change to suit your project. Here's how we can make some nicer named signals for inputs & outputs + wire fw_ready = mprj_io[12]; + wire ext_data_out = mprj_io[29]; + + wire [1:0] driver_sel; + wire ext_clk, ext_latch, ext_scan, ext_data_in; + assign mprj_io[21] = ext_clk; + assign mprj_io[22] = ext_data_in; + assign mprj_io[23] = ext_scan; + assign mprj_io[24] = ext_latch; + assign mprj_io[9:8] = driver_sel; + ///// + + + wire flash_csb; + wire flash_clk; + wire flash_io0; + wire flash_io1; + + wire VDD3V3 = power1; + wire VDD1V8 = power2; + wire USER_VDD3V3 = power3; + wire USER_VDD1V8 = power4; + wire VSS = 1'b0; + + caravel uut ( + .vddio (VDD3V3), + .vssio (VSS), + .vdda (VDD3V3), + .vssa (VSS), + .vccd (VDD1V8), + .vssd (VSS), + .vdda1 (USER_VDD3V3), + .vdda2 (USER_VDD3V3), + .vssa1 (VSS), + .vssa2 (VSS), + .vccd1 (USER_VDD1V8), + .vccd2 (USER_VDD1V8), + .vssd1 (VSS), + .vssd2 (VSS), + .clock (clk), + .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 #( + // change the hex file to match your project + .FILENAME("scan_controller.hex") + ) spiflash ( + .csb(flash_csb), + .clk(flash_clk), + .io0(flash_io0), + .io1(flash_io1), + .io2(), // not used + .io3() // not used + ); + +endmodule +`default_nettype wire
diff --git a/verilog/dv/scan_controller_ext/test_scan_controller.py b/verilog/dv/scan_controller_ext/test_scan_controller.py new file mode 100644 index 0000000..40af416 --- /dev/null +++ b/verilog/dv/scan_controller_ext/test_scan_controller.py
@@ -0,0 +1,71 @@ +import cocotb +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, ClockCycles, with_timeout + +@cocotb.test() +async def test_start(dut): + clock = Clock(dut.clk, 25, units="ns") # 40M + cocotb.fork(clock.start()) + + dut.driver_sel.value = 0b00 # external + dut.ext_clk.value = 0 + dut.ext_latch.value = 0 + dut.ext_scan.value = 0 + dut.ext_data_in.value = 0 + + dut.RSTB.value = 0 + dut.power1.value = 0 + dut.power2.value = 0 + dut.power3.value = 0 + dut.power4.value = 0 + + await ClockCycles(dut.clk, 8) + dut.power1.value = 1 + await ClockCycles(dut.clk, 8) + dut.power2.value = 1 + await ClockCycles(dut.clk, 8) + dut.power3.value = 1 + await ClockCycles(dut.clk, 8) + dut.power4.value = 1 + + await ClockCycles(dut.clk, 80) + dut.RSTB.value = 1 + + # wait with a timeout for the project to become active + await with_timeout(RisingEdge(dut.fw_ready), 650, 'us') + print("firmware ready") + + # send some data in + dut.ext_data_in.value = 1 + for i in range(8): + dut.ext_clk.value = 1 + await ClockCycles(dut.clk, 1) + dut.ext_clk.value = 0 + await ClockCycles(dut.clk, 1) + if i == 3: + dut.ext_data_in.value = 0 + + # latch it + dut.ext_latch.value = 1 + await ClockCycles(dut.clk, 1) + dut.ext_latch.value = 0 + await ClockCycles(dut.clk, 1) + + # scan enable + dut.ext_scan.value = 1 + dut.ext_clk.value = 1 + await ClockCycles(dut.clk, 1) + dut.ext_scan.value = 0 + + # drive the data out + for i in range(8): + dut.ext_clk.value = 1 + await ClockCycles(dut.clk, 1) + dut.ext_clk.value = 0 + await ClockCycles(dut.clk, 1) + print(dut.ext_data_out.value) + if i < 4: + assert(dut.ext_data_out.value == 1) + else: + assert(dut.ext_data_out.value == 0) +