Skip to content

Commit

Permalink
Implement meminit transfer
Browse files Browse the repository at this point in the history
  • Loading branch information
povik committed Nov 21, 2024
1 parent cf348c4 commit 1e9c97e
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 3 deletions.
33 changes: 30 additions & 3 deletions src/slang_frontend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,16 @@ static const RTLIL::Const convert_const(const slang::ConstantValue &constval)
log_abort();
}

static const RTLIL::Const reverse_data(RTLIL::Const &orig, int width)
{
std::vector<RTLIL::State> bits;
log_assert(orig.size() % width == 0);
bits.reserve(orig.size());
for (int i = orig.size() - width; i >= 0; i -= width)
bits.insert(bits.end(), orig.begin() + i, orig.begin() + i + width);
return bits;
}

template<typename T>
void transfer_attrs(T &from, RTLIL::AttrObject *to)
{
Expand Down Expand Up @@ -2845,9 +2855,26 @@ struct PopulateNetlist : public TimingPatternInterpretor, public ast::ASTVisitor
log_assert(storage);
auto const_ = convert_const(*storage);
if (!const_.is_fully_undef()) {
auto wire = netlist.wire(sym);
log_assert(wire);
wire->attributes[RTLIL::ID::init] = const_;
if (is_inferred_memory(sym)) {
RTLIL::IdString id = netlist.id(sym);
RTLIL::Memory *m = netlist.canvas->memories.at(id);
RTLIL::Cell *meminit = netlist.canvas->addCell(NEW_ID, ID($meminit_v2));
int abits = 32;
ast_invariant(sym, m->width * m->size == const_.size());
meminit->setParam(ID::MEMID, id.str());
meminit->setParam(ID::PRIORITY, 0);
meminit->setParam(ID::ABITS, abits);
meminit->setParam(ID::WORDS, m->size);
meminit->setParam(ID::WIDTH, m->width);
meminit->setPort(ID::ADDR, m->start_offset);
bool little_endian = sym.getType().getFixedRange().isLittleEndian();
meminit->setPort(ID::DATA, little_endian ? const_ : reverse_data(const_, m->width));
meminit->setPort(ID::EN, RTLIL::Const(RTLIL::S1, m->width));
} else {
auto wire = netlist.wire(sym);
log_assert(wire);
wire->attributes[RTLIL::ID::init] = const_;
}
}
}
}, [&](auto&, const ast::InstanceSymbol&) {
Expand Down
102 changes: 102 additions & 0 deletions tests/various/meminit.ys
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
design -reset
read_slang --no-implicit-memories <<EOF
module top();
(* rom_block *)
reg [3:0] x[1:0];
reg [3:0] y[1:0];

initial begin
x <= '{7, 1};
y <= '{7, 1};
end

always_comb
assert(x[0] === y[0] && x[1] === y[1]);
endmodule
EOF

chformal -lower
memory_map
sat -verify -enable_undef -prove-asserts

design -reset
read_slang --no-implicit-memories <<EOF
module top();
(* rom_block *)
reg [3:0] x[0:1];
reg [3:0] y[0:1];

initial begin
x <= '{7, 1};
y <= '{7, 1};
end

always_comb
assert(x[0] === y[0] && x[1] === y[1]);
endmodule
EOF

chformal -lower
memory_map
sat -verify -enable_undef -prove-asserts

design -reset
read_slang --no-implicit-memories <<EOF
module top();
(* rom_block *)
reg [3:0] x[1:2];
reg [3:0] y[1:2];

initial begin
x <= '{7, 1};
y <= '{7, 1};
end

always_comb
assert(x[1] === y[1] && x[2] === y[2]);
endmodule
EOF
chformal -lower
memory_map
sat -verify -enable_undef -prove-asserts

design -reset
read_slang --no-implicit-memories <<EOF
module top();
(* rom_block *)
reg [3:0] x[2:1];
reg [3:0] y[2:1];

initial begin
x <= '{7, 1};
y <= '{7, 1};
end

always_comb
assert(x[1] === y[1] && x[2] === y[2]);
endmodule
EOF
chformal -lower
memory_map
sat -verify -enable_undef -prove-asserts

design -reset
read_slang --no-implicit-memories <<EOF
module top();
(* rom_block *)
reg [3:0] x[0:-1];
reg [3:0] y[0:-1];

initial begin
x <= '{7, 1};
y <= '{7, 1};
end

always_comb
assert(x[0] === y[0] && x[-1] === y[-1]);
endmodule
EOF
dump
chformal -lower
memory_map
sat -verify -enable_undef -prove-asserts

0 comments on commit 1e9c97e

Please sign in to comment.