add missing files
[soc-cxxrtl-sim.git] / ls180_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 <fstream>
16
17 #include "ls180.cpp"
18
19 #define VCD
20
21 #ifdef VCD
22 #include <backends/cxxrtl/cxxrtl_vcd.h>
23 #endif
24
25 using namespace std;
26
27 extern "C" {
28
29 /* nothing sophisticated: set up a listening socket
30 */
31 int setup_socket()
32 {
33 int listenfd = 0;
34 struct sockaddr_in serv_addr;
35
36 listenfd = socket(AF_INET, SOCK_STREAM, 0);
37 memset(&serv_addr, '0', sizeof(serv_addr));
38
39 serv_addr.sin_family = AF_INET;
40 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
41 serv_addr.sin_port = htons(44853);
42
43 bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
44 listen(listenfd, 1);
45
46 return listenfd;
47 }
48
49 /* sees if there is an incoming connection (non-blocking). if so,
50 accept it and return it
51 */
52 int get_connection(int listenfd)
53 {
54 int connfd = 0;
55 int flag = 1;
56 int status;
57 fd_set active_fd_set;
58
59 struct timeval tv;
60
61 tv.tv_sec = 0;
62 tv.tv_usec = 1;
63
64 /* Initialize the set of active sockets. */
65 FD_ZERO (&active_fd_set);
66 FD_SET (listenfd, &active_fd_set);
67
68 /* Block until input arrives on one or more active sockets. */
69 status = select (FD_SETSIZE, &active_fd_set, NULL, NULL, &tv);
70 switch (status)
71 {
72 case -1:
73 printf("Error listening on socket\n");
74 exit(status); // error
75 return -1;
76 case 0:
77 return -1; // timeout (nothing read)
78 default:
79 // return accepted socket
80 connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
81 setsockopt(connfd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag,
82 sizeof(int));
83 return connfd;
84 }
85 }
86
87 /* reads from a socket if it is ready (a single byte) and returns 1 if success
88 */
89 int read_handler(int fdread, char *buffer)
90 {
91 ssize_t read_len;
92 fd_set read_fds;
93 FD_ZERO(&read_fds);
94 FD_SET(fdread, &read_fds);
95 int status;
96 struct timeval tv;
97
98 tv.tv_sec = 0;
99 tv.tv_usec = 1;
100
101 status = select(fdread+1, &read_fds, NULL, NULL, &tv);
102 switch (status)
103 {
104 case -1:
105 printf("Error reading on socket\n");
106 exit(status); // error
107 return 0;
108 case 0:
109 return 0; // timeout (nothing read)
110 default:
111 status = read(fdread, buffer, 1);
112 if (status == -1) {
113 printf("Error reading on socket\n");
114 close(fdread);
115 }
116 return status;
117 }
118 }
119
120 } // extern "C"
121
122 /* main function which polls the socket and talks openocd jtagremote protocol.
123 dead simple: incoming number 0-7 sets TCK, TMS and TDK. request "R"
124 indicates that receiver wants to know the status of TDO.
125 "Q" means "quit socket".
126 */
127 int read_openocd_jtagremote(cxxrtl_design::p_ls180 &top, int sock)
128 {
129 char c;
130 if (read_handler(sock, &c) != 1) {
131 return sock;
132 }
133 printf ("read %c\n", c);
134 if ((c >= '0') && (c <= '7'))
135 {
136 top.p_jtag__tck.set<bool>(((c - '0') >> 2) & 1);
137 top.p_jtag__tms.set<bool>(((c - '0') >> 1) & 1);
138 top.p_jtag__tdi.set<bool>((c - '0') & 1);
139 }
140 if (c == 'R')
141 {
142 uint8_t val = top.p_jtag__tdo.get<uint8_t>() + '0';
143 if(-1 == write(sock, &val, 1))
144 {
145 printf("Error writing on socket\n");
146 close(sock);
147 sock = -1;
148 }
149 }
150 if (c == 'Q') {
151 printf("disconnect request\n");
152 close(sock);
153 sock = -1;
154 }
155 return sock;
156 }
157
158 int main()
159 {
160 cxxrtl_design::p_ls180 top;
161 int steps = 0;
162
163 #ifdef VCD
164 // Load the debug items of the top down the whole design hierarchy
165 cxxrtl::debug_items all_debug_items;
166 top.debug_info(all_debug_items);
167
168 // set up vcdwriter with 1ns resu
169 cxxrtl::vcd_writer vcd;
170 vcd.timescale(1, "us");
171 #endif
172
173 int listenfd = setup_socket();
174 int sock = -1;
175
176 #ifdef VCD
177 //vcd.add_without_memories(all_debug_items);
178 vcd.add(all_debug_items);
179 std::ofstream waves("waves.vcd");
180 #endif
181
182 top.step();
183 #ifdef VCD
184 vcd.sample(0);
185 #endif
186 while (true) {
187
188 top.p_sys__clk.set<bool>(false);
189 top.step();
190 #ifdef VCD
191 vcd.sample(steps*2 + 0);
192 #endif
193 top.p_sys__clk.set<bool>(true);
194 top.step();
195 #ifdef VCD
196 vcd.sample(steps*2 + 1);
197 #endif
198 steps++;
199
200 // if no current connection see if there is one
201 if (sock == -1) {
202 sock = get_connection(listenfd);
203 }
204 /* read and process incoming jtag. sock set to -1 if disconnected */
205 sock = read_openocd_jtagremote(top, sock);
206
207 waves << vcd.buffer;
208 vcd.buffer.clear();
209 }
210 }
211