mirror of
https://github.com/YosysHQ/yosys
synced 2025-07-23 12:48:54 +00:00
kernel/mem: Introduce transparency masks.
This commit is contained in:
parent
681a1c07e5
commit
e6f3d1c225
8 changed files with 407 additions and 117 deletions
41
kernel/mem.h
41
kernel/mem.h
|
@ -31,7 +31,19 @@ struct MemRd : RTLIL::AttrObject {
|
|||
int wide_log2;
|
||||
bool clk_enable, clk_polarity, ce_over_srst;
|
||||
Const arst_value, srst_value, init_value;
|
||||
bool transparent;
|
||||
// One bit for every write port, true iff simultanous read on this
|
||||
// port and write on the other port will bypass the written data
|
||||
// to this port's output (default behavior is to read old value).
|
||||
// Can only be set for write ports that have the same clock domain.
|
||||
std::vector<bool> transparency_mask;
|
||||
// One bit for every write port, true iff simultanous read on this
|
||||
// port and write on the other port will return an all-X (don't care)
|
||||
// value. Mutually exclusive with transparency_mask.
|
||||
// Can only be set for write ports that have the same clock domain.
|
||||
// For optimization purposes, this will also be set if we can
|
||||
// determine that the two ports can never be active simultanously
|
||||
// (making the above vacuously true).
|
||||
std::vector<bool> collision_x_mask;
|
||||
SigSpec clk, en, arst, srst, addr, data;
|
||||
|
||||
MemRd() : removed(false), cell(nullptr) {}
|
||||
|
@ -139,15 +151,34 @@ struct Mem : RTLIL::AttrObject {
|
|||
// If write port idx2 currently has priority over write port idx1,
|
||||
// inserts extra logic on idx1's enable signal to disable writes
|
||||
// when idx2 is writing to the same address, then removes the priority
|
||||
// from the priority mask.
|
||||
void emulate_priority(int idx1, int idx2);
|
||||
// from the priority mask. If there is a memory port that is
|
||||
// transparent with idx1, but not with idx2, that port is converted
|
||||
// to use soft transparency logic.
|
||||
void emulate_priority(int idx1, int idx2, FfInitVals *initvals);
|
||||
|
||||
// Creates soft-transparency logic on read port ridx, bypassing the
|
||||
// data from write port widx. Should only be called when ridx is
|
||||
// transparent wrt widx in the first place. Once we're done, the
|
||||
// transparency_mask bit will be cleared, and the collision_x_mask
|
||||
// bit will be set instead (since whatever value is read will be
|
||||
// replaced by the soft transparency logic).
|
||||
void emulate_transparency(int widx, int ridx, FfInitVals *initvals);
|
||||
|
||||
// Prepares for merging write port idx2 into idx1 (where idx1 < idx2).
|
||||
// Specifically, takes care of priority masks: any priority relations
|
||||
// that idx2 had are replicated onto idx1, unless they conflict with
|
||||
// priorities already present on idx1, in which case emulate_priority
|
||||
// is called.
|
||||
void prepare_wr_merge(int idx1, int idx2);
|
||||
// is called. Likewise, ensures transparency and undefined collision
|
||||
// masks of all read ports have the same values for both ports,
|
||||
// calling emulate_transparency if necessary.
|
||||
void prepare_wr_merge(int idx1, int idx2, FfInitVals *initvals);
|
||||
|
||||
// Prepares for merging read port idx2 into idx1.
|
||||
// Specifically, makes sure the transparency and undefined collision
|
||||
// masks of both ports are equal, by changing undefined behavior
|
||||
// of one port to the other's defined behavior, or by calling
|
||||
// emulate_transparency if necessary.
|
||||
void prepare_rd_merge(int idx1, int idx2, FfInitVals *initvals);
|
||||
|
||||
// Prepares the memory for widening a port to a given width. This
|
||||
// involves ensuring that start_offset and size are aligned to the
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue