From 7a292e0aa25de10caba0cb2af48cdb3169e6f6b3 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sat, 10 Apr 2021 15:01:40 +0100 Subject: [PATCH] add ghdl wishbone basic test --- ls180/post_pnr/cocotb/Makefile | 2 +- ls180/post_pnr/cocotb/run_ghdl_wb.sh | 11 ++ ls180/post_pnr/cocotb/test.py | 154 +++++++++++++++++++++++++-- 3 files changed, 160 insertions(+), 7 deletions(-) create mode 100755 ls180/post_pnr/cocotb/run_ghdl_wb.sh diff --git a/ls180/post_pnr/cocotb/Makefile b/ls180/post_pnr/cocotb/Makefile index 1255036..006c168 100644 --- a/ls180/post_pnr/cocotb/Makefile +++ b/ls180/post_pnr/cocotb/Makefile @@ -15,7 +15,7 @@ VHDL_SOURCES = \ $(wildcard $(VSTDIR)/*.vst) \ $(wildcard $(NSXLIBDIR)/*.vhd) \ $(wildcard $(NIOLIBDIR)/*.vhd) -TOPLEVEL=corona +TOPLEVEL=ls180 TOPLEVEL_LANG=vhdl MODULE=test SIM=ghdl diff --git a/ls180/post_pnr/cocotb/run_ghdl_wb.sh b/ls180/post_pnr/cocotb/run_ghdl_wb.sh new file mode 100755 index 0000000..3d76ec1 --- /dev/null +++ b/ls180/post_pnr/cocotb/run_ghdl_wb.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +# Only run test in reset state as running CPU takes too much time to simulate +make \ + SIM=ghdl \ + COCOTB_RESULTS_FILE=results_iverilog.xml \ + COCOTB_HDL_TIMEUNIT=100ps \ + TESTCASE="wishbone_basic" \ + SIM_BUILD=sim_build_iverilog + + diff --git a/ls180/post_pnr/cocotb/test.py b/ls180/post_pnr/cocotb/test.py index 68057e3..4a86580 100644 --- a/ls180/post_pnr/cocotb/test.py +++ b/ls180/post_pnr/cocotb/test.py @@ -15,21 +15,21 @@ def setup_sim(dut, *, clk_period, run): """Initialize CPU and setup clock""" clk_steps = get_sim_steps(clk_period, "ns") - cocotb.fork(Clock(dut.clk_from_pad, clk_steps).start()) + cocotb.fork(Clock(dut.sys_clk, clk_steps).start()) - dut.rst_from_pad <= 1 - dut.clk_from_pad <= 0 + dut.sys_rst <= 1 + dut.sys_clk <= 0 if run: yield Timer(int(10.5*clk_steps)) - dut.rst_from_pad <= 0 + dut.sys_rst <= 0 yield Timer(int(5*clk_steps)) def setup_jtag(dut, *, tck_period): # Make this a generator if False: yield Timer(0) - return JTAG_Master(dut.tck_from_pad, dut.tms_from_pad, - dut.tdi_from_pad, dut.tdo_to_pad, + return JTAG_Master(dut.jtag_tck, dut.jtag_tms, + dut.jtag_tdi, dut.jtag_tdo, clk_period=tck_period, ir_width=4) @@ -116,3 +116,145 @@ def idcode_run(dut): dut._log.info("IDCODE test completed") +from itertools import chain + +import cocotb +from cocotb.clock import Clock +from cocotb.triggers import Timer +from cocotb.utils import get_sim_steps +from cocotb.binary import BinaryValue + +from c4m.nmigen.jtag.tap import IOType +from c4m.cocotb.jtag.c4m_jtag import JTAG_Master +from c4m.cocotb.jtag.c4m_jtag_svfcocotb import SVF_Executor + +from soc.config.pinouts import get_pinspecs +from soc.debug.jtag import Pins + + +@cocotb.test() +def wishbone_basic(dut): + """ + Test of an added Wishbone interface + """ + clk_period = 100 # 10MHz + tck_period = 3000 # 0.3MHz + + data_in = BinaryValue() + # these have to match with soc.debug.jtag.JTAG ircodes + cmd_MEMADDRESS = BinaryValue("0101") # 5 + cmd_MEMREAD = BinaryValue("0110") # 6 + cmd_MEMREADWRITE = BinaryValue("0111") # 7 + + info = "Running Wishbone basic test" + yield from setup_sim(dut, clk_period=clk_period, run=True) + master = yield from setup_jtag(wrap, tck_period = tck_period) + + # Load the memory address + yield master.load_ir(cmd_MEMADDRESS) + dut._log.info("Loading address") + + data_in.binstr = "000000000000000000000000000001" + dut._log.info(" input: {}".format(data_in.binstr)) + yield master.shift_data(data_in) + dut._log.info(" output: {}".format(master.result.binstr)) + + # Do write + yield master.load_ir(cmd_MEMREADWRITE) + dut._log.info("Writing memory") + + data_in.binstr = "01010101" * 8 + dut._log.info(" input: {}".format(data_in.binstr)) + yield master.shift_data(data_in) + dut._log.info(" output: {}".format(master.result.binstr)) + + data_in.binstr = "10101010" * 8 + dut._log.info(" input: {}".format(data_in.binstr)) + yield master.shift_data(data_in) + dut._log.info(" output: {}".format(master.result.binstr)) + + # Load the memory address + yield master.load_ir(cmd_MEMADDRESS) + dut._log.info("Loading address") + + data_in.binstr = "000000000000000000000000000001" + dut._log.info(" input: {}".format(data_in.binstr)) + yield master.shift_data(data_in) + dut._log.info(" output: {}".format(master.result.binstr)) + assert master.result.binstr == "000000000000000000000000000000" + + # Do read and write + yield master.load_ir(cmd_MEMREADWRITE) + dut._log.info("Reading and writing memory") + + data_in.binstr = "10101010" * 4 + dut._log.info(" input: {}".format(data_in.binstr)) + yield master.shift_data(data_in) + dut._log.info(" output: {}".format(master.result.binstr)) + assert master.result.binstr == "01010101" * 4 + + data_in.binstr = "01010101" * 4 + dut._log.info(" input: {}".format(data_in.binstr)) + yield master.shift_data(data_in) + dut._log.info(" output: {}".format(master.result.binstr)) + assert master.result.binstr == "10101010" * 4 + + # Load the memory address + yield master.load_ir(cmd_MEMADDRESS) + dut._log.info("Loading address") + + data_in.binstr = "000000000000000000000000000001" + dut._log.info(" input: {}".format(data_in.binstr)) + yield master.shift_data(data_in) + dut._log.info(" output: {}".format(master.result.binstr)) + assert master.result.binstr == "000000000000000000000000000010" + + # Do read + yield master.load_ir(cmd_MEMREAD) + dut._log.info("Reading memory") + data_in.binstr = "00000000" * 4 + + dut._log.info(" input: {}".format(data_in.binstr)) + yield master.shift_data(data_in) + dut._log.info(" output: {}".format(master.result.binstr)) + assert master.result.binstr == "10101010" * 4 + + dut._log.info(" input: {}".format(data_in.binstr)) + yield master.shift_data(data_in) + dut._log.info(" output: {}".format(master.result.binstr)) + assert master.result.binstr == "01010101" * 4 + + # Load the memory address + yield master.load_ir(cmd_MEMADDRESS) # MEMADDR + dut._log.info("Loading address") + + data_in.binstr = "0000000000000000000000000000001" + dut._log.info(" input: {}".format(data_in.binstr)) + yield master.shift_data(data_in) + dut._log.info(" output: {}".format(master.result.binstr)) + assert master.result.binstr == "000000000000000000000000000010" + + # Do read + yield master.load_ir(cmd_MEMREAD) # MEMREAD + dut._log.info("Reading memory") + data_in.binstr = "00000000" * 4 + + dut._log.info(" input: {}".format(data_in.binstr)) + yield master.shift_data(data_in) + dut._log.info(" output: {}".format(master.result.binstr)) + assert master.result.binstr == "10101010" * 4 + + dut._log.info(" input: {}".format(data_in.binstr)) + yield master.shift_data(data_in) + dut._log.info(" output: {}".format(master.result.binstr)) + assert master.result.binstr == "01010101" * 4 + + dut._log.info("{!r}".format(wbmem)) + + +# demo / debug how to get boundary scan names. run "python3 test.py" +if __name__ == '__main__': + pinouts = get_jtag_boundary() + for pin in pinouts: + # example: ('eint', '2', , 'eint_2', 125) + print (pin) -- 2.30.2