f277deecf4c95fe790b6c2b571adbcbe6d343a17
[soc-cxxrtl-sim.git] / small_jtag_test / main.cpp
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <sys/select.h>
6 #include <sys/types.h>
7 #include <sys/socket.h>
8 #include <netinet/in.h>
9 #include <arpa/inet.h>
10 #include <sys/fcntl.h>
11 #include <netinet/in.h>
12 #include <netinet/tcp.h>
13
14 #include <iostream>
15 #include "add.cpp"
16
17 using namespace std;
18
19 extern "C" {
20
21 /* nothing sophisticated: set up a listening socket
22 */
23 int setup_socket()
24 {
25 int listenfd = 0;
26 struct sockaddr_in serv_addr;
27
28 listenfd = socket(AF_INET, SOCK_STREAM, 0);
29 memset(&serv_addr, '0', sizeof(serv_addr));
30
31 serv_addr.sin_family = AF_INET;
32 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
33 serv_addr.sin_port = htons(5000);
34
35 bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
36 listen(listenfd, 1);
37
38 return listenfd;
39 }
40
41 /* sees if there is an incoming connection (non-blocking). if so,
42 accept it and return it
43 */
44 int get_connection(int listenfd)
45 {
46 int connfd = 0;
47 int flag = 1;
48 int status;
49 fd_set active_fd_set;
50
51 struct timeval tv;
52
53 tv.tv_sec = 0;
54 tv.tv_usec = 1;
55
56 /* Initialize the set of active sockets. */
57 FD_ZERO (&active_fd_set);
58 FD_SET (listenfd, &active_fd_set);
59
60 /* Block until input arrives on one or more active sockets. */
61 status = select (FD_SETSIZE, &active_fd_set, NULL, NULL, &tv);
62 switch (status)
63 {
64 case -1:
65 printf("Error listening on socket\n");
66 exit(status); // error
67 return -1;
68 case 0:
69 return -1; // timeout (nothing read)
70 default:
71 // return accepted socket
72 connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
73 setsockopt(connfd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag,
74 sizeof(int));
75 return connfd;
76 }
77 }
78
79 /* reads from a socket if it is ready (a single byte) and returns 1 if success
80 */
81 int read_handler(int fdread, char *buffer)
82 {
83 ssize_t read_len;
84 fd_set read_fds;
85 FD_ZERO(&read_fds);
86 FD_SET(fdread, &read_fds);
87 int status;
88 struct timeval tv;
89
90 tv.tv_sec = 0;
91 tv.tv_usec = 1;
92
93 status = select(fdread+1, &read_fds, NULL, NULL, &tv);
94 switch (status)
95 {
96 case -1:
97 printf("Error reading on socket\n");
98 exit(status); // error
99 return 0;
100 case 0:
101 return 0; // timeout (nothing read)
102 default:
103 return read(fdread, buffer, 1);
104 }
105 }
106
107 } // extern "C"
108
109 /* main function which polls the socket and talks openocd jtagremote protocol.
110 dead simple: incoming number 0-7 sets TCK, TMS and TDK. request "R"
111 indicates that receiver wants to know the status of TDO.
112 "Q" means "quit socket".
113 */
114 int read_openocd_jtagremote(cxxrtl_design::p_add &top, int sock)
115 {
116 char c;
117 if (read_handler(sock, &c) != 1) {
118 return sock;
119 }
120 printf ("read %c\n", c);
121 if ((c >= '0') && (c <= '7'))
122 {
123 top.p_tck.set<bool>(((c - '0') >> 2) & 1);
124 top.p_tms.set<bool>(((c - '0') >> 1) & 1);
125 top.p_tdi.set<bool>((c - '0') & 1);
126 }
127 if (c == 'R')
128 {
129 uint8_t val = top.p_tdo.get<uint8_t>() + '0';
130 if(-1 == write(sock, &val, 1))
131 {
132 printf("Error writing on socket\n");
133 close(sock);
134 sock = -1;
135 }
136 }
137 if (c == 'Q') {
138 printf("disconnect request\n");
139 close(sock);
140 sock = -1;
141 }
142 return sock;
143 }
144
145 int main()
146 {
147 cxxrtl_design::p_add top;
148
149 int listenfd = setup_socket();
150 int sock = -1;
151
152 top.step();
153 while (true) {
154
155 top.p_clk.set<bool>(false);
156 top.step();
157 top.p_clk.set<bool>(true);
158 top.step();
159
160 // if no current connection see if there is one
161 if (sock == -1) {
162 sock = get_connection(listenfd);
163 }
164 /* read and process incoming jtag. sock set to -1 if disconnected */
165 sock = read_openocd_jtagremote(top, sock);
166
167 // quick check that the output is correct (it's an adder: go figure)
168 /*
169 top.p_a.set<uint8_t>(5);
170 top.p_b.set<uint8_t>(3);
171 uint32_t f = top.p_f.get<uint32_t>();
172
173 cout << "f " << f << endl;
174 */
175 }
176 }
177