32 cci::cci_param<bool> p_read_write;
33 cci::cci_param<std::string> p_expect;
34 cci::cci_param<std::string> p_highlight;
37 std::atomic_bool m_running;
38 std::thread rcv_thread_id;
40 std::atomic<bool> c_flag;
44 sc_core::sc_event ecmdev;
45 bool processing =
false;
49 static struct termios oldtty;
50 static bool oldtty_valid;
53#pragma message("CharBackendStdio not yet implemented for WIN32")
55 static void catch_fn(
int signo) {}
57 static void tty_reset()
60 if (char_backend_stdio::oldtty_valid) {
70 std::string& rtrim(std::string& s)
72 const char*
t =
"\n\r\f\v";
73 s.erase(s.find_last_not_of(
t) + 1);
76 std::string getecmdstr(
const std::string& cmd)
78 return ecmd.substr(cmd.length(), ecmd.find_first_of(
"\n") - cmd.length());
87 if (!processing)
return;
89 const std::string
sendstr =
"send ";
90 const std::string
waitstr =
"wait ";
91 const std::string
exitstr =
"exit";
96 if (std::regex_search(line,
restr)) {
97 SCP_WARN(())(
"Found expect string {}", rtrim(line));
98 ecmd.erase(0, ecmd.find_first_of(
"\n"));
99 if (ecmd !=
"") ecmd.erase(0, 1);
106 for (
char c : getecmdstr(
sendstr)) {
110 ecmd.erase(0, ecmd.find_first_of(
"\n"));
111 if (ecmd !=
"") ecmd.erase(0, 1);
117 ecmdev.notify(
stod(getecmdstr(
waitstr)), sc_core::SC_SEC);
118 ecmd.erase(0, ecmd.find_first_of(
"\n"));
119 if (ecmd !=
"") ecmd.erase(0, 1);
142 : sc_core::sc_module(name)
143 , p_read_write(
"read_write",
true,
"read_write if true start rcv_thread")
144 , p_expect(
"expect",
"",
"string of expect commands")
145 , p_highlight(
"ansi_highlight",
"",
"ANSI highlight code to use for output, default bold")
146 , socket(
"biflow_socket")
150 SCP_TRACE(()) <<
"CharBackendStdio constructor";
155 if (p_expect.get_value() !=
"") {
158 SCP_WARN(())(
"Processing expect string {}", ecmd);
161 gs::SigHandler::get().register_on_exit_cb(std::string(this->name()) +
".char_backend_stdio::tty_reset",
163 gs::SigHandler::get().add_sig_handler(
SIGINT, gs::SigHandler::Handler_CB::PASS);
164 gs::SigHandler::get().register_handler(std::string(this->name()) +
".char_backend_stdio::SIGINT_handler",
170 if (p_read_write) rcv_thread_id = std::thread(&char_backend_stdio::rcv_thread,
this);
177 void enqueue(
char c) { socket.
enqueue(
c); }
195 int r = read(
fd, &
c, 1);
208 void writefn(tlm::tlm_generic_payload&
txn, sc_core::sc_time&
t)
211 if (!p_highlight.get_value().empty()) std::cout << p_highlight.get_value();
212 for (
int i = 0;
i <
txn.get_streaming_width();
i++) {
214 if ((
char)data[
i] ==
'\n') {
218 line = line + (
char)data[
i];
221 if (!p_highlight.get_value().empty()) std::cout <<
"\x1B[0m";
225 void start_of_simulation()
227 if (!char_backend_stdio::oldtty_valid) {
231 char_backend_stdio::oldtty =
tty;
232 char_backend_stdio::oldtty_valid =
true;
238 void end_of_simulation() { tty_reset(); }
242 gs::SigHandler::get().deregister_on_exit_cb(std::string(name()) +
".char_backend_stdio::tty_reset");
243 gs::SigHandler::get().deregister_handler(std::string(name()) +
".char_backend_stdio::SIGINT_handler");
245 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:227