From a8fc3642ad70262f7ec34eeeb957bd15da12f4b1 Mon Sep 17 00:00:00 2001 From: Colin Date: Wed, 19 Jan 2022 12:32:39 +0000 Subject: [PATCH] Add dpi of jtag --- demo/helloworld/Makefile | 9 +- soc/dpi/common/tcp_server.c | 437 ++++++++++++++++++++++++++++++++++++ soc/dpi/common/tcp_server.h | 69 ++++++ soc/dpi/jtagdpi/jtagdpi.c | 154 +++++++++++++ soc/dpi/jtagdpi/jtagdpi.h | 56 +++++ soc/dpi/jtagdpi/jtagdpi.sv | 47 ++++ soc/flist | 44 ---- soc/soc.mk | 56 +++++ 8 files changed, 822 insertions(+), 50 deletions(-) create mode 100644 soc/dpi/common/tcp_server.c create mode 100644 soc/dpi/common/tcp_server.h create mode 100644 soc/dpi/jtagdpi/jtagdpi.c create mode 100644 soc/dpi/jtagdpi/jtagdpi.h create mode 100644 soc/dpi/jtagdpi/jtagdpi.sv delete mode 100644 soc/flist create mode 100644 soc/soc.mk diff --git a/demo/helloworld/Makefile b/demo/helloworld/Makefile index e2cdebc..fae92cc 100644 --- a/demo/helloworld/Makefile +++ b/demo/helloworld/Makefile @@ -41,16 +41,13 @@ swerv_define : ##################### Verilog Builds ##################################### -defines = $(BUILD_DIR)/common_defines.vh ${RV_DESIGN}/include/swerv_types.sv -includes = -I${RV_DESIGN}/include -I${BUILD_DIR} -I${RV_SOC} - verilator-build: swerv_define echo '`undef ASSERT_ON' >> ${BUILD_DIR}/common_defines.vh verilator --cc -CFLAGS ${CFLAGS} \ - $(defines) \ - $(includes) \ + $(BUILD_DIR)/common_defines.vh \ + -I${BUILD_DIR} \ -Wno-UNOPTFLAT \ - -f ${RV_SOC}/flist \ + -F ${RV_SOC}/soc.mk \ $(RV_SOC)/soc_top.sv \ --top-module soc_top -exe test_soc_top.cpp --autoflush $(VERILATOR_DEBUG) cp ${DEMODIR}/test_soc_top.cpp obj_dir diff --git a/soc/dpi/common/tcp_server.c b/soc/dpi/common/tcp_server.c new file mode 100644 index 0000000..1caf2f8 --- /dev/null +++ b/soc/dpi/common/tcp_server.c @@ -0,0 +1,437 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +#include "tcp_server.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * Simple buffer for passing data between TCP sockets and DPI modules + */ +const int BUFSIZE_BYTE = 256; + +struct tcp_buf { + unsigned int rptr; + unsigned int wptr; + char buf[BUFSIZE_BYTE]; +}; + +/** + * TCP Server thread context structure + */ +struct tcp_server_ctx { + // Writeable by the host thread + char *display_name; + uint16_t listen_port; + volatile bool socket_run; + // Writeable by the server thread + tcp_buf *buf_in; + tcp_buf *buf_out; + int sfd; // socket fd + int cfd; // client fd + pthread_t sock_thread; +}; + +static bool tcp_buffer_is_full(struct tcp_buf *buf) { + if (buf->wptr >= buf->rptr) { + return (buf->wptr - buf->rptr) == (BUFSIZE_BYTE - 1); + } else { + return (buf->rptr - buf->wptr) == 1; + } +} + +static bool tcp_buffer_is_empty(struct tcp_buf *buf) { + return (buf->wptr == buf->rptr); +} + +static void tcp_buffer_put_byte(struct tcp_buf *buf, char dat) { + bool done = false; + while (!done) { + if (!tcp_buffer_is_full(buf)) { + buf->buf[buf->wptr++] = dat; + buf->wptr %= BUFSIZE_BYTE; + done = true; + } + } +} + +static bool tcp_buffer_get_byte(struct tcp_buf *buf, char *dat) { + if (tcp_buffer_is_empty(buf)) { + return false; + } + *dat = buf->buf[buf->rptr++]; + buf->rptr %= BUFSIZE_BYTE; + return true; +} + +static struct tcp_buf *tcp_buffer_new(void) { + struct tcp_buf *buf_new; + buf_new = (struct tcp_buf *)malloc(sizeof(struct tcp_buf)); + buf_new->rptr = 0; + buf_new->wptr = 0; + return buf_new; +} + +static void tcp_buffer_free(struct tcp_buf **buf) { + free(*buf); + *buf = NULL; +} + +/** + * Start a TCP server + * + * This function creates attempts to create a new TCP socket instance. The + * socket is a non-blocking stream socket, with buffering disabled. + * + * @param ctx context object + * @return 0 on success, -1 in case of an error + */ +static int start(struct tcp_server_ctx *ctx) { + int rv; + + assert(ctx->sfd == 0 && "Server already started."); + + // create socket + int sfd = socket(AF_INET, SOCK_STREAM, 0); + if (sfd == -1) { + fprintf(stderr, "%s: Unable to create socket: %s (%d)\n", ctx->display_name, + strerror(errno), errno); + return -1; + } + + rv = fcntl(sfd, F_SETFL, O_NONBLOCK); + if (rv != 0) { + fprintf(stderr, "%s: Unable to make socket non-blocking: %s (%d)\n", + ctx->display_name, strerror(errno), errno); + return -1; + } + + // reuse existing socket (if existing) + int reuse_socket = 1; + rv = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse_socket, sizeof(int)); + if (rv != 0) { + fprintf(stderr, "%s: Unable to set socket options: %s (%d)\n", + ctx->display_name, strerror(errno), errno); + return -1; + } + + // stop tcp socket from buffering (buffering prevents timely responses to + // OpenOCD which severly limits debugging performance) + int tcp_nodelay = 1; + rv = setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, &tcp_nodelay, sizeof(int)); + if (rv != 0) { + fprintf(stderr, "%s: Unable to set socket nodelay: %s (%d)\n", + ctx->display_name, strerror(errno), errno); + return -1; + } + + // bind server + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr.sin_port = htons(ctx->listen_port); + + rv = bind(sfd, (struct sockaddr *)&addr, sizeof(addr)); + if (rv != 0) { + fprintf(stderr, "%s: Failed to bind socket: %s (%d)\n", ctx->display_name, + strerror(errno), errno); + return -1; + } + + // listen for incoming connections + rv = listen(sfd, 1); + if (rv != 0) { + fprintf(stderr, "%s: Failed to listen on socket: %s (%d)\n", + ctx->display_name, strerror(errno), errno); + return -1; + } + + ctx->sfd = sfd; + assert(ctx->sfd > 0); + + return 0; +} + +/** + * Accept an incoming connection from a client (nonblocking) + * + * The resulting client fd is made non-blocking. + * + * @param ctx context object + * @return 0 on success, any other value indicates an error + */ +static int client_tryaccept(struct tcp_server_ctx *ctx) { + int rv; + + assert(ctx->sfd > 0); + assert(ctx->cfd == 0); + + int cfd = accept(ctx->sfd, NULL, NULL); + + if (cfd == -1 && errno == EAGAIN) { + return -EAGAIN; + } + + if (cfd == -1) { + fprintf(stderr, "%s: Unable to accept incoming connection: %s (%d)\n", + ctx->display_name, strerror(errno), errno); + return -1; + } + + rv = fcntl(cfd, F_SETFL, O_NONBLOCK); + if (rv != 0) { + fprintf(stderr, "%s: Unable to make client socket non-blocking: %s (%d)\n", + ctx->display_name, strerror(errno), errno); + return -1; + } + + ctx->cfd = cfd; + assert(ctx->cfd > 0); + + printf("%s: Accepted client connection\n", ctx->display_name); + + return 0; +} + +/** + * Stop the TCP server + * + * @param ctx context object + */ +static void stop(struct tcp_server_ctx *ctx) { + assert(ctx); + if (!ctx->sfd) { + return; + } + close(ctx->sfd); + ctx->sfd = 0; +} + +/** + * Receive a byte from a connected client + * + * @param ctx context object + * @param cmd byte received + * @return true if a byte was read + */ +static bool get_byte(struct tcp_server_ctx *ctx, char *cmd) { + assert(ctx); + + ssize_t num_read = read(ctx->cfd, cmd, 1); + + if (num_read == 0) { + return false; + } + if (num_read == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + return false; + } else if (errno == EBADF) { + // Possibly client went away? Accept a new connection. + fprintf(stderr, "%s: Client disappeared.\n", ctx->display_name); + tcp_server_client_close(ctx); + return false; + } else { + fprintf(stderr, "%s: Error while reading from client: %s (%d)\n", + ctx->display_name, strerror(errno), errno); + assert(0 && "Error reading from client"); + } + } + assert(num_read == 1); + return true; +} + +/** + * Send a byte to a connected client + * + * @param ctx context object + * @param cmd byte to send + */ +static void put_byte(struct tcp_server_ctx *ctx, char cmd) { + while (1) { + ssize_t num_written = send(ctx->cfd, &cmd, sizeof(cmd), MSG_NOSIGNAL); + if (num_written == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + continue; + } else if (errno == EPIPE) { + printf("%s: Remote disconnected.\n", ctx->display_name); + tcp_server_client_close(ctx); + break; + } else { + fprintf(stderr, "%s: Error while writing to client: %s (%d)\n", + ctx->display_name, strerror(errno), errno); + assert(0 && "Error writing to client."); + } + } + if (num_written >= 1) { + break; + } + } +} + +/** + * Cleanup server context + * + * @param ctx context object + */ +static void ctx_free(struct tcp_server_ctx *ctx) { + // Free the buffers + tcp_buffer_free(&ctx->buf_in); + tcp_buffer_free(&ctx->buf_out); + // Free the display name + free(ctx->display_name); + // Free the ctx + free(ctx); + ctx = NULL; +} + +/** + * Thread function to create a new server instance + * + * @param ctx_void context object + * @return Always returns NULL + */ +static void *server_create(void *ctx_void) { + // Cast to a server struct + struct tcp_server_ctx *ctx = (struct tcp_server_ctx *)ctx_void; + struct timeval timeout; + + // Start the server + int rv = start(ctx); + if (rv != 0) { + fprintf(stderr, "%s: Unable to create TCP server on port %d\n", + ctx->display_name, ctx->listen_port); + goto err_cleanup_return; + } + + // Initialise timeout + timeout.tv_sec = 0; + + // Initialise fd_set + + // Start waiting for connection / data + char xfer_data; + while (ctx->socket_run) { + // Initialise structure of fds + fd_set read_fds; + FD_ZERO(&read_fds); + if (ctx->sfd) { + FD_SET(ctx->sfd, &read_fds); + } + if (ctx->cfd) { + FD_SET(ctx->cfd, &read_fds); + } + // max fd num + int mfd = (ctx->cfd > ctx->sfd) ? ctx->cfd : ctx->sfd; + + // Set timeout - 50us gives good performance + timeout.tv_usec = 50; + + // Wait for socket activity or timeout + rv = select(mfd + 1, &read_fds, NULL, NULL, &timeout); + + if (rv < 0) { + printf("%s: Socket read failed, port: %d\n", ctx->display_name, + ctx->listen_port); + tcp_server_client_close(ctx); + } + + // New connection + if (FD_ISSET(ctx->sfd, &read_fds)) { + client_tryaccept(ctx); + } + + // New client data + if (FD_ISSET(ctx->cfd, &read_fds)) { + while (get_byte(ctx, &xfer_data)) { + tcp_buffer_put_byte(ctx->buf_in, xfer_data); + } + } + + if (ctx->cfd != 0) { + while (tcp_buffer_get_byte(ctx->buf_out, &xfer_data)) { + put_byte(ctx, xfer_data); + } + } + } + +err_cleanup_return: + + // Simulation done - clean up + tcp_server_client_close(ctx); + stop(ctx); + + return NULL; +} + +// Abstract interface functions +tcp_server_ctx *tcp_server_create(const char *display_name, int listen_port) { + struct tcp_server_ctx *ctx = + (struct tcp_server_ctx *)calloc(1, sizeof(struct tcp_server_ctx)); + assert(ctx); + + // Create the buffers + struct tcp_buf *buf_in = tcp_buffer_new(); + struct tcp_buf *buf_out = tcp_buffer_new(); + assert(buf_in); + assert(buf_out); + + // Populate the struct with buffer pointers + ctx->buf_in = buf_in; + ctx->buf_out = buf_out; + + // Set up socket details + ctx->socket_run = true; + ctx->listen_port = listen_port; + ctx->display_name = strdup(display_name); + assert(ctx->display_name); + + if (pthread_create(&ctx->sock_thread, NULL, server_create, (void *)ctx) != + 0) { + fprintf(stderr, "%s: Unable to create TCP socket thread\n", + ctx->display_name); + ctx_free(ctx); + free(ctx); + return NULL; + } + return ctx; +} + +bool tcp_server_read(struct tcp_server_ctx *ctx, char *dat) { + return tcp_buffer_get_byte(ctx->buf_in, dat); +} + +void tcp_server_write(struct tcp_server_ctx *ctx, char dat) { + tcp_buffer_put_byte(ctx->buf_out, dat); +} + +void tcp_server_close(struct tcp_server_ctx *ctx) { + // Shut down the socket thread + ctx->socket_run = false; + pthread_join(ctx->sock_thread, NULL); + ctx_free(ctx); +} + +void tcp_server_client_close(struct tcp_server_ctx *ctx) { + assert(ctx); + + if (!ctx->cfd) { + return; + } + + close(ctx->cfd); + ctx->cfd = 0; +} diff --git a/soc/dpi/common/tcp_server.h b/soc/dpi/common/tcp_server.h new file mode 100644 index 0000000..303c09c --- /dev/null +++ b/soc/dpi/common/tcp_server.h @@ -0,0 +1,69 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +/** + * Functions to create and interact with a threaded TCP server + * + * This is intended to be used by simulation add-on DPI modules to provide + * basic TCP socket communication between a host and simulated peripherals. + */ + +#ifndef TCP_SERVER_H_ +#define TCP_SERVER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +struct tcp_server_ctx; + +/** + * Non-blocking read of a byte from a connected client + * + * @param ctx tcp server context object + * @param dat byte received + * @return true if a byte was read + */ +bool tcp_server_read(struct tcp_server_ctx *ctx, char *dat); + +/** + * Write a byte to a connected client + * + * The write is internally buffered and so does not block if the client is not + * ready to accept data, but does block if the buffer is full. + * + * @param ctx tcp server context object + * @param dat byte to send + */ +void tcp_server_write(struct tcp_server_ctx *ctx, char dat); + +/** + * Create a new TCP server instance + * + * @param display_name C string description of server + * @param listen_port On which port the server should listen + * @return A pointer to the created context struct + */ +tcp_server_ctx *tcp_server_create(const char *display_name, int listen_port); + +/** + * Shut down the server and free all reserved memory + * + * @param ctx tcp server context object + */ +void tcp_server_close(struct tcp_server_ctx *ctx); + +/** + * Instruct the server to disconnect a client + * + * @param ctx tcp server context object + */ +void tcp_server_client_close(struct tcp_server_ctx *ctx); + +#ifdef __cplusplus +} // extern "C" +#endif +#endif // TCP_SERVER_H_ diff --git a/soc/dpi/jtagdpi/jtagdpi.c b/soc/dpi/jtagdpi/jtagdpi.c new file mode 100644 index 0000000..5d1ee6f --- /dev/null +++ b/soc/dpi/jtagdpi/jtagdpi.c @@ -0,0 +1,154 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +#include "jtagdpi.h" + +#include +#include +#include +#include +#include + +#include "../common/tcp_server.h" + +struct jtagdpi_ctx { + // Server context + struct tcp_server_ctx *sock; + // Signals + uint8_t tck; + uint8_t tms; + uint8_t tdi; + uint8_t tdo; + uint8_t trst_n; + uint8_t srst_n; +}; + +/** + * Reset the JTAG signals to a "dongle unplugged" state + */ +static void reset_jtag_signals(struct jtagdpi_ctx *ctx) { + assert(ctx); + + ctx->tck = 0; + ctx->tms = 0; + ctx->tdi = 0; + + // trst_n is pulled down (reset active) by default + ctx->trst_n = 0; + + // srst_n is pulled up (reset not active) by default + ctx->srst_n = 1; +} + +/** + * Update the JTAG signals in the context structure + */ +static void update_jtag_signals(struct jtagdpi_ctx *ctx) { + assert(ctx); + + /* + * Documentation pointer: + * The remote_bitbang protocol implemented below is documented in the OpenOCD + * source tree at doc/manual/jtag/drivers/remote_bitbang.txt, or online at + * https://repo.or.cz/openocd.git/blob/HEAD:/doc/manual/jtag/drivers/remote_bitbang.txt + */ + + // read a command byte + char cmd; + if (!tcp_server_read(ctx->sock, &cmd)) { + return; + } + + bool act_send_resp = false; + bool act_quit = false; + + // parse received command byte + if (cmd >= '0' && cmd <= '7') { + // JTAG write + char cmd_bit = cmd - '0'; + ctx->tdi = (cmd_bit >> 0) & 0x1; + ctx->tms = (cmd_bit >> 1) & 0x1; + ctx->tck = (cmd_bit >> 2) & 0x1; + } else if (cmd >= 'r' && cmd <= 'u') { + // JTAG reset (active high from OpenOCD) + char cmd_bit = cmd - 'r'; + ctx->srst_n = !((cmd_bit >> 0) & 0x1); + ctx->trst_n = !((cmd_bit >> 1) & 0x1); + } else if (cmd == 'R') { + // JTAG read + act_send_resp = true; + } else if (cmd == 'B') { + // printf("%s: BLINK ON!\n", ctx->display_name); + } else if (cmd == 'b') { + // printf("%s: BLINK OFF!\n", ctx->display_name); + } else if (cmd == 'Q') { + // quit (client disconnect) + act_quit = true; + } else { + fprintf(stderr, + "JTAG DPI Protocol violation detected: unsupported command %c\n", + cmd); + exit(1); + } + + // send tdo as response + if (act_send_resp) { + char tdo_ascii = ctx->tdo + '0'; + tcp_server_write(ctx->sock, tdo_ascii); + } + + if (act_quit) { + printf("JTAG DPI: Remote disconnected.\n"); + tcp_server_client_close(ctx->sock); + } +} + +void *jtagdpi_create(const char *display_name, int listen_port) { + struct jtagdpi_ctx *ctx = + (struct jtagdpi_ctx *)calloc(1, sizeof(struct jtagdpi_ctx)); + assert(ctx); + + // Create socket + ctx->sock = tcp_server_create(display_name, listen_port); + + reset_jtag_signals(ctx); + + printf( + "\n" + "JTAG: Virtual JTAG interface %s is listening on port %d. Use\n" + "OpenOCD and the following configuration to connect:\n" + " interface remote_bitbang\n" + " remote_bitbang_host localhost\n" + " remote_bitbang_port %d\n", + display_name, listen_port, listen_port); + + return (void *)ctx; +} + +void jtagdpi_close(void *ctx_void) { + struct jtagdpi_ctx *ctx = (struct jtagdpi_ctx *)ctx_void; + if (!ctx) { + return; + } + tcp_server_close(ctx->sock); + free(ctx); +} + +void jtagdpi_tick(void *ctx_void, svBit *tck, svBit *tms, svBit *tdi, + svBit *trst_n, svBit *srst_n, const svBit tdo) { + struct jtagdpi_ctx *ctx = (struct jtagdpi_ctx *)ctx_void; + + ctx->tdo = tdo; + + // TODO: Evaluate moving this functionality into a separate thread + if (ctx) { + update_jtag_signals(ctx); + } + + *tdi = ctx->tdi; + *tms = ctx->tms; + *tck = ctx->tck; + *srst_n = ctx->srst_n; + *trst_n = ctx->trst_n; +} diff --git a/soc/dpi/jtagdpi/jtagdpi.h b/soc/dpi/jtagdpi/jtagdpi.h new file mode 100644 index 0000000..0888871 --- /dev/null +++ b/soc/dpi/jtagdpi/jtagdpi.h @@ -0,0 +1,56 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +#ifndef JTAGDPI_H_ +#define JTAGDPI_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct jtagdpi_ctx; + +/** + * Constructor: Create and initialize jtagdpi context object + * + * Call from a initial block. + * + * @param display_name Name of the JTAG interface (for display purposes only) + * @param listen_port Port to listen on + * @return an initialized struct jtagdpi_ctx context object + */ +void *jtagdpi_create(const char *display_name, int listen_port); + +/** + * Destructor: Close all connections and free all resources + * + * Call from a finish block. + * + * @param ctx_void a struct jtagdpi_ctx context object + */ +void jtagdpi_close(void *ctx_void); + +/** + * Drive JTAG signals + * + * Call this function from the simulation at every clock tick to read/write + * from/to the JTAG signals. + * + * @param ctx_void a struct jtagdpi_ctx context object + * @param tck JTAG test clock signal + * @param tms JTAG test mode select signal + * @param tdi JTAG test data input signal + * @param trst_n JTAG test reset signal (active low) + * @param srst_n JTAG system reset signal (active low) + * @param tdo JTAG test data out + */ +void jtagdpi_tick(void *ctx_void, svBit *tck, svBit *tms, svBit *tdi, + svBit *trst_n, svBit *srst_n, const svBit tdo); + +#ifdef __cplusplus +} // extern "C" +#endif +#endif // JTAGDPI_H_ diff --git a/soc/dpi/jtagdpi/jtagdpi.sv b/soc/dpi/jtagdpi/jtagdpi.sv new file mode 100644 index 0000000..50b0cca --- /dev/null +++ b/soc/dpi/jtagdpi/jtagdpi.sv @@ -0,0 +1,47 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +module jtagdpi #( + parameter string Name = "jtag0", // name of the JTAG interface (display only) + parameter int ListenPort = 44853 // TCP port to listen on +)( + input logic clk_i, + input logic rst_ni, + + output logic jtag_tck, + output logic jtag_tms, + output logic jtag_tdi, + input logic jtag_tdo, + output logic jtag_trst_n, + output logic jtag_srst_n +); + + import "DPI-C" + function chandle jtagdpi_create(input string name, input int listen_port); + + import "DPI-C" + function void jtagdpi_tick(input chandle ctx, output bit tck, output bit tms, + output bit tdi, output bit trst_n, + output bit srst_n, input bit tdo); + + import "DPI-C" + function void jtagdpi_close(input chandle ctx); + + chandle ctx; + + initial begin + ctx = jtagdpi_create(Name, ListenPort); + end + + final begin + jtagdpi_close(ctx); + ctx = 0; + end + + always_ff @(posedge clk_i, negedge rst_ni) begin + jtagdpi_tick(ctx, jtag_tck, jtag_tms, jtag_tdi, jtag_trst_n, jtag_srst_n, + jtag_tdo); + end + +endmodule diff --git a/soc/flist b/soc/flist deleted file mode 100644 index 1d634e3..0000000 --- a/soc/flist +++ /dev/null @@ -1,44 +0,0 @@ -$RV_ROOT/design/swerv_wrapper.sv -$RV_ROOT/design/mem.sv -$RV_ROOT/design/pic_ctrl.sv -$RV_ROOT/design/swerv.sv -$RV_ROOT/design/dma_ctrl.sv -$RV_ROOT/design/ifu/ifu_aln_ctl.sv -$RV_ROOT/design/ifu/ifu_compress_ctl.sv -$RV_ROOT/design/ifu/ifu_ifc_ctl.sv -$RV_ROOT/design/ifu/ifu_bp_ctl.sv -$RV_ROOT/design/ifu/ifu_ic_mem.sv -$RV_ROOT/design/ifu/ifu_mem_ctl.sv -$RV_ROOT/design/ifu/ifu_iccm_mem.sv -$RV_ROOT/design/ifu/ifu.sv -$RV_ROOT/design/dec/dec_decode_ctl.sv -$RV_ROOT/design/dec/dec_gpr_ctl.sv -$RV_ROOT/design/dec/dec_ib_ctl.sv -$RV_ROOT/design/dec/dec_tlu_ctl.sv -$RV_ROOT/design/dec/dec_trigger.sv -$RV_ROOT/design/dec/dec.sv -$RV_ROOT/design/exu/exu_alu_ctl.sv -$RV_ROOT/design/exu/exu_mul_ctl.sv -$RV_ROOT/design/exu/exu_div_ctl.sv -$RV_ROOT/design/exu/exu.sv -$RV_ROOT/design/lsu/lsu.sv -$RV_ROOT/design/lsu/lsu_clkdomain.sv -$RV_ROOT/design/lsu/lsu_addrcheck.sv -$RV_ROOT/design/lsu/lsu_lsc_ctl.sv -$RV_ROOT/design/lsu/lsu_stbuf.sv -$RV_ROOT/design/lsu/lsu_bus_buffer.sv -$RV_ROOT/design/lsu/lsu_bus_intf.sv -$RV_ROOT/design/lsu/lsu_ecc.sv -$RV_ROOT/design/lsu/lsu_dccm_mem.sv -$RV_ROOT/design/lsu/lsu_dccm_ctl.sv -$RV_ROOT/design/lsu/lsu_trigger.sv -$RV_ROOT/design/dbg/dbg.sv -$RV_ROOT/design/dmi/dmi_wrapper.v -$RV_ROOT/design/dmi/dmi_jtag_to_core_sync.v -$RV_ROOT/design/dmi/rvjtag_tap.sv --v $RV_ROOT/design/lib/beh_lib.sv --v $RV_ROOT/design/lib/mem_lib.sv --v $RV_ROOT/design/lib/ahb_to_axi4.sv --v $RV_ROOT/design/lib/axi4_to_ahb.sv - -$RV_ROOT/soc/ahb_sif.sv \ No newline at end of file diff --git a/soc/soc.mk b/soc/soc.mk new file mode 100644 index 0000000..f4d1e9f --- /dev/null +++ b/soc/soc.mk @@ -0,0 +1,56 @@ +../design/include/swerv_types.sv + +../design/swerv_wrapper.sv +../design/mem.sv +../design/pic_ctrl.sv +../design/swerv.sv +../design/dma_ctrl.sv +../design/ifu/ifu_aln_ctl.sv +../design/ifu/ifu_compress_ctl.sv +../design/ifu/ifu_ifc_ctl.sv +../design/ifu/ifu_bp_ctl.sv +../design/ifu/ifu_ic_mem.sv +../design/ifu/ifu_mem_ctl.sv +../design/ifu/ifu_iccm_mem.sv +../design/ifu/ifu.sv +../design/dec/dec_decode_ctl.sv +../design/dec/dec_gpr_ctl.sv +../design/dec/dec_ib_ctl.sv +../design/dec/dec_tlu_ctl.sv +../design/dec/dec_trigger.sv +../design/dec/dec.sv +../design/exu/exu_alu_ctl.sv +../design/exu/exu_mul_ctl.sv +../design/exu/exu_div_ctl.sv +../design/exu/exu.sv +../design/lsu/lsu.sv +../design/lsu/lsu_clkdomain.sv +../design/lsu/lsu_addrcheck.sv +../design/lsu/lsu_lsc_ctl.sv +../design/lsu/lsu_stbuf.sv +../design/lsu/lsu_bus_buffer.sv +../design/lsu/lsu_bus_intf.sv +../design/lsu/lsu_ecc.sv +../design/lsu/lsu_dccm_mem.sv +../design/lsu/lsu_dccm_ctl.sv +../design/lsu/lsu_trigger.sv +../design/dbg/dbg.sv +../design/dmi/dmi_wrapper.v +../design/dmi/dmi_jtag_to_core_sync.v +../design/dmi/rvjtag_tap.sv +-v ../design/lib/beh_lib.sv +-v ../design/lib/mem_lib.sv +-v ../design/lib/ahb_to_axi4.sv +-v ../design/lib/axi4_to_ahb.sv + +./ahb_sif.sv + +-I../design/include +-I./ + +-CFLAGS -lpthread +-LDFLAGS -lpthread + +./dpi/common/tcp_server.c +./dpi/jtagdpi/jtagdpi.sv +./dpi/jtagdpi/jtagdpi.c