parent
5c87fc09ef
commit
8214134b89
|
@ -1,2 +1,2 @@
|
||||||
本分支(bram)是在master分支的基础上,将指令和数据存储器由LUTRAM(DRAM)改为BRAM,以便可以运行更大的(C语言)程序。
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
|
||||||
|
+incdir+../rtl/core
|
||||||
|
|
||||||
|
../rtl/core/clint.sv
|
||||||
|
../rtl/core/csr_reg.sv
|
||||||
|
../rtl/core/defines.sv
|
||||||
|
../rtl/core/divider.sv
|
||||||
|
../rtl/core/exu.sv
|
||||||
|
../rtl/core/exu_alu_datapath.sv
|
||||||
|
../rtl/core/exu_commit.sv
|
||||||
|
../rtl/core/exu_dispatch.sv
|
||||||
|
../rtl/core/exu_mem.sv
|
||||||
|
../rtl/core/exu_muldiv.sv
|
||||||
|
../rtl/core/gpr_reg.sv
|
||||||
|
../rtl/core/idu.sv
|
||||||
|
../rtl/core/idu_exu.sv
|
||||||
|
../rtl/core/ifu.sv
|
||||||
|
../rtl/core/ifu_idu.sv
|
||||||
|
../rtl/core/pipe_ctrl.sv
|
||||||
|
../rtl/core/rst_ctrl.sv
|
||||||
|
../rtl/core/tinyriscv_core.sv
|
||||||
|
|
||||||
|
../rtl/debug/jtag_dm.sv
|
||||||
|
../rtl/debug/jtag_driver.sv
|
||||||
|
../rtl/debug/jtag_top.sv
|
||||||
|
|
||||||
|
../rtl/perips/gpio.sv
|
||||||
|
../rtl/perips/ram.sv
|
||||||
|
../rtl/perips/rom.sv
|
||||||
|
../rtl/perips/timer.sv
|
||||||
|
../rtl/perips/uart.sv
|
||||||
|
|
||||||
|
../rtl/sys_bus/rib.sv
|
||||||
|
|
||||||
|
../rtl/top/tinyriscv_soc_top.sv
|
||||||
|
|
||||||
|
../rtl/utils/full_handshake_rx.sv
|
||||||
|
../rtl/utils/full_handshake_tx.sv
|
||||||
|
../rtl/utils/gen_buf.sv
|
||||||
|
../rtl/utils/gen_dff.sv
|
||||||
|
../rtl/utils/gen_ram.sv
|
||||||
|
../rtl/utils/vld_rdy.sv
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "defines.v"
|
`include "defines.sv"
|
||||||
|
|
||||||
// core local interruptor module
|
// core local interruptor module
|
||||||
// 核心中断管理、仲裁模块
|
// 核心中断管理、仲裁模块
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "defines.v"
|
`include "defines.sv"
|
||||||
|
|
||||||
// CSR寄存器模块
|
// CSR寄存器模块
|
||||||
module csr_reg(
|
module csr_reg(
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "defines.v"
|
`include "defines.sv"
|
||||||
|
|
||||||
// 除法模块
|
// 除法模块
|
||||||
// 试商法实现32位整数除法
|
// 试商法实现32位整数除法
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "defines.v"
|
`include "defines.sv"
|
||||||
|
|
||||||
// 执行模块
|
// 执行模块
|
||||||
// 纯组合逻辑电路
|
// 纯组合逻辑电路
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "defines.v"
|
`include "defines.sv"
|
||||||
|
|
||||||
|
|
||||||
`define DATAPATH_MUX_WIDTH (32+32+16)
|
`define DATAPATH_MUX_WIDTH (32+32+16)
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "defines.v"
|
`include "defines.sv"
|
||||||
|
|
||||||
|
|
||||||
module exu_commit(
|
module exu_commit(
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "defines.v"
|
`include "defines.sv"
|
||||||
|
|
||||||
|
|
||||||
module exu_dispatch(
|
module exu_dispatch(
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "defines.v"
|
`include "defines.sv"
|
||||||
|
|
||||||
|
|
||||||
module exu_mem(
|
module exu_mem(
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "defines.v"
|
`include "defines.sv"
|
||||||
|
|
||||||
|
|
||||||
module exu_muldiv(
|
module exu_muldiv(
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "defines.v"
|
`include "defines.sv"
|
||||||
|
|
||||||
// 通用寄存器模块
|
// 通用寄存器模块
|
||||||
module gpr_reg(
|
module gpr_reg(
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "defines.v"
|
`include "defines.sv"
|
||||||
|
|
||||||
// 译码模块
|
// 译码模块
|
||||||
// 纯组合逻辑电路
|
// 纯组合逻辑电路
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "defines.v"
|
`include "defines.sv"
|
||||||
|
|
||||||
// 将译码结果向执行模块传递
|
// 将译码结果向执行模块传递
|
||||||
module idu_exu(
|
module idu_exu(
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "defines.v"
|
`include "defines.sv"
|
||||||
|
|
||||||
// 取指模块
|
// 取指模块
|
||||||
module ifu(
|
module ifu(
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "defines.v"
|
`include "defines.sv"
|
||||||
|
|
||||||
// 将指令向译码模块传递
|
// 将指令向译码模块传递
|
||||||
module ifu_idu(
|
module ifu_idu(
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "defines.v"
|
`include "defines.sv"
|
||||||
|
|
||||||
// 流水线控制模块
|
// 流水线控制模块
|
||||||
// 发出暂停、冲刷流水线信号
|
// 发出暂停、冲刷流水线信号
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "defines.v"
|
`include "defines.sv"
|
||||||
|
|
||||||
// 复位控制模块
|
// 复位控制模块
|
||||||
module rst_ctrl(
|
module rst_ctrl(
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "defines.v"
|
`include "defines.sv"
|
||||||
|
|
||||||
// tinyriscv处理器核顶层模块
|
// tinyriscv处理器核顶层模块
|
||||||
module tinyriscv_core(
|
module tinyriscv_core(
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "../core/defines.v"
|
`include "../core/defines.sv"
|
||||||
|
|
||||||
// JTAG顶层模块
|
// JTAG顶层模块
|
||||||
module jtag_top #(
|
module jtag_top #(
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "../core/defines.v"
|
`include "../core/defines.sv"
|
||||||
|
|
||||||
|
|
||||||
module ram #(
|
module ram #(
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "../core/defines.v"
|
`include "../core/defines.sv"
|
||||||
|
|
||||||
|
|
||||||
module rom #(
|
module rom #(
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "../core/defines.v"
|
`include "../core/defines.sv"
|
||||||
|
|
||||||
// 32位向上计数定时器模块
|
// 32位向上计数定时器模块
|
||||||
module timer(
|
module timer(
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "../core/defines.v"
|
`include "../core/defines.sv"
|
||||||
|
|
||||||
// 串口收发模块(默认: 115200, 8,N,1)
|
// 串口收发模块(默认: 115200, 8,N,1)
|
||||||
module uart(
|
module uart(
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "../core/defines.v"
|
`include "../core/defines.sv"
|
||||||
|
|
||||||
// tinyriscv soc顶层模块
|
// tinyriscv soc顶层模块
|
||||||
module tinyriscv_soc_top(
|
module tinyriscv_soc_top(
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
`include "../core/defines.v"
|
`include "../core/defines.sv"
|
||||||
|
|
||||||
|
|
||||||
module gen_ram #(
|
module gen_ram #(
|
|
@ -1,6 +1,5 @@
|
||||||
|
RISCV_TOOLS_PATH := /opt/riscv/bin
|
||||||
RISCV_TOOLS_PATH := $(TOOLCHAIN_DIR)/tools/gnu-mcu-eclipse-riscv-none-gcc-8.2.0-2.2-20190521-0004-win64/bin
|
RISCV_TOOLS_PREFIX := riscv32-unknown-elf-
|
||||||
RISCV_TOOLS_PREFIX := riscv-none-embed-
|
|
||||||
|
|
||||||
RISCV_GCC := $(abspath $(RISCV_TOOLS_PATH)/$(RISCV_TOOLS_PREFIX)gcc)
|
RISCV_GCC := $(abspath $(RISCV_TOOLS_PATH)/$(RISCV_TOOLS_PREFIX)gcc)
|
||||||
RISCV_AS := $(abspath $(RISCV_TOOLS_PATH)/$(RISCV_TOOLS_PREFIX)as)
|
RISCV_AS := $(abspath $(RISCV_TOOLS_PATH)/$(RISCV_TOOLS_PREFIX)as)
|
||||||
|
@ -11,6 +10,8 @@ RISCV_AR := $(abspath $(RISCV_TOOLS_PATH)/$(RISCV_TOOLS_PREFIX)ar)
|
||||||
RISCV_OBJCOPY := $(abspath $(RISCV_TOOLS_PATH)/$(RISCV_TOOLS_PREFIX)objcopy)
|
RISCV_OBJCOPY := $(abspath $(RISCV_TOOLS_PATH)/$(RISCV_TOOLS_PREFIX)objcopy)
|
||||||
RISCV_READELF := $(abspath $(RISCV_TOOLS_PATH)/$(RISCV_TOOLS_PREFIX)readelf)
|
RISCV_READELF := $(abspath $(RISCV_TOOLS_PATH)/$(RISCV_TOOLS_PREFIX)readelf)
|
||||||
|
|
||||||
|
BIN_TO_MEM := $(COMMON_DIR)/../../tools/BinToMem.py
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: $(TARGET)
|
all: $(TARGET)
|
||||||
|
|
||||||
|
@ -34,7 +35,7 @@ C_OBJS := $(C_SRCS:.c=.o)
|
||||||
LINK_OBJS += $(ASM_OBJS) $(C_OBJS)
|
LINK_OBJS += $(ASM_OBJS) $(C_OBJS)
|
||||||
LINK_DEPS += $(LINKER_SCRIPT)
|
LINK_DEPS += $(LINKER_SCRIPT)
|
||||||
|
|
||||||
CLEAN_OBJS += $(TARGET) $(LINK_OBJS) $(TARGET).dump $(TARGET).bin
|
CLEAN_OBJS += $(TARGET) $(LINK_OBJS) $(TARGET).dump $(TARGET).bin $(TARGET).hex $(TARGET).mem
|
||||||
|
|
||||||
CFLAGS += -march=$(RISCV_ARCH)
|
CFLAGS += -march=$(RISCV_ARCH)
|
||||||
CFLAGS += -mabi=$(RISCV_ABI)
|
CFLAGS += -mabi=$(RISCV_ABI)
|
||||||
|
@ -44,6 +45,7 @@ $(TARGET): $(LINK_OBJS) $(LINK_DEPS) Makefile
|
||||||
$(RISCV_GCC) $(CFLAGS) $(INCLUDES) $(LINK_OBJS) -o $@ $(LDFLAGS)
|
$(RISCV_GCC) $(CFLAGS) $(INCLUDES) $(LINK_OBJS) -o $@ $(LDFLAGS)
|
||||||
$(RISCV_OBJCOPY) -O binary $@ $@.bin
|
$(RISCV_OBJCOPY) -O binary $@ $@.bin
|
||||||
$(RISCV_OBJDUMP) --disassemble-all $@ > $@.dump
|
$(RISCV_OBJDUMP) --disassemble-all $@ > $@.dump
|
||||||
|
$(BIN_TO_MEM) $@.bin $@.mem
|
||||||
|
|
||||||
$(ASM_OBJS): %.o: %.S
|
$(ASM_OBJS): %.o: %.S
|
||||||
$(RISCV_GCC) $(CFLAGS) $(INCLUDES) -c -o $@ $<
|
$(RISCV_GCC) $(CFLAGS) $(INCLUDES) -c -o $@ $<
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
# Object files
|
testbench_verilator
|
||||||
*.o
|
*.log
|
||||||
*.ko
|
*.vcd
|
||||||
*.obj
|
|
||||||
*.bin
|
*.bin
|
||||||
*.dump
|
cobj_dir/
|
||||||
inst.data
|
|
||||||
out.vvp
|
|
||||||
tinyriscv_soc_tb.vcd
|
|
||||||
jtag_tb.vcd
|
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
|
||||||
|
PROG := ../sdk/examples/simple/simple.mem
|
||||||
|
PROG_DIR := $(shell dirname $(PROG))
|
||||||
|
|
||||||
|
MAKE := make
|
||||||
|
VERILATOR := verilator
|
||||||
|
|
||||||
|
VERI_FLAGS += +vcd
|
||||||
|
VERI_CFLAGS +=
|
||||||
|
|
||||||
|
VERI_VFLAGS += -DRVFI
|
||||||
|
|
||||||
|
TRACE_ENABLE := 1
|
||||||
|
|
||||||
|
RTL_FILES = ../rtl.flist
|
||||||
|
|
||||||
|
VERI_OBJ_DIR := cobj_dir
|
||||||
|
|
||||||
|
ifeq ($(findstring +vcd,$(VERI_FLAGS)),+vcd)
|
||||||
|
VERI_TRACE = "--trace"
|
||||||
|
VERI_CFLAGS += "-DVCD_TRACE"
|
||||||
|
else
|
||||||
|
VERI_TRACE =
|
||||||
|
endif
|
||||||
|
|
||||||
|
SIM_SRC := sim_jtag.sv
|
||||||
|
|
||||||
|
SIM_SRC += tb_top_verilator.sv \
|
||||||
|
tb_top_verilator.cpp
|
||||||
|
|
||||||
|
SIM_TOP_MODULE := tb_top_verilator
|
||||||
|
|
||||||
|
.DEFAULT_GOAL := sim
|
||||||
|
all: sim
|
||||||
|
|
||||||
|
.PHONY: recompile
|
||||||
|
recompile:
|
||||||
|
rm -rf $(VERI_OBJ_DIR) testbench_verilator
|
||||||
|
$(MAKE) -C ./remote_bitbang clean
|
||||||
|
$(MAKE) -C $(PROG_DIR) clean
|
||||||
|
$(MAKE) compile
|
||||||
|
|
||||||
|
.PHONY: compile
|
||||||
|
compile: remote_bitbang/librbs.so $(PROG) testbench_verilator
|
||||||
|
|
||||||
|
testbench_verilator:
|
||||||
|
$(VERILATOR) --cc --sv --exe \
|
||||||
|
$(VERI_TRACE) \
|
||||||
|
--Wno-lint --Wno-UNOPTFLAT \
|
||||||
|
--Wno-MODDUP --top-module \
|
||||||
|
$(SIM_TOP_MODULE) \
|
||||||
|
-f $(RTL_FILES) \
|
||||||
|
$(SIM_SRC) \
|
||||||
|
--Mdir $(VERI_OBJ_DIR) \
|
||||||
|
$(VERI_VFLAGS) \
|
||||||
|
-LDFLAGS "-L../remote_bitbang \
|
||||||
|
-Wl,--enable-new-dtags -Wl,-rpath,remote_bitbang -lrbs" \
|
||||||
|
-CFLAGS "-std=gnu++11 $(VERI_CFLAGS)"
|
||||||
|
$(MAKE) -C $(VERI_OBJ_DIR) -f V$(SIM_TOP_MODULE).mk
|
||||||
|
cp $(VERI_OBJ_DIR)/V$(SIM_TOP_MODULE) testbench_verilator
|
||||||
|
|
||||||
|
remote_bitbang/librbs.so:
|
||||||
|
$(MAKE) -C ./remote_bitbang all
|
||||||
|
|
||||||
|
$(PROG):
|
||||||
|
$(MAKE) -C $(PROG_DIR)
|
||||||
|
|
||||||
|
.PHONY: run
|
||||||
|
run:
|
||||||
|
./testbench_verilator "+firmware=$(PROG)"
|
||||||
|
|
||||||
|
.PHONY: sim
|
||||||
|
sim: recompile run
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -rf $(VERI_OBJ_DIR) testbench_verilator *.log *.vcd
|
||||||
|
$(MAKE) -C ./remote_bitbang clean
|
||||||
|
$(MAKE) -C $(PROG_DIR) clean
|
||||||
|
|
||||||
|
.PHONY: help
|
||||||
|
help:
|
||||||
|
@echo 'rebuild all:'
|
||||||
|
@echo 'make PROG=/path/file.mem recompile'
|
||||||
|
@echo 'run directly:'
|
||||||
|
@echo 'make PROG=/path/file.mem run'
|
||||||
|
@echo 'rebuild & run:'
|
||||||
|
@echo 'make PROG=/path/file.mem sim'
|
||||||
|
@echo 'clean obj files:'
|
||||||
|
@echo 'make PROG=/path/file.mem clean'
|
|
@ -1,50 +1,3 @@
|
||||||
# compile_rtl.py
|
|
||||||
|
|
||||||
编译rtl代码。
|
|
||||||
|
|
||||||
使用方法:
|
|
||||||
|
|
||||||
`python compile_rtl.py [rtl目录相对路径]`
|
|
||||||
|
|
||||||
比如:
|
|
||||||
|
|
||||||
`python compile_rtl.py ..`
|
|
||||||
|
|
||||||
# sim_new_nowave.py
|
|
||||||
|
|
||||||
对指定的bin文件(重新生成inst.data文件)进行测试。
|
|
||||||
|
|
||||||
使用方法:
|
|
||||||
|
|
||||||
windows系统下:
|
|
||||||
|
|
||||||
`python sim_new_nowave.py ..\tests\isa\generated\rv32ui-p-add.bin inst.data`
|
|
||||||
|
|
||||||
Linux系统下:
|
|
||||||
|
|
||||||
`python sim_new_nowave.py ../tests/isa/generated/rv32ui-p-add.bin inst.data`
|
|
||||||
|
|
||||||
# sim_default_nowave.py
|
|
||||||
|
|
||||||
对已经存在的inst.data文件进行测试。
|
|
||||||
|
|
||||||
使用方法:
|
|
||||||
|
|
||||||
`python sim_default_nowave.py`
|
|
||||||
|
|
||||||
# test_all_isa.py
|
|
||||||
|
|
||||||
一次性测试../tests/isa/generated目录下的所有指令。
|
|
||||||
|
|
||||||
使用方法:
|
|
||||||
|
|
||||||
`python test_all_isa.py`
|
|
||||||
|
|
||||||
# test_jtag.py
|
|
||||||
|
|
||||||
测试JTAG的内存读、写功能。
|
|
||||||
|
|
||||||
使用方法:
|
|
||||||
|
|
||||||
`python test_jtag.py`
|
|
||||||
|
|
||||||
|
|
|
@ -1,75 +0,0 @@
|
||||||
import sys
|
|
||||||
import filecmp
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
|
|
||||||
# 主函数
|
|
||||||
def main():
|
|
||||||
rtl_dir = sys.argv[1]
|
|
||||||
|
|
||||||
if rtl_dir != r'..':
|
|
||||||
tb_file = r'/tb/compliance_test/tinyriscv_soc_tb.v'
|
|
||||||
else:
|
|
||||||
tb_file = r'/tb/tinyriscv_soc_tb.v'
|
|
||||||
|
|
||||||
# iverilog程序
|
|
||||||
iverilog_cmd = ['iverilog']
|
|
||||||
# 顶层模块
|
|
||||||
#iverilog_cmd += ['-s', r'tinyriscv_soc_tb']
|
|
||||||
# 编译生成文件
|
|
||||||
iverilog_cmd += ['-o', r'out.vvp']
|
|
||||||
# 头文件(defines.v)路径
|
|
||||||
iverilog_cmd += ['-I', rtl_dir + r'/rtl/core']
|
|
||||||
# 宏定义,仿真输出文件
|
|
||||||
iverilog_cmd += ['-D', r'OUTPUT="signature.output"']
|
|
||||||
# testbench文件
|
|
||||||
iverilog_cmd.append(rtl_dir + tb_file)
|
|
||||||
# ../rtl/core
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/clint.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/csr_reg.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/defines.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/divider.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/exu.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/exu_alu_datapath.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/exu_commit.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/exu_dispatch.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/exu_mem.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/exu_muldiv.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/gpr_reg.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/idu.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/idu_exu.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/ifu.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/ifu_idu.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/pipe_ctrl.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/tinyriscv_core.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/rst_ctrl.v')
|
|
||||||
# ../rtl/perips
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/perips/ram.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/perips/rom.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/perips/timer.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/perips/uart.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/perips/gpio.v')
|
|
||||||
# ../rtl/debug
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/debug/jtag_dm.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/debug/jtag_driver.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/debug/jtag_top.v')
|
|
||||||
# ../rtl/sys_bus
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/sys_bus/rib.v')
|
|
||||||
# ../rtl/utils
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/utils/full_handshake_rx.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/utils/full_handshake_tx.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/utils/gen_buf.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/utils/gen_dff.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/utils/gen_ram.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/utils/vld_rdy.v')
|
|
||||||
# ../rtl/top
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/top/tinyriscv_soc_top.v')
|
|
||||||
|
|
||||||
# 编译
|
|
||||||
process = subprocess.Popen(iverilog_cmd)
|
|
||||||
process.wait(timeout=5)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
sys.exit(main())
|
|
|
@ -1,11 +0,0 @@
|
||||||
# Object files
|
|
||||||
*.o
|
|
||||||
*.ko
|
|
||||||
*.obj
|
|
||||||
*.bin
|
|
||||||
*.dump
|
|
||||||
inst.data
|
|
||||||
out.vvp
|
|
||||||
tinyriscv_soc_tb.vcd
|
|
||||||
run.log
|
|
||||||
signature.output
|
|
|
@ -1,11 +0,0 @@
|
||||||
对新的指令测试项进行测试。
|
|
||||||
|
|
||||||
使用方法:
|
|
||||||
|
|
||||||
Windows系统下:
|
|
||||||
|
|
||||||
`python compliance_test.py ..\..\tests\riscv-compliance\build_generated\rv32i\I-ADD-01.elf.bin inst.data`
|
|
||||||
|
|
||||||
Linux系统下:
|
|
||||||
|
|
||||||
`python compliance_test.py ../../tests/riscv-compliance/build_generated/rv32i/I-ADD-01.elf.bin inst.data`
|
|
|
@ -1,96 +0,0 @@
|
||||||
import sys
|
|
||||||
import filecmp
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
|
|
||||||
# 找出path目录下的所有reference_output文件
|
|
||||||
def list_ref_files(path):
|
|
||||||
files = []
|
|
||||||
list_dir = os.walk(path)
|
|
||||||
for maindir, subdir, all_file in list_dir:
|
|
||||||
for filename in all_file:
|
|
||||||
apath = os.path.join(maindir, filename)
|
|
||||||
if apath.endswith('.reference_output'):
|
|
||||||
files.append(apath)
|
|
||||||
|
|
||||||
return files
|
|
||||||
|
|
||||||
# 根据bin文件找到对应的reference_output文件
|
|
||||||
def get_reference_file(bin_file):
|
|
||||||
file_path, file_name = os.path.split(bin_file)
|
|
||||||
tmp = file_name.split('.')
|
|
||||||
# 得到bin文件的前缀部分
|
|
||||||
prefix = tmp[0]
|
|
||||||
#print('bin prefix: %s' % prefix)
|
|
||||||
|
|
||||||
files = []
|
|
||||||
if (bin_file.find('rv32im') != -1):
|
|
||||||
files = list_ref_files(r'../../tests/riscv-compliance/riscv-test-suite/rv32im/references')
|
|
||||||
elif (bin_file.find('rv32i') != -1):
|
|
||||||
files = list_ref_files(r'../../tests/riscv-compliance/riscv-test-suite/rv32i/references')
|
|
||||||
elif (bin_file.find('rv32Zicsr') != -1):
|
|
||||||
files = list_ref_files(r'../../tests/riscv-compliance/riscv-test-suite/rv32Zicsr/references')
|
|
||||||
elif (bin_file.find('rv32Zifencei') != -1):
|
|
||||||
files = list_ref_files(r'../../tests/riscv-compliance/riscv-test-suite/rv32Zifencei/references')
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# 根据bin文件前缀找到对应的reference_output文件
|
|
||||||
for file in files:
|
|
||||||
if (file.find(prefix) != -1):
|
|
||||||
return file
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
# 主函数
|
|
||||||
def main():
|
|
||||||
#print(sys.argv[0] + ' ' + sys.argv[1] + ' ' + sys.argv[2])
|
|
||||||
|
|
||||||
# 1.将bin文件转成mem文件
|
|
||||||
cmd = r'python ../../tools/BinToMem_CLI.py' + ' ' + sys.argv[1] + ' ' + sys.argv[2]
|
|
||||||
f = os.popen(cmd)
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
# 2.编译rtl文件
|
|
||||||
cmd = r'python ../compile_rtl.py' + r' ../..'
|
|
||||||
f = os.popen(cmd)
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
# 3.运行
|
|
||||||
logfile = open('run.log', 'w')
|
|
||||||
vvp_cmd = [r'vvp']
|
|
||||||
vvp_cmd.append(r'out.vvp')
|
|
||||||
process = subprocess.Popen(vvp_cmd, stdout=logfile, stderr=logfile)
|
|
||||||
process.wait(timeout=5)
|
|
||||||
logfile.close()
|
|
||||||
|
|
||||||
# 4.比较结果
|
|
||||||
ref_file = get_reference_file(sys.argv[1])
|
|
||||||
if (ref_file != None):
|
|
||||||
# 如果文件大小不一致,直接报fail
|
|
||||||
if (os.path.getsize('signature.output') != os.path.getsize(ref_file)):
|
|
||||||
print('!!! FAIL, size != !!!')
|
|
||||||
return
|
|
||||||
f1 = open('signature.output')
|
|
||||||
f2 = open(ref_file)
|
|
||||||
f1_lines = f1.readlines()
|
|
||||||
i = 0
|
|
||||||
# 逐行比较
|
|
||||||
for line in f2.readlines():
|
|
||||||
# 只要有一行内容不一样就报fail
|
|
||||||
if (f1_lines[i] != line):
|
|
||||||
print('!!! FAIL, content != !!!')
|
|
||||||
f1.close()
|
|
||||||
f2.close()
|
|
||||||
return
|
|
||||||
i = i + 1
|
|
||||||
f1.close()
|
|
||||||
f2.close()
|
|
||||||
print('### PASS ###')
|
|
||||||
else:
|
|
||||||
print('No ref file found, please check result by yourself.')
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
sys.exit(main())
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
*.o
|
||||||
|
*.d
|
||||||
|
*.so
|
|
@ -0,0 +1,124 @@
|
||||||
|
# Copyright (C) 2020 ETH Zurich and University of Bologna
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Author: Robert Balas (balasr@iis.ee.ethz.ch)
|
||||||
|
|
||||||
|
CFLAGS = -Wall -Wextra -Wno-missing-field-initializers \
|
||||||
|
-Wno-unused-function -Wno-missing-braces \
|
||||||
|
-O2 -g -march=native \
|
||||||
|
-DENABLE_LOGGING -DNDEBUG
|
||||||
|
CFLAGS_DBG =
|
||||||
|
# we need gnu11 and no-strict-aliasing
|
||||||
|
ALL_CFLAGS = -std=gnu11 -fno-strict-aliasing $(CFLAGS)
|
||||||
|
ALL_CFLAGS_DBG = -std=gnu11 -Wall -Wextra -Wno-missing-field-initializers \
|
||||||
|
-Wno-unused-function -Wno-missing-braces \
|
||||||
|
-O0 -g -fno-strict-aliasing \
|
||||||
|
-fsanitize=address -fno-omit-frame-pointer \
|
||||||
|
-DENABLE_LOGGING -DENABLE_DEBUG $(CFLAGS_DBG)\
|
||||||
|
# -fsanitize=undefined \
|
||||||
|
# -fsanitize=leak \
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: better path?
|
||||||
|
LIB_DIRS =
|
||||||
|
LIBS =
|
||||||
|
INCLUDE_DIRS = ./
|
||||||
|
|
||||||
|
|
||||||
|
LDFLAGS = $(addprefix -L, $(LIB_DIRS))
|
||||||
|
LDLIBS = $(addprefix -l, $(LIBS))
|
||||||
|
|
||||||
|
SRCS = remote_bitbang.c sim_jtag.c
|
||||||
|
OBJS = $(SRCS:.c=.o)
|
||||||
|
INCLUDES = $(addprefix -I, $(INCLUDE_DIRS))
|
||||||
|
|
||||||
|
HEADERS = $(wildcard *.h)
|
||||||
|
|
||||||
|
# libs
|
||||||
|
SV_LIB = librbs.so
|
||||||
|
|
||||||
|
# header file dependency generation
|
||||||
|
DEPDIR := .d
|
||||||
|
DEPDIRS := $(addsuffix /$(DEPDIR),.)
|
||||||
|
# goal: make gcc put a dependency file called obj.Td (derived from subdir/obj.o)
|
||||||
|
# in subdir/.d/
|
||||||
|
DEPFLAGS = -MT $@ -MMD -MP -MF $(@D)/$(DEPDIR)/$(patsubst %.o,%.Td,$(@F))
|
||||||
|
# move gcc generated header dependencies to DEPDIR
|
||||||
|
# this rename step is here to make the header dependency generation "atomic"
|
||||||
|
POSTCOMPILE = @mv -f $(@D)/$(DEPDIR)/$(patsubst %.o,%.Td,$(@F)) \
|
||||||
|
$(@D)/$(DEPDIR)/$(patsubst %.o,%.d,$(@F)) && touch $@
|
||||||
|
|
||||||
|
# GNU recommendations for install targets
|
||||||
|
prefix = /usr/local
|
||||||
|
exec_prefix = $(prefix)
|
||||||
|
bindir = $(exec_prefix)/bin
|
||||||
|
libdir = $(exec_prefix)/lib
|
||||||
|
includedir = $(prefix)/include
|
||||||
|
|
||||||
|
INSTALL = install
|
||||||
|
INSTALL_PROGRAM = $(INSTALL)
|
||||||
|
INSTALL_DATA = ${INSTALL} -m 644
|
||||||
|
|
||||||
|
CTAGS = ctags
|
||||||
|
|
||||||
|
# compilation targets
|
||||||
|
all: sv-lib
|
||||||
|
|
||||||
|
debug: ALL_CFLAGS = $(ALL_CFLAGS_DBG)
|
||||||
|
debug: all
|
||||||
|
|
||||||
|
sv-lib: ALL_CFLAGS += -fPIC
|
||||||
|
sv-lib: $(SV_LIB)
|
||||||
|
|
||||||
|
#compilation boilerplate
|
||||||
|
$(SV_LIB): $(OBJS)
|
||||||
|
$(LD) -shared -E --exclude-libs ALL -o $(SV_LIB) $(LDFLAGS) \
|
||||||
|
$(OBJS) $(LDLIBS)
|
||||||
|
|
||||||
|
# $@ = name of target
|
||||||
|
# $< = first dependency
|
||||||
|
%.o: %.c
|
||||||
|
%.o: %.c $(DEPDIR)/%.d $(DEPDIRS)
|
||||||
|
$(CC) $(DEPFLAGS) $(ALL_CFLAGS) $(INCLUDES) $(LDFLAGS) \
|
||||||
|
-c $(CPPFLAGS) $< -o $@ $(LDLIBS)
|
||||||
|
$(POSTCOMPILE)
|
||||||
|
|
||||||
|
# check if we need to create the dependencies folders (gcc doesn't)
|
||||||
|
$(DEPDIRS):
|
||||||
|
$(shell mkdir -p $(DEPDIRS) > /dev/null)
|
||||||
|
# make won't fail if the dependency file doesn't exist
|
||||||
|
$(addsuffix /$(DEPDIR)/%.d,. main benchmark test dpi): ;
|
||||||
|
|
||||||
|
# prevent automatic deletion as intermediate file
|
||||||
|
.PRECIOUS: $(addsuffix /$(DEPDIR)/%.d,. main benchmark test dpi)
|
||||||
|
|
||||||
|
# emacs tag generation
|
||||||
|
.PHONY: TAGS
|
||||||
|
TAGS:
|
||||||
|
$(CTAGS) -R -e -h=".c.h" --tag-relative=always \
|
||||||
|
. $(LIB_DIRS) $(INCLUDE_DIRS) $(BINUTILS_PATH)/bfd
|
||||||
|
|
||||||
|
# TODO: missing install targets
|
||||||
|
# cleanup
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -rf $(SV_LIB) $(OBJS) $(DEPDIRS)
|
||||||
|
|
||||||
|
.PHONY: distclean
|
||||||
|
distclean: clean
|
||||||
|
rm -f TAGS
|
||||||
|
|
||||||
|
# include auto generated header dependency information
|
||||||
|
include $(wildcard $(addsuffix /*.d,$(DEPDIRS)))
|
|
@ -0,0 +1,34 @@
|
||||||
|
/* Copyright (C) 2020 ETH Zurich and University of Bologna
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Author: Robert Balas (balasr@iis.ee.ethz.ch)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "remote_bitbang.h"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
unsigned char jtag_TCK, jtag_TMS, jtag_TDI, jtag_TRSTn;
|
||||||
|
unsigned char jtag_TDO = 0;
|
||||||
|
|
||||||
|
printf("calling rbs_init\n");
|
||||||
|
int v = rbs_init(0);
|
||||||
|
|
||||||
|
printf("tick 1\n");
|
||||||
|
rbs_tick(&jtag_TCK, &jtag_TMS, &jtag_TDI, &jtag_TRSTn, jtag_TDO);
|
||||||
|
printf("jtag exit is %d\n", rbs_done());
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,275 @@
|
||||||
|
// See LICENSE.Berkeley for license details.
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "remote_bitbang.h"
|
||||||
|
|
||||||
|
int rbs_init(uint16_t port)
|
||||||
|
{
|
||||||
|
socket_fd = 0;
|
||||||
|
client_fd = 0;
|
||||||
|
recv_start = 0;
|
||||||
|
recv_end = 0;
|
||||||
|
rbs_err = 0;
|
||||||
|
|
||||||
|
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (socket_fd == -1) {
|
||||||
|
fprintf(stderr, "remote_bitbang failed to make socket: %s (%d)\n",
|
||||||
|
strerror(errno), errno);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
fcntl(socket_fd, F_SETFL, O_NONBLOCK);
|
||||||
|
int reuseaddr = 1;
|
||||||
|
if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr,
|
||||||
|
sizeof(int)) == -1) {
|
||||||
|
fprintf(stderr, "remote_bitbang failed setsockopt: %s (%d)\n",
|
||||||
|
strerror(errno), errno);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
addr.sin_port = htons(port);
|
||||||
|
|
||||||
|
if (bind(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
|
||||||
|
fprintf(stderr, "remote_bitbang failed to bind socket: %s (%d)\n",
|
||||||
|
strerror(errno), errno);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listen(socket_fd, 1) == -1) {
|
||||||
|
fprintf(stderr, "remote_bitbang failed to listen on socket: %s (%d)\n",
|
||||||
|
strerror(errno), errno);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
socklen_t addrlen = sizeof(addr);
|
||||||
|
if (getsockname(socket_fd, (struct sockaddr *)&addr, &addrlen) == -1) {
|
||||||
|
fprintf(stderr, "remote_bitbang getsockname failed: %s (%d)\n",
|
||||||
|
strerror(errno), errno);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
tck = 1;
|
||||||
|
tms = 1;
|
||||||
|
tdi = 1;
|
||||||
|
trstn = 1;
|
||||||
|
quit = 0;
|
||||||
|
|
||||||
|
fprintf(stderr, "JTAG remote bitbang server is ready\n");
|
||||||
|
fprintf(stderr, "Listening on port %d\n", ntohs(addr.sin_port));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rbs_accept()
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Attempting to accept client socket\n");
|
||||||
|
int again = 1;
|
||||||
|
while (again != 0) {
|
||||||
|
client_fd = accept(socket_fd, NULL, NULL);
|
||||||
|
if (client_fd == -1) {
|
||||||
|
if (errno == EAGAIN) {
|
||||||
|
// No client waiting to connect right now.
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "failed to accept on socket: %s (%d)\n",
|
||||||
|
strerror(errno), errno);
|
||||||
|
again = 0;
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fcntl(client_fd, F_SETFL, O_NONBLOCK);
|
||||||
|
fprintf(stderr, "Accepted successfully.");
|
||||||
|
again = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void rbs_tick(unsigned char *jtag_tck, unsigned char *jtag_tms,
|
||||||
|
unsigned char *jtag_tdi, unsigned char *jtag_trstn,
|
||||||
|
unsigned char jtag_tdo)
|
||||||
|
{
|
||||||
|
if (client_fd > 0) {
|
||||||
|
tdo = jtag_tdo;
|
||||||
|
rbs_execute_command();
|
||||||
|
} else {
|
||||||
|
rbs_accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
*jtag_tck = tck;
|
||||||
|
*jtag_tms = tms;
|
||||||
|
*jtag_tdi = tdi;
|
||||||
|
*jtag_trstn = trstn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rbs_reset()
|
||||||
|
{
|
||||||
|
// trstn = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rbs_set_pins(char _tck, char _tms, char _tdi)
|
||||||
|
{
|
||||||
|
tck = _tck;
|
||||||
|
tms = _tms;
|
||||||
|
tdi = _tdi;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rbs_execute_command()
|
||||||
|
{
|
||||||
|
char command;
|
||||||
|
int again = 1;
|
||||||
|
while (again) {
|
||||||
|
ssize_t num_read = read(client_fd, &command, sizeof(command));
|
||||||
|
if (num_read == -1) {
|
||||||
|
if (errno == EAGAIN) {
|
||||||
|
// We'll try again the next call.
|
||||||
|
if (VERBOSE)
|
||||||
|
fprintf(
|
||||||
|
stderr,
|
||||||
|
"Received no command. Will try again on the next call\n");
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,
|
||||||
|
"remote_bitbang failed to read on socket: %s (%d)\n",
|
||||||
|
strerror(errno), errno);
|
||||||
|
again = 0;
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
} else if (num_read == 0) {
|
||||||
|
fprintf(stderr, "No command received. Stopping further reads.\n");
|
||||||
|
// again = 1;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
again = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int dosend = 0;
|
||||||
|
|
||||||
|
char tosend = '?';
|
||||||
|
|
||||||
|
switch (command) {
|
||||||
|
case 'B':
|
||||||
|
if (VERBOSE)
|
||||||
|
fprintf(stderr, "*BLINK*\n");
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
if (VERBOSE)
|
||||||
|
fprintf(stderr, "blink off\n");
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
if (VERBOSE)
|
||||||
|
fprintf(stderr, "r-reset\n");
|
||||||
|
rbs_reset();
|
||||||
|
break; // This is wrong. 'r' has other bits that indicated TRST and
|
||||||
|
// SRST.
|
||||||
|
case 's':
|
||||||
|
if (VERBOSE)
|
||||||
|
fprintf(stderr, "s-reset\n");
|
||||||
|
rbs_reset();
|
||||||
|
break; // This is wrong.
|
||||||
|
case 't':
|
||||||
|
if (VERBOSE)
|
||||||
|
fprintf(stderr, "t-reset\n");
|
||||||
|
rbs_reset();
|
||||||
|
break; // This is wrong.
|
||||||
|
case 'u':
|
||||||
|
if (VERBOSE)
|
||||||
|
fprintf(stderr, "u-reset\n");
|
||||||
|
rbs_reset();
|
||||||
|
break; // This is wrong.
|
||||||
|
case '0':
|
||||||
|
if (VERBOSE)
|
||||||
|
fprintf(stderr, "Write 0 0 0\n");
|
||||||
|
rbs_set_pins(0, 0, 0);
|
||||||
|
break;
|
||||||
|
case '1':
|
||||||
|
if (VERBOSE)
|
||||||
|
fprintf(stderr, "Write 0 0 1\n");
|
||||||
|
rbs_set_pins(0, 0, 1);
|
||||||
|
break;
|
||||||
|
case '2':
|
||||||
|
if (VERBOSE)
|
||||||
|
fprintf(stderr, "Write 0 1 0\n");
|
||||||
|
rbs_set_pins(0, 1, 0);
|
||||||
|
break;
|
||||||
|
case '3':
|
||||||
|
if (VERBOSE)
|
||||||
|
fprintf(stderr, "Write 0 1 1\n");
|
||||||
|
rbs_set_pins(0, 1, 1);
|
||||||
|
break;
|
||||||
|
case '4':
|
||||||
|
if (VERBOSE)
|
||||||
|
fprintf(stderr, "Write 1 0 0\n");
|
||||||
|
rbs_set_pins(1, 0, 0);
|
||||||
|
break;
|
||||||
|
case '5':
|
||||||
|
if (VERBOSE)
|
||||||
|
fprintf(stderr, "Write 1 0 1\n");
|
||||||
|
rbs_set_pins(1, 0, 1);
|
||||||
|
break;
|
||||||
|
case '6':
|
||||||
|
if (VERBOSE)
|
||||||
|
fprintf(stderr, "Write 1 1 0\n");
|
||||||
|
rbs_set_pins(1, 1, 0);
|
||||||
|
break;
|
||||||
|
case '7':
|
||||||
|
if (VERBOSE)
|
||||||
|
fprintf(stderr, "Write 1 1 1\n");
|
||||||
|
rbs_set_pins(1, 1, 1);
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
if (VERBOSE)
|
||||||
|
fprintf(stderr, "Read req\n");
|
||||||
|
dosend = 1;
|
||||||
|
tosend = tdo ? '1' : '0';
|
||||||
|
break;
|
||||||
|
case 'Q':
|
||||||
|
if (VERBOSE)
|
||||||
|
fprintf(stderr, "Quit req\n");
|
||||||
|
quit = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "remote_bitbang got unsupported command '%c'\n",
|
||||||
|
command);
|
||||||
|
}
|
||||||
|
if (dosend) {
|
||||||
|
while (1) {
|
||||||
|
ssize_t bytes = write(client_fd, &tosend, sizeof(tosend));
|
||||||
|
if (bytes == -1) {
|
||||||
|
fprintf(stderr, "failed to write to socket: %s (%d)\n",
|
||||||
|
strerror(errno), errno);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
if (bytes > 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (quit) {
|
||||||
|
fprintf(stderr, "Remote end disconnected\n");
|
||||||
|
close(client_fd);
|
||||||
|
client_fd = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char rbs_done()
|
||||||
|
{
|
||||||
|
return quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rbs_exit_code()
|
||||||
|
{
|
||||||
|
return rbs_err;
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
// See LICENSE.Berkeley for license details.
|
||||||
|
|
||||||
|
#ifndef REMOTE_BITBANG_H
|
||||||
|
#define REMOTE_BITBANG_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#define VERBOSE 0
|
||||||
|
|
||||||
|
int rbs_err;
|
||||||
|
|
||||||
|
unsigned char tck;
|
||||||
|
unsigned char tms;
|
||||||
|
unsigned char tdi;
|
||||||
|
unsigned char trstn;
|
||||||
|
unsigned char tdo;
|
||||||
|
unsigned char quit;
|
||||||
|
|
||||||
|
int socket_fd;
|
||||||
|
int client_fd;
|
||||||
|
|
||||||
|
static const ssize_t buf_size = 64 * 1024;
|
||||||
|
char recv_buf[64 * 1024];
|
||||||
|
ssize_t recv_start, recv_end;
|
||||||
|
|
||||||
|
// Create a new server, listening for connections from localhost on the given
|
||||||
|
// port.
|
||||||
|
int rbs_init(uint16_t port);
|
||||||
|
|
||||||
|
// Do a bit of work.
|
||||||
|
void rbs_tick(unsigned char *jtag_tck, unsigned char *jtag_tms,
|
||||||
|
unsigned char *jtag_tdi, unsigned char *jtag_trstn,
|
||||||
|
unsigned char jtag_tdo);
|
||||||
|
|
||||||
|
unsigned char rbs_done();
|
||||||
|
|
||||||
|
int rbs_exit_code();
|
||||||
|
|
||||||
|
// Check for a client connecting, and accept if there is one.
|
||||||
|
void rbs_accept();
|
||||||
|
// Execute any commands the client has for us.
|
||||||
|
// But we only execute 1 because we need time for the
|
||||||
|
// simulation to run.
|
||||||
|
void rbs_execute_command();
|
||||||
|
|
||||||
|
// Reset. Currently does nothing.
|
||||||
|
void rbs_reset();
|
||||||
|
|
||||||
|
void rbs_set_pins(char _tck, char _tms, char _tdi);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,29 @@
|
||||||
|
// See LICENSE.SiFive for license details.
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "remote_bitbang.h"
|
||||||
|
|
||||||
|
int init = 0;
|
||||||
|
|
||||||
|
int jtag_tick(int port, unsigned char *jtag_TCK, unsigned char *jtag_TMS,
|
||||||
|
unsigned char *jtag_TDI, unsigned char *jtag_TRSTn,
|
||||||
|
unsigned char jtag_TDO)
|
||||||
|
|
||||||
|
{
|
||||||
|
if (!init) {
|
||||||
|
if (port < 0 || port > UINT16_MAX)
|
||||||
|
fprintf(stderr, "Port number of out range: %d\n", port);
|
||||||
|
init = rbs_init(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
rbs_tick(jtag_TCK, jtag_TMS, jtag_TDI, jtag_TRSTn, jtag_TDO);
|
||||||
|
if (VERBOSE)
|
||||||
|
fprintf(
|
||||||
|
stderr,
|
||||||
|
"Tick with: TCK=%hhd TMS=%hhd TDI=%hhd TRSTn=%hhd --> TDO=%hhd\n",
|
||||||
|
*jtag_TCK, *jtag_TMS, *jtag_TDI, *jtag_TRSTn, jtag_TDO);
|
||||||
|
|
||||||
|
return rbs_done() ? (rbs_exit_code() << 1 | 1) : 0;
|
||||||
|
}
|
|
@ -1,28 +0,0 @@
|
||||||
import sys
|
|
||||||
import filecmp
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
|
|
||||||
# 主函数
|
|
||||||
def main():
|
|
||||||
#print(sys.argv[0] + ' ' + sys.argv[1] + ' ' + sys.argv[2])
|
|
||||||
|
|
||||||
# 1.编译rtl文件
|
|
||||||
cmd = r'python compile_rtl.py' + r' ..'
|
|
||||||
f = os.popen(cmd)
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
# 2.运行
|
|
||||||
vvp_cmd = [r'vvp']
|
|
||||||
vvp_cmd.append(r'out.vvp')
|
|
||||||
process = subprocess.Popen(vvp_cmd)
|
|
||||||
try:
|
|
||||||
process.wait(timeout=10)
|
|
||||||
except subprocess.TimeoutExpired:
|
|
||||||
print('!!!Fail, vvp exec timeout!!!')
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
sys.exit(main())
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
// See LICENSE.SiFive for license details.
|
||||||
|
//VCS coverage exclude_file
|
||||||
|
import "DPI-C" function int jtag_tick
|
||||||
|
(
|
||||||
|
input int port,
|
||||||
|
output bit jtag_TCK,
|
||||||
|
output bit jtag_TMS,
|
||||||
|
output bit jtag_TDI,
|
||||||
|
output bit jtag_TRSTn,
|
||||||
|
|
||||||
|
input bit jtag_TDO
|
||||||
|
);
|
||||||
|
|
||||||
|
module sim_jtag #(
|
||||||
|
parameter TICK_DELAY = 50,
|
||||||
|
parameter PORT = 0
|
||||||
|
)(
|
||||||
|
|
||||||
|
input clock,
|
||||||
|
input reset,
|
||||||
|
|
||||||
|
input enable,
|
||||||
|
input init_done,
|
||||||
|
|
||||||
|
output jtag_TCK,
|
||||||
|
output jtag_TMS,
|
||||||
|
output jtag_TDI,
|
||||||
|
output jtag_TRSTn,
|
||||||
|
|
||||||
|
input jtag_TDO_data,
|
||||||
|
input jtag_TDO_driven,
|
||||||
|
|
||||||
|
output [31:0] exit
|
||||||
|
);
|
||||||
|
|
||||||
|
reg [31:0] tickCounterReg;
|
||||||
|
wire [31:0] tickCounterNxt;
|
||||||
|
|
||||||
|
assign tickCounterNxt = (tickCounterReg == 0) ? TICK_DELAY : (tickCounterReg - 1);
|
||||||
|
|
||||||
|
bit r_reset;
|
||||||
|
|
||||||
|
wire [31:0] random_bits = $random;
|
||||||
|
|
||||||
|
wire #0.1 __jtag_TDO = jtag_TDO_driven ?
|
||||||
|
jtag_TDO_data : random_bits[0];
|
||||||
|
|
||||||
|
bit __jtag_TCK;
|
||||||
|
bit __jtag_TMS;
|
||||||
|
bit __jtag_TDI;
|
||||||
|
bit __jtag_TRSTn;
|
||||||
|
int __exit;
|
||||||
|
|
||||||
|
reg init_done_sticky;
|
||||||
|
|
||||||
|
assign #0.1 jtag_TCK = __jtag_TCK;
|
||||||
|
assign #0.1 jtag_TMS = __jtag_TMS;
|
||||||
|
assign #0.1 jtag_TDI = __jtag_TDI;
|
||||||
|
assign #0.1 jtag_TRSTn = __jtag_TRSTn;
|
||||||
|
|
||||||
|
assign #0.1 exit = __exit;
|
||||||
|
|
||||||
|
always @(posedge clock) begin
|
||||||
|
r_reset <= reset;
|
||||||
|
if (reset || r_reset) begin
|
||||||
|
__exit = 0;
|
||||||
|
tickCounterReg <= TICK_DELAY;
|
||||||
|
init_done_sticky <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
init_done_sticky <= init_done | init_done_sticky;
|
||||||
|
if (enable && init_done_sticky) begin
|
||||||
|
tickCounterReg <= tickCounterNxt;
|
||||||
|
if (tickCounterReg == 0) begin
|
||||||
|
__exit = jtag_tick(PORT,
|
||||||
|
__jtag_TCK,
|
||||||
|
__jtag_TMS,
|
||||||
|
__jtag_TDI,
|
||||||
|
__jtag_TRSTn,
|
||||||
|
__jtag_TDO);
|
||||||
|
end
|
||||||
|
end // if (enable && init_done_sticky)
|
||||||
|
end // else: !if(reset || r_reset)
|
||||||
|
end // always @ (posedge clock)
|
||||||
|
|
||||||
|
endmodule
|
|
@ -1,33 +0,0 @@
|
||||||
import sys
|
|
||||||
import filecmp
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
|
|
||||||
# 主函数
|
|
||||||
def main():
|
|
||||||
#print(sys.argv[0] + ' ' + sys.argv[1] + ' ' + sys.argv[2])
|
|
||||||
|
|
||||||
# 1.将bin文件转成mem文件
|
|
||||||
cmd = r'python ../tools/BinToMem_CLI.py' + ' ' + sys.argv[1] + ' ' + sys.argv[2]
|
|
||||||
f = os.popen(cmd)
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
# 2.编译rtl文件
|
|
||||||
cmd = r'python compile_rtl.py' + r' ..'
|
|
||||||
f = os.popen(cmd)
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
# 3.运行
|
|
||||||
vvp_cmd = [r'vvp']
|
|
||||||
vvp_cmd.append(r'out.vvp')
|
|
||||||
process = subprocess.Popen(vvp_cmd)
|
|
||||||
try:
|
|
||||||
process.wait(timeout=20)
|
|
||||||
except subprocess.TimeoutExpired:
|
|
||||||
print('!!!Fail, vvp exec timeout!!!')
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
sys.exit(main())
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
// Copyright 2018 Robert Balas <balasr@student.ethz.ch>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
|
||||||
|
// Top level wrapper for a verilator RI5CY testbench
|
||||||
|
// Contributor: Robert Balas <balasr@student.ethz.ch>
|
||||||
|
|
||||||
|
#include "svdpi.h"
|
||||||
|
#include "Vtb_top_verilator__Dpi.h"
|
||||||
|
#include "Vtb_top_verilator.h"
|
||||||
|
#include "verilated_vcd_c.h"
|
||||||
|
#include "verilated.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <fstream>
|
||||||
|
#include <exception>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cerrno>
|
||||||
|
|
||||||
|
//void dump_memory();
|
||||||
|
double sc_time_stamp();
|
||||||
|
|
||||||
|
static vluint64_t t = 0;
|
||||||
|
Vtb_top_verilator *top;
|
||||||
|
|
||||||
|
int main(int argc, char **argv, char **env)
|
||||||
|
{
|
||||||
|
Verilated::commandArgs(argc, argv);
|
||||||
|
Verilated::traceEverOn(true);
|
||||||
|
top = new Vtb_top_verilator();
|
||||||
|
|
||||||
|
//svSetScope(svGetScopeFromName(
|
||||||
|
// "TOP.tb_top_verilator.u_ram.ram"));
|
||||||
|
//Verilated::scopesDump();
|
||||||
|
|
||||||
|
#ifdef VCD_TRACE
|
||||||
|
VerilatedVcdC *tfp = new VerilatedVcdC;
|
||||||
|
top->trace(tfp, 99);
|
||||||
|
tfp->open("verilator_tb.vcd");
|
||||||
|
#endif
|
||||||
|
top->fetch_enable_i = 1;
|
||||||
|
top->clk_i = 0;
|
||||||
|
top->rst_ni = 0;
|
||||||
|
|
||||||
|
top->eval();
|
||||||
|
//dump_memory();
|
||||||
|
|
||||||
|
while (!Verilated::gotFinish()) {
|
||||||
|
if (t > 40)
|
||||||
|
top->rst_ni = 1;
|
||||||
|
top->clk_i = !top->clk_i;
|
||||||
|
top->eval();
|
||||||
|
#ifdef VCD_TRACE
|
||||||
|
tfp->dump(t);
|
||||||
|
#endif
|
||||||
|
t += 5;
|
||||||
|
if (t > 1000)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#ifdef VCD_TRACE
|
||||||
|
tfp->close();
|
||||||
|
#endif
|
||||||
|
delete top;
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
double sc_time_stamp()
|
||||||
|
{
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
void dump_memory()
|
||||||
|
{
|
||||||
|
errno = 0;
|
||||||
|
std::ofstream mem_file;
|
||||||
|
svLogicVecVal addr = {0};
|
||||||
|
|
||||||
|
mem_file.exceptions(std::ofstream::failbit | std::ofstream::badbit);
|
||||||
|
try {
|
||||||
|
mem_file.open("memory_dump.bin");
|
||||||
|
for (size_t i = 0; i < 1048576; i++) {
|
||||||
|
addr.aval = i;
|
||||||
|
uint32_t val = read_byte(&addr);
|
||||||
|
mem_file << std::setfill('0') << std::setw(2) << std::hex << val
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
mem_file.close();
|
||||||
|
|
||||||
|
std::cout << "finished dumping memory" << std::endl;
|
||||||
|
|
||||||
|
} catch (std::ofstream::failure e) {
|
||||||
|
std::cerr << "exception opening/reading/closing file memory_dump.bin\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
|
@ -0,0 +1,48 @@
|
||||||
|
// Copyright 2018 Robert Balas <balasr@student.ethz.ch>
|
||||||
|
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||||
|
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||||
|
// compliance with the License. You may obtain a copy of the License at
|
||||||
|
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||||
|
// or agreed to in writing, software, hardware and materials distributed under
|
||||||
|
// this 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.
|
||||||
|
|
||||||
|
// Top level wrapper for a verilator RI5CY testbench
|
||||||
|
// Contributor: Robert Balas <balasr@student.ethz.ch>
|
||||||
|
|
||||||
|
|
||||||
|
module tb_top_verilator #(
|
||||||
|
|
||||||
|
) (
|
||||||
|
input clk_i,
|
||||||
|
input rst_ni,
|
||||||
|
input fetch_enable_i
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
initial begin: load_prog
|
||||||
|
automatic logic [1023:0] firmware;
|
||||||
|
|
||||||
|
if($value$plusargs("firmware=%s", firmware)) begin
|
||||||
|
//if($test$plusargs("verbose"))
|
||||||
|
$display("[TESTBENCH] %t: loading firmware %0s ...",
|
||||||
|
$time, firmware);
|
||||||
|
$readmemh (firmware, u_tinyriscv_soc_top.u_rom.u_gen_ram.ram);
|
||||||
|
//$display("mem[0x80]=0x%x", u_ram.ram.mem[32]);
|
||||||
|
//$display("mem[0x84]=0x%x", u_ram.ram.mem[33]);
|
||||||
|
end else begin
|
||||||
|
$display("No firmware specified");
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
tinyriscv_soc_top u_tinyriscv_soc_top(
|
||||||
|
.clk(clk_i),
|
||||||
|
.rst_ext_i(rst_ni)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule // tb_top_verilator
|
|
@ -1,43 +0,0 @@
|
||||||
import os
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
# 找出path目录下的所有bin文件
|
|
||||||
def list_binfiles(path):
|
|
||||||
files = []
|
|
||||||
list_dir = os.walk(path)
|
|
||||||
for maindir, subdir, all_file in list_dir:
|
|
||||||
for filename in all_file:
|
|
||||||
apath = os.path.join(maindir, filename)
|
|
||||||
if apath.endswith('.bin'):
|
|
||||||
files.append(apath)
|
|
||||||
|
|
||||||
return files
|
|
||||||
|
|
||||||
# 主函数
|
|
||||||
def main():
|
|
||||||
bin_files = list_binfiles(r'../tests/isa/generated')
|
|
||||||
|
|
||||||
anyfail = False
|
|
||||||
|
|
||||||
# 对每一个bin文件进行测试
|
|
||||||
for file in bin_files:
|
|
||||||
#print(file)
|
|
||||||
cmd = r'python sim_new_nowave.py' + ' ' + file + ' ' + 'inst.data'
|
|
||||||
f = os.popen(cmd)
|
|
||||||
r = f.read()
|
|
||||||
f.close()
|
|
||||||
if (r.find('TEST_PASS') != -1):
|
|
||||||
print(file + ' PASS')
|
|
||||||
else:
|
|
||||||
print(file + ' !!!FAIL!!!')
|
|
||||||
anyfail = True
|
|
||||||
break
|
|
||||||
|
|
||||||
if (anyfail == False):
|
|
||||||
print('Congratulation, All PASS...')
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
sys.exit(main())
|
|
|
@ -1,72 +0,0 @@
|
||||||
import sys
|
|
||||||
import filecmp
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
|
|
||||||
# 主函数
|
|
||||||
def main():
|
|
||||||
rtl_dir = '..'
|
|
||||||
|
|
||||||
tb_file = r'/tb/jtag_tb.v'
|
|
||||||
|
|
||||||
# iverilog程序
|
|
||||||
iverilog_cmd = ['iverilog']
|
|
||||||
# 顶层模块
|
|
||||||
#iverilog_cmd += ['-s', r'tinyriscv_soc_tb']
|
|
||||||
# 编译生成文件
|
|
||||||
iverilog_cmd += ['-o', r'out.vvp']
|
|
||||||
# 头文件(defines.v)路径
|
|
||||||
iverilog_cmd += ['-I', rtl_dir + r'/rtl/core']
|
|
||||||
# 宏定义,仿真输出文件
|
|
||||||
iverilog_cmd += ['-D', r'OUTPUT="signature.output"']
|
|
||||||
# testbench文件
|
|
||||||
iverilog_cmd.append(rtl_dir + tb_file)
|
|
||||||
# ../rtl/core
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/clint.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/csr_reg.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/defines.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/divider.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/exu.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/exu_alu_datapath.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/exu_commit.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/exu_dispatch.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/exu_mem.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/exu_muldiv.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/gpr_reg.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/idu.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/idu_exu.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/ifu.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/ifu_idu.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/pipe_ctrl.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/tinyriscv_core.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/core/rst_ctrl.v')
|
|
||||||
# ../rtl/perips
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/perips/ram.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/perips/rom.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/perips/timer.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/perips/uart.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/perips/gpio.v')
|
|
||||||
# ../rtl/debug
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/debug/jtag_dm.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/debug/jtag_driver.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/debug/jtag_top.v')
|
|
||||||
# ../rtl/sys_bus
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/sys_bus/rib.v')
|
|
||||||
# ../rtl/utils
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/utils/full_handshake_rx.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/utils/full_handshake_tx.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/utils/gen_buf.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/utils/gen_dff.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/utils/gen_ram.v')
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/utils/vld_rdy.v')
|
|
||||||
# ../rtl/top
|
|
||||||
iverilog_cmd.append(rtl_dir + r'/rtl/top/tinyriscv_soc_top.v')
|
|
||||||
|
|
||||||
# 编译
|
|
||||||
process = subprocess.Popen(iverilog_cmd)
|
|
||||||
process.wait(timeout=5)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
sys.exit(main())
|
|
|
@ -1,3 +0,0 @@
|
||||||
tinyriscv_soc_tb.v是适用于旧的指令测试testbench文件。
|
|
||||||
|
|
||||||
compliance_test/tinyriscv_soc_tb.v是适用于新的指令测试testbench文件。
|
|
|
@ -1,535 +0,0 @@
|
||||||
`timescale 1 ns / 1 ps
|
|
||||||
|
|
||||||
`include "defines.v"
|
|
||||||
|
|
||||||
// select one option only
|
|
||||||
`define TEST_PROG 1
|
|
||||||
//`define TEST_JTAG 1
|
|
||||||
|
|
||||||
|
|
||||||
// testbench module
|
|
||||||
module tinyriscv_soc_tb;
|
|
||||||
|
|
||||||
reg clk;
|
|
||||||
reg rst_n;
|
|
||||||
|
|
||||||
|
|
||||||
always #10 clk = ~clk; // 50MHz
|
|
||||||
|
|
||||||
wire[31:0] x3 = tinyriscv_soc_top_0.u_tinyriscv_core.u_gpr_reg.regs[3];
|
|
||||||
wire[31:0] x26 = tinyriscv_soc_top_0.u_tinyriscv_core.u_gpr_reg.regs[26];
|
|
||||||
wire[31:0] x27 = tinyriscv_soc_top_0.u_tinyriscv_core.u_gpr_reg.regs[27];
|
|
||||||
|
|
||||||
wire[31:0] ex_end_flag = tinyriscv_soc_top_0.u_ram.u_gen_ram.ram[4];
|
|
||||||
wire[31:0] begin_signature = tinyriscv_soc_top_0.u_ram.u_gen_ram.ram[2];
|
|
||||||
wire[31:0] end_signature = tinyriscv_soc_top_0.u_ram.u_gen_ram.ram[3];
|
|
||||||
|
|
||||||
integer r;
|
|
||||||
integer fd;
|
|
||||||
|
|
||||||
`ifdef TEST_JTAG
|
|
||||||
reg TCK;
|
|
||||||
reg TMS;
|
|
||||||
reg TDI;
|
|
||||||
wire TDO;
|
|
||||||
|
|
||||||
integer i;
|
|
||||||
reg[39:0] shift_reg;
|
|
||||||
reg in;
|
|
||||||
wire[39:0] req_data = tinyriscv_soc_top_0.u_jtag_top.u_jtag_driver.dtm_req_data;
|
|
||||||
wire[4:0] ir_reg = tinyriscv_soc_top_0.u_jtag_top.u_jtag_driver.ir_reg;
|
|
||||||
wire dtm_req_valid = tinyriscv_soc_top_0.u_jtag_top.u_jtag_driver.dtm_req_valid;
|
|
||||||
wire[31:0] dmstatus = tinyriscv_soc_top_0.u_jtag_top.u_jtag_dm.dmstatus;
|
|
||||||
`endif
|
|
||||||
|
|
||||||
initial begin
|
|
||||||
clk = 0;
|
|
||||||
rst_n = 1'b1;
|
|
||||||
`ifdef TEST_JTAG
|
|
||||||
TCK = 1;
|
|
||||||
TMS = 1;
|
|
||||||
TDI = 1;
|
|
||||||
`endif
|
|
||||||
$display("test running...");
|
|
||||||
#100
|
|
||||||
rst_n = 1'b0;
|
|
||||||
#100
|
|
||||||
rst_n = 1'b1;
|
|
||||||
#200
|
|
||||||
/*
|
|
||||||
`ifdef TEST_PROG
|
|
||||||
wait(x26 == 32'b1) // wait sim end, when x26 == 1
|
|
||||||
#100
|
|
||||||
if (x27 == 32'b1) begin
|
|
||||||
$display("~~~~~~~~~~~~~~~~~~~ TEST_PASS ~~~~~~~~~~~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~ ##### ## #### #### ~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~ # # # # # # ~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~ # # # # #### #### ~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~ ##### ###### # #~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~ # # # # # # #~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~ # # # #### #### ~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
|
||||||
end else begin
|
|
||||||
$display("~~~~~~~~~~~~~~~~~~~ TEST_FAIL ~~~~~~~~~~~~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~~###### ## # # ~~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~~# # # # # ~~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~~##### # # # # ~~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~~# ###### # # ~~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~~# # # # # ~~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~~# # # # ######~~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
|
||||||
$display("fail testnum = %2d", x3);
|
|
||||||
for (r = 0; r < 32; r = r + 1)
|
|
||||||
$display("x%2d = 0x%x", r, tinyriscv_soc_top_0.u_tinyriscv_core.u_gpr_reg.regs[r]);
|
|
||||||
end
|
|
||||||
`endif
|
|
||||||
*/
|
|
||||||
|
|
||||||
wait(ex_end_flag == 32'h1); // wait sim end
|
|
||||||
|
|
||||||
fd = $fopen(`OUTPUT); // OUTPUT的值在命令行里定义
|
|
||||||
for (r = begin_signature; r < end_signature; r = r + 4) begin
|
|
||||||
$fdisplay(fd, "%x", tinyriscv_soc_top_0.u_rom.u_gen_ram.ram[r[31:2]]);
|
|
||||||
end
|
|
||||||
$fclose(fd);
|
|
||||||
|
|
||||||
`ifdef TEST_JTAG
|
|
||||||
// reset
|
|
||||||
for (i = 0; i < 8; i++) begin
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
end
|
|
||||||
|
|
||||||
// IR
|
|
||||||
shift_reg = 40'b10001;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SELECT-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SELECT-IR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// CAPTURE-IR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-IR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-IR & EXIT1-IR
|
|
||||||
for (i = 5; i > 0; i--) begin
|
|
||||||
if (shift_reg[0] == 1'b1)
|
|
||||||
TDI = 1'b1;
|
|
||||||
else
|
|
||||||
TDI = 1'b0;
|
|
||||||
|
|
||||||
if (i == 1)
|
|
||||||
TMS = 1;
|
|
||||||
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
in = TDO;
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
shift_reg = {{(35){1'b0}}, in, shift_reg[4:1]};
|
|
||||||
end
|
|
||||||
|
|
||||||
// PAUSE-IR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// EXIT2-IR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// UPDATE-IR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// dmi write
|
|
||||||
shift_reg = {6'h10, {(32){1'b0}}, 2'b10};
|
|
||||||
|
|
||||||
// SELECT-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// CAPTURE-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-DR & EXIT1-DR
|
|
||||||
for (i = 40; i > 0; i--) begin
|
|
||||||
if (shift_reg[0] == 1'b1)
|
|
||||||
TDI = 1'b1;
|
|
||||||
else
|
|
||||||
TDI = 1'b0;
|
|
||||||
|
|
||||||
if (i == 1)
|
|
||||||
TMS = 1;
|
|
||||||
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
in = TDO;
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
shift_reg = {in, shift_reg[39:1]};
|
|
||||||
end
|
|
||||||
|
|
||||||
// PAUSE-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// EXIT2-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// UPDATE-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
$display("ir_reg = 0x%x", ir_reg);
|
|
||||||
$display("dtm_req_valid = %d", dtm_req_valid);
|
|
||||||
$display("req_data = 0x%x", req_data);
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
$display("dmstatus = 0x%x", dmstatus);
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SELECT-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// dmi read
|
|
||||||
shift_reg = {6'h11, {(32){1'b0}}, 2'b01};
|
|
||||||
|
|
||||||
// CAPTURE-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-DR & EXIT1-DR
|
|
||||||
for (i = 40; i > 0; i--) begin
|
|
||||||
if (shift_reg[0] == 1'b1)
|
|
||||||
TDI = 1'b1;
|
|
||||||
else
|
|
||||||
TDI = 1'b0;
|
|
||||||
|
|
||||||
if (i == 1)
|
|
||||||
TMS = 1;
|
|
||||||
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
in = TDO;
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
shift_reg = {in, shift_reg[39:1]};
|
|
||||||
end
|
|
||||||
|
|
||||||
// PAUSE-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// EXIT2-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// UPDATE-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SELECT-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// dmi read
|
|
||||||
shift_reg = {6'h11, {(32){1'b0}}, 2'b00};
|
|
||||||
|
|
||||||
// CAPTURE-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-DR & EXIT1-DR
|
|
||||||
for (i = 40; i > 0; i--) begin
|
|
||||||
if (shift_reg[0] == 1'b1)
|
|
||||||
TDI = 1'b1;
|
|
||||||
else
|
|
||||||
TDI = 1'b0;
|
|
||||||
|
|
||||||
if (i == 1)
|
|
||||||
TMS = 1;
|
|
||||||
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
in = TDO;
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
shift_reg = {in, shift_reg[39:1]};
|
|
||||||
end
|
|
||||||
|
|
||||||
#100
|
|
||||||
|
|
||||||
$display("shift_reg = 0x%x", shift_reg[33:2]);
|
|
||||||
|
|
||||||
if (dmstatus == shift_reg[33:2]) begin
|
|
||||||
$display("######################");
|
|
||||||
$display("### jtag test pass ###");
|
|
||||||
$display("######################");
|
|
||||||
end else begin
|
|
||||||
$display("######################");
|
|
||||||
$display("!!! jtag test fail !!!");
|
|
||||||
$display("######################");
|
|
||||||
end
|
|
||||||
`endif
|
|
||||||
|
|
||||||
$finish;
|
|
||||||
end
|
|
||||||
|
|
||||||
// sim timeout
|
|
||||||
initial begin
|
|
||||||
#500000
|
|
||||||
$display("Time Out.");
|
|
||||||
$finish;
|
|
||||||
end
|
|
||||||
|
|
||||||
// read mem data
|
|
||||||
initial begin
|
|
||||||
$readmemh ("inst.data", tinyriscv_soc_top_0.u_rom.u_gen_ram.ram);
|
|
||||||
end
|
|
||||||
|
|
||||||
// generate wave file, used by gtkwave
|
|
||||||
initial begin
|
|
||||||
$dumpfile("tinyriscv_soc_tb.vcd");
|
|
||||||
$dumpvars(0, tinyriscv_soc_tb);
|
|
||||||
end
|
|
||||||
|
|
||||||
tinyriscv_soc_top tinyriscv_soc_top_0(
|
|
||||||
.clk(clk),
|
|
||||||
.rst_ext_i(rst_n)
|
|
||||||
`ifdef TEST_JTAG
|
|
||||||
,
|
|
||||||
.jtag_TCK(TCK),
|
|
||||||
.jtag_TMS(TMS),
|
|
||||||
.jtag_TDI(TDI),
|
|
||||||
.jtag_TDO(TDO)
|
|
||||||
`endif
|
|
||||||
);
|
|
||||||
|
|
||||||
endmodule
|
|
733
tb/jtag_tb.v
733
tb/jtag_tb.v
|
@ -1,733 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2020 Blue Liang, liangkangnan@163.com
|
|
||||||
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
`timescale 1 ns / 1 ps
|
|
||||||
|
|
||||||
`include "defines.v"
|
|
||||||
|
|
||||||
|
|
||||||
`define JTAG_CLK 500 // 1MHz. This value do not less than 100
|
|
||||||
|
|
||||||
|
|
||||||
module jtag_tb;
|
|
||||||
|
|
||||||
reg clk;
|
|
||||||
reg rst_n;
|
|
||||||
|
|
||||||
reg TCK;
|
|
||||||
reg TMS;
|
|
||||||
reg TDI;
|
|
||||||
wire TDO;
|
|
||||||
|
|
||||||
reg[39:0] shift_reg;
|
|
||||||
reg in;
|
|
||||||
reg[39:0] resp_data;
|
|
||||||
|
|
||||||
|
|
||||||
always #10 clk = ~clk; // core clock = 50MHz
|
|
||||||
|
|
||||||
|
|
||||||
integer i;
|
|
||||||
integer j;
|
|
||||||
|
|
||||||
|
|
||||||
task tap_reset;
|
|
||||||
begin
|
|
||||||
for (i = 0; i < 8; i = i + 1) begin
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
endtask
|
|
||||||
|
|
||||||
task select_ir;
|
|
||||||
input[39:0] ir;
|
|
||||||
|
|
||||||
begin
|
|
||||||
// IR
|
|
||||||
shift_reg = ir;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SELECT-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SELECT-IR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// CAPTURE-IR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-IR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-IR & EXIT1-IR
|
|
||||||
for (i = 5; i > 0; i = i - 1) begin
|
|
||||||
if (shift_reg[0] == 1'b1)
|
|
||||||
TDI = 1'b1;
|
|
||||||
else
|
|
||||||
TDI = 1'b0;
|
|
||||||
|
|
||||||
if (i == 1)
|
|
||||||
TMS = 1;
|
|
||||||
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
in = TDO;
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
shift_reg = {{(35){1'b0}}, in, shift_reg[4:1]};
|
|
||||||
end
|
|
||||||
|
|
||||||
// PAUSE-IR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// EXIT2-IR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// UPDATE-IR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
end
|
|
||||||
endtask
|
|
||||||
|
|
||||||
task dmi_write;
|
|
||||||
input[5:0] addr;
|
|
||||||
input[31:0] data;
|
|
||||||
output[39:0] out;
|
|
||||||
|
|
||||||
begin
|
|
||||||
// op write
|
|
||||||
shift_reg = {addr, data, 2'b10};
|
|
||||||
|
|
||||||
// SELECT-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// CAPTURE-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-DR & EXIT1-DR
|
|
||||||
for (i = 40; i > 0; i = i - 1) begin
|
|
||||||
if (shift_reg[0] == 1'b1)
|
|
||||||
TDI = 1'b1;
|
|
||||||
else
|
|
||||||
TDI = 1'b0;
|
|
||||||
|
|
||||||
if (i == 1)
|
|
||||||
TMS = 1;
|
|
||||||
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
in = TDO;
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
shift_reg = {in, shift_reg[39:1]};
|
|
||||||
end
|
|
||||||
|
|
||||||
// PAUSE-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// EXIT2-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// UPDATE-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// op nop
|
|
||||||
shift_reg = {addr, {(32){1'b0}}, 2'b00};
|
|
||||||
|
|
||||||
// SELECT-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// CAPTURE-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-DR & EXIT1-DR
|
|
||||||
for (i = 40; i > 0; i = i - 1) begin
|
|
||||||
if (shift_reg[0] == 1'b1)
|
|
||||||
TDI = 1'b1;
|
|
||||||
else
|
|
||||||
TDI = 1'b0;
|
|
||||||
|
|
||||||
if (i == 1)
|
|
||||||
TMS = 1;
|
|
||||||
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
in = TDO;
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
shift_reg = {in, shift_reg[39:1]};
|
|
||||||
end
|
|
||||||
|
|
||||||
// PAUSE-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// EXIT2-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// UPDATE-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
out = shift_reg;
|
|
||||||
end
|
|
||||||
endtask
|
|
||||||
|
|
||||||
task dmi_read;
|
|
||||||
input[5:0] addr;
|
|
||||||
output[39:0] out;
|
|
||||||
|
|
||||||
begin
|
|
||||||
// op read
|
|
||||||
shift_reg = {addr, {(32){1'b0}}, 2'b01};
|
|
||||||
|
|
||||||
// SELECT-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// CAPTURE-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-DR & EXIT1-DR
|
|
||||||
for (i = 40; i > 0; i = i - 1) begin
|
|
||||||
if (shift_reg[0] == 1'b1)
|
|
||||||
TDI = 1'b1;
|
|
||||||
else
|
|
||||||
TDI = 1'b0;
|
|
||||||
|
|
||||||
if (i == 1)
|
|
||||||
TMS = 1;
|
|
||||||
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
in = TDO;
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
shift_reg = {in, shift_reg[39:1]};
|
|
||||||
end
|
|
||||||
|
|
||||||
// PAUSE-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// EXIT2-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// UPDATE-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// op nop
|
|
||||||
shift_reg = {addr, {(32){1'b0}}, 2'b00};
|
|
||||||
|
|
||||||
// SELECT-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// CAPTURE-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-DR & EXIT1-DR
|
|
||||||
for (i = 40; i > 0; i = i - 1) begin
|
|
||||||
if (shift_reg[0] == 1'b1)
|
|
||||||
TDI = 1'b1;
|
|
||||||
else
|
|
||||||
TDI = 1'b0;
|
|
||||||
|
|
||||||
if (i == 1)
|
|
||||||
TMS = 1;
|
|
||||||
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
in = TDO;
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
shift_reg = {in, shift_reg[39:1]};
|
|
||||||
end
|
|
||||||
|
|
||||||
// PAUSE-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// EXIT2-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// UPDATE-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 1;
|
|
||||||
#`JTAG_CLK
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
out = shift_reg;
|
|
||||||
end
|
|
||||||
endtask
|
|
||||||
|
|
||||||
|
|
||||||
initial begin
|
|
||||||
clk = 0;
|
|
||||||
rst_n = 1'b1;
|
|
||||||
|
|
||||||
TCK = 1;
|
|
||||||
TMS = 1;
|
|
||||||
TDI = 1;
|
|
||||||
shift_reg = 40'h0;
|
|
||||||
resp_data = 40'h0;
|
|
||||||
in = 1'b0;
|
|
||||||
|
|
||||||
$display("test running...");
|
|
||||||
#100
|
|
||||||
rst_n = 1'b0;
|
|
||||||
#100
|
|
||||||
rst_n = 1'b1;
|
|
||||||
#200
|
|
||||||
|
|
||||||
/*************************** start test ***************************/
|
|
||||||
// reset TAP state machine
|
|
||||||
tap_reset();
|
|
||||||
// select dm regs
|
|
||||||
select_ir(40'b10001);
|
|
||||||
// reset dm module
|
|
||||||
dmi_write(6'h10, 32'h0, resp_data);
|
|
||||||
|
|
||||||
// read dmstatus reg
|
|
||||||
dmi_read(6'h11, resp_data);
|
|
||||||
$display("dmstatus = 0x%x", resp_data[33:2]);
|
|
||||||
|
|
||||||
// write data to memory
|
|
||||||
dmi_write(6'h38, 32'h20050404, resp_data); // write sbcs
|
|
||||||
dmi_write(6'h39, 32'h0, resp_data); // write sbaddress0
|
|
||||||
for (j = 0; j < 5; j = j + 1) begin
|
|
||||||
$display("write: addr = 0x%x, data = 0x%x", j * 4, 32'h0 + j);
|
|
||||||
dmi_write(6'h3c, 32'h0 + j, resp_data); // write sbdata0
|
|
||||||
end
|
|
||||||
|
|
||||||
// read data from memory
|
|
||||||
dmi_write(6'h38, 32'h20158404, resp_data); // write sbcs
|
|
||||||
dmi_write(6'h39, 32'h0, resp_data); // write sbaddress0
|
|
||||||
for (j = 0; j < 5; j = j + 1) begin
|
|
||||||
dmi_read(6'h3c, resp_data); // read sbdata0
|
|
||||||
$display("read: addr = 0x%x, data = 0x%x", j * 4, resp_data[33:2]);
|
|
||||||
end
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
|
||||||
// Check whether the data read is equal to the data written.
|
|
||||||
///////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
$finish;
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
// sim timeout
|
|
||||||
initial begin
|
|
||||||
#10000000
|
|
||||||
$display("Time Out.");
|
|
||||||
$finish;
|
|
||||||
end
|
|
||||||
|
|
||||||
// generate wave file, used by gtkwave
|
|
||||||
initial begin
|
|
||||||
$dumpfile("jtag_tb.vcd");
|
|
||||||
$dumpvars(0, jtag_tb);
|
|
||||||
end
|
|
||||||
|
|
||||||
tinyriscv_soc_top tinyriscv_soc_top_0(
|
|
||||||
.clk(clk),
|
|
||||||
.rst_ext_i(rst_n),
|
|
||||||
.jtag_TCK(TCK),
|
|
||||||
.jtag_TMS(TMS),
|
|
||||||
.jtag_TDI(TDI),
|
|
||||||
.jtag_TDO(TDO)
|
|
||||||
);
|
|
||||||
|
|
||||||
endmodule
|
|
|
@ -1,521 +0,0 @@
|
||||||
`timescale 1 ns / 1 ps
|
|
||||||
|
|
||||||
`include "defines.v"
|
|
||||||
|
|
||||||
// select one option only
|
|
||||||
`define TEST_PROG 1
|
|
||||||
//`define TEST_JTAG 1
|
|
||||||
|
|
||||||
|
|
||||||
// testbench module
|
|
||||||
module tinyriscv_soc_tb;
|
|
||||||
|
|
||||||
reg clk;
|
|
||||||
reg rst_n;
|
|
||||||
|
|
||||||
|
|
||||||
always #10 clk = ~clk; // 50MHz
|
|
||||||
|
|
||||||
wire[31:0] x3 = tinyriscv_soc_top_0.u_tinyriscv_core.u_gpr_reg.regs[3];
|
|
||||||
wire[31:0] x26 = tinyriscv_soc_top_0.u_tinyriscv_core.u_gpr_reg.regs[26];
|
|
||||||
wire[31:0] x27 = tinyriscv_soc_top_0.u_tinyriscv_core.u_gpr_reg.regs[27];
|
|
||||||
|
|
||||||
integer r;
|
|
||||||
|
|
||||||
`ifdef TEST_JTAG
|
|
||||||
reg TCK;
|
|
||||||
reg TMS;
|
|
||||||
reg TDI;
|
|
||||||
wire TDO;
|
|
||||||
|
|
||||||
integer i;
|
|
||||||
reg[39:0] shift_reg;
|
|
||||||
reg in;
|
|
||||||
wire[39:0] req_data = tinyriscv_soc_top_0.u_jtag_top.u_jtag_driver.dtm_req_data;
|
|
||||||
wire[4:0] ir_reg = tinyriscv_soc_top_0.u_jtag_top.u_jtag_driver.ir_reg;
|
|
||||||
wire dtm_req_valid = tinyriscv_soc_top_0.u_jtag_top.u_jtag_driver.dtm_req_valid;
|
|
||||||
wire[31:0] dmstatus = tinyriscv_soc_top_0.u_jtag_top.u_jtag_dm.dmstatus;
|
|
||||||
`endif
|
|
||||||
|
|
||||||
initial begin
|
|
||||||
clk = 0;
|
|
||||||
rst_n = 1'b1;
|
|
||||||
`ifdef TEST_JTAG
|
|
||||||
TCK = 1;
|
|
||||||
TMS = 1;
|
|
||||||
TDI = 1;
|
|
||||||
`endif
|
|
||||||
$display("test running...");
|
|
||||||
#100
|
|
||||||
rst_n = 1'b0;
|
|
||||||
#100
|
|
||||||
rst_n = 1'b1;
|
|
||||||
#200
|
|
||||||
|
|
||||||
`ifdef TEST_PROG
|
|
||||||
wait(x26 == 32'b1) // wait sim end, when x26 == 1
|
|
||||||
#100
|
|
||||||
if (x27 == 32'b1) begin
|
|
||||||
$display("~~~~~~~~~~~~~~~~~~~ TEST_PASS ~~~~~~~~~~~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~ ##### ## #### #### ~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~ # # # # # # ~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~ # # # # #### #### ~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~ ##### ###### # #~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~ # # # # # # #~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~ # # # #### #### ~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
|
||||||
end else begin
|
|
||||||
$display("~~~~~~~~~~~~~~~~~~~ TEST_FAIL ~~~~~~~~~~~~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~~###### ## # # ~~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~~# # # # # ~~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~~##### # # # # ~~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~~# ###### # # ~~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~~# # # # # ~~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~~# # # # ######~~~~~~~~~~");
|
|
||||||
$display("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
|
||||||
$display("fail testnum = %2d", x3);
|
|
||||||
for (r = 0; r < 32; r = r + 1)
|
|
||||||
$display("x%2d = 0x%x", r, tinyriscv_soc_top_0.u_tinyriscv_core.u_gpr_reg.regs[r]);
|
|
||||||
end
|
|
||||||
`endif
|
|
||||||
|
|
||||||
`ifdef TEST_JTAG
|
|
||||||
// reset
|
|
||||||
for (i = 0; i < 8; i++) begin
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
end
|
|
||||||
|
|
||||||
// IR
|
|
||||||
shift_reg = 40'b10001;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SELECT-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SELECT-IR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// CAPTURE-IR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-IR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-IR & EXIT1-IR
|
|
||||||
for (i = 5; i > 0; i--) begin
|
|
||||||
if (shift_reg[0] == 1'b1)
|
|
||||||
TDI = 1'b1;
|
|
||||||
else
|
|
||||||
TDI = 1'b0;
|
|
||||||
|
|
||||||
if (i == 1)
|
|
||||||
TMS = 1;
|
|
||||||
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
in = TDO;
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
shift_reg = {{(35){1'b0}}, in, shift_reg[4:1]};
|
|
||||||
end
|
|
||||||
|
|
||||||
// PAUSE-IR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// EXIT2-IR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// UPDATE-IR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// dmi write
|
|
||||||
shift_reg = {6'h10, {(32){1'b0}}, 2'b10};
|
|
||||||
|
|
||||||
// SELECT-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// CAPTURE-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-DR & EXIT1-DR
|
|
||||||
for (i = 40; i > 0; i--) begin
|
|
||||||
if (shift_reg[0] == 1'b1)
|
|
||||||
TDI = 1'b1;
|
|
||||||
else
|
|
||||||
TDI = 1'b0;
|
|
||||||
|
|
||||||
if (i == 1)
|
|
||||||
TMS = 1;
|
|
||||||
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
in = TDO;
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
shift_reg = {in, shift_reg[39:1]};
|
|
||||||
end
|
|
||||||
|
|
||||||
// PAUSE-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// EXIT2-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// UPDATE-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
$display("ir_reg = 0x%x", ir_reg);
|
|
||||||
$display("dtm_req_valid = %d", dtm_req_valid);
|
|
||||||
$display("req_data = 0x%x", req_data);
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
$display("dmstatus = 0x%x", dmstatus);
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SELECT-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// dmi read
|
|
||||||
shift_reg = {6'h11, {(32){1'b0}}, 2'b01};
|
|
||||||
|
|
||||||
// CAPTURE-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-DR & EXIT1-DR
|
|
||||||
for (i = 40; i > 0; i--) begin
|
|
||||||
if (shift_reg[0] == 1'b1)
|
|
||||||
TDI = 1'b1;
|
|
||||||
else
|
|
||||||
TDI = 1'b0;
|
|
||||||
|
|
||||||
if (i == 1)
|
|
||||||
TMS = 1;
|
|
||||||
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
in = TDO;
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
shift_reg = {in, shift_reg[39:1]};
|
|
||||||
end
|
|
||||||
|
|
||||||
// PAUSE-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// EXIT2-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// UPDATE-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// IDLE
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SELECT-DR
|
|
||||||
TMS = 1;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// dmi read
|
|
||||||
shift_reg = {6'h11, {(32){1'b0}}, 2'b00};
|
|
||||||
|
|
||||||
// CAPTURE-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-DR
|
|
||||||
TMS = 0;
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
// SHIFT-DR & EXIT1-DR
|
|
||||||
for (i = 40; i > 0; i--) begin
|
|
||||||
if (shift_reg[0] == 1'b1)
|
|
||||||
TDI = 1'b1;
|
|
||||||
else
|
|
||||||
TDI = 1'b0;
|
|
||||||
|
|
||||||
if (i == 1)
|
|
||||||
TMS = 1;
|
|
||||||
|
|
||||||
TCK = 0;
|
|
||||||
#100
|
|
||||||
in = TDO;
|
|
||||||
TCK = 1;
|
|
||||||
#100
|
|
||||||
TCK = 0;
|
|
||||||
|
|
||||||
shift_reg = {in, shift_reg[39:1]};
|
|
||||||
end
|
|
||||||
|
|
||||||
#100
|
|
||||||
|
|
||||||
$display("shift_reg = 0x%x", shift_reg[33:2]);
|
|
||||||
|
|
||||||
if (dmstatus == shift_reg[33:2]) begin
|
|
||||||
$display("######################");
|
|
||||||
$display("### jtag test pass ###");
|
|
||||||
$display("######################");
|
|
||||||
end else begin
|
|
||||||
$display("######################");
|
|
||||||
$display("!!! jtag test fail !!!");
|
|
||||||
$display("######################");
|
|
||||||
end
|
|
||||||
`endif
|
|
||||||
|
|
||||||
$finish;
|
|
||||||
end
|
|
||||||
|
|
||||||
// sim timeout
|
|
||||||
initial begin
|
|
||||||
#1000000
|
|
||||||
$display("Time Out.");
|
|
||||||
$finish;
|
|
||||||
end
|
|
||||||
|
|
||||||
// read mem data
|
|
||||||
initial begin
|
|
||||||
$readmemh ("inst.data", tinyriscv_soc_top_0.u_rom.u_gen_ram.ram);
|
|
||||||
end
|
|
||||||
|
|
||||||
// generate wave file, used by gtkwave
|
|
||||||
initial begin
|
|
||||||
$dumpfile("tinyriscv_soc_tb.vcd");
|
|
||||||
$dumpvars(0, tinyriscv_soc_tb);
|
|
||||||
end
|
|
||||||
|
|
||||||
tinyriscv_soc_top tinyriscv_soc_top_0(
|
|
||||||
.clk(clk),
|
|
||||||
.rst_ext_i(rst_n)
|
|
||||||
`ifdef TEST_JTAG
|
|
||||||
,
|
|
||||||
.jtag_TCK(TCK),
|
|
||||||
.jtag_TMS(TMS),
|
|
||||||
.jtag_TDI(TDI),
|
|
||||||
.jtag_TDO(TDO)
|
|
||||||
`endif
|
|
||||||
);
|
|
||||||
|
|
||||||
endmodule
|
|
|
@ -4,6 +4,3 @@
|
||||||
*.obj
|
*.obj
|
||||||
*.bin
|
*.bin
|
||||||
*.dump
|
*.dump
|
||||||
|
|
||||||
__pycache__
|
|
||||||
gnu-mcu-eclipse-riscv-none-gcc-8.2.0-2.2-20190521-0004-win64
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue