This commit is contained in:
Akash Levy 2026-05-27 01:51:54 -07:00
parent e39395132d
commit 89717069fe
2 changed files with 61 additions and 1 deletions

View File

@ -23,6 +23,24 @@
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
static void merge_add_attributes(Cell *dst, const Cell *outer, const Cell *inner)
{
dst->attributes = outer->attributes;
for (const auto &attr : inner->attributes)
if (attr.first != ID::src && !dst->attributes.count(attr.first))
dst->attributes[attr.first] = attr.second;
std::string outer_src = outer->get_src_attribute();
std::string inner_src = inner->get_src_attribute();
if (outer_src.empty()) {
if (!inner_src.empty())
dst->set_src_attribute(inner_src);
} else if (!inner_src.empty() && inner_src != outer_src) {
dst->set_src_attribute(outer_src + "|" + inner_src);
}
}
struct OptAddcinWorker
{
struct Leaf {
@ -189,7 +207,7 @@ struct OptAddcinWorker
Wire *wide_y_wire = module->addWire(NEW_ID2_SUFFIX("addcin_y"), rewrite.width + 1);
SigSpec wide_y(wide_y_wire);
Cell *wide_add = module->addCell(NEW_ID2_SUFFIX("addcin"), ID($add));
wide_add->attributes = rewrite.outer->attributes;
merge_add_attributes(wide_add, rewrite.outer, rewrite.inner);
wide_add->setPort(ID::A, wide_a);
wide_add->setPort(ID::B, wide_b);
wide_add->setPort(ID::Y, wide_y);

View File

@ -379,3 +379,45 @@ design -load postopt
select -assert-count 3 t:$add
design -reset
log -pop
# ============================================================================
# Group D: Metadata preservation
# ============================================================================
# Test D1: replacement adder preserves attributes from both consumed adders.
#
# Shape:
# add_ab : s = a + b (* src="inner_add.v:10.1-10.8", inner_marker=1 *)
# add_cin : y = s + cin (* src="outer_add.v:20.1-20.8", outer_marker=1 *)
#
# The replacement cell is the only remaining $add. It should keep the outer
# cell's attributes, import inner-only metadata, and retain both source
# locations in its merged src attribute.
log -header "D1: merge attributes from inner and outer cells"
log -push
design -reset
read_verilog -icells <<EOF
module top(
input wire [3:0] a,
input wire [3:0] b,
input wire cin,
output wire [3:0] y
);
wire [3:0] s;
(* src = "inner_add.v:10.1-10.8", inner_marker = 1 *)
\$add #(.A_WIDTH(4), .B_WIDTH(4), .Y_WIDTH(4), .A_SIGNED(0), .B_SIGNED(0))
add_ab (.A(a), .B(b), .Y(s));
(* src = "outer_add.v:20.1-20.8", outer_marker = 1 *)
\$add #(.A_WIDTH(4), .B_WIDTH(1), .Y_WIDTH(4), .A_SIGNED(0), .B_SIGNED(0))
add_cin (.A(s), .B(cin), .Y(y));
endmodule
EOF
check -assert
opt_addcin
select -assert-count 1 t:$add
select -assert-count 1 t:$add a:outer_marker %i
select -assert-count 1 t:$add a:inner_marker %i
select -assert-count 1 t:$add a:src=*outer_add.v* %i
select -assert-count 1 t:$add a:src=*inner_add.v* %i
design -reset
log -pop