--- /dev/null
+STATE RESET IDLE;
+TIR 0 ;
+HIR 5 TDI (1f) SMASK (1f) ;
+//HDR 1 TDI (00) SMASK (01) ;
+TDR 0 ;
+//Loading device with 'idcode' instruction.
+SIR 4 TDI (1) SMASK (f) ;
+//SDR 32 TDI (00000000) SMASK (ffffffff) TDO (00000c7f) SMASK (ffffffff) ;
+SDR 32 TDI (00000000) SMASK (ffffffff) TDO (000018ff) MASK (ffffffff) ;
+//
+
+// set to DMI "address"
+SIR 4 TDI (8) SMASK (f) ;
+// set DMI "ctrl" address (0)
+SDR 8 TDI (0) SMASK (ff) ;
+// set to DMI "data read"
+SIR 4 TDI (9) SMASK (f) ;
+// read 64 bit
+SDR 64 TDI (0000000000000000) SMASK (0000000000000000) TDO (0000000000000004) MASK (ffffffffffffffff) ;
+
+// set to DMI "address"
+SIR 4 TDI (8) SMASK (f) ;
+// set DMI "ctrl" address (0)
+SDR 8 TDI (0) SMASK (ff) ;
+// set to DMI "data write-read"
+SIR 4 TDI (a) SMASK (f) ;
+// write-read 64 bit
+SDR 64 TDI (0000000000000002) SMASK (ffffffffffffffff) TDO (0000000000000004) MASK (ffffffffffffffff) ;
+
+// set to DMI "address"
+SIR 4 TDI (8) SMASK (f) ;
+// set DMI "ctrl" address (0)
+SDR 8 TDI (0) SMASK (ff) ;
+// set to DMI "data read"
+SIR 4 TDI (9) SMASK (f) ;
+// read 64 bit
+SDR 64 TDI (0000000000000000) SMASK (0000000000000000) TDO (0000000000000002) MASK (ffffffffffffffff) ;
+
+// set to DMI "address"
+SIR 4 TDI (8) SMASK (f) ;
+// set DMI "MSR" address (3)
+SDR 8 TDI (3) SMASK (ff) ;
+// set to DMI "data read"
+SIR 4 TDI (9) SMASK (f) ;
+// read 64 bit
+SDR 64 TDI (0000000000000000) SMASK (0000000000000000) TDO (00000000deadbeef) MASK (ffffffffffffffff) ;
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/select.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/fcntl.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+
+#include <iostream>
+#include <fstream>
+
+#include "ls180.cpp"
+
+#define VCD
+
+#ifdef VCD
+#include <backends/cxxrtl/cxxrtl_vcd.h>
+#endif
+
+using namespace std;
+
+extern "C" {
+
+/* nothing sophisticated: set up a listening socket
+ */
+int setup_socket()
+{
+ int listenfd = 0;
+ struct sockaddr_in serv_addr;
+
+ listenfd = socket(AF_INET, SOCK_STREAM, 0);
+ memset(&serv_addr, '0', sizeof(serv_addr));
+
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ serv_addr.sin_port = htons(44853);
+
+ bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
+ listen(listenfd, 1);
+
+ return listenfd;
+}
+
+/* sees if there is an incoming connection (non-blocking). if so,
+ accept it and return it
+ */
+int get_connection(int listenfd)
+{
+ int connfd = 0;
+ int flag = 1;
+ int status;
+ fd_set active_fd_set;
+
+ struct timeval tv;
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 1;
+
+ /* Initialize the set of active sockets. */
+ FD_ZERO (&active_fd_set);
+ FD_SET (listenfd, &active_fd_set);
+
+ /* Block until input arrives on one or more active sockets. */
+ status = select (FD_SETSIZE, &active_fd_set, NULL, NULL, &tv);
+ switch (status)
+ {
+ case -1:
+ printf("Error listening on socket\n");
+ exit(status); // error
+ return -1;
+ case 0:
+ return -1; // timeout (nothing read)
+ default:
+ // return accepted socket
+ connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
+ setsockopt(connfd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag,
+ sizeof(int));
+ return connfd;
+ }
+}
+
+/* reads from a socket if it is ready (a single byte) and returns 1 if success
+ */
+int read_handler(int fdread, char *buffer)
+{
+ ssize_t read_len;
+ fd_set read_fds;
+ FD_ZERO(&read_fds);
+ FD_SET(fdread, &read_fds);
+ int status;
+ struct timeval tv;
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 1;
+
+ status = select(fdread+1, &read_fds, NULL, NULL, &tv);
+ switch (status)
+ {
+ case -1:
+ printf("Error reading on socket\n");
+ exit(status); // error
+ return 0;
+ case 0:
+ return 0; // timeout (nothing read)
+ default:
+ status = read(fdread, buffer, 1);
+ if (status == -1) {
+ printf("Error reading on socket\n");
+ close(fdread);
+ }
+ return status;
+ }
+}
+
+} // extern "C"
+
+/* main function which polls the socket and talks openocd jtagremote protocol.
+ dead simple: incoming number 0-7 sets TCK, TMS and TDK. request "R"
+ indicates that receiver wants to know the status of TDO.
+ "Q" means "quit socket".
+*/
+int read_openocd_jtagremote(cxxrtl_design::p_ls180 &top, int sock)
+{
+ char c;
+ if (read_handler(sock, &c) != 1) {
+ return sock;
+ }
+ printf ("read %c\n", c);
+ if ((c >= '0') && (c <= '7'))
+ {
+ top.p_jtag__tck.set<bool>(((c - '0') >> 2) & 1);
+ top.p_jtag__tms.set<bool>(((c - '0') >> 1) & 1);
+ top.p_jtag__tdi.set<bool>((c - '0') & 1);
+ }
+ if (c == 'R')
+ {
+ uint8_t val = top.p_jtag__tdo.get<uint8_t>() + '0';
+ if(-1 == write(sock, &val, 1))
+ {
+ printf("Error writing on socket\n");
+ close(sock);
+ sock = -1;
+ }
+ }
+ if (c == 'Q') {
+ printf("disconnect request\n");
+ close(sock);
+ sock = -1;
+ }
+ return sock;
+}
+
+int main()
+{
+ cxxrtl_design::p_ls180 top;
+ int steps = 0;
+
+#ifdef VCD
+ // Load the debug items of the top down the whole design hierarchy
+ cxxrtl::debug_items all_debug_items;
+ top.debug_info(all_debug_items);
+
+ // set up vcdwriter with 1ns resu
+ cxxrtl::vcd_writer vcd;
+ vcd.timescale(1, "us");
+#endif
+
+ int listenfd = setup_socket();
+ int sock = -1;
+
+#ifdef VCD
+ //vcd.add_without_memories(all_debug_items);
+ vcd.add(all_debug_items);
+ std::ofstream waves("waves.vcd");
+#endif
+
+ top.step();
+#ifdef VCD
+ vcd.sample(0);
+#endif
+ while (true) {
+
+ top.p_sys__clk.set<bool>(false);
+ top.step();
+#ifdef VCD
+ vcd.sample(steps*2 + 0);
+#endif
+ top.p_sys__clk.set<bool>(true);
+ top.step();
+#ifdef VCD
+ vcd.sample(steps*2 + 1);
+#endif
+ steps++;
+
+ // if no current connection see if there is one
+ if (sock == -1) {
+ sock = get_connection(listenfd);
+ }
+ /* read and process incoming jtag. sock set to -1 if disconnected */
+ sock = read_openocd_jtagremote(top, sock);
+
+ waves << vcd.buffer;
+ vcd.buffer.clear();
+ }
+}
+