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()
82 old_console_mode_valid =
true;
88 descriptor_t get_stdin_descriptor()
92 SCP_WARN(())(
"char_backend_stdio: Failed to get standard input descriptor. Error: {}",
GetLastError());
103 enqueue(
record.Event.KeyEvent.uChar.AsciiChar);
133 descriptor_t get_stdin_descriptor() {
return STDIN_FILENO; }
135 static void restore_old_mode()
148 old_console_mode =
tty;
149 old_console_mode_valid =
true;
172 int r = read(
fd, &
c, 1);
187 void catch_fn(
int signo) {}
189 static void tty_reset()
191 if (old_console_mode_valid) {
199 std::string& rtrim(std::string& s)
201 const char*
t =
"\n\r\f\v";
202 s.erase(s.find_last_not_of(
t) + 1);
205 std::string getecmdstr(
const std::string& cmd)
207 return ecmd.substr(cmd.length(), ecmd.find_first_of(
"\n") - cmd.length());
214 void expect_process()
216 if (!processing)
return;
218 const std::string
sendstr =
"send ";
219 const std::string
waitstr =
"wait ";
220 const std::string
exitstr =
"exit";
224 std::regex
restr(str);
225 if (std::regex_search(line,
restr)) {
226 SCP_WARN(())(
"Found expect string {}", rtrim(line));
227 ecmd.erase(0, ecmd.find_first_of(
"\n"));
228 if (ecmd !=
"") ecmd.erase(0, 1);
235 for (
char c : getecmdstr(
sendstr)) {
239 ecmd.erase(0, ecmd.find_first_of(
"\n"));
240 if (ecmd !=
"") ecmd.erase(0, 1);
246 ecmdev.notify(
stod(getecmdstr(
waitstr)), sc_core::SC_SEC);
247 ecmd.erase(0, ecmd.find_first_of(
"\n"));
248 if (ecmd !=
"") ecmd.erase(0, 1);
271 : sc_core::sc_module(name)
272 , p_read_write(
"read_write",
true,
"read_write if true start rcv_thread")
273 , p_expect(
"expect",
"",
"string of expect commands")
274 , p_highlight(
"ansi_highlight",
"",
"ANSI highlight code to use for output, default bold")
275 , socket(
"biflow_socket")
279 SCP_TRACE(()) <<
"CharBackendStdio constructor";
281 stdin_fd = get_stdin_descriptor();
286 if (p_expect.get_value() !=
"") {
289 SCP_WARN(())(
"Processing expect string {}", ecmd);
294 gs::SigHandler::get().add_sigint_handler(gs::Handler_CB::PASS);
295 gs::SigHandler::get().register_handler(std::string(this->name()) +
".char_backend_stdio::SIGINT_handler",
301 if (p_read_write) rcv_thread_id = std::thread(&char_backend_stdio::rcv_thread,
this);
304 std::atexit(tty_reset);
309 void enqueue(
char c) { socket.
enqueue(
c); }
311 void writefn(tlm::tlm_generic_payload& txn, sc_core::sc_time&
t)
313 uint8_t* data = txn.get_data_ptr();
314 if (!p_highlight.get_value().empty()) std::cout << p_highlight.get_value();
315 for (
int i = 0;
i < txn.get_streaming_width();
i++) {
317 if ((
char)data[
i] ==
'\n') {
321 line = line + (
char)data[
i];
324 if (!p_highlight.get_value().empty()) std::cout <<
"\x1B[0m";
328 void start_of_simulation()
330 if (!old_console_mode_valid) {
335 void end_of_simulation() { tty_reset(); }
339 gs::SigHandler::get().deregister_on_exit_cb(std::string(name()) +
".char_backend_stdio::tty_reset");
340 gs::SigHandler::get().deregister_handler(std::string(name()) +
".char_backend_stdio::SIGINT_handler");
342 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