1 /* -*- c++ -*- 2 * yosys -- Yosys Open SYnthesis Suite 3 * 4 * Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com> 5 * 6 * Permission to use, copy, modify, and/or distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * 18 */ 19 20 21 // *** NOTE TO THE READER *** 22 // 23 // Maybe you have just opened this file in the hope to learn more about the 24 // Yosys API. Let me congratulate you on this great decision! ;) 25 // 26 // If you want to know how the design is represented by Yosys in the memory, 27 // you should read "kernel/rtlil.h". 28 // 29 // If you want to know how to register a command with Yosys, you could read 30 // "kernel/register.h", but it would be easier to just look at a simple 31 // example instead. A simple one would be "passes/cmds/log.cc". 32 // 33 // This header is very boring. It just defines some general things that 34 // belong nowhere else and includes the interesting headers. 35 // 36 // Find more information in the "guidelines/GettingStarted" file. 37 38 39 #ifndef YOSYS_H 40 #define YOSYS_H 41 42 #include <map> 43 #include <set> 44 #include <tuple> 45 #include <vector> 46 #include <string> 47 #include <algorithm> 48 #include <functional> 49 #include <unordered_map> 50 #include <unordered_set> 51 #include <initializer_list> 52 #include <stdexcept> 53 #include <memory> 54 #include <cmath> 55 #include <cstddef> 56 57 #include <sstream> 58 #include <fstream> 59 #include <istream> 60 #include <ostream> 61 #include <iostream> 62 63 #include <stdarg.h> 64 #include <stdlib.h> 65 #include <string.h> 66 #include <stdint.h> 67 #include <stdio.h> 68 #include <limits.h> 69 70 #ifdef WITH_PYTHON 71 #include <Python.h> 72 #endif 73 74 #ifndef _YOSYS_ 75 # error It looks like you are trying to build Yosys without the config defines set. \ 76 When building Yosys with a custom make system, make sure you set all the \ 77 defines the Yosys Makefile would set for your build configuration. 78 #endif 79 80 #ifdef YOSYS_ENABLE_TCL 81 # include <tcl.h> 82 # ifdef YOSYS_MXE_HACKS 83 extern Tcl_Command Tcl_CreateCommand(Tcl_Interp *interp, const char *cmdName, Tcl_CmdProc *proc, ClientData clientData, Tcl_CmdDeleteProc *deleteProc); 84 extern Tcl_Interp *Tcl_CreateInterp(void); 85 extern void Tcl_DeleteInterp(Tcl_Interp *interp); 86 extern int Tcl_Eval(Tcl_Interp *interp, const char *script); 87 extern int Tcl_EvalFile(Tcl_Interp *interp, const char *fileName); 88 extern void Tcl_Finalize(void); 89 extern int Tcl_GetCommandInfo(Tcl_Interp *interp, const char *cmdName, Tcl_CmdInfo *infoPtr); 90 extern const char *Tcl_GetStringResult(Tcl_Interp *interp); 91 extern Tcl_Obj *Tcl_NewStringObj(const char *bytes, int length); 92 extern Tcl_Obj *Tcl_NewIntObj(int intValue); 93 extern Tcl_Obj *Tcl_NewListObj(int objc, Tcl_Obj *const objv[]); 94 extern Tcl_Obj *Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, int flags); 95 # endif 96 # undef CONST 97 # undef INLINE 98 #endif 99 100 #ifdef _WIN32 101 # undef NOMINMAX 102 # define NOMINMAX 1 103 # undef YY_NO_UNISTD_H 104 # define YY_NO_UNISTD_H 1 105 106 # include <windows.h> 107 # include <io.h> 108 # include <direct.h> 109 110 # define strtok_r strtok_s 111 # define strdup _strdup 112 # define snprintf _snprintf 113 # define getcwd _getcwd 114 # define mkdir _mkdir 115 # define popen _popen 116 # define pclose _pclose 117 118 # ifndef __MINGW32__ 119 # define PATH_MAX MAX_PATH 120 # define isatty _isatty 121 # define fileno _fileno 122 # endif 123 124 // The following defines conflict with our identifiers: 125 # undef CONST 126 // `wingdi.h` defines a TRANSPARENT macro that conflicts with X(TRANSPARENT) entry in kernel/constids.inc 127 # undef TRANSPARENT 128 #endif 129 130 #ifndef PATH_MAX 131 # define PATH_MAX 4096 132 #endif 133 134 #define YOSYS_NAMESPACE Yosys 135 #define PRIVATE_NAMESPACE_BEGIN namespace { 136 #define PRIVATE_NAMESPACE_END } 137 #define YOSYS_NAMESPACE_BEGIN namespace Yosys { 138 #define YOSYS_NAMESPACE_END } 139 #define YOSYS_NAMESPACE_PREFIX Yosys:: 140 #define USING_YOSYS_NAMESPACE using namespace Yosys; 141 142 #if defined(__GNUC__) || defined(__clang__) 143 # define YS_ATTRIBUTE(...) __attribute__((__VA_ARGS__)) 144 #elif defined(_MSC_VER) 145 # define YS_ATTRIBUTE(...) 146 #else 147 # define YS_ATTRIBUTE(...) 148 #endif 149 150 #if defined(__GNUC__) || defined(__clang__) 151 # define YS_MAYBE_UNUSED __attribute__((__unused__)) 152 #else 153 # define YS_MAYBE_UNUSED 154 #endif 155 156 #if __cplusplus >= 201703L 157 # define YS_FALLTHROUGH [[fallthrough]]; 158 #elif defined(__clang__) 159 # define YS_FALLTHROUGH [[clang::fallthrough]]; 160 #elif defined(__GNUC__) 161 # define YS_FALLTHROUGH [[gnu::fallthrough]]; 162 #else 163 # define YS_FALLTHROUGH 164 #endif 165 166 YOSYS_NAMESPACE_BEGIN 167 168 // Note: All headers included in hashlib.h must be included 169 // outside of YOSYS_NAMESPACE before this or bad things will happen. 170 #ifdef HASHLIB_H 171 # undef HASHLIB_H 172 # include "kernel/hashlib.h" 173 #else 174 # include "kernel/hashlib.h" 175 # undef HASHLIB_H 176 #endif 177 178 using std::vector; 179 using std::string; 180 using std::tuple; 181 using std::pair; 182 183 using std::make_tuple; 184 using std::make_pair; 185 using std::get; 186 using std::min; 187 using std::max; 188 189 // A primitive shared string implementation that does not 190 // move its .c_str() when the object is copied or moved. 191 struct shared_str { 192 std::shared_ptr<string> content; shared_strshared_str193 shared_str() { } shared_strshared_str194 shared_str(string s) { content = std::shared_ptr<string>(new string(s)); } shared_strshared_str195 shared_str(const char *s) { content = std::shared_ptr<string>(new string(s)); } c_strshared_str196 const char *c_str() const { return content->c_str(); } strshared_str197 const string &str() const { return *content; } 198 bool operator==(const shared_str &other) const { return *content == *other.content; } hashshared_str199 unsigned int hash() const { return hashlib::hash_ops<std::string>::hash(*content); } 200 }; 201 202 using hashlib::mkhash; 203 using hashlib::mkhash_init; 204 using hashlib::mkhash_add; 205 using hashlib::mkhash_xorshift; 206 using hashlib::hash_ops; 207 using hashlib::hash_cstr_ops; 208 using hashlib::hash_ptr_ops; 209 using hashlib::hash_obj_ops; 210 using hashlib::dict; 211 using hashlib::idict; 212 using hashlib::pool; 213 using hashlib::mfp; 214 215 namespace RTLIL { 216 struct IdString; 217 struct Const; 218 struct SigBit; 219 struct SigSpec; 220 struct Wire; 221 struct Cell; 222 struct Memory; 223 struct Process; 224 struct Module; 225 struct Design; 226 struct Monitor; 227 enum State : unsigned char; 228 } 229 230 namespace AST { 231 struct AstNode; 232 } 233 234 using RTLIL::IdString; 235 using RTLIL::Const; 236 using RTLIL::SigBit; 237 using RTLIL::SigSpec; 238 using RTLIL::Wire; 239 using RTLIL::Cell; 240 using RTLIL::Module; 241 using RTLIL::Design; 242 243 namespace hashlib { 244 template<> struct hash_ops<RTLIL::Wire*> : hash_obj_ops {}; 245 template<> struct hash_ops<RTLIL::Cell*> : hash_obj_ops {}; 246 template<> struct hash_ops<RTLIL::Memory*> : hash_obj_ops {}; 247 template<> struct hash_ops<RTLIL::Process*> : hash_obj_ops {}; 248 template<> struct hash_ops<RTLIL::Module*> : hash_obj_ops {}; 249 template<> struct hash_ops<RTLIL::Design*> : hash_obj_ops {}; 250 template<> struct hash_ops<RTLIL::Monitor*> : hash_obj_ops {}; 251 template<> struct hash_ops<AST::AstNode*> : hash_obj_ops {}; 252 253 template<> struct hash_ops<const RTLIL::Wire*> : hash_obj_ops {}; 254 template<> struct hash_ops<const RTLIL::Cell*> : hash_obj_ops {}; 255 template<> struct hash_ops<const RTLIL::Memory*> : hash_obj_ops {}; 256 template<> struct hash_ops<const RTLIL::Process*> : hash_obj_ops {}; 257 template<> struct hash_ops<const RTLIL::Module*> : hash_obj_ops {}; 258 template<> struct hash_ops<const RTLIL::Design*> : hash_obj_ops {}; 259 template<> struct hash_ops<const RTLIL::Monitor*> : hash_obj_ops {}; 260 template<> struct hash_ops<const AST::AstNode*> : hash_obj_ops {}; 261 } 262 263 void memhasher_on(); 264 void memhasher_off(); 265 void memhasher_do(); 266 267 extern bool memhasher_active; 268 inline void memhasher() { if (memhasher_active) memhasher_do(); } 269 270 void yosys_banner(); 271 int ceil_log2(int x) YS_ATTRIBUTE(const); 272 std::string stringf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 1, 2)); 273 std::string vstringf(const char *fmt, va_list ap); 274 int readsome(std::istream &f, char *s, int n); 275 std::string next_token(std::string &text, const char *sep = " \t\r\n", bool long_strings = false); 276 std::vector<std::string> split_tokens(const std::string &text, const char *sep = " \t\r\n"); 277 bool patmatch(const char *pattern, const char *string); 278 #if !defined(YOSYS_DISABLE_SPAWN) 279 int run_command(const std::string &command, std::function<void(const std::string&)> process_line = std::function<void(const std::string&)>()); 280 #endif 281 std::string make_temp_file(std::string template_str = "/tmp/yosys_XXXXXX"); 282 std::string make_temp_dir(std::string template_str = "/tmp/yosys_XXXXXX"); 283 bool check_file_exists(std::string filename, bool is_exec = false); 284 bool is_absolute_path(std::string filename); 285 void remove_directory(std::string dirname); 286 std::string escape_filename_spaces(const std::string& filename); 287 288 template<typename T> int GetSize(const T &obj) { return obj.size(); } 289 int GetSize(RTLIL::Wire *wire); 290 291 extern int autoidx; 292 extern int yosys_xtrace; 293 294 YOSYS_NAMESPACE_END 295 296 #include "kernel/log.h" 297 #include "kernel/rtlil.h" 298 #include "kernel/register.h" 299 300 YOSYS_NAMESPACE_BEGIN 301 302 using RTLIL::State; 303 using RTLIL::SigChunk; 304 using RTLIL::SigSig; 305 306 namespace hashlib { 307 template<> struct hash_ops<RTLIL::State> : hash_ops<int> {}; 308 } 309 310 void yosys_setup(); 311 312 #ifdef WITH_PYTHON 313 bool yosys_already_setup(); 314 #endif 315 316 void yosys_shutdown(); 317 318 #ifdef YOSYS_ENABLE_TCL 319 Tcl_Interp *yosys_get_tcl_interp(); 320 #endif 321 322 extern RTLIL::Design *yosys_design; 323 324 RTLIL::IdString new_id(std::string file, int line, std::string func); 325 326 #define NEW_ID \ 327 YOSYS_NAMESPACE_PREFIX new_id(__FILE__, __LINE__, __FUNCTION__) 328 329 // Create a statically allocated IdString object, using for example ID::A or ID($add). 330 // 331 // Recipe for Converting old code that is using conversion of strings like ID::A and 332 // "$add" for creating IdStrings: Run below SED command on the .cc file and then use for 333 // example "meld foo.cc foo.cc.orig" to manually compile errors, if necessary. 334 // 335 // sed -i.orig -r 's/"\\\\([a-zA-Z0-9_]+)"/ID(\1)/g; s/"(\$[a-zA-Z0-9_]+)"/ID(\1)/g;' <filename> 336 // 337 #define ID(_id) ([]() { const char *p = "\\" #_id, *q = p[1] == '$' ? p+1 : p; \ 338 static const YOSYS_NAMESPACE_PREFIX RTLIL::IdString id(q); return id; })() 339 namespace ID = RTLIL::ID; 340 341 RTLIL::Design *yosys_get_design(); 342 std::string proc_self_dirname(); 343 std::string proc_share_dirname(); 344 std::string proc_program_prefix(); 345 const char *create_prompt(RTLIL::Design *design, int recursion_counter); 346 std::vector<std::string> glob_filename(const std::string &filename_pattern); 347 void rewrite_filename(std::string &filename); 348 349 void run_pass(std::string command, RTLIL::Design *design = nullptr); 350 void run_frontend(std::string filename, std::string command, std::string *backend_command, std::string *from_to_label = nullptr, RTLIL::Design *design = nullptr); 351 void run_frontend(std::string filename, std::string command, RTLIL::Design *design = nullptr); 352 void run_backend(std::string filename, std::string command, RTLIL::Design *design = nullptr); 353 void shell(RTLIL::Design *design); 354 355 // journal of all input and output files read (for "yosys -E") 356 extern std::set<std::string> yosys_input_files, yosys_output_files; 357 358 // from kernel/version_*.o (cc source generated from Makefile) 359 extern const char *yosys_version_str; 360 361 // from passes/cmds/design.cc 362 extern std::map<std::string, RTLIL::Design*> saved_designs; 363 extern std::vector<RTLIL::Design*> pushed_designs; 364 365 // from passes/cmds/pluginc.cc 366 extern std::map<std::string, void*> loaded_plugins; 367 #ifdef WITH_PYTHON 368 extern std::map<std::string, void*> loaded_python_plugins; 369 #endif 370 extern std::map<std::string, std::string> loaded_plugin_aliases; 371 void load_plugin(std::string filename, std::vector<std::string> aliases); 372 373 extern std::string yosys_share_dirname; 374 extern std::string yosys_abc_executable; 375 376 YOSYS_NAMESPACE_END 377 378 #endif 379