1 // Copyright 2017-2019 VMware, Inc.
2 // SPDX-License-Identifier: BSD-2-Clause
3 //
4 // The BSD-2 license (the License) set forth below applies to all parts of the
5 // Cascade project. You may not use this file except in compliance with the
6 // License.
7 //
8 // BSD-2 License
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are met:
12 //
13 // 1. Redistributions of source code must retain the above copyright notice, this
14 // list of conditions and the following disclaimer.
15 //
16 // 2. Redistributions in binary form must reproduce the above copyright notice,
17 // this list of conditions and the following disclaimer in the documentation
18 // and/or other materials provided with the distribution.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND
21 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 #include <iostream>
32 #include <mutex>
33 #include <ncurses.h>
34 #include <string>
35 #include "cl/cl.h"
36 #include "common/bits.h"
37 #include "target/compiler/remote_compiler.h"
38 #include "target/core/sw/sw_compiler.h"
39
40 using namespace cascade;
41 using namespace cascade::cl;
42 using namespace std;
43
44 namespace {
45
46 __attribute__((unused)) auto& g = Group::create("Software Target Options");
47 auto& port = StrArg<size_t>::create("--port")
48 .usage("<int>")
49 .description("Port to listen for connections on")
50 .initial(8800);
51 auto& path = StrArg<string>::create("--path")
52 .usage("<path/to/socket>")
53 .description("Path to listen for connections on")
54 .initial("/tmp/fpga_socket");
55
toggle_pad(Bits & pad,mutex & pad_lock,char c)56 void toggle_pad(Bits& pad, mutex& pad_lock, char c) {
57 lock_guard<mutex> lg(pad_lock);
58 pad.flip(c-'1');
59 }
60
toggle_rst(Bits & rst,mutex & rst_lock)61 void toggle_rst(Bits& rst, mutex& rst_lock) {
62 lock_guard<mutex> lg(rst_lock);
63 rst.flip(0);
64 }
65
draw_pad(Bits & pad,mutex & pad_lock,int row,int col)66 void draw_pad(Bits& pad, mutex& pad_lock, int row, int col) {
67 lock_guard<mutex> lg(pad_lock);
68 for (int i = 0; i < 4; ++i) {
69 const auto p = pad.get(i) ? '_' : '-';
70 attron(COLOR_PAIR(2));
71 mvprintw((row/2)+1, (col/2)+(2*i)-4, "%c ", p);
72 attroff(COLOR_PAIR(2));
73 }
74 }
75
draw_rst(Bits & rst,mutex & rst_lock,int row,int col)76 void draw_rst(Bits& rst, mutex& rst_lock, int row, int col) {
77 lock_guard<mutex> lg(rst_lock);
78 const auto r = rst.to_bool() ? '_' : '-';
79 attron(COLOR_PAIR(1));
80 mvprintw((row/2)+1, (col/2)+6, "%c ", r);
81 attroff(COLOR_PAIR(1));
82 }
83
draw_led(Bits & led,mutex & led_lock,int row,int col)84 void draw_led(Bits& led, mutex& led_lock, int row, int col) {
85 lock_guard<mutex> lg(led_lock);
86 for (int i = 0; i < 8; ++i) {
87 const auto l = led.get(i);
88 const auto cl = l ? 1 : 2;
89 const auto ch = l ? '*' : '.';
90 attron(COLOR_PAIR(cl));
91 mvprintw((row/2)-1, (col/2)+(2*i)-8, "%c ", ch);
92 attroff(COLOR_PAIR(cl));
93 }
94 }
95
96 } // namespace
97
main(int argc,char ** argv)98 int main(int argc, char** argv) {
99 // Parse command line:
100 Simple::read(argc, argv);
101
102 initscr();
103 timeout(1000/40);
104 noecho();
105 curs_set(0);
106 raw();
107 start_color();
108
109 init_color(COLOR_WHITE, 700, 700, 700);
110 init_pair(1, COLOR_RED, COLOR_BLACK);
111 init_pair(2, COLOR_WHITE, COLOR_BLACK);
112
113 Bits led(8, 0);
114 Bits pad(4, 0);
115 Bits rst(1, 0);
116
117 mutex led_lock;
118 mutex pad_lock;
119 mutex rst_lock;
120
121 auto* rc = new RemoteCompiler();
122 rc->set_path(::path.value());
123 rc->set_port(::port.value());
124 auto* sc = new sw::SwCompiler();
125 sc->set_led(&led, &led_lock);
126 sc->set_pad(&pad, &pad_lock);
127 sc->set_reset(&rst, &rst_lock);
128 rc->set("sw", sc);
129 rc->run();
130
131 for (auto running = true; running; ) {
132 auto input = getch();
133 switch (input) {
134 case '1':
135 case '2':
136 case '3':
137 case '4':
138 toggle_pad(pad, pad_lock, input);
139 break;
140 case 'r':
141 toggle_rst(rst, rst_lock);
142 break;
143 case 'q':
144 running = false;
145 rc->stop_now();
146 break;
147 default:
148 break;
149 }
150
151 int row;
152 int col;
153 getmaxyx(stdscr, row, col);
154 draw_pad(pad, pad_lock, row, col);
155 draw_rst(rst, rst_lock, row, col);
156 draw_led(led, led_lock, row, col);
157 refresh();
158 }
159 endwin();
160
161 delete rc;
162
163 cout << "Goodbye!" << endl;
164 return 0;
165 }
166