yowasp-yosys 0.55.0.3.post946.dev0__py3-none-any.whl → 0.56.0.141.post974.dev0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. yowasp_yosys/sby.py +39 -8
  2. yowasp_yosys/share/include/frontends/ast/ast.h +34 -38
  3. yowasp_yosys/share/include/kernel/celltypes.h +6 -0
  4. yowasp_yosys/share/include/kernel/consteval.h +5 -1
  5. yowasp_yosys/share/include/kernel/constids.inc +1 -0
  6. yowasp_yosys/share/include/kernel/ffinit.h +3 -3
  7. yowasp_yosys/share/include/kernel/ffmerge.h +1 -1
  8. yowasp_yosys/share/include/kernel/hashlib.h +43 -16
  9. yowasp_yosys/share/include/kernel/io.h +382 -8
  10. yowasp_yosys/share/include/kernel/json.h +2 -2
  11. yowasp_yosys/share/include/kernel/log.h +1 -0
  12. yowasp_yosys/share/include/kernel/register.h +42 -4
  13. yowasp_yosys/share/include/kernel/rtlil.h +6 -2
  14. yowasp_yosys/share/include/kernel/satgen.h +6 -4
  15. yowasp_yosys/share/include/kernel/sigtools.h +130 -26
  16. yowasp_yosys/share/include/kernel/yosys_common.h +9 -0
  17. yowasp_yosys/share/include/passes/techmap/libparse.h +235 -0
  18. yowasp_yosys/share/python3/sby_autotune.py +1 -1
  19. yowasp_yosys/share/python3/sby_cmdline.py +13 -0
  20. yowasp_yosys/share/python3/sby_core.py +208 -85
  21. yowasp_yosys/share/python3/sby_design.py +4 -0
  22. yowasp_yosys/share/python3/sby_engine_abc.py +15 -4
  23. yowasp_yosys/share/python3/sby_engine_aiger.py +14 -9
  24. yowasp_yosys/share/python3/sby_engine_btor.py +15 -4
  25. yowasp_yosys/share/python3/sby_engine_smtbmc.py +40 -27
  26. yowasp_yosys/share/python3/sby_status.py +388 -115
  27. yowasp_yosys/yosys.wasm +0 -0
  28. {yowasp_yosys-0.55.0.3.post946.dev0.dist-info → yowasp_yosys-0.56.0.141.post974.dev0.dist-info}/METADATA +1 -1
  29. {yowasp_yosys-0.55.0.3.post946.dev0.dist-info → yowasp_yosys-0.56.0.141.post974.dev0.dist-info}/RECORD +32 -31
  30. {yowasp_yosys-0.55.0.3.post946.dev0.dist-info → yowasp_yosys-0.56.0.141.post974.dev0.dist-info}/WHEEL +0 -0
  31. {yowasp_yosys-0.55.0.3.post946.dev0.dist-info → yowasp_yosys-0.56.0.141.post974.dev0.dist-info}/entry_points.txt +0 -0
  32. {yowasp_yosys-0.55.0.3.post946.dev0.dist-info → yowasp_yosys-0.56.0.141.post974.dev0.dist-info}/top_level.txt +0 -0
yowasp_yosys/sby.py CHANGED
@@ -22,7 +22,7 @@ import json, os, sys, shutil, tempfile, re
22
22
  from sby_cmdline import parser_func
23
23
  from sby_core import SbyConfig, SbyTask, SbyAbort, SbyTaskloop, process_filename, dress_message
24
24
  from sby_jobserver import SbyJobClient, process_jobserver_environment
25
- from sby_status import SbyStatusDb
25
+ from sby_status import SbyStatusDb, remove_db, FileInUseError
26
26
  import time, platform, click
27
27
 
28
28
  release_version = 'unknown SBY version'
@@ -54,6 +54,7 @@ dump_taskinfo = args.dump_taskinfo
54
54
  dump_files = args.dump_files
55
55
  reusedir = False
56
56
  setupmode = args.setupmode
57
+ linkmode = args.linkmode
57
58
  autotune = args.autotune
58
59
  autotune_config = args.autotune_config
59
60
  sequential = args.sequential
@@ -61,8 +62,17 @@ jobcount = args.jobcount
61
62
  init_config_file = args.init_config_file
62
63
  status_show = args.status
63
64
  status_reset = args.status_reset
65
+ status_cancels = args.status_cancels
66
+ task_status = args.task_status
67
+ status_live_formats = args.live_formats
68
+ status_format = args.status_format
69
+ status_latest = args.status_latest
70
+
71
+ if autotune and linkmode:
72
+ print("ERROR: --link flag currently not available with --autotune")
73
+ sys.exit(1)
64
74
 
65
- if status_show or status_reset:
75
+ if status_show or status_reset or task_status or status_format:
66
76
  target = workdir_prefix or workdir or sbyfile
67
77
  if target is None:
68
78
  print("ERROR: Specify a .sby config file or working directory to use --status.")
@@ -85,15 +95,29 @@ if status_show or status_reset:
85
95
 
86
96
  status_db = SbyStatusDb(status_path, task=None)
87
97
 
88
- if status_show:
89
- status_db.print_status_summary()
90
- sys.exit(0)
91
-
92
98
  if status_reset:
93
99
  status_db.reset()
100
+ elif status_db.test_schema():
101
+ print(f"ERROR: Status database does not match expected format. Use --statusreset to reset.")
102
+ sys.exit(1)
103
+
104
+ if status_show:
105
+ status_db.print_status_summary(status_latest)
106
+
107
+ if status_format:
108
+ status_db.print_status_summary_fmt(tasknames, status_format, status_latest)
109
+
110
+ if task_status:
111
+ status_db.print_task_summary()
94
112
 
95
113
  status_db.db.close()
114
+
115
+ if status_live_formats:
116
+ print(f"WARNING: --live option found but not used.")
117
+
96
118
  sys.exit(0)
119
+ elif status_latest:
120
+ print(f"WARNING: --latest flag found but not used.")
97
121
 
98
122
 
99
123
  if sbyfile is not None:
@@ -369,6 +393,7 @@ if dump_taskinfo:
369
393
  "mode": cfg.options.get("mode"),
370
394
  "engines": cfg.engines,
371
395
  "script": cfg.script,
396
+ "cancelledby": cfg.cancelledby,
372
397
  }
373
398
  print(json.dumps(taskinfo, indent=2))
374
399
  sys.exit(0)
@@ -450,6 +475,12 @@ def start_task(taskloop, taskname):
450
475
  print("*", file=gitignore)
451
476
  with open(f"{my_workdir}/status.path", "w") as status_path:
452
477
  print(my_status_db, file=status_path)
478
+ if os.path.exists(f"{my_workdir}/{my_status_db}") and opt_force:
479
+ try:
480
+ remove_db(f"{my_workdir}/{my_status_db}")
481
+ except FileInUseError:
482
+ # don't delete an open database
483
+ pass
453
484
 
454
485
  junit_ts_name = os.path.basename(sbyfile[:-4]) if sbyfile is not None else workdir if workdir is not None else "stdin"
455
486
  junit_tc_name = taskname if taskname is not None else "default"
@@ -465,7 +496,7 @@ def start_task(taskloop, taskname):
465
496
  else:
466
497
  junit_filename = "junit"
467
498
 
468
- task = SbyTask(sbyconfig, my_workdir, early_logmsgs, reusedir, taskloop)
499
+ task = SbyTask(sbyconfig, my_workdir, early_logmsgs, reusedir, status_cancels, taskloop, name=taskname, live_formats=status_live_formats)
469
500
 
470
501
  for k, v in exe_paths.items():
471
502
  task.exe_paths[k] = v
@@ -495,7 +526,7 @@ def start_task(taskloop, taskname):
495
526
  task.exit_callback = exit_callback
496
527
 
497
528
  if not autotune:
498
- task.setup_procs(setupmode)
529
+ task.setup_procs(setupmode, linkmode)
499
530
  task.task_local_abort = not throw_err
500
531
 
501
532
  return task
@@ -28,6 +28,7 @@
28
28
 
29
29
  #include "kernel/rtlil.h"
30
30
  #include "kernel/fmt.h"
31
+ #include "frontends/verilog/verilog_location.h"
31
32
  #include <stdint.h>
32
33
  #include <set>
33
34
 
@@ -153,6 +154,7 @@ namespace AST
153
154
  AST_MODPORT,
154
155
  AST_MODPORTMEMBER,
155
156
  AST_PACKAGE,
157
+ AST_IMPORT,
156
158
 
157
159
  AST_WIRETYPE,
158
160
  AST_TYPEDEF,
@@ -162,12 +164,7 @@ namespace AST
162
164
  AST_BIND
163
165
  };
164
166
 
165
- struct AstSrcLocType {
166
- unsigned int first_line, last_line;
167
- unsigned int first_column, last_column;
168
- AstSrcLocType() : first_line(0), last_line(0), first_column(0), last_column(0) {}
169
- AstSrcLocType(int _first_line, int _first_column, int _last_line, int _last_column) : first_line(_first_line), last_line(_last_line), first_column(_first_column), last_column(_last_column) {}
170
- };
167
+ using AstSrcLocType = Location;
171
168
 
172
169
  // convert an node type to a string (e.g. for debug output)
173
170
  std::string type2str(AstNodeType type);
@@ -183,10 +180,10 @@ namespace AST
183
180
  AstNodeType type;
184
181
 
185
182
  // the list of child nodes for this node
186
- std::vector<AstNode*> children;
183
+ std::vector<std::unique_ptr<AstNode>> children;
187
184
 
188
185
  // the list of attributes assigned to this node
189
- std::map<RTLIL::IdString, AstNode*> attributes;
186
+ std::map<RTLIL::IdString, std::unique_ptr<AstNode>> attributes;
190
187
  bool get_bool_attribute(RTLIL::IdString id);
191
188
 
192
189
  // node content - most of it is unused in most node types
@@ -212,7 +209,7 @@ namespace AST
212
209
  int unpacked_dimensions;
213
210
 
214
211
  // this is set by simplify and used during RTLIL generation
215
- AstNode *id2ast;
212
+ AstNode* id2ast;
216
213
 
217
214
  // this is used by simplify to detect if basic analysis has been performed already on the node
218
215
  bool basic_prep;
@@ -223,7 +220,6 @@ namespace AST
223
220
  // this is the original sourcecode location that resulted in this AST node
224
221
  // it is automatically set by the constructor using AST::current_filename and
225
222
  // the AST::get_line_num() callback function.
226
- std::string filename;
227
223
  AstSrcLocType location;
228
224
 
229
225
  // are we embedded in an lvalue, param?
@@ -234,9 +230,9 @@ namespace AST
234
230
  bool in_param_from_above;
235
231
 
236
232
  // creating and deleting nodes
237
- AstNode(AstNodeType type = AST_NONE, AstNode *child1 = nullptr, AstNode *child2 = nullptr, AstNode *child3 = nullptr, AstNode *child4 = nullptr);
238
- AstNode *clone() const;
239
- void cloneInto(AstNode *other) const;
233
+ AstNode(AstSrcLocType loc, AstNodeType type = AST_NONE, std::unique_ptr<AstNode> child1 = nullptr, std::unique_ptr<AstNode> child2 = nullptr, std::unique_ptr<AstNode> child3 = nullptr, std::unique_ptr<AstNode> child4 = nullptr);
234
+ std::unique_ptr<AstNode> clone() const;
235
+ void cloneInto(AstNode &other) const;
240
236
  void delete_children();
241
237
  ~AstNode();
242
238
 
@@ -265,14 +261,14 @@ namespace AST
265
261
  // it also sets the id2ast pointers so that identifier lookups are fast in genRTLIL()
266
262
  bool simplify(bool const_fold, int stage, int width_hint, bool sign_hint);
267
263
  void replace_result_wire_name_in_function(const std::string &from, const std::string &to);
268
- AstNode *readmem(bool is_readmemh, std::string mem_filename, AstNode *memory, int start_addr, int finish_addr, bool unconditional_init);
264
+ std::unique_ptr<AstNode> readmem(bool is_readmemh, std::string mem_filename, AstNode *memory, int start_addr, int finish_addr, bool unconditional_init);
269
265
  void expand_genblock(const std::string &prefix);
270
266
  void label_genblks(std::set<std::string>& existing, int &counter);
271
267
  void mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg_places,
272
268
  dict<AstNode*, uint32_t> &mem2reg_flags, dict<AstNode*, uint32_t> &proc_flags, uint32_t &status_flags);
273
- bool mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod, AstNode *block, AstNode *&async_block);
269
+ bool mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod, AstNode *block, AstNode* async_block);
274
270
  bool mem2reg_check(pool<AstNode*> &mem2reg_set);
275
- void mem2reg_remove(pool<AstNode*> &mem2reg_set, vector<AstNode*> &delnodes);
271
+ void mem2reg_remove(pool<AstNode*> &mem2reg_set);
276
272
  void meminfo(int &mem_width, int &mem_size, int &addr_bits);
277
273
  bool detect_latch(const std::string &var);
278
274
  const RTLIL::Module* lookup_cell_module();
@@ -288,7 +284,7 @@ namespace AST
288
284
  };
289
285
  bool has_const_only_constructs();
290
286
  bool replace_variables(std::map<std::string, varinfo_t> &variables, AstNode *fcall, bool must_succeed);
291
- AstNode *eval_const_function(AstNode *fcall, bool must_succeed);
287
+ std::unique_ptr<AstNode> eval_const_function(AstNode *fcall, bool must_succeed);
292
288
  bool is_simple_const_expr();
293
289
 
294
290
  // helper for parsing format strings
@@ -305,29 +301,30 @@ namespace AST
305
301
  std::vector<RTLIL::Binding *> genBindings() const;
306
302
 
307
303
  // used by genRTLIL() for detecting expression width and sign
308
- void detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *found_real = NULL);
309
- void detectSignWidth(int &width_hint, bool &sign_hint, bool *found_real = NULL);
304
+ void detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *found_real = nullptr);
305
+ void detectSignWidth(int &width_hint, bool &sign_hint, bool *found_real = nullptr);
310
306
 
311
307
  // create RTLIL code for this AST node
312
308
  // for expressions the resulting signal vector is returned
313
309
  // all generated cell instances, etc. are written to the RTLIL::Module pointed to by AST_INTERNAL::current_module
314
310
  RTLIL::SigSpec genRTLIL(int width_hint = -1, bool sign_hint = false);
315
- RTLIL::SigSpec genWidthRTLIL(int width, bool sgn, const dict<RTLIL::SigBit, RTLIL::SigBit> *new_subst_ptr = NULL);
311
+ RTLIL::SigSpec genWidthRTLIL(int width, bool sgn, const dict<RTLIL::SigBit, RTLIL::SigBit> *new_subst_ptr = nullptr);
316
312
 
317
313
  // compare AST nodes
318
314
  bool operator==(const AstNode &other) const;
319
315
  bool operator!=(const AstNode &other) const;
320
316
  bool contains(const AstNode *other) const;
317
+ AstNode operator=(AstNode) = delete;
321
318
 
322
319
  // helper functions for creating AST nodes for constants
323
- static AstNode *mkconst_int(uint32_t v, bool is_signed, int width = 32);
324
- static AstNode *mkconst_bits(const std::vector<RTLIL::State> &v, bool is_signed, bool is_unsized);
325
- static AstNode *mkconst_bits(const std::vector<RTLIL::State> &v, bool is_signed);
326
- static AstNode *mkconst_str(const std::vector<RTLIL::State> &v);
327
- static AstNode *mkconst_str(const std::string &str);
320
+ static std::unique_ptr<AstNode> mkconst_int(AstSrcLocType loc, uint32_t v, bool is_signed, int width = 32);
321
+ static std::unique_ptr<AstNode> mkconst_bits(AstSrcLocType loc, const std::vector<RTLIL::State> &v, bool is_signed, bool is_unsized);
322
+ static std::unique_ptr<AstNode> mkconst_bits(AstSrcLocType loc, const std::vector<RTLIL::State> &v, bool is_signed);
323
+ static std::unique_ptr<AstNode> mkconst_str(AstSrcLocType loc, const std::vector<RTLIL::State> &v);
324
+ static std::unique_ptr<AstNode> mkconst_str(AstSrcLocType loc, const std::string &str);
328
325
 
329
326
  // helper function to create an AST node for a temporary register
330
- AstNode *mktemp_logic(const std::string &name, AstNode *mod, bool nosync, int range_left, int range_right, bool is_signed);
327
+ std::unique_ptr<AstNode> mktemp_logic(AstSrcLocType loc, const std::string &name, AstNode *mod, bool nosync, int range_left, int range_right, bool is_signed);
331
328
 
332
329
  // helper function for creating sign-extended const objects
333
330
  RTLIL::Const bitsAsConst(int width, bool is_signed);
@@ -356,12 +353,12 @@ namespace AST
356
353
 
357
354
  // helper to clone the node with some of its subexpressions replaced with zero (this is used
358
355
  // to evaluate widths of dynamic ranges)
359
- AstNode *clone_at_zero();
356
+ std::unique_ptr<AstNode> clone_at_zero();
360
357
 
361
- void set_attribute(RTLIL::IdString key, AstNode *node)
358
+ void set_attribute(RTLIL::IdString key, std::unique_ptr<AstNode> node)
362
359
  {
363
- attributes[key] = node;
364
360
  node->set_in_param_flag(true);
361
+ attributes[key] = std::move(node);
365
362
  }
366
363
 
367
364
  // helper to set in_lvalue/in_param flags from the hierarchy context (the actual flag
@@ -377,7 +374,7 @@ namespace AST
377
374
  void fixup_hierarchy_flags(bool force_descend = false);
378
375
 
379
376
  // helpers for indexing
380
- AstNode *make_index_range(AstNode *node, bool unpacked_range = false);
377
+ std::unique_ptr<AstNode> make_index_range(AstNode *node, bool unpacked_range = false);
381
378
  AstNode *get_struct_member() const;
382
379
 
383
380
  // helper to print errors from simplify/genrtlil code
@@ -391,12 +388,11 @@ namespace AST
391
388
  // parametric modules are supported directly by the AST library
392
389
  // therefore we need our own derivate of RTLIL::Module with overloaded virtual functions
393
390
  struct AstModule : RTLIL::Module {
394
- AstNode *ast;
391
+ std::unique_ptr<AstNode> ast;
395
392
  bool nolatches, nomeminit, nomem2reg, mem2reg, noblackbox, lib, nowb, noopt, icells, pwires, autowire;
396
- ~AstModule() override;
397
393
  RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool mayfail) override;
398
394
  RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail) override;
399
- std::string derive_common(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, AstNode **new_ast_out, bool quiet = false);
395
+ std::string derive_common(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, std::unique_ptr<AstNode>* new_ast_out, bool quiet = false);
400
396
  void expand_interfaces(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces) override;
401
397
  bool reprocess_if_necessary(RTLIL::Design *design) override;
402
398
  RTLIL::Module *clone() const override;
@@ -406,9 +402,9 @@ namespace AST
406
402
  // this must be set by the language frontend before parsing the sources
407
403
  // the AstNode constructor then uses current_filename and get_line_num()
408
404
  // to initialize the filename and linenum properties of new nodes
409
- extern std::string current_filename;
410
- extern void (*set_line_num)(int);
411
- extern int (*get_line_num)();
405
+ // extern std::string current_filename;
406
+ // also set by the language frontend to control some AST processing
407
+ extern bool sv_mode_but_global_and_used_for_literally_one_condition;
412
408
 
413
409
  // for stats
414
410
  unsigned long long astnode_count();
@@ -418,7 +414,7 @@ namespace AST
418
414
  void use_internal_line_num();
419
415
 
420
416
  // call a DPI function
421
- AstNode *dpi_call(const std::string &rtype, const std::string &fname, const std::vector<std::string> &argtypes, const std::vector<AstNode*> &args);
417
+ std::unique_ptr<AstNode> dpi_call(AstSrcLocType loc, const std::string &rtype, const std::string &fname, const std::vector<std::string> &argtypes, const std::vector<std::unique_ptr<AstNode>> &args);
422
418
 
423
419
  // Helper functions related to handling SystemVerilog interfaces
424
420
  std::pair<std::string,std::string> split_modport_from_type(std::string name_type);
@@ -464,7 +460,7 @@ namespace AST_INTERNAL
464
460
  process_and_replace_module(RTLIL::Design *design,
465
461
  RTLIL::Module *old_module,
466
462
  AST::AstNode *new_ast,
467
- AST::AstNode *original_ast = nullptr);
463
+ std::unique_ptr<AST::AstNode> original_ast = nullptr);
468
464
  }
469
465
 
470
466
  YOSYS_NAMESPACE_END
@@ -334,6 +334,7 @@ struct CellTypes
334
334
  return v;
335
335
  }
336
336
 
337
+ // Consider using the ConstEval struct instead if you need named ports and/or multiple outputs
337
338
  static RTLIL::Const eval(RTLIL::IdString type, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len, bool *errp = nullptr)
338
339
  {
339
340
  if (type == ID($sshr) && !signed1)
@@ -416,6 +417,7 @@ struct CellTypes
416
417
  log_abort();
417
418
  }
418
419
 
420
+ // Consider using the ConstEval struct instead if you need named ports and/or multiple outputs
419
421
  static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool *errp = nullptr)
420
422
  {
421
423
  if (cell->type == ID($slice)) {
@@ -503,10 +505,13 @@ struct CellTypes
503
505
  return eval(cell->type, arg1, arg2, signed_a, signed_b, result_len, errp);
504
506
  }
505
507
 
508
+ // Consider using the ConstEval struct instead if you need named ports and/or multiple outputs
506
509
  static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, bool *errp = nullptr)
507
510
  {
508
511
  if (cell->type.in(ID($mux), ID($_MUX_)))
509
512
  return const_mux(arg1, arg2, arg3);
513
+ if (cell->type == ID($_NMUX_))
514
+ return eval_not(const_mux(arg1, arg2, arg3));
510
515
  if (cell->type == ID($bwmux))
511
516
  return const_bwmux(arg1, arg2, arg3);
512
517
  if (cell->type == ID($pmux))
@@ -520,6 +525,7 @@ struct CellTypes
520
525
  return eval(cell, arg1, arg2, errp);
521
526
  }
522
527
 
528
+ // Consider using the ConstEval struct instead if you need named ports and/or multiple outputs
523
529
  static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, const RTLIL::Const &arg4, bool *errp = nullptr)
524
530
  {
525
531
  if (cell->type == ID($_AOI4_))
@@ -349,7 +349,11 @@ struct ConstEval
349
349
  return false;
350
350
 
351
351
  bool eval_err = false;
352
- RTLIL::Const eval_ret = CellTypes::eval(cell, sig_a.as_const(), sig_b.as_const(), sig_c.as_const(), sig_d.as_const(), &eval_err);
352
+ RTLIL::Const eval_ret;
353
+ if (sig_s.size() > 0 && eval(sig_s, undef, cell)) {
354
+ eval_ret = CellTypes::eval(cell, sig_a.as_const(), sig_b.as_const(), sig_s.as_const(), &eval_err);
355
+ } else
356
+ eval_ret = CellTypes::eval(cell, sig_a.as_const(), sig_b.as_const(), sig_c.as_const(), sig_d.as_const(), &eval_err);
353
357
 
354
358
  if (eval_err)
355
359
  return false;
@@ -286,3 +286,4 @@ X(A_WIDTHS)
286
286
  X(B_WIDTHS)
287
287
  X(C_WIDTHS)
288
288
  X(C_SIGNED)
289
+ X(raise_error)
@@ -27,10 +27,10 @@ YOSYS_NAMESPACE_BEGIN
27
27
 
28
28
  struct FfInitVals
29
29
  {
30
- const SigMap *sigmap;
30
+ const SigMapView *sigmap;
31
31
  dict<SigBit, std::pair<State,SigBit>> initbits;
32
32
 
33
- void set(const SigMap *sigmap_, RTLIL::Module *module)
33
+ void set(const SigMapView *sigmap_, RTLIL::Module *module)
34
34
  {
35
35
  sigmap = sigmap_;
36
36
  initbits.clear();
@@ -126,7 +126,7 @@ struct FfInitVals
126
126
  initbits.clear();
127
127
  }
128
128
 
129
- FfInitVals (const SigMap *sigmap, RTLIL::Module *module)
129
+ FfInitVals (const SigMapView *sigmap, RTLIL::Module *module)
130
130
  {
131
131
  set(sigmap, module);
132
132
  }
@@ -58,7 +58,7 @@ YOSYS_NAMESPACE_BEGIN
58
58
 
59
59
  struct FfMergeHelper
60
60
  {
61
- const SigMap *sigmap;
61
+ const SigMapView *sigmap;
62
62
  RTLIL::Module *module;
63
63
  FfInitVals *initvals;
64
64
 
@@ -451,16 +451,21 @@ class dict {
451
451
  return 1;
452
452
  }
453
453
 
454
- int do_lookup(const K &key, Hasher::hash_t &hash) const
454
+ int do_lookup(const K &key, Hasher::hash_t &hash)
455
455
  {
456
456
  if (hashtable.empty())
457
457
  return -1;
458
458
 
459
459
  if (entries.size() * hashtable_size_trigger > hashtable.size()) {
460
- ((dict*)this)->do_rehash();
460
+ do_rehash();
461
461
  hash = do_hash(key);
462
462
  }
463
463
 
464
+ return do_lookup_internal(key, hash);
465
+ }
466
+
467
+ int do_lookup_internal(const K &key, Hasher::hash_t hash) const
468
+ {
464
469
  int index = hashtable[hash];
465
470
 
466
471
  while (index >= 0 && !ops.cmp(entries[index].udata.first, key)) {
@@ -471,6 +476,14 @@ class dict {
471
476
  return index;
472
477
  }
473
478
 
479
+ int do_lookup_no_rehash(const K &key, Hasher::hash_t hash) const
480
+ {
481
+ if (hashtable.empty())
482
+ return -1;
483
+
484
+ return do_lookup_internal(key, hash);
485
+ }
486
+
474
487
  int do_insert(const K &key, Hasher::hash_t &hash)
475
488
  {
476
489
  if (hashtable.empty()) {
@@ -694,14 +707,14 @@ public:
694
707
  int count(const K &key) const
695
708
  {
696
709
  Hasher::hash_t hash = do_hash(key);
697
- int i = do_lookup(key, hash);
710
+ int i = do_lookup_no_rehash(key, hash);
698
711
  return i < 0 ? 0 : 1;
699
712
  }
700
713
 
701
714
  int count(const K &key, const_iterator it) const
702
715
  {
703
716
  Hasher::hash_t hash = do_hash(key);
704
- int i = do_lookup(key, hash);
717
+ int i = do_lookup_no_rehash(key, hash);
705
718
  return i < 0 || i > it.index ? 0 : 1;
706
719
  }
707
720
 
@@ -717,7 +730,7 @@ public:
717
730
  const_iterator find(const K &key) const
718
731
  {
719
732
  Hasher::hash_t hash = do_hash(key);
720
- int i = do_lookup(key, hash);
733
+ int i = do_lookup_no_rehash(key, hash);
721
734
  if (i < 0)
722
735
  return end();
723
736
  return const_iterator(this, i);
@@ -735,7 +748,7 @@ public:
735
748
  const T& at(const K &key) const
736
749
  {
737
750
  Hasher::hash_t hash = do_hash(key);
738
- int i = do_lookup(key, hash);
751
+ int i = do_lookup_no_rehash(key, hash);
739
752
  if (i < 0)
740
753
  throw std::out_of_range("dict::at()");
741
754
  return entries[i].udata.second;
@@ -744,7 +757,7 @@ public:
744
757
  const T& at(const K &key, const T &defval) const
745
758
  {
746
759
  Hasher::hash_t hash = do_hash(key);
747
- int i = do_lookup(key, hash);
760
+ int i = do_lookup_no_rehash(key, hash);
748
761
  if (i < 0)
749
762
  return defval;
750
763
  return entries[i].udata.second;
@@ -906,16 +919,21 @@ protected:
906
919
  return 1;
907
920
  }
908
921
 
909
- int do_lookup(const K &key, Hasher::hash_t &hash) const
922
+ int do_lookup(const K &key, Hasher::hash_t &hash)
910
923
  {
911
924
  if (hashtable.empty())
912
925
  return -1;
913
926
 
914
927
  if (entries.size() * hashtable_size_trigger > hashtable.size()) {
915
- ((pool*)this)->do_rehash();
928
+ do_rehash();
916
929
  hash = do_hash(key);
917
930
  }
918
931
 
932
+ return do_lookup_internal(key, hash);
933
+ }
934
+
935
+ int do_lookup_internal(const K &key, Hasher::hash_t hash) const
936
+ {
919
937
  int index = hashtable[hash];
920
938
 
921
939
  while (index >= 0 && !ops.cmp(entries[index].udata, key)) {
@@ -926,6 +944,14 @@ protected:
926
944
  return index;
927
945
  }
928
946
 
947
+ int do_lookup_no_rehash(const K &key, Hasher::hash_t hash) const
948
+ {
949
+ if (hashtable.empty())
950
+ return -1;
951
+
952
+ return do_lookup_internal(key, hash);
953
+ }
954
+
929
955
  int do_insert(const K &value, Hasher::hash_t &hash)
930
956
  {
931
957
  if (hashtable.empty()) {
@@ -1087,14 +1113,14 @@ public:
1087
1113
  int count(const K &key) const
1088
1114
  {
1089
1115
  Hasher::hash_t hash = do_hash(key);
1090
- int i = do_lookup(key, hash);
1116
+ int i = do_lookup_no_rehash(key, hash);
1091
1117
  return i < 0 ? 0 : 1;
1092
1118
  }
1093
1119
 
1094
1120
  int count(const K &key, const_iterator it) const
1095
1121
  {
1096
1122
  Hasher::hash_t hash = do_hash(key);
1097
- int i = do_lookup(key, hash);
1123
+ int i = do_lookup_no_rehash(key, hash);
1098
1124
  return i < 0 || i > it.index ? 0 : 1;
1099
1125
  }
1100
1126
 
@@ -1110,7 +1136,7 @@ public:
1110
1136
  const_iterator find(const K &key) const
1111
1137
  {
1112
1138
  Hasher::hash_t hash = do_hash(key);
1113
- int i = do_lookup(key, hash);
1139
+ int i = do_lookup_no_rehash(key, hash);
1114
1140
  if (i < 0)
1115
1141
  return end();
1116
1142
  return const_iterator(this, i);
@@ -1222,7 +1248,7 @@ public:
1222
1248
  int at(const K &key) const
1223
1249
  {
1224
1250
  Hasher::hash_t hash = database.do_hash(key);
1225
- int i = database.do_lookup(key, hash);
1251
+ int i = database.do_lookup_no_rehash(key, hash);
1226
1252
  if (i < 0)
1227
1253
  throw std::out_of_range("idict::at()");
1228
1254
  return i + offset;
@@ -1231,7 +1257,7 @@ public:
1231
1257
  int at(const K &key, int defval) const
1232
1258
  {
1233
1259
  Hasher::hash_t hash = database.do_hash(key);
1234
- int i = database.do_lookup(key, hash);
1260
+ int i = database.do_lookup_no_rehash(key, hash);
1235
1261
  if (i < 0)
1236
1262
  return defval;
1237
1263
  return i + offset;
@@ -1240,7 +1266,7 @@ public:
1240
1266
  int count(const K &key) const
1241
1267
  {
1242
1268
  Hasher::hash_t hash = database.do_hash(key);
1243
- int i = database.do_lookup(key, hash);
1269
+ int i = database.do_lookup_no_rehash(key, hash);
1244
1270
  return i < 0 ? 0 : 1;
1245
1271
  }
1246
1272
 
@@ -1327,7 +1353,8 @@ public:
1327
1353
  return p;
1328
1354
  }
1329
1355
 
1330
- // Merge sets if the given indices belong to different sets
1356
+ // Merge sets if the given indices belong to different sets.
1357
+ // Makes ifind(j) the root of the merged set.
1331
1358
  void imerge(int i, int j)
1332
1359
  {
1333
1360
  i = ifind(i);