yowasp-yosys 0.56.0.141.post974.dev0__py3-none-any.whl → 0.58.0.0.post1010__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 (35) hide show
  1. yowasp_yosys/share/gowin/cells_sim.v +0 -8
  2. yowasp_yosys/share/gowin/cells_xtra_gw1n.v +7 -0
  3. yowasp_yosys/share/gowin/cells_xtra_gw2a.v +12 -0
  4. yowasp_yosys/share/gowin/cells_xtra_gw5a.v +84 -0
  5. yowasp_yosys/share/include/backends/rtlil/rtlil_backend.h +1 -0
  6. yowasp_yosys/share/include/frontends/ast/ast.h +6 -1
  7. yowasp_yosys/share/include/kernel/bitpattern.h +50 -1
  8. yowasp_yosys/share/include/kernel/celltypes.h +19 -9
  9. yowasp_yosys/share/include/kernel/consteval.h +2 -2
  10. yowasp_yosys/share/include/kernel/constids.inc +859 -137
  11. yowasp_yosys/share/include/kernel/drivertools.h +6 -5
  12. yowasp_yosys/share/include/kernel/ffinit.h +5 -5
  13. yowasp_yosys/share/include/kernel/hashlib.h +88 -38
  14. yowasp_yosys/share/include/kernel/io.h +17 -2
  15. yowasp_yosys/share/include/kernel/log.h +102 -31
  16. yowasp_yosys/share/include/kernel/macc.h +1 -1
  17. yowasp_yosys/share/include/kernel/mem.h +4 -2
  18. yowasp_yosys/share/include/kernel/rtlil.h +268 -61
  19. yowasp_yosys/share/include/kernel/satgen.h +1 -1
  20. yowasp_yosys/share/include/kernel/threading.h +186 -0
  21. yowasp_yosys/share/include/kernel/utils.h +11 -0
  22. yowasp_yosys/share/include/kernel/yosys_common.h +9 -13
  23. yowasp_yosys/share/include/passes/fsm/fsmdata.h +18 -33
  24. yowasp_yosys/share/include/passes/techmap/libparse.h +1 -1
  25. yowasp_yosys/share/lattice/cells_bb_ecp5.v +4 -0
  26. yowasp_yosys/share/python3/sby_engine_abc.py +5 -2
  27. yowasp_yosys/share/simlib.v +34 -0
  28. yowasp_yosys/share/techmap.v +34 -2
  29. yowasp_yosys/smtbmc.py +5 -0
  30. yowasp_yosys/yosys.wasm +0 -0
  31. {yowasp_yosys-0.56.0.141.post974.dev0.dist-info → yowasp_yosys-0.58.0.0.post1010.dist-info}/METADATA +1 -1
  32. {yowasp_yosys-0.56.0.141.post974.dev0.dist-info → yowasp_yosys-0.58.0.0.post1010.dist-info}/RECORD +35 -34
  33. {yowasp_yosys-0.56.0.141.post974.dev0.dist-info → yowasp_yosys-0.58.0.0.post1010.dist-info}/WHEEL +0 -0
  34. {yowasp_yosys-0.56.0.141.post974.dev0.dist-info → yowasp_yosys-0.58.0.0.post1010.dist-info}/entry_points.txt +0 -0
  35. {yowasp_yosys-0.56.0.141.post974.dev0.dist-info → yowasp_yosys-0.58.0.0.post1010.dist-info}/top_level.txt +0 -0
@@ -20,6 +20,7 @@
20
20
  #ifndef DRIVERTOOLS_H
21
21
  #define DRIVERTOOLS_H
22
22
 
23
+ #include <string>
23
24
  #include <type_traits>
24
25
 
25
26
  #include "kernel/rtlil.h"
@@ -39,11 +40,11 @@ struct DriveChunk;
39
40
 
40
41
  struct DriveSpec;
41
42
 
42
- const char *log_signal(DriveChunkWire const &chunk);
43
- const char *log_signal(DriveChunkPort const &chunk);
44
- const char *log_signal(DriveChunkMarker const &chunk);
45
- const char *log_signal(DriveChunk const &chunk);
46
- const char *log_signal(DriveSpec const &chunk);
43
+ std::string log_signal(DriveChunkWire const &chunk);
44
+ std::string log_signal(DriveChunkPort const &chunk);
45
+ std::string log_signal(DriveChunkMarker const &chunk);
46
+ std::string log_signal(DriveChunk const &chunk);
47
+ std::string log_signal(DriveSpec const &chunk);
47
48
 
48
49
  enum class DriveType : unsigned char
49
50
  {
@@ -74,10 +74,10 @@ struct FfInitVals
74
74
 
75
75
  RTLIL::Const operator()(const RTLIL::SigSpec &sig) const
76
76
  {
77
- RTLIL::Const res;
77
+ RTLIL::Const::Builder res_bits(GetSize(sig));
78
78
  for (auto bit : sig)
79
- res.bits().push_back((*this)(bit));
80
- return res;
79
+ res_bits.push_back((*this)(bit));
80
+ return res_bits.build();
81
81
  }
82
82
 
83
83
  void set_init(RTLIL::SigBit bit, RTLIL::State val)
@@ -93,12 +93,12 @@ struct FfInitVals
93
93
  initbits[mbit] = std::make_pair(val,abit);
94
94
  auto it2 = abit.wire->attributes.find(ID::init);
95
95
  if (it2 != abit.wire->attributes.end()) {
96
- it2->second.bits()[abit.offset] = val;
96
+ it2->second.set(abit.offset, val);
97
97
  if (it2->second.is_fully_undef())
98
98
  abit.wire->attributes.erase(it2);
99
99
  } else if (val != State::Sx) {
100
100
  Const cval(State::Sx, GetSize(abit.wire));
101
- cval.bits()[abit.offset] = val;
101
+ cval.set(abit.offset, val);
102
102
  abit.wire->attributes[ID::init] = cval;
103
103
  }
104
104
  }
@@ -12,6 +12,7 @@
12
12
  #ifndef HASHLIB_H
13
13
  #define HASHLIB_H
14
14
 
15
+ #include <array>
15
16
  #include <stdexcept>
16
17
  #include <algorithm>
17
18
  #include <optional>
@@ -100,7 +101,7 @@ private:
100
101
  uint32_t hash = ((a << 5) + a) ^ b;
101
102
  return hash;
102
103
  }
103
- public:
104
+ public:
104
105
  void hash32(uint32_t i) {
105
106
  state = djb2_xor(i, state);
106
107
  state = mkhash_xorshift(fudge ^ state);
@@ -113,7 +114,7 @@ private:
113
114
  return;
114
115
  }
115
116
  [[nodiscard]]
116
- hash_t yield() {
117
+ hash_t yield() const {
117
118
  return (hash_t)state;
118
119
  }
119
120
 
@@ -127,6 +128,7 @@ private:
127
128
  *this = hash_ops<T>::hash_into(t, *this);
128
129
  }
129
130
 
131
+ [[deprecated]]
130
132
  void commutative_eat(hash_t t) {
131
133
  state ^= t;
132
134
  }
@@ -166,8 +168,17 @@ struct hash_ops {
166
168
  } else if constexpr (std::is_pointer_v<T>) {
167
169
  return hash_ops<uintptr_t>::hash_into((uintptr_t) a, h);
168
170
  } else if constexpr (std::is_same_v<T, std::string>) {
169
- for (auto c : a)
170
- h.hash32(c);
171
+ int size = a.size();
172
+ int i = 0;
173
+ while (i + 8 < size) {
174
+ uint64_t v;
175
+ memcpy(&v, a.data() + i, 8);
176
+ h.hash64(v);
177
+ i += 8;
178
+ }
179
+ uint64_t v = 0;
180
+ memcpy(&v, a.data() + i, size - i);
181
+ h.hash64(v);
171
182
  return h;
172
183
  } else {
173
184
  return a.hash_into(h);
@@ -177,58 +188,64 @@ struct hash_ops {
177
188
  };
178
189
 
179
190
  template<typename P, typename Q> struct hash_ops<std::pair<P, Q>> {
180
- static inline bool cmp(std::pair<P, Q> a, std::pair<P, Q> b) {
191
+ static inline bool cmp(const std::pair<P, Q> &a, const std::pair<P, Q> &b) {
181
192
  return a == b;
182
193
  }
183
- [[nodiscard]] static inline Hasher hash_into(std::pair<P, Q> a, Hasher h) {
194
+ [[nodiscard]] static inline Hasher hash_into(const std::pair<P, Q> &a, Hasher h) {
184
195
  h = hash_ops<P>::hash_into(a.first, h);
185
196
  h = hash_ops<Q>::hash_into(a.second, h);
186
197
  return h;
187
198
  }
188
- HASH_TOP_LOOP_FST (std::pair<P, Q> a) HASH_TOP_LOOP_SND
199
+ HASH_TOP_LOOP_FST (const std::pair<P, Q> &a) HASH_TOP_LOOP_SND
200
+ [[nodiscard]] static inline Hasher hash(const P &p, const Q &q) {
201
+ Hasher h;
202
+ h = hash_ops<P>::hash_into(p, h);
203
+ h = hash_ops<Q>::hash_into(q, h);
204
+ return h;
205
+ }
189
206
  };
190
207
 
191
208
  template<typename... T> struct hash_ops<std::tuple<T...>> {
192
- static inline bool cmp(std::tuple<T...> a, std::tuple<T...> b) {
209
+ static inline bool cmp(const std::tuple<T...> &a, const std::tuple<T...> &b) {
193
210
  return a == b;
194
211
  }
195
212
  template<size_t I = 0>
196
- static inline typename std::enable_if<I == sizeof...(T), Hasher>::type hash_into(std::tuple<T...>, Hasher h) {
213
+ static inline typename std::enable_if<I == sizeof...(T), Hasher>::type hash_into(const std::tuple<T...> &, Hasher h) {
197
214
  return h;
198
215
  }
199
216
  template<size_t I = 0>
200
- static inline typename std::enable_if<I != sizeof...(T), Hasher>::type hash_into(std::tuple<T...> a, Hasher h) {
217
+ static inline typename std::enable_if<I != sizeof...(T), Hasher>::type hash_into(const std::tuple<T...> &a, Hasher h) {
201
218
  typedef hash_ops<typename std::tuple_element<I, std::tuple<T...>>::type> element_ops_t;
202
219
  h = hash_into<I+1>(a, h);
203
220
  h = element_ops_t::hash_into(std::get<I>(a), h);
204
221
  return h;
205
222
  }
206
- HASH_TOP_LOOP_FST (std::tuple<T...> a) HASH_TOP_LOOP_SND
223
+ HASH_TOP_LOOP_FST (const std::tuple<T...> &a) HASH_TOP_LOOP_SND
207
224
  };
208
225
 
209
226
  template<typename T> struct hash_ops<std::vector<T>> {
210
- static inline bool cmp(std::vector<T> a, std::vector<T> b) {
227
+ static inline bool cmp(const std::vector<T> &a, const std::vector<T> &b) {
211
228
  return a == b;
212
229
  }
213
- [[nodiscard]] static inline Hasher hash_into(std::vector<T> a, Hasher h) {
230
+ [[nodiscard]] static inline Hasher hash_into(const std::vector<T> &a, Hasher h) {
214
231
  h.eat((uint32_t)a.size());
215
232
  for (auto k : a)
216
233
  h.eat(k);
217
234
  return h;
218
235
  }
219
- HASH_TOP_LOOP_FST (std::vector<T> a) HASH_TOP_LOOP_SND
236
+ HASH_TOP_LOOP_FST (const std::vector<T> &a) HASH_TOP_LOOP_SND
220
237
  };
221
238
 
222
239
  template<typename T, size_t N> struct hash_ops<std::array<T, N>> {
223
- static inline bool cmp(std::array<T, N> a, std::array<T, N> b) {
240
+ static inline bool cmp(const std::array<T, N> &a, const std::array<T, N> &b) {
224
241
  return a == b;
225
242
  }
226
- [[nodiscard]] static inline Hasher hash_into(std::array<T, N> a, Hasher h) {
243
+ [[nodiscard]] static inline Hasher hash_into(const std::array<T, N> &a, Hasher h) {
227
244
  for (const auto& k : a)
228
245
  h = hash_ops<T>::hash_into(k, h);
229
246
  return h;
230
247
  }
231
- HASH_TOP_LOOP_FST (std::array<T, N> a) HASH_TOP_LOOP_SND
248
+ HASH_TOP_LOOP_FST (const std::array<T, N> &a) HASH_TOP_LOOP_SND
232
249
  };
233
250
 
234
251
  struct hash_cstr_ops {
@@ -300,10 +317,10 @@ template<> struct hash_ops<std::monostate> {
300
317
  };
301
318
 
302
319
  template<typename... T> struct hash_ops<std::variant<T...>> {
303
- static inline bool cmp(std::variant<T...> a, std::variant<T...> b) {
320
+ static inline bool cmp(const std::variant<T...> &a, const std::variant<T...> &b) {
304
321
  return a == b;
305
322
  }
306
- [[nodiscard]] static inline Hasher hash_into(std::variant<T...> a, Hasher h) {
323
+ [[nodiscard]] static inline Hasher hash_into(const std::variant<T...> &a, Hasher h) {
307
324
  std::visit([& h](const auto &v) { h.eat(v); }, a);
308
325
  h.eat(a.index());
309
326
  return h;
@@ -311,10 +328,10 @@ template<typename... T> struct hash_ops<std::variant<T...>> {
311
328
  };
312
329
 
313
330
  template<typename T> struct hash_ops<std::optional<T>> {
314
- static inline bool cmp(std::optional<T> a, std::optional<T> b) {
331
+ static inline bool cmp(const std::optional<T> &a, const std::optional<T> &b) {
315
332
  return a == b;
316
333
  }
317
- [[nodiscard]] static inline Hasher hash_into(std::optional<T> a, Hasher h) {
334
+ [[nodiscard]] static inline Hasher hash_into(const std::optional<T> &a, Hasher h) {
318
335
  if(a.has_value())
319
336
  h.eat(*a);
320
337
  else
@@ -356,6 +373,33 @@ template<typename K, int offset = 0, typename OPS = hash_ops<K>> class idict;
356
373
  template<typename K, typename OPS = hash_ops<K>> class pool;
357
374
  template<typename K, typename OPS = hash_ops<K>> class mfp;
358
375
 
376
+ // Computes the hash value of an unordered set of elements.
377
+ // See https://www.preprints.org/manuscript/201710.0192/v1/download.
378
+ // This is the Sum(4) algorithm from that paper, which has good collision resistance,
379
+ // much better than Sum(1) or Xor(1) (and somewhat better than Xor(4)).
380
+ class commutative_hash {
381
+ public:
382
+ commutative_hash() {
383
+ buckets.fill(0);
384
+ }
385
+ template <typename T>
386
+ void eat(const T &obj) {
387
+ eat(hash_ops<T>::hash(obj));
388
+ }
389
+ void eat(const Hasher &h) {
390
+ Hasher::hash_t v = h.yield();
391
+ size_t index = v & (buckets.size() - 1);
392
+ buckets[index] += v;
393
+ }
394
+ [[nodiscard]] Hasher hash_into(Hasher h) const {
395
+ for (auto b : buckets)
396
+ h.eat(b);
397
+ return h;
398
+ }
399
+ private:
400
+ std::array<Hasher::hash_t, 4> buckets;
401
+ };
402
+
359
403
  template<typename K, typename T, typename OPS>
360
404
  class dict {
361
405
  struct entry_t
@@ -484,12 +528,11 @@ class dict {
484
528
  return do_lookup_internal(key, hash);
485
529
  }
486
530
 
487
- int do_insert(const K &key, Hasher::hash_t &hash)
531
+ int do_insert(const K &key, const Hasher::hash_t &hash)
488
532
  {
489
533
  if (hashtable.empty()) {
490
534
  entries.emplace_back(std::pair<K, T>(key, T()), -1);
491
535
  do_rehash();
492
- hash = do_hash(key);
493
536
  } else {
494
537
  entries.emplace_back(std::pair<K, T>(key, T()), hashtable[hash]);
495
538
  hashtable[hash] = entries.size() - 1;
@@ -497,12 +540,11 @@ class dict {
497
540
  return entries.size() - 1;
498
541
  }
499
542
 
500
- int do_insert(const std::pair<K, T> &value, Hasher::hash_t &hash)
543
+ int do_insert(const std::pair<K, T> &value, const Hasher::hash_t &hash)
501
544
  {
502
545
  if (hashtable.empty()) {
503
546
  entries.emplace_back(value, -1);
504
547
  do_rehash();
505
- hash = do_hash(value.first);
506
548
  } else {
507
549
  entries.emplace_back(value, hashtable[hash]);
508
550
  hashtable[hash] = entries.size() - 1;
@@ -510,13 +552,11 @@ class dict {
510
552
  return entries.size() - 1;
511
553
  }
512
554
 
513
- int do_insert(std::pair<K, T> &&rvalue, Hasher::hash_t &hash)
555
+ int do_insert(std::pair<K, T> &&rvalue, const Hasher::hash_t &hash)
514
556
  {
515
557
  if (hashtable.empty()) {
516
- auto key = rvalue.first;
517
558
  entries.emplace_back(std::forward<std::pair<K, T>>(rvalue), -1);
518
559
  do_rehash();
519
- hash = do_hash(key);
520
560
  } else {
521
561
  entries.emplace_back(std::forward<std::pair<K, T>>(rvalue), hashtable[hash]);
522
562
  hashtable[hash] = entries.size() - 1;
@@ -533,13 +573,16 @@ public:
533
573
  int index;
534
574
  const_iterator(const dict *ptr, int index) : ptr(ptr), index(index) { }
535
575
  public:
536
- typedef std::forward_iterator_tag iterator_category;
576
+ typedef std::bidirectional_iterator_tag iterator_category;
537
577
  typedef std::pair<K, T> value_type;
538
578
  typedef ptrdiff_t difference_type;
539
- typedef std::pair<K, T>* pointer;
540
- typedef std::pair<K, T>& reference;
579
+ typedef const std::pair<K, T>* pointer;
580
+ typedef const std::pair<K, T>& reference;
541
581
  const_iterator() { }
542
582
  const_iterator operator++() { index--; return *this; }
583
+ const_iterator operator++(int) { const_iterator tmp = *this; index--; return tmp; }
584
+ const_iterator operator--() { index++; return *this; }
585
+ const_iterator operator--(int) { const_iterator tmp = *this; index++; return tmp; }
543
586
  const_iterator operator+=(int amt) { index -= amt; return *this; }
544
587
  bool operator<(const const_iterator &other) const { return index > other.index; }
545
588
  bool operator==(const const_iterator &other) const { return index == other.index; }
@@ -573,6 +616,13 @@ public:
573
616
  const std::pair<K, T> *operator->() const { return &ptr->entries[index].udata; }
574
617
  operator const_iterator() const { return const_iterator(ptr, index); }
575
618
  };
619
+ using reverse_iterator = std::reverse_iterator<const_iterator>;
620
+ reverse_iterator rbegin() const {
621
+ return std::make_reverse_iterator(end());
622
+ }
623
+ reverse_iterator rend() const {
624
+ return std::make_reverse_iterator(begin());
625
+ }
576
626
 
577
627
  constexpr dict()
578
628
  {
@@ -801,14 +851,14 @@ public:
801
851
  }
802
852
 
803
853
  [[nodiscard]] Hasher hash_into(Hasher h) const {
854
+ commutative_hash comm;
804
855
  for (auto &it : entries) {
805
856
  Hasher entry_hash;
806
857
  entry_hash.eat(it.udata.first);
807
858
  entry_hash.eat(it.udata.second);
808
- h.commutative_eat(entry_hash.yield());
859
+ comm.eat(entry_hash);
809
860
  }
810
- h.eat(entries.size());
811
- return h;
861
+ return comm.hash_into(h);
812
862
  }
813
863
 
814
864
  void reserve(size_t n) { entries.reserve(n); }
@@ -822,7 +872,7 @@ public:
822
872
 
823
873
  const_iterator begin() const { return const_iterator(this, int(entries.size())-1); }
824
874
  const_iterator element(int n) const { return const_iterator(this, int(entries.size())-1-n); }
825
- const_iterator end() const { return const_iterator(nullptr, -1); }
875
+ const_iterator end() const { return const_iterator(this, -1); }
826
876
  };
827
877
 
828
878
  template<typename K, typename OPS>
@@ -1184,11 +1234,11 @@ public:
1184
1234
  }
1185
1235
 
1186
1236
  [[nodiscard]] Hasher hash_into(Hasher h) const {
1237
+ commutative_hash comm;
1187
1238
  for (auto &it : entries) {
1188
- h.commutative_eat(ops.hash(it.udata).yield());
1239
+ comm.eat(ops.hash(it.udata));
1189
1240
  }
1190
- h.eat(entries.size());
1191
- return h;
1241
+ return comm.hash_into(h);
1192
1242
  }
1193
1243
 
1194
1244
  void reserve(size_t n) { entries.reserve(n); }
@@ -8,6 +8,10 @@
8
8
 
9
9
  YOSYS_NAMESPACE_BEGIN
10
10
 
11
+ namespace RTLIL {
12
+ struct IdString;
13
+ }
14
+
11
15
  inline std::string vstringf(const char *fmt, va_list ap)
12
16
  {
13
17
  // For the common case of strings shorter than 128, save a heap
@@ -240,7 +244,8 @@ constexpr void check_format(std::string_view fmt, int fmt_start, bool *has_escap
240
244
  case CONVSPEC_CHAR_PTR:
241
245
  if constexpr (!std::is_convertible_v<Arg, const char *> &&
242
246
  !std::is_convertible_v<Arg, const std::string &> &&
243
- !std::is_convertible_v<Arg, const std::string_view &>) {
247
+ !std::is_convertible_v<Arg, const std::string_view &> &&
248
+ !std::is_convertible_v<Arg, const RTLIL::IdString &>) {
244
249
  YOSYS_ABORT("Expected type convertible to char *");
245
250
  }
246
251
  *specs = found;
@@ -279,6 +284,10 @@ void format_emit_string(std::string &result, std::string_view spec, int *dynamic
279
284
  void format_emit_string_view(std::string &result, std::string_view spec, int *dynamic_ints,
280
285
  DynamicIntCount num_dynamic_ints, std::string_view arg);
281
286
 
287
+ // Emit the string representation of `arg` that has been converted to a `RTLIL::IdString'.
288
+ void format_emit_idstring(std::string &result, std::string_view spec, int *dynamic_ints,
289
+ DynamicIntCount num_dynamic_ints, const RTLIL::IdString &arg);
290
+
282
291
  // Emit the string representation of `arg` that has been converted to a `double'.
283
292
  void format_emit_void_ptr(std::string &result, std::string_view spec, int *dynamic_ints,
284
293
  DynamicIntCount num_dynamic_ints, const void *arg);
@@ -329,6 +338,11 @@ inline void format_emit_one(std::string &result, std::string_view fmt, const Fou
329
338
  format_emit_string_view(result, spec, dynamic_ints, num_dynamic_ints, s);
330
339
  return;
331
340
  }
341
+ if constexpr (std::is_convertible_v<Arg, const RTLIL::IdString &>) {
342
+ const RTLIL::IdString &s = arg;
343
+ format_emit_idstring(result, spec, dynamic_ints, num_dynamic_ints, s);
344
+ return;
345
+ }
332
346
  break;
333
347
  case CONVSPEC_VOID_PTR:
334
348
  if constexpr (std::is_convertible_v<Arg, const void *>) {
@@ -423,6 +437,7 @@ public:
423
437
  {
424
438
  return format_emit_toplevel(fmt, has_escapes, specs, args...);
425
439
  }
440
+ std::string_view format_string() const { return fmt; }
426
441
  private:
427
442
  std::string_view fmt;
428
443
  bool has_escapes = false;
@@ -433,7 +448,7 @@ template <typename T> struct WrapType { using type = T; };
433
448
  template <typename T> using TypeIdentity = typename WrapType<T>::type;
434
449
 
435
450
  template <typename... Args>
436
- inline std::string stringf(FmtString<TypeIdentity<Args>...> fmt, Args... args)
451
+ inline std::string stringf(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
437
452
  {
438
453
  return fmt.format(args...);
439
454
  }
@@ -119,30 +119,12 @@ extern int log_make_debug;
119
119
  extern int log_force_debug;
120
120
  extern int log_debug_suppressed;
121
121
 
122
- void logv(const char *format, va_list ap);
123
- void logv_header(RTLIL::Design *design, const char *format, va_list ap);
124
- void logv_warning(const char *format, va_list ap);
125
- void logv_warning_noprefix(const char *format, va_list ap);
126
- [[noreturn]] void logv_error(const char *format, va_list ap);
122
+ [[deprecated]]
127
123
  [[noreturn]] void logv_file_error(const string &filename, int lineno, const char *format, va_list ap);
128
124
 
129
- void log(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2));
130
- void log_header(RTLIL::Design *design, const char *format, ...) YS_ATTRIBUTE(format(printf, 2, 3));
131
- void log_warning(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2));
132
- void log_experimental(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2));
133
-
134
125
  void set_verific_logging(void (*cb)(int msg_type, const char *message_id, const char* file_path, unsigned int left_line, unsigned int left_col, unsigned int right_line, unsigned int right_col, const char *msg));
135
126
  extern void (*log_verific_callback)(int msg_type, const char *message_id, const char* file_path, unsigned int left_line, unsigned int left_col, unsigned int right_line, unsigned int right_col, const char *msg);
136
127
 
137
- // Log with filename to report a problem in a source file.
138
- void log_file_warning(const std::string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4));
139
- void log_file_info(const std::string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4));
140
-
141
- void log_warning_noprefix(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2));
142
- [[noreturn]] void log_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2));
143
- [[noreturn]] void log_file_error(const string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4));
144
- [[noreturn]] void log_cmd_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2));
145
-
146
128
  #ifndef NDEBUG
147
129
  static inline bool ys_debug(int n = 0) { if (log_force_debug) return true; log_debug_suppressed += n; return false; }
148
130
  #else
@@ -150,6 +132,79 @@ static inline bool ys_debug(int = 0) { return false; }
150
132
  #endif
151
133
  # define log_debug(...) do { if (ys_debug(1)) log(__VA_ARGS__); } while (0)
152
134
 
135
+ void log_formatted_string(std::string_view format, std::string str);
136
+ template <typename... Args>
137
+ inline void log(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
138
+ {
139
+ if (log_make_debug && !ys_debug(1))
140
+ return;
141
+ log_formatted_string(fmt.format_string(), fmt.format(args...));
142
+ }
143
+
144
+ void log_formatted_header(RTLIL::Design *design, std::string_view format, std::string str);
145
+ template <typename... Args>
146
+ inline void log_header(RTLIL::Design *design, FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
147
+ {
148
+ log_formatted_header(design, fmt.format_string(), fmt.format(args...));
149
+ }
150
+
151
+ void log_formatted_warning(std::string_view prefix, std::string str);
152
+ template <typename... Args>
153
+ inline void log_warning(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
154
+ {
155
+ log_formatted_warning("Warning: ", fmt.format(args...));
156
+ }
157
+
158
+ inline void log_formatted_warning_noprefix(std::string str)
159
+ {
160
+ log_formatted_warning("", str);
161
+ }
162
+ template <typename... Args>
163
+ inline void log_warning_noprefix(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
164
+ {
165
+ log_formatted_warning("", fmt.format(args...));
166
+ }
167
+
168
+ void log_experimental(const std::string &str);
169
+
170
+ // Log with filename to report a problem in a source file.
171
+ void log_formatted_file_warning(std::string_view filename, int lineno, std::string str);
172
+ template <typename... Args>
173
+ void log_file_warning(std::string_view filename, int lineno, FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
174
+ {
175
+ log_formatted_file_warning(filename, lineno, fmt.format(args...));
176
+ }
177
+
178
+ void log_formatted_file_info(std::string_view filename, int lineno, std::string str);
179
+ template <typename... Args>
180
+ void log_file_info(std::string_view filename, int lineno, FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
181
+ {
182
+ if (log_make_debug && !ys_debug(1))
183
+ return;
184
+ log_formatted_file_info(filename, lineno, fmt.format(args...));
185
+ }
186
+
187
+ [[noreturn]] void log_formatted_error(std::string str);
188
+ template <typename... Args>
189
+ [[noreturn]] void log_error(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
190
+ {
191
+ log_formatted_error(fmt.format(args...));
192
+ }
193
+
194
+ [[noreturn]] void log_formatted_file_error(std::string_view filename, int lineno, std::string str);
195
+ template <typename... Args>
196
+ [[noreturn]] void log_file_error(std::string_view filename, int lineno, FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
197
+ {
198
+ log_formatted_file_error(filename, lineno, fmt.format(args...));
199
+ }
200
+
201
+ [[noreturn]] void log_formatted_cmd_error(std::string str);
202
+ template <typename... Args>
203
+ [[noreturn]] void log_cmd_error(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
204
+ {
205
+ log_formatted_cmd_error(fmt.format(args...));
206
+ }
207
+
153
208
  static inline void log_suppressed() {
154
209
  if (log_debug_suppressed && !log_make_debug) {
155
210
  log("<suppressed ~%d debug messages>\n", log_debug_suppressed);
@@ -204,11 +259,9 @@ extern dict<std::string, LogExpectedItem> log_expect_log, log_expect_warning, lo
204
259
  extern dict<std::string, LogExpectedItem> log_expect_prefix_log, log_expect_prefix_warning, log_expect_prefix_error;
205
260
  void log_check_expected();
206
261
 
207
- const char *log_signal(const RTLIL::SigSpec &sig, bool autoint = true);
208
- const char *log_const(const RTLIL::Const &value, bool autoint = true);
262
+ std::string log_signal(const RTLIL::SigSpec &sig, bool autoint = true);
263
+ std::string log_const(const RTLIL::Const &value, bool autoint = true);
209
264
  const char *log_id(const RTLIL::IdString &id);
210
- const char *log_str(const char *str);
211
- const char *log_str(std::string const &str);
212
265
 
213
266
  template<typename T> static inline const char *log_id(T *obj, const char *nullstr = nullptr) {
214
267
  if (nullstr && obj == nullptr)
@@ -220,16 +273,20 @@ void log_module(RTLIL::Module *module, std::string indent = "");
220
273
  void log_cell(RTLIL::Cell *cell, std::string indent = "");
221
274
  void log_wire(RTLIL::Wire *wire, std::string indent = "");
222
275
 
276
+ [[noreturn]]
277
+ void log_assert_failure(const char *expr, const char *file, int line);
223
278
  #ifndef NDEBUG
224
279
  static inline void log_assert_worker(bool cond, const char *expr, const char *file, int line) {
225
- if (!cond) log_error("Assert `%s' failed in %s:%d.\n", expr, file, line);
280
+ if (!cond) log_assert_failure(expr, file, line);
226
281
  }
227
282
  # define log_assert(_assert_expr_) YOSYS_NAMESPACE_PREFIX log_assert_worker(_assert_expr_, #_assert_expr_, __FILE__, __LINE__)
228
283
  #else
229
284
  # define log_assert(_assert_expr_) do { if (0) { (void)(_assert_expr_); } } while(0)
230
285
  #endif
231
286
 
232
- #define log_abort() YOSYS_NAMESPACE_PREFIX log_error("Abort in %s:%d.\n", __FILE__, __LINE__)
287
+ [[noreturn]]
288
+ void log_abort_internal(const char *file, int line);
289
+ #define log_abort() YOSYS_NAMESPACE_PREFIX log_abort_internal(__FILE__, __LINE__)
233
290
  #define log_ping() YOSYS_NAMESPACE_PREFIX log("-- %s:%d %s --\n", __FILE__, __LINE__, __PRETTY_FUNCTION__)
234
291
 
235
292
 
@@ -351,13 +408,27 @@ static inline void log_dump_val_worker(unsigned long int v) { log("%lu", v); }
351
408
  static inline void log_dump_val_worker(long long int v) { log("%lld", v); }
352
409
  static inline void log_dump_val_worker(unsigned long long int v) { log("%lld", v); }
353
410
  #endif
354
- static inline void log_dump_val_worker(char c) { log(c >= 32 && c < 127 ? "'%c'" : "'\\x%02x'", c); }
355
- static inline void log_dump_val_worker(unsigned char c) { log(c >= 32 && c < 127 ? "'%c'" : "'\\x%02x'", c); }
411
+ static inline void log_dump_val_worker(char c)
412
+ {
413
+ if (c >= 32 && c < 127) {
414
+ log("'%c'", c);
415
+ } else {
416
+ log("'\\x%02x'", c);
417
+ }
418
+ }
419
+ static inline void log_dump_val_worker(unsigned char c)
420
+ {
421
+ if (c >= 32 && c < 127) {
422
+ log("'%c'", c);
423
+ } else {
424
+ log("'\\x%02x'", c);
425
+ }
426
+ }
356
427
  static inline void log_dump_val_worker(bool v) { log("%s", v ? "true" : "false"); }
357
428
  static inline void log_dump_val_worker(double v) { log("%f", v); }
358
429
  static inline void log_dump_val_worker(char *v) { log("%s", v); }
359
430
  static inline void log_dump_val_worker(const char *v) { log("%s", v); }
360
- static inline void log_dump_val_worker(std::string v) { log("%s", v.c_str()); }
431
+ static inline void log_dump_val_worker(std::string v) { log("%s", v); }
361
432
  static inline void log_dump_val_worker(PerformanceTimer p) { log("%f seconds", p.sec()); }
362
433
  static inline void log_dump_args_worker(const char *p) { log_assert(*p == 0); }
363
434
  void log_dump_val_worker(RTLIL::IdString v);
@@ -374,7 +445,7 @@ static inline void log_dump_val_worker(dict<K, T> &v) {
374
445
  log("{");
375
446
  bool first = true;
376
447
  for (auto &it : v) {
377
- log(first ? " " : ", ");
448
+ log("%s ", first ? "" : ",");
378
449
  log_dump_val_worker(it.first);
379
450
  log(": ");
380
451
  log_dump_val_worker(it.second);
@@ -388,7 +459,7 @@ static inline void log_dump_val_worker(pool<K> &v) {
388
459
  log("{");
389
460
  bool first = true;
390
461
  for (auto &it : v) {
391
- log(first ? " " : ", ");
462
+ log("%s ", first ? "" : ",");
392
463
  log_dump_val_worker(it);
393
464
  first = false;
394
465
  }
@@ -400,7 +471,7 @@ static inline void log_dump_val_worker(std::vector<K> &v) {
400
471
  log("{");
401
472
  bool first = true;
402
473
  for (auto &it : v) {
403
- log(first ? " " : ", ");
474
+ log("%s ", first ? "" : ",");
404
475
  log_dump_val_worker(it);
405
476
  first = false;
406
477
  }
@@ -262,7 +262,7 @@ struct Macc
262
262
 
263
263
  bool eval(RTLIL::Const &result) const
264
264
  {
265
- for (auto &bit : result.bits())
265
+ for (auto bit : result)
266
266
  bit = State::S0;
267
267
 
268
268
  for (auto &port : terms)
@@ -255,11 +255,13 @@ private:
255
255
  // return the offset the addr would have in the range at `it`
256
256
  size_t _range_offset(std::map<addr_t, RTLIL::Const>::iterator it, addr_t addr) const { return (addr - it->first) * _data_width; }
257
257
  // assuming _range_contains(it, addr), return an iterator pointing to the data at addr
258
- std::vector<State>::iterator _range_data(std::map<addr_t, RTLIL::Const>::iterator it, addr_t addr) { return it->second.bits().begin() + _range_offset(it, addr); }
258
+ RTLIL::Const::iterator _range_data(std::map<addr_t, RTLIL::Const>::iterator it, addr_t addr) {
259
+ return RTLIL::Const::iterator(it->second, _range_offset(it, addr));
260
+ }
259
261
  // internal version of reserve_range that returns an iterator to the range
260
262
  std::map<addr_t, RTLIL::Const>::iterator _reserve_range(addr_t begin_addr, addr_t end_addr);
261
263
  // write a single word at addr, return iterator to next word
262
- std::vector<State>::iterator _range_write(std::vector<State>::iterator it, RTLIL::Const const &data);
264
+ RTLIL::Const::iterator _range_write(RTLIL::Const::iterator it, RTLIL::Const const &data);
263
265
  public:
264
266
  class range {
265
267
  int _data_width;