PandA-2024.02
memory_initialization_c_writer.cpp
Go to the documentation of this file.
1 /*
2  *
3  * _/_/_/ _/_/ _/ _/ _/_/_/ _/_/
4  * _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/
5  * _/_/_/ _/_/_/_/ _/ _/_/ _/ _/ _/_/_/_/
6  * _/ _/ _/ _/ _/ _/ _/ _/ _/
7  * _/ _/ _/ _/ _/ _/_/_/ _/ _/
8  *
9  * ***********************************************
10  * PandA Project
11  * URL: http://panda.dei.polimi.it
12  * Politecnico di Milano - DEIB
13  * System Architectures Group
14  * ***********************************************
15  * Copyright (c) 2019-2024 Politecnico di Milano
16  *
17  * This file is part of the PandA framework.
18  *
19  * The PandA framework is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program. If not, see <http://www.gnu.org/licenses/>.
31  *
32  */
33 
36 
38 #include "Parameter.hpp"
39 
41 #include "testbench_generation.hpp"
42 
44 #include "behavioral_helper.hpp"
45 #include "tree_helper.hpp"
46 #include "tree_manager.hpp"
47 #include "tree_node.hpp"
48 #include "tree_reindex.hpp"
49 
51 #include "dbgPrintHelper.hpp"
53 #include "utility.hpp"
54 
56  const IndentedOutputStreamRef _indented_output_stream, const tree_managerConstRef _TM,
57  const BehavioralHelperConstRef _behavioral_helper, const unsigned long int _reserved_mem_bytes,
58  const tree_nodeConstRef _function_parameter, const TestbenchGeneration_MemoryType _testbench_generation_memory_type,
59  const ParameterConstRef _parameters)
60  : MemoryInitializationWriterBase(_TM, _behavioral_helper, _reserved_mem_bytes, _function_parameter,
61  _testbench_generation_memory_type, _parameters),
62  indented_output_stream(_indented_output_stream)
63 {
64  debug_level = _parameters->get_class_debug_level(GET_CLASS(*this));
65 }
66 
67 static bool is_all_8zeros(const std::string& str)
68 {
69  size_t size = str.size();
70  if(size % 8 != 0 || size == 8)
71  {
72  return false;
73  }
74  for(size_t i = 0; i < size; ++i)
75  {
76  if(str.at(i) != '0')
77  {
78  return false;
79  }
80  }
81  return true;
82 }
83 
84 void MemoryInitializationCWriter::Process(const std::string& content)
85 {
87  "-->Writing C code to write " + content + " in binary form to initialize memory");
88  tree_nodeConstRef base_type;
91  "---Currently writing " + GET_CONST_NODE(status.back().first)->get_kind_text());
92  switch(GET_CONST_NODE(status.back().first)->get_kind())
93  {
94  case pointer_type_K:
95  case integer_type_K:
96  case real_type_K:
97  case boolean_type_K:
98  case void_type_K:
99  base_type = status.back().first;
100  break;
101  case array_type_K:
102  case CharType_K:
103  case enumeral_type_K:
104  case complex_type_K:
105  case record_type_K:
106  case union_type_K:
107  case function_type_K:
108  case lang_type_K:
109  case method_type_K:
110  case nullptr_type_K:
111  case offset_type_K:
112  case qual_union_type_K:
113  case reference_type_K:
114  case set_type_K:
115  case template_type_parm_K:
116  case typename_type_K:
117  case type_argument_pack_K:
118  case type_pack_expansion_K:
119  case vector_type_K:
120  THROW_ERROR("Unexpected type in initializing parameter/variable: " +
121  GET_CONST_NODE(status.back().first)->get_kind_text());
122  break;
123  case aggr_init_expr_K:
124  case binfo_K:
125  case block_K:
126  case call_expr_K:
127  case case_label_expr_K:
128  case constructor_K:
129  case error_mark_K:
130  case identifier_node_K:
131  case ssa_name_K:
132  case statement_list_K:
133  case target_expr_K:
134  case target_mem_ref_K:
135  case target_mem_ref461_K:
136  case tree_list_K:
137  case tree_vec_K:
138  case lut_expr_K:
139  case CASE_CPP_NODES:
141  case CASE_CST_NODES:
142  case CASE_DECL_NODES:
143  case CASE_FAKE_NODES:
144  case CASE_GIMPLE_NODES:
145  case CASE_PRAGMA_NODES:
149  default:
151  "Not supported node: " + GET_CONST_NODE(status.back().first)->get_kind_text());
152  }
153  THROW_ASSERT(base_type, "");
154  std::string binary_value = "";
155  unsigned long long size = 0;
156  switch(GET_CONST_NODE(base_type)->get_kind())
157  {
158  case void_type_K:
159  case boolean_type_K:
160  size = 8;
161  binary_value = ConvertInBinary(content, size, false, true);
162  break;
163  case integer_type_K:
164  size = tree_helper::Size(base_type);
165  binary_value = ConvertInBinary(content, size, false, tree_helper::IsUnsignedIntegerType(base_type));
166  break;
167  case real_type_K:
168  size = tree_helper::Size(base_type);
169  binary_value = ConvertInBinary(content, size, true, false);
170  break;
171  case pointer_type_K:
172  size = tree_helper::Size(base_type);
173  binary_value = ConvertInBinary(content, size, false, true);
174  break;
175  case array_type_K:
176  case CharType_K:
177  case enumeral_type_K:
178  case complex_type_K:
179  case record_type_K:
180  case union_type_K:
181  case function_type_K:
182  case lang_type_K:
183  case method_type_K:
184  case nullptr_type_K:
185  case offset_type_K:
186  case qual_union_type_K:
187  case reference_type_K:
188  case set_type_K:
189  case template_type_parm_K:
190  case typename_type_K:
191  case type_argument_pack_K:
192  case type_pack_expansion_K:
193  case vector_type_K:
194  THROW_ERROR("Unexpected type in initializing parameter/variable: " +
195  GET_CONST_NODE(base_type)->get_kind_text());
196  break;
197  case aggr_init_expr_K:
198  case binfo_K:
199  case block_K:
200  case call_expr_K:
201  case case_label_expr_K:
202  case constructor_K:
203  case error_mark_K:
204  case identifier_node_K:
205  case ssa_name_K:
206  case statement_list_K:
207  case target_expr_K:
208  case target_mem_ref_K:
209  case target_mem_ref461_K:
210  case tree_list_K:
211  case tree_vec_K:
212  case lut_expr_K:
213  case CASE_CPP_NODES:
215  case CASE_CST_NODES:
216  case CASE_DECL_NODES:
217  case CASE_FAKE_NODES:
218  case CASE_GIMPLE_NODES:
219  case CASE_PRAGMA_NODES:
223  default:
225  "Not supported node: " + GET_CONST_NODE(base_type)->get_kind_text());
226  }
227  THROW_ASSERT(binary_value.size() % 8 == 0, "");
228  written_bytes += binary_value.size() / 8;
230  {
232  {
233  THROW_ASSERT(write_in_a_file, "unexpected condition");
234  indented_output_stream->Append("fprintf(__bambu_testbench_fp, \"//parameter: " +
236  " value: " + content + "\\n\");\n");
237  indented_output_stream->Append("fprintf(__bambu_testbench_fp, \"p" + binary_value + "\\n\");\n");
238  break;
239  }
241  {
242  if(write_in_a_file)
243  {
244  for(size_t bit = 0; bit < binary_value.size(); bit += 8)
245  {
246  memory_init_file << "m" + binary_value.substr(binary_value.size() - 8 - bit, 8) + "\n";
247  }
248  }
249  else
250  {
251  indented_output_stream->Append("fprintf(__bambu_testbench_fp, \"//memory initialization for variable: " +
253  " value: " + content + "\\n\");\n");
254  if(is_all_8zeros(binary_value))
255  {
256  indented_output_stream->Append("for (__testbench_index = 0; "
257  "__testbench_index < " +
258  STR(binary_value.size() / 8) + "; " +
259  "++__testbench_index)\n"
260  " fprintf(__bambu_testbench_fp, \"m00000000\\n\");\n");
261  }
262  else
263  {
264  for(size_t bit = 0; bit < binary_value.size(); bit += 8)
265  {
266  indented_output_stream->Append("fprintf(__bambu_testbench_fp, \"m" +
267  binary_value.substr(binary_value.size() - 8 - bit, 8) + "\\n\");\n");
268  }
269  }
270  }
271  break;
272  }
274  {
275  THROW_ASSERT(write_in_a_file, "unexpected condition");
276  indented_output_stream->Append("fprintf(__bambu_testbench_fp, \"//expected value for output: " +
278  " value: " + content + "\\n\");\n");
279  for(size_t bit = 0; bit < binary_value.size(); bit += 8)
280  {
281  indented_output_stream->Append("fprintf(__bambu_testbench_fp, \"o" +
282  binary_value.substr(binary_value.size() - 8 - bit, 8) + "\\n\");\n");
283  }
284  break;
285  }
287  default:
288  THROW_UNREACHABLE("");
289  }
290 
292  "<--Added code to write " + content + " (" + STR(binary_value.size() / 8) +
293  " bytes) in binary form to initialize memory");
294 }
295 
297 {
298  write_in_a_file = true;
300  memory_init_file.open(file_variable.c_str());
301 }
302 
304 {
306  indented_output_stream->Append("FILE * __bambu_testbench_fp_local_copy;\n");
307  indented_output_stream->Append("char * line = NULL;\n");
308  indented_output_stream->Append("size_t len = 0;\n");
309  indented_output_stream->Append("ssize_t read;\n");
310  indented_output_stream->Append("__bambu_testbench_fp_local_copy = fopen(\"" + file_variable + "\", \"r\");\n");
311  indented_output_stream->Append("if (__bambu_testbench_fp_local_copy == NULL)\n");
312  indented_output_stream->Append(" exit(1);\n");
313  indented_output_stream->Append("while ((read = getline(&line, &len, __bambu_testbench_fp_local_copy)) != -1) {\n");
314  indented_output_stream->Append(" fprintf(__bambu_testbench_fp, \"%s\", line);\n");
316  indented_output_stream->Append("fclose(__bambu_testbench_fp_local_copy);\n");
317  indented_output_stream->Append("if (line)\n");
318  indented_output_stream->Append(" free(line);\n");
320 }
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
File containing functions and utilities to support the printing of debug messagges.
const tree_nodeConstRef function_parameter
The variable/parameter being printed.
#define CASE_BINARY_EXPRESSION
This macro collects all case labels for binary_expr objects.
Definition: tree_node.hpp:463
std::string filename
#define GET_CLASS(obj)
Macro returning the actual type of an object.
std::vector< std::pair< const tree_nodeConstRef, size_t > > status
The stack representing the current status of the parser; the content is the last dumped element...
#define CASE_DECL_NODES
NOTE that cast_expr is a unary expression but it could not be included in the CASE_UNARY_EXPRESSION b...
Definition: tree_node.hpp:672
Functor used to write initialization of the memory writer.
Generate HDL testbench for the top-level kernel testing.
Class to print indented code.
std::string ConvertInBinary(const std::string &C_value, unsigned long long precision, const bool real_type, bool unsigned_type)
Convert a string storing a number in decimal format into a string in binary format.
Node not yet supported.
Definition: exceptions.hpp:323
std::string file_variable
variable used to write in a variable
unsigned long int written_bytes
The number of bytes currently written.
void FinalizeFileInit() override
Copy and close the file.
#define STR(s)
Macro which performs a lexical_cast to a string.
std::ofstream memory_init_file
temporary file used to store the formatted memory values
static bool IsUnsignedIntegerType(const tree_nodeConstRef &type)
Return true if the treenode is of unsigned integer type.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
Definition: exceptions.hpp:292
static unsigned long long Size(const tree_nodeConstRef &tn)
Return the size of a tree object.
bool write_in_a_file
the data will be written in a data copied by the caller
#define CASE_QUATERNARY_EXPRESSION
This macro collects all case labels for quaternary_expr objects.
Definition: tree_node.hpp:574
#define CASE_UNARY_EXPRESSION
This macro collects all case labels for unary_expr objects.
Definition: tree_node.hpp:371
void Append(const std::string &str)
Append a string to the output.
const BehavioralHelperConstRef behavioral_helper
The behavioral helper.
#define GET_CONST_NODE(t)
Definition: tree_node.hpp:347
static bool is_all_8zeros(const std::string &str)
Classes specification of the tree_node data structures.
This file collects some utility functions and macros.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
Definition: exceptions.hpp:263
std::string PrintVariable(unsigned int var) const
Print the name of the variable associated to the index.
MemoryInitializationCWriter(const IndentedOutputStreamRef indented_output_stream, const tree_managerConstRef TM, const BehavioralHelperConstRef behavioral_helper, const unsigned long int reserved_mem_bytes, const tree_nodeConstRef function_parameter, const TestbenchGeneration_MemoryType testbench_generation_memory_type, const ParameterConstRef parameters)
Constructor.
void ActivateFileInit(const std::string &filename) override
In case the test_v has a size over a threshold write the tests on a file.
This file collects some utility functions.
#define CASE_CST_NODES
This macro collects all case labels for cast nodes.
Definition: tree_node.hpp:689
Class specification of the tree_reindex support class.
#define CASE_FAKE_NODES
This macro collects all case labels for fake or empty nodes.
Definition: tree_node.hpp:635
const TestbenchGeneration_MemoryType testbench_generation_memory_type
The type of initialization being written.
char str[25]
Definition: fixedptc.c:8
#define THROW_ERROR_CODE(code, str_expr)
helper function used to throw an error with a code error
Definition: exceptions.hpp:266
this class is used to manage the command-line or XML options.
#define CASE_CPP_NODES
This macro collects all case labels for cpp nodes.
Definition: tree_node.hpp:644
#define CASE_GIMPLE_NODES
This macro collects all cases labels for gimple nodes.
Definition: tree_node.hpp:700
Functor used to write c code which writes initialization of the memory.
const IndentedOutputStreamRef indented_output_stream
The stream where C code has to be written.
TestbenchGeneration_MemoryType
Enum class used to specify which type of content has to be printed for memory initialization.
#define CASE_TERNARY_EXPRESSION
This macro collects all case labels for ternary_expr objects.
Definition: tree_node.hpp:550
Class specification of the manager of the tree structures extracted from the raw file.
void Process(const std::string &content) override
Process an element.
#define CASE_PRAGMA_NODES
This macro collects all case labels for pragma objects.
Definition: tree_node.hpp:610
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...
Definition: exceptions.hpp:289

Generated on Mon Feb 12 2024 13:02:54 for PandA-2024.02 by doxygen 1.8.13