44 cci::cci_param<bool> p_read_write;
45 cci::cci_param<std::string> p_expect;
46 cci::cci_param<std::string> p_highlight;
49 std::atomic_bool m_running;
50 std::thread rcv_thread_id;
51 std::atomic<bool> c_flag;
55 sc_core::sc_event ecmdev;
56 bool processing =
false;
57 static descriptor_t stdin_fd;
66 static console_mode_t old_console_mode;
67 static bool old_console_mode_valid;
71 static void restore_old_mode()
79 static void set_raw_mode()
81 if (!old_console_mode_valid &&
GetConsoleMode(stdin_fd, &old_console_mode)) {
82 old_console_mode_valid =
true;
88 static void set_default_mode()
93 descriptor_t get_stdin_descriptor()
97 SCP_WARN(())(
"char_backend_stdio: Failed to get standard input descriptor. Error: {}",
GetLastError());
108 enqueue(
record.Event.KeyEvent.uChar.AsciiChar);
138 descriptor_t get_stdin_descriptor() {
return STDIN_FILENO; }
140 static void restore_old_mode()
147 static void set_raw_mode()
151 if (!old_console_mode_valid) {
152 old_console_mode =
tty;
153 old_console_mode_valid =
true;
159 static void set_default_mode()
184 int r = read(
fd, &
c, 1);
199 void catch_fn(
int signo) {}
201 static void tty_reset()
203 if (old_console_mode_valid) {
211 std::string& rtrim(std::string& s)
213 const char*
t =
"\n\r\f\v";
214 s.erase(s.find_last_not_of(
t) + 1);
217 std::string getecmdstr(
const std::string& cmd)
219 return ecmd.substr(cmd.length(), ecmd.find_first_of(
"\n") - cmd.length());
226 void expect_process()
228 if (!processing)
return;
230 const std::string
sendstr =
"send ";
231 const std::string
waitstr =
"wait ";
232 const std::string
exitstr =
"exit";
236 std::regex
restr(str);
237 if (std::regex_search(line,
restr)) {
238 SCP_WARN(())(
"Found expect string {}", rtrim(line));
239 ecmd.erase(0, ecmd.find_first_of(
"\n"));
240 if (ecmd !=
"") ecmd.erase(0, 1);
247 for (
char c : getecmdstr(
sendstr)) {
251 ecmd.erase(0, ecmd.find_first_of(
"\n"));
252 if (ecmd !=
"") ecmd.erase(0, 1);
258 ecmdev.notify(
stod(getecmdstr(
waitstr)), sc_core::SC_SEC);
259 ecmd.erase(0, ecmd.find_first_of(
"\n"));
260 if (ecmd !=
"") ecmd.erase(0, 1);
283 : sc_core::sc_module(name)
284 , p_read_write(
"read_write",
true,
"read_write if true start rcv_thread")
285 , p_expect(
"expect",
"",
"string of expect commands")
286 , p_highlight(
"ansi_highlight",
"",
"ANSI highlight code to use for output, default bold")
287 , socket(
"biflow_socket")
291 SCP_TRACE(()) <<
"CharBackendStdio constructor";
293 stdin_fd = get_stdin_descriptor();
298 if (p_expect.get_value() !=
"") {
301 SCP_WARN(())(
"Processing expect string {}", ecmd);
304 gs::SigHandler::get().register_on_exit_cb(std::string(this->name()) +
".char_backend_stdio::tty_reset",
306 gs::SigHandler::get().add_sigint_handler(gs::Handler_CB::PASS);
307 gs::SigHandler::get().register_handler(std::string(this->name()) +
".char_backend_stdio::SIGINT_handler",
313 if (p_read_write) rcv_thread_id = std::thread(&char_backend_stdio::rcv_thread,
this);
316 std::atexit(tty_reset);
321 void enqueue(
char c) { socket.
enqueue(
c); }
323 void writefn(tlm::tlm_generic_payload& txn, sc_core::sc_time&
t)
325 uint8_t* data = txn.get_data_ptr();
326 if (!p_highlight.get_value().empty()) std::cout << p_highlight.get_value();
327 for (
int i = 0;
i < txn.get_streaming_width();
i++) {
329 if ((
char)data[
i] ==
'\n') {
333 line = line + (
char)data[
i];
336 if (!p_highlight.get_value().empty()) std::cout <<
"\x1B[0m";
340 void start_of_simulation()
342 if (!old_console_mode_valid) {
347 void end_of_simulation() { tty_reset(); }
351 gs::SigHandler::get().deregister_on_exit_cb(std::string(name()) +
".char_backend_stdio::tty_reset");
352 gs::SigHandler::get().deregister_handler(std::string(name()) +
".char_backend_stdio::SIGINT_handler");
354 if (rcv_thread_id.joinable()) rcv_thread_id.join();
void register_b_transport(MODULE *mod, void(MODULE::*cb)(tlm::tlm_generic_payload &, sc_core::sc_time &))
Register b_transport to be called whenever data is received from the socket.
Definition biflow-socket.h:226