quic/qbox
Loading...
Searching...
No Matches
char_backend_file.h
1/*
2 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
12#ifndef _GS_UART_BACKEND_FILE_H_
13#define _GS_UART_BACKEND_FILE_H_
14
15#include <systemc>
16#include <tlm.h>
17#include <tlm_utils/simple_target_socket.h>
18
19#include <async_event.h>
20#include <uutils.h>
21#include <ports/biflow-socket.h>
22#include <module_factory_registery.h>
23
24#include <queue>
25#include <stdlib.h>
26#include <scp/report.h>
27class char_backend_file : public sc_core::sc_module
28{
29protected:
30 cci::cci_param<std::string> p_read_file;
31 cci::cci_param<std::string> p_write_file;
32 cci::cci_param<unsigned int> p_baudrate;
33
34private:
35 FILE* r_file = nullptr;
36 FILE* w_file = nullptr;
37 double delay;
38 SCP_LOGGER();
39
40public:
42 sc_core::sc_event update_event;
43
49 char_backend_file(sc_core::sc_module_name name)
50 : sc_core::sc_module(name)
51 , p_read_file("read_file", "", "read file path")
52 , p_write_file("write_file", "", "write file path")
53 , p_baudrate("baudrate", 0, "number of bytes per second")
54 , socket("biflow_socket")
55 {
56 SCP_TRACE(()) << "constructor";
57
58 if (p_write_file.get_value().empty() && p_read_file.get_value().empty()) {
59 SCP_ERR(()) << "At least one of read_file or write_file must be specified.\n";
60 }
61
62 SC_THREAD(rcv_thread);
63 sensitive << update_event;
64
65 socket.register_b_transport(this, &char_backend_file::writefn);
66 }
67 void start_of_simulation()
68 {
69 if (!p_read_file.get_value().empty()) {
70 r_file = fopen(p_read_file.get_value().c_str(), "r");
71
72 if (r_file == NULL) SCP_ERR(()) << "Error opening the input file " << p_read_file.get_value() << ".\n";
73 update_event.notify(sc_core::SC_ZERO_TIME);
74 }
75
76 if (!p_write_file.get_value().empty()) {
77 w_file = fopen(p_write_file.get_value().c_str(), "w");
78
79 if (w_file == NULL) SCP_ERR(()) << "Error opening the output file " << p_write_file.get_value() << ".\n";
80
81 socket.can_receive_any();
82 }
83 }
84 void end_of_elaboration() {}
85
86 void rcv_thread()
87 {
88 if (p_baudrate.get_value() == 0)
89 delay = 0;
90 else
91 delay = (1.0 / p_baudrate.get_value());
92 char c;
93 while (fread(&c, sizeof(char), 1, r_file) == 1) {
94 socket.enqueue(c);
95 sc_core::wait(delay, sc_core::SC_SEC);
96 }
97 socket.enqueue(EOF);
98 fclose(r_file);
99 r_file = nullptr;
100 }
101
102 void writefn(tlm::tlm_generic_payload& txn, sc_core::sc_time& t)
103 {
104 uint8_t* data = txn.get_data_ptr();
105 for (int i = 0; i < txn.get_streaming_width(); i++) {
106 size_t ret = fwrite(&data[i], sizeof(uint8_t), 1, w_file);
107 if (ret != 1) {
108 SCP_ERR(()) << "Error writing to the file.\n";
109 }
110 }
111 fflush(w_file);
112 }
113
115 {
116 if (w_file != NULL) {
117 fclose(w_file);
118 }
119
120 if (r_file != NULL) {
121 fclose(r_file);
122 }
123 }
124};
125// GSC_MODULE_REGISTER(char_backend_file);
126extern "C" void module_register();
127#endif
Definition target.h:160
Definition char_backend_file.h:28
Definition biflow-socket.h:73
void can_receive_any()
can_receive_any Allow unlimited items to arrive.
Definition biflow-socket.h:263
void enqueue(T data)
enqueue Enqueue data to be sent (unlimited queue size) NOTE: Thread safe.
Definition biflow-socket.h:276
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