@@ -481,18 +481,58 @@ void MemMapping::dump_config(MemConfig &cfg) {
481
481
}
482
482
}
483
483
484
+ std::pair<bool , Const> search_for_attribute (Mem mem, IdString attr) {
485
+ // priority of attributes:
486
+ // 1. attributes on memory itself
487
+ // 2. attributes on a read or write port
488
+ // 3. attributes on data signal of a read or write port
489
+ // 4. attributes on address signal of a read or write port
490
+
491
+ if (mem.has_attribute (attr))
492
+ return std::make_pair (true , mem.attributes .at (attr));
493
+
494
+ for (auto &port: mem.rd_ports )
495
+ if (port.has_attribute (attr))
496
+ return std::make_pair (true , port.attributes .at (attr));
497
+ for (auto &port: mem.wr_ports )
498
+ if (port.has_attribute (attr))
499
+ return std::make_pair (true , port.attributes .at (attr));
500
+
501
+ for (auto &port: mem.rd_ports )
502
+ for (SigBit bit: port.data )
503
+ if (bit.is_wire () && bit.wire ->has_attribute (attr))
504
+ return std::make_pair (true , bit.wire ->attributes .at (attr));
505
+ for (auto &port: mem.wr_ports )
506
+ for (SigBit bit: port.data )
507
+ if (bit.is_wire () && bit.wire ->has_attribute (attr))
508
+ return std::make_pair (true , bit.wire ->attributes .at (attr));
509
+
510
+ for (auto &port: mem.rd_ports )
511
+ for (SigBit bit: port.addr )
512
+ if (bit.is_wire () && bit.wire ->has_attribute (attr))
513
+ return std::make_pair (true , bit.wire ->attributes .at (attr));
514
+ for (auto &port: mem.wr_ports )
515
+ for (SigBit bit: port.addr )
516
+ if (bit.is_wire () && bit.wire ->has_attribute (attr))
517
+ return std::make_pair (true , bit.wire ->attributes .at (attr));
518
+
519
+ return std::make_pair (false , Const ());
520
+ }
521
+
484
522
// Go through memory attributes to determine user-requested mapping style.
485
523
void MemMapping::determine_style () {
486
524
kind = RamKind::Auto;
487
525
style = " " ;
488
- if (mem.get_bool_attribute (ID::lram)) {
526
+ auto find_attr = search_for_attribute (mem, ID::lram);
527
+ if (find_attr.first && find_attr.second .as_bool ()) {
489
528
kind = RamKind::Huge;
490
529
log (" found attribute 'lram' on memory %s.%s, forced mapping to huge RAM\n " , log_id (mem.module ->name ), log_id (mem.memid ));
491
530
return ;
492
531
}
493
532
for (auto attr: {ID::ram_block, ID::rom_block, ID::ram_style, ID::rom_style, ID::ramstyle, ID::romstyle, ID::syn_ramstyle, ID::syn_romstyle}) {
494
- if (mem.has_attribute (attr)) {
495
- Const val = mem.attributes .at (attr);
533
+ find_attr = search_for_attribute (mem, attr);
534
+ if (find_attr.first ) {
535
+ Const val = find_attr.second ;
496
536
if (val == 1 ) {
497
537
kind = RamKind::NotLogic;
498
538
log (" found attribute '%s = 1' on memory %s.%s, disabled mapping to FF\n " , log_id (attr), log_id (mem.module ->name ), log_id (mem.memid ));
@@ -526,8 +566,11 @@ void MemMapping::determine_style() {
526
566
return ;
527
567
}
528
568
}
529
- if (mem.get_bool_attribute (ID::logic_block))
530
- kind = RamKind::Logic;
569
+ for (auto attr: {ID::logic_block, ID::no_ram}){
570
+ find_attr = search_for_attribute (mem, attr);
571
+ if (find_attr.first && find_attr.second .as_bool ())
572
+ kind = RamKind::Logic;
573
+ }
531
574
}
532
575
533
576
// Determine whether the memory can be mapped entirely to soft logic.
0 commit comments