remove cruft, add comments
[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 /* reads from a socket if it is ready (a single byte) and returns 1 if success
22 */
23 int read_handler(int fdread, char *buffer)
24 {
25 ssize_t read_len;
26 fd_set read_fds;
27 FD_ZERO(&read_fds);
28 struct timeval tv;
29 FD_SET(fdread, &read_fds);
30 int status;
31
32 tv.tv_sec = 0;
33 tv.tv_usec = 1;
34
35 status = select(fdread+1, &read_fds, NULL, NULL, &tv);
36 switch (status)
37 {
38 case -1:
39 printf("Error reading on socket\n");
40 exit(status); // error
41 return 0;
42 case 0:
43 return 0; // timeout (nothing read)
44 default:
45 return read(fdread, buffer, 1);
46 }
47 }
48
49 /* nothing sophisticated: wait for an incoming connection
50 */
51 int get_connection()
52 {
53 int listenfd = 0, connfd = 0;
54 int flag = 1;
55 struct sockaddr_in serv_addr;
56
57 listenfd = socket(AF_INET, SOCK_STREAM, 0);
58 memset(&serv_addr, '0', sizeof(serv_addr));
59
60 serv_addr.sin_family = AF_INET;
61 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
62 serv_addr.sin_port = htons(5000);
63
64 bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
65
66 listen(listenfd, 1);
67
68 connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
69 close(listenfd);
70
71 setsockopt(connfd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int));
72 return connfd;
73 }
74
75 } // extern "C"
76
77 /* main function which polls the socket and talks openocd jtagremote protocol.
78 dead simple: incoming number 0-7 sets TCK, TMS and TDK. request "R"
79 indicates that receiver wants to know the status of TDO.
80 "Q" means "quit socket".
81 */
82 void read_openocd_jtagremote(cxxrtl_design::p_add &top, int sock)
83 {
84 char c;
85 if (read_handler(sock, &c) != 1) {
86 return;
87 }
88 printf ("read %c\n", c);
89 if ((c >= '0') && (c <= '7'))
90 {
91 top.p_tck.set<bool>(((c - '0') >> 2) & 1);
92 top.p_tms.set<bool>(((c - '0') >> 1) & 1);
93 top.p_tdi.set<bool>((c - '0') & 1);
94 }
95 if (c == 'R')
96 {
97 uint8_t val = top.p_tdo.get<uint8_t>() + '0';
98 if(-1 == write(sock, &val, 1))
99 {
100 printf("Error writing on socket\n");
101 exit(-1);
102 }
103 }
104 if (c == 'Q') {
105 printf("disconnect request\n");
106 exit(-1);
107 }
108 }
109
110 int main()
111 {
112 cxxrtl_design::p_add top;
113
114 int sock = get_connection();
115
116 top.step();
117 while (true) {
118
119 top.p_clk.set<bool>(false);
120 top.step();
121 top.p_clk.set<bool>(true);
122 top.step();
123
124 /* read and process incoming jtag */
125 read_openocd_jtagremote(top, sock);
126
127 // quick check that the output is correct (it's an adder: go figure)
128 /*
129 top.p_a.set<uint8_t>(5);
130 top.p_b.set<uint8_t>(3);
131 uint32_t f = top.p_f.get<uint32_t>();
132
133 cout << "f " << f << endl;
134 */
135 }
136 }
137