Add in a SimJTAG to connect to OpenOCD's remote-bitbang interface.
This is simpler than JTAGVPI and is supported better by Verilor. It is also the same thing Spike uses.
This commit is contained in:
parent
206892899f
commit
e82328336e
32
csrc/SimJTAG.cc
Normal file
32
csrc/SimJTAG.cc
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// See LICENSE.SiFive for license details.
|
||||||
|
|
||||||
|
#include <vpi_user.h>
|
||||||
|
#include <svdpi.h>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include "remote_bitbang.h"
|
||||||
|
|
||||||
|
remote_bitbang_t* jtag;
|
||||||
|
|
||||||
|
extern "C" int jtag_tick
|
||||||
|
(
|
||||||
|
unsigned char * jtag_TCK,
|
||||||
|
unsigned char * jtag_TMS,
|
||||||
|
unsigned char * jtag_TDI,
|
||||||
|
unsigned char * jtag_TRSTn,
|
||||||
|
unsigned char jtag_TDO
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!jtag) {
|
||||||
|
s_vpi_vlog_info info;
|
||||||
|
if (!vpi_get_vlog_info(&info)) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
// TODO: Pass in real port number
|
||||||
|
jtag = new remote_bitbang_t(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
jtag->tick(jtag_TCK, jtag_TMS, jtag_TDI, jtag_TRSTn, jtag_TDO);
|
||||||
|
|
||||||
|
return jtag->done() ? (jtag->exit_code() << 1 | 1) : 0;
|
||||||
|
|
||||||
|
}
|
@ -6,6 +6,7 @@
|
|||||||
#include "verilated_vcd_c.h"
|
#include "verilated_vcd_c.h"
|
||||||
#endif
|
#endif
|
||||||
#include <fesvr/dtm.h>
|
#include <fesvr/dtm.h>
|
||||||
|
#include "remote_bitbang.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@ -15,6 +16,8 @@
|
|||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
|
||||||
extern dtm_t* dtm;
|
extern dtm_t* dtm;
|
||||||
|
extern remote_bitbang_t * jtag;
|
||||||
|
|
||||||
static uint64_t trace_count = 0;
|
static uint64_t trace_count = 0;
|
||||||
bool verbose;
|
bool verbose;
|
||||||
bool done_reset;
|
bool done_reset;
|
||||||
@ -169,6 +172,8 @@ done_processing:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
dtm = new dtm_t(to_dtm);
|
dtm = new dtm_t(to_dtm);
|
||||||
|
//TODO: Specify port.
|
||||||
|
jtag = new remote_bitbang_t(0);
|
||||||
|
|
||||||
signal(SIGTERM, handle_sigterm);
|
signal(SIGTERM, handle_sigterm);
|
||||||
|
|
||||||
@ -183,7 +188,8 @@ done_processing:
|
|||||||
}
|
}
|
||||||
done_reset = true;
|
done_reset = true;
|
||||||
|
|
||||||
while (!dtm->done() && !tile->io_success && trace_count < max_cycles) {
|
while (!dtm->done() && !jtag->done() &&
|
||||||
|
!tile->io_success && trace_count < max_cycles) {
|
||||||
tile->clock = 0;
|
tile->clock = 0;
|
||||||
tile->eval();
|
tile->eval();
|
||||||
#if VM_TRACE
|
#if VM_TRACE
|
||||||
@ -213,6 +219,11 @@ done_processing:
|
|||||||
fprintf(stderr, "*** FAILED *** (code = %d, seed %d) after %ld cycles\n", dtm->exit_code(), random_seed, trace_count);
|
fprintf(stderr, "*** FAILED *** (code = %d, seed %d) after %ld cycles\n", dtm->exit_code(), random_seed, trace_count);
|
||||||
ret = dtm->exit_code();
|
ret = dtm->exit_code();
|
||||||
}
|
}
|
||||||
|
else if (jtag->exit_code())
|
||||||
|
{
|
||||||
|
fprintf(stderr, "*** FAILED *** (code = %d, seed %d) after %ld cycles\n", jtag->exit_code(), random_seed, trace_count);
|
||||||
|
ret = jtag->exit_code();
|
||||||
|
}
|
||||||
else if (trace_count == max_cycles)
|
else if (trace_count == max_cycles)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "*** FAILED *** (timeout, seed %d) after %ld cycles\n", random_seed, trace_count);
|
fprintf(stderr, "*** FAILED *** (timeout, seed %d) after %ld cycles\n", random_seed, trace_count);
|
||||||
@ -224,6 +235,7 @@ done_processing:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dtm) delete dtm;
|
if (dtm) delete dtm;
|
||||||
|
if (jtag) delete jtag;
|
||||||
if (tile) delete tile;
|
if (tile) delete tile;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
196
csrc/remote_bitbang.cc
Normal file
196
csrc/remote_bitbang.cc
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
// 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 <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include "remote_bitbang.h"
|
||||||
|
|
||||||
|
/////////// remote_bitbang_t
|
||||||
|
|
||||||
|
remote_bitbang_t::remote_bitbang_t(uint16_t port) :
|
||||||
|
socket_fd(0),
|
||||||
|
client_fd(0),
|
||||||
|
recv_start(0),
|
||||||
|
recv_end(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;
|
||||||
|
|
||||||
|
printf("Listening on port %d\n",
|
||||||
|
ntohs(addr.sin_port));
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void remote_bitbang_t::accept()
|
||||||
|
{
|
||||||
|
|
||||||
|
fprintf(stderr,"Attempting to accept client socket\n");
|
||||||
|
|
||||||
|
client_fd = ::accept(socket_fd, NULL, NULL);
|
||||||
|
if (client_fd == -1) {
|
||||||
|
if (errno == EAGAIN) {
|
||||||
|
// No client waiting to connect right now.
|
||||||
|
fprintf(stderr, "Not Accepted: Received EAGAIN error\n");
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "failed to accept on socket: %s (%d)\n", strerror(errno),
|
||||||
|
errno);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fcntl(client_fd, F_SETFL, O_NONBLOCK);
|
||||||
|
fprintf(stderr, "Accepted successfully.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void remote_bitbang_t::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;
|
||||||
|
execute_command();
|
||||||
|
} else {
|
||||||
|
this->accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
* jtag_tck = tck;
|
||||||
|
* jtag_tms = tms;
|
||||||
|
* jtag_tdi = tdi;
|
||||||
|
* jtag_trstn = trstn;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void remote_bitbang_t::reset(){
|
||||||
|
//trstn = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void remote_bitbang_t::set_pins(char _tck, char _tms, char _tdi){
|
||||||
|
tck = _tck;
|
||||||
|
tms = _tms;
|
||||||
|
tdi = _tdi;
|
||||||
|
}
|
||||||
|
|
||||||
|
void remote_bitbang_t::execute_command()
|
||||||
|
{
|
||||||
|
char command;
|
||||||
|
|
||||||
|
ssize_t num_read = read(client_fd, &command, sizeof(command));
|
||||||
|
if (num_read == -1) {
|
||||||
|
if (errno == EAGAIN) {
|
||||||
|
// We'll try again the next call.
|
||||||
|
fprintf(stderr, "Received no command. Will try again on the next call\n");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "remote_bitbang failed to read on socket: %s (%d)\n",
|
||||||
|
strerror(errno), errno);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_read == 0) {
|
||||||
|
fprintf(stderr, "No Command Received.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "Received a command %c\n", command);
|
||||||
|
|
||||||
|
int dosend = 0;
|
||||||
|
|
||||||
|
char tosend = '?';
|
||||||
|
|
||||||
|
switch (command) {
|
||||||
|
case 'B': /* fprintf(stderr, "*BLINK*\n"); */ break;
|
||||||
|
case 'b': /* fprintf(stderr, "_______\n"); */ break;
|
||||||
|
case 'r': reset(); break; // This is wrong. 'r' has other bits that indicated TRST and SRST.
|
||||||
|
case '0': set_pins(0, 0, 0); break;
|
||||||
|
case '1': set_pins(0, 0, 1); break;
|
||||||
|
case '2': set_pins(0, 1, 0); break;
|
||||||
|
case '3': set_pins(0, 1, 1); break;
|
||||||
|
case '4': set_pins(1, 0, 0); break;
|
||||||
|
case '5': set_pins(1, 0, 1); break;
|
||||||
|
case '6': set_pins(1, 1, 0); break;
|
||||||
|
case '7': set_pins(1, 1, 1); break;
|
||||||
|
case 'R': dosend = 1; tosend = tdo ? '1' : '0'; break;
|
||||||
|
case 'Q': 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) {
|
||||||
|
// The remote disconnected.
|
||||||
|
fprintf(stderr, "Remote end disconnected\n");
|
||||||
|
close(client_fd);
|
||||||
|
client_fd = 0;
|
||||||
|
}
|
||||||
|
}
|
59
csrc/remote_bitbang.h
Normal file
59
csrc/remote_bitbang.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// See LICENSE.Berkeley for license details.
|
||||||
|
|
||||||
|
#ifndef REMOTE_BITBANG_H
|
||||||
|
#define REMOTE_BITBANG_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
class remote_bitbang_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Create a new server, listening for connections from localhost on the given
|
||||||
|
// port.
|
||||||
|
remote_bitbang_t(uint16_t port);
|
||||||
|
|
||||||
|
// Do a bit of work.
|
||||||
|
void tick(unsigned char * jtag_tck,
|
||||||
|
unsigned char * jtag_tms,
|
||||||
|
unsigned char * jtag_tdi,
|
||||||
|
unsigned char * jtag_trstn,
|
||||||
|
unsigned char jtag_tdo);
|
||||||
|
|
||||||
|
unsigned char done() {return quit;}
|
||||||
|
|
||||||
|
int exit_code() {return err;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
int 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[buf_size];
|
||||||
|
ssize_t recv_start, recv_end;
|
||||||
|
|
||||||
|
// Check for a client connecting, and accept if there is one.
|
||||||
|
void accept();
|
||||||
|
// Execute any commands the client has for us.
|
||||||
|
// But we only execute 1 because we need time for the
|
||||||
|
// simulation to run.
|
||||||
|
void execute_command();
|
||||||
|
|
||||||
|
// Reset. Currently does nothing.
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
void set_pins(char _tck, char _tms, char _tdi);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -8,7 +8,7 @@ output_dir = $(sim_dir)/output
|
|||||||
|
|
||||||
include $(base_dir)/Makefrag
|
include $(base_dir)/Makefrag
|
||||||
|
|
||||||
CXXSRCS := emulator SimDTM
|
CXXSRCS := emulator SimDTM SimJTAG remote_bitbang
|
||||||
CXXFLAGS := $(CXXFLAGS) -std=c++11 -I$(RISCV)/include -I$(base_dir)/csrc
|
CXXFLAGS := $(CXXFLAGS) -std=c++11 -I$(RISCV)/include -I$(base_dir)/csrc
|
||||||
LDFLAGS := $(LDFLAGS) -L$(RISCV)/lib -Wl,-rpath,$(RISCV)/lib -L$(abspath $(sim_dir)) -lfesvr -lpthread
|
LDFLAGS := $(LDFLAGS) -L$(RISCV)/lib -Wl,-rpath,$(RISCV)/lib -L$(abspath $(sim_dir)) -lfesvr -lpthread
|
||||||
|
|
||||||
|
@ -62,8 +62,9 @@ CONFIGS=AMBAUnitTestConfig TLSimpleUnitTestConfig TLWidthUnitTestConfig
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(SUITE), JtagDtmSuite)
|
ifeq ($(SUITE), JtagDtmSuite)
|
||||||
CONFIGS_32=WithJtagDTM_DefaultRV32Config
|
PROJECT=freechips.rocketchip.system
|
||||||
CONFIGS_64=WithJtagDTM_DefaultConfig
|
CONFIGS_32=WithJtagDTMSystem_DefaultRV32Config
|
||||||
|
CONFIGS_64=WithJtagDTMSystem_DefaultConfig
|
||||||
CONFIGS += $(CONFIGS_32)
|
CONFIGS += $(CONFIGS_32)
|
||||||
CONFIGS += $(CONFIGS_64)
|
CONFIGS += $(CONFIGS_64)
|
||||||
endif
|
endif
|
||||||
@ -208,44 +209,68 @@ stamps/%/emulator-torture-$(TORTURE_CONFIG).stamp: stamps/%/emulator-debug.stamp
|
|||||||
|
|
||||||
# Targets for JTAG DTM full-chain simulation
|
# Targets for JTAG DTM full-chain simulation
|
||||||
|
|
||||||
OPENOCD_DIR ?= $(RISCV)
|
|
||||||
|
|
||||||
# If this is defined empty, then all tests would run.
|
# If this is defined empty, then all tests would run.
|
||||||
JTAG_DTM_TEST ?= MemTest64
|
JTAG_DTM_TEST ?= MemTest64
|
||||||
|
|
||||||
ifdef DEBUG
|
ifdef DEBUG
|
||||||
JTAG_STAMP_SUFFIX=-debug
|
JTAG_STAMP_SUFFIX=-debug
|
||||||
JTAG_DEBUG_SUFFIX=-debug
|
JTAG_DEBUG_SUFFIX=-debug
|
||||||
JTAG_VCDPLUS_32= +vcdplusfile=regression32.vcd
|
VSIM_JTAG_VCDPLUS_32= +vcdplusfile=regression32.vcd
|
||||||
JTAG_VCDPLUS_64= +vcdplusfile=regression64.vcd
|
VSIM_JTAG_VCDPLUS_64= +vcdplusfile=regression64.vcd
|
||||||
|
EMULATOR_JTAG_VCDPLUS_32= -v regression32.vcd
|
||||||
|
EMULATOR_JTAG_VCDPLUS_64= -v regression64.vcd
|
||||||
OPENOCD_DEBUG= -d
|
OPENOCD_DEBUG= -d
|
||||||
else
|
else
|
||||||
JTAG_STAMP_SUFFIX=-ndebug
|
JTAG_STAMP_SUFFIX=-ndebug
|
||||||
endif
|
endif
|
||||||
|
stamps/%/vsim-jtag-dtm-32-$(JTAG_DTM_TEST).stamp: stamps/%/vsim$(JTAG_STAMP_SUFFIX).stamp
|
||||||
stamps/%/jtag-dtm-32-$(JTAG_DTM_TEST).stamp: stamps/%/vsim$(JTAG_STAMP_SUFFIX).stamp
|
|
||||||
export RISCV=$(RISCV) && $(abspath $(TOP))/riscv-tools/riscv-tests/debug/gdbserver.py \
|
export RISCV=$(RISCV) && $(abspath $(TOP))/riscv-tools/riscv-tests/debug/gdbserver.py \
|
||||||
--sim_cmd "$(abspath $(TOP))/vsim/simv-$(PROJECT)-$*$(JTAG_DEBUG_SUFFIX) +verbose $(JTAG_VCDPLUS_32)" \
|
--sim_cmd="$(abspath $(TOP))/vsim/simv-$(PROJECT)-$*$(JTAG_DEBUG_SUFFIX) +verbose $(VSIM_JTAG_VCDPLUS_32)" \
|
||||||
--server_cmd="$(OPENOCD_DIR)/bin/openocd $(OPENOCD_DEBUG) \
|
--server_cmd="$(RISCV)/bin/openocd $(OPENOCD_DEBUG) \
|
||||||
--s $(OPENOCD_DIR)/share/openocd/scripts" \
|
--s $(RISCV)/share/openocd/scripts" \
|
||||||
--freedom-e300-sim \
|
$(abspath $(TOP))/scripts/FreedomSim.py \
|
||||||
$(JTAG_DTM_TEST)
|
$(JTAG_DTM_TEST)
|
||||||
date > $@
|
date > $@
|
||||||
|
|
||||||
stamps/%/jtag-dtm-64-$(JTAG_DTM_TEST).stamp: stamps/%/vsim$(JTAG_STAMP_SUFFIX).stamp
|
stamps/%/vsim-jtag-dtm-64-$(JTAG_DTM_TEST).stamp: stamps/%/vsim$(JTAG_STAMP_SUFFIX).stamp
|
||||||
export RISCV=$(RISCV) && $(abspath $(TOP))/riscv-tools/riscv-tests/debug/gdbserver.py \
|
export RISCV=$(RISCV) && $(abspath $(TOP))/riscv-tools/riscv-tests/debug/gdbserver.py \
|
||||||
--sim_cmd "$(abspath $(TOP))/vsim/simv-$(PROJECT)-$*$(JTAG_DEBUG_SUFFIX) +verbose $(JTAG_VCDPLUS_64)" \
|
--sim_cmdrun "$(abspath $(TOP))/vsim/simv-$(PROJECT)-$*$(JTAG_DEBUG_SUFFIX) +verbose $(VSIM_JTAG_VCDPLUS_64)" \
|
||||||
--server_cmd="$(OPENOCD_INSTALL)_$(OPENOCD_VERSION)/bin/openocd $(OPENOCD_DEBUG) \
|
--server_cmd="$(OPENOCD_INSTALL)_$(OPENOCD_VERSION)/bin/openocd $(OPENOCD_DEBUG) \
|
||||||
--s $(OPENOCD_INSTALL)_$(OPENOCD_VERSION)/share/openocd/scripts" \
|
--s $(OPENOCD_INSTALL)_$(OPENOCD_VERSION)/share/openocd/scripts" \
|
||||||
--freedom-u500-sim \
|
$(abspath $(TOP))/scripts/FreedomSim.py \
|
||||||
$(JTAG_DTM_TEST)
|
$(JTAG_DTM_TEST)
|
||||||
date > $@
|
date > $@
|
||||||
|
|
||||||
JTAG_DTM_32_TEST_STAMPS=$(foreach config,$(CONFIGS_32),stamps/$(config)/jtag-dtm-32-$(JTAG_DTM_TEST).stamp)
|
stamps/%/emulator-jtag-dtm-32-$(JTAG_DTM_TEST).stamp: stamps/%/emulator$(JTAG_STAMP_SUFFIX).stamp
|
||||||
JTAG_DTM_64_TEST_STAMPS=$(foreach config,$(CONFIGS_64),stamps/$(config)/jtag-dtm-64-$(JTAG_DTM_TEST).stamp)
|
export RISCV=$(RISCV) && $(abspath $(TOP))/riscv-tools/riscv-tests/debug/gdbserver.py \
|
||||||
|
--sim_cmd "$(abspath $(TOP))/emulator/emulator-$(PROJECT)-$*$(JTAG_DEBUG_SUFFIX) +verbose $(EMULATOR_JTAG_VCDPLUS_32) dummybin | tee emulator.log" \
|
||||||
|
--server_cmd="$(RISCV)/bin/openocd $(OPENOCD_DEBUG) \
|
||||||
|
--s $(RISCV)/share/openocd/scripts" \
|
||||||
|
$(abspath $(TOP))/scripts/FreedomSim.py \
|
||||||
|
$(JTAG_DTM_TEST)
|
||||||
|
date > $@
|
||||||
|
|
||||||
jtag-dtm-tests-32 : $(JTAG_DTM_32_TEST_STAMPS)
|
stamps/%/emulator-jtag-dtm-64-$(JTAG_DTM_TEST).stamp: stamps/%/emulator$(JTAG_STAMP_SUFFIX).stamp
|
||||||
jtag-dtm-tests-64 : $(JTAG_DTM_64_TEST_STAMPS)
|
export RISCV=$(RISCV) && $(abspath $(TOP))/riscv-tools/riscv-tests/debug/gdbserver.py \
|
||||||
|
--sim_cmd "$(abspath $(TOP))/emulator/emulator-$(PROJECT)-$*$(JTAG_DEBUG_SUFFIX) +verbose $(EMULATOR_JTAG_VCDPLUS_64) dummybin | tee emulator.log" \
|
||||||
|
--server_cmd="$(RISCV)/bin/openocd $(OPENOCD_DEBUG) \
|
||||||
|
--s $(RISCV)/share/openocd/scripts" \
|
||||||
|
$(abspath $(TOP))/scripts/FreedomSim.py \
|
||||||
|
$(JTAG_DTM_TEST)
|
||||||
|
date > $@
|
||||||
|
|
||||||
|
VSIM_JTAG_DTM_32_TEST_STAMPS=$(foreach config,$(CONFIGS_32),stamps/$(config)/vsim-jtag-dtm-32-$(JTAG_DTM_TEST).stamp)
|
||||||
|
VSIM_JTAG_DTM_64_TEST_STAMPS=$(foreach config,$(CONFIGS_64),stamps/$(config)/vsim-jtag-dtm-64-$(JTAG_DTM_TEST).stamp)
|
||||||
|
|
||||||
|
EMULATOR_JTAG_DTM_32_TEST_STAMPS=$(foreach config,$(CONFIGS_32),stamps/$(config)/emulator-jtag-dtm-32-$(JTAG_DTM_TEST).stamp)
|
||||||
|
EMULATOR_JTAG_DTM_64_TEST_STAMPS=$(foreach config,$(CONFIGS_64),stamps/$(config)/emulator-jtag-dtm-64-$(JTAG_DTM_TEST).stamp)
|
||||||
|
|
||||||
|
vsim-jtag-dtm-tests-32 : $(VSIM_JTAG_DTM_32_TEST_STAMPS)
|
||||||
|
vsim-jtag-dtm-tests-64 : $(VSIM_JTAG_DTM_64_TEST_STAMPS)
|
||||||
|
|
||||||
|
emulator-jtag-dtm-tests-32 : $(EMULATOR_JTAG_DTM_32_TEST_STAMPS)
|
||||||
|
emulator-jtag-dtm-tests-64 : $(EMULATOR_JTAG_DTM_64_TEST_STAMPS)
|
||||||
|
|
||||||
# Targets for JTAG DTM full-chain simulation
|
# Targets for JTAG DTM full-chain simulation
|
||||||
jtag-dtm-regression: jtag-dtm-tests-32 jtag-dtm-tests-64
|
vsim-jtag-dtm-regression: vsim-jtag-dtm-tests-32 vsim-jtag-dtm-tests-64
|
||||||
|
emulator-jtag-dtm-regression: emulator-jtag-dtm-tests-32 emulator-jtag-dtm-tests-64
|
||||||
|
@ -9,6 +9,8 @@ import freechips.rocketchip.coreplex._
|
|||||||
import freechips.rocketchip.devices.debug.{IncludeJtagDTM, JtagDTMKey}
|
import freechips.rocketchip.devices.debug.{IncludeJtagDTM, JtagDTMKey}
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
|
|
||||||
|
class WithJtagDTMSystem extends freechips.rocketchip.coreplex.WithJtagDTM
|
||||||
|
|
||||||
class BaseConfig extends Config(new BaseCoreplexConfig().alter((site,here,up) => {
|
class BaseConfig extends Config(new BaseCoreplexConfig().alter((site,here,up) => {
|
||||||
// DTS descriptive parameters
|
// DTS descriptive parameters
|
||||||
case DTSModel => "freechips,rocketchip-unknown"
|
case DTSModel => "freechips,rocketchip-unknown"
|
||||||
|
@ -16,13 +16,15 @@ sim_vsrcs = \
|
|||||||
$(generated_dir)/$(long_name).behav_srams.v \
|
$(generated_dir)/$(long_name).behav_srams.v \
|
||||||
$(base_dir)/vsrc/$(TB).v \
|
$(base_dir)/vsrc/$(TB).v \
|
||||||
$(base_dir)/vsrc/SimDTM.v \
|
$(base_dir)/vsrc/SimDTM.v \
|
||||||
|
$(base_dir)/vsrc/SimJTAG.v \
|
||||||
$(bb_vsrcs)
|
$(bb_vsrcs)
|
||||||
|
|
||||||
# C sources
|
# C sources
|
||||||
|
|
||||||
sim_csrcs = \
|
sim_csrcs = \
|
||||||
$(base_dir)/csrc/SimDTM.cc \
|
$(base_dir)/csrc/SimDTM.cc \
|
||||||
$(base_dir)/csrc/jtag_vpi.c
|
$(base_dir)/csrc/SimJTAG.cc \
|
||||||
|
$(base_dir)/csrc/remote_bitbang.cc \
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
# Build Verilog
|
# Build Verilog
|
||||||
|
79
vsrc/SimJTAG.v
Normal file
79
vsrc/SimJTAG.v
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
// See LICENSE.SiFive for license details.
|
||||||
|
|
||||||
|
import "DPI-C" function int jtag_tick
|
||||||
|
(
|
||||||
|
output bit jtag_TCK,
|
||||||
|
output bit jtag_TMS,
|
||||||
|
output bit jtag_TDI,
|
||||||
|
output bit jtag_TRSTn,
|
||||||
|
|
||||||
|
input bit jtag_TDO
|
||||||
|
);
|
||||||
|
|
||||||
|
module SimJTAG #(
|
||||||
|
parameter TICK_DELAY = 50
|
||||||
|
)(
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
end else begin
|
||||||
|
if (enable && init_done) begin
|
||||||
|
tickCounterReg <= tickCounterNxt;
|
||||||
|
if (tickCounterReg == 0) begin
|
||||||
|
__exit = jtag_tick(
|
||||||
|
__jtag_TCK,
|
||||||
|
__jtag_TMS,
|
||||||
|
__jtag_TDI,
|
||||||
|
__jtag_TRSTn,
|
||||||
|
__jtag_TDO);
|
||||||
|
end
|
||||||
|
end // if (enable && init_done)
|
||||||
|
end // else: !if(reset || r_reset)
|
||||||
|
end // always @ (posedge clock)
|
||||||
|
|
||||||
|
endmodule
|
Loading…
Reference in New Issue
Block a user