xilinx: use specify blocks in place of abc9_{arrival,required}

This commit is contained in:
Eddie Hung 2020-02-11 14:22:43 -08:00
parent 0e7c55e2a7
commit 577545488a
3 changed files with 670 additions and 347 deletions

View File

@ -364,25 +364,14 @@ Verilog Attributes and non-standard features
it as the external-facing pin of an I/O pad, and prevents ``iopadmap`` it as the external-facing pin of an I/O pad, and prevents ``iopadmap``
from inserting another pad cell on it. from inserting another pad cell on it.
- The module attribute ``abc9_box_id`` specifies a positive integer linking a - The module attribute ``abc9_box`` is a boolean specifying a blackbox or
blackbox or whitebox definition to a corresponding entry in a `abc9` whitebox definition for use by `abc9`.
box-file.
- The port attribute ``abc9_carry`` marks the carry-in (if an input port) and - The port attribute ``abc9_carry`` marks the carry-in (if an input port) and
carry-out (if output port) ports of a box. This information is necessary for carry-out (if output port) ports of a box. This information is necessary for
`abc9` to preserve the integrity of carry-chains. Specifying this attribute `abc9` to preserve the integrity of carry-chains. Specifying this attribute
onto a bus port will affect only its most significant bit. onto a bus port will affect only its most significant bit.
- The output port attribute ``abc9_arrival`` specifies an integer, or a string
of space-separated integers to be used as the arrival time of this blackbox
port. It can be used, for example, to specify the clk-to-Q delay of a flip-
flop output for consideration during `abc9` techmapping.
- The input port attribute ``abc9_required`` specifies an integer, or a string
of space-separated integers to be used as the required time of this blackbox
port. It can be used, for example, to specify the setup-time of a flip-flop
input for consideration during `abc9` techmapping.
- The module attribute ``abc9_flop`` is a boolean marking the module as a - The module attribute ``abc9_flop`` is a boolean marking the module as a
flip-flop. This allows `abc9` to analyse its contents in order to perform flip-flop. This allows `abc9` to analyse its contents in order to perform
sequential synthesis. sequential synthesis.

View File

@ -70,54 +70,6 @@ void check(RTLIL::Design *design)
carry_out = port_name; carry_out = port_name;
} }
} }
auto it = w->attributes.find("\\abc9_arrival");
if (it != w->attributes.end()) {
int count = 0;
if (it->second.flags == 0) {
if (it->second.as_int() < 0)
log_error("%s.%s has negative arrival value %d!\n", log_id(m), log_id(port_name),
it->second.as_int());
count++;
}
else
for (const auto &tok : split_tokens(it->second.decode_string())) {
if (tok.find_first_not_of("0123456789") != std::string::npos)
log_error("%s.%s has non-integer arrival value '%s'!\n", log_id(m), log_id(port_name),
tok.c_str());
if (atoi(tok.c_str()) < 0)
log_error("%s.%s has negative arrival value %s!\n", log_id(m), log_id(port_name),
tok.c_str());
count++;
}
if (count > 1 && count != GetSize(w))
log_error("%s.%s is %d bits wide but abc9_arrival = %s has %d value(s)!\n", log_id(m), log_id(port_name),
GetSize(w), log_signal(it->second), count);
}
it = w->attributes.find("\\abc9_required");
if (it != w->attributes.end()) {
int count = 0;
if (it->second.flags == 0) {
if (it->second.as_int() < 0)
log_error("%s.%s has negative required value %d!\n", log_id(m), log_id(port_name),
it->second.as_int());
count++;
}
else
for (const auto &tok : split_tokens(it->second.decode_string())) {
if (tok.find_first_not_of("0123456789") != std::string::npos)
log_error("%s.%s has non-integer required value '%s'!\n", log_id(m), log_id(port_name),
tok.c_str());
if (atoi(tok.c_str()) < 0)
log_error("%s.%s has negative required value %s!\n", log_id(m), log_id(port_name),
tok.c_str());
count++;
}
if (count > 1 && count != GetSize(w))
log_error("%s.%s is %d bits wide but abc9_required = %s has %d value(s)!\n", log_id(m), log_id(port_name),
GetSize(w), log_signal(it->second), count);
}
} }
if (carry_in != IdString() && carry_out == IdString()) if (carry_in != IdString() && carry_out == IdString())
@ -428,16 +380,15 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
void prep_delays(RTLIL::Design *design) void prep_delays(RTLIL::Design *design)
{ {
pool<Module*> flops; // Derive and collect all blackbox modules, and collect all blackbox instantiations
pool<Module*> derived;
std::vector<Cell*> cells; std::vector<Cell*> cells;
dict<IdString,dict<IdString,std::vector<int>>> requireds_cache;
for (auto module : design->selected_modules()) { for (auto module : design->selected_modules()) {
if (module->processes.size() > 0) { if (module->processes.size() > 0) {
log("Skipping module %s as it contains processes.\n", log_id(module)); log("Skipping module %s as it contains processes.\n", log_id(module));
continue; continue;
} }
cells.clear();
for (auto cell : module->cells()) { for (auto cell : module->cells()) {
if (cell->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_), ID($__ABC9_DELAY))) if (cell->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_), ID($__ABC9_DELAY)))
continue; continue;
@ -447,119 +398,186 @@ void prep_delays(RTLIL::Design *design)
continue; continue;
if (!inst_module->get_blackbox_attribute()) if (!inst_module->get_blackbox_attribute())
continue; continue;
if (inst_module->get_bool_attribute(ID(abc9_flop))) {
IdString derived_type = inst_module->derive(design, cell->parameters);
inst_module = design->module(derived_type);
log_assert(inst_module);
flops.insert(inst_module);
continue; // because all flop required times
// will be captured in the flop box
}
if (inst_module->attributes.count(ID(abc9_box))) if (inst_module->attributes.count(ID(abc9_box)))
continue; continue;
IdString derived_type = inst_module->derive(design, cell->parameters);
inst_module = design->module(derived_type);
log_assert(inst_module);
derived.insert(inst_module);
cells.emplace_back(cell); cells.emplace_back(cell);
} }
}
for (auto cell : cells) { // Transform all $specify3 and $specrule to abc9_{arrival,required} attributes
RTLIL::Module* inst_module = module->design->module(cell->type); std::vector<Module*> flops;
log_assert(inst_module); dict<SigBit, int> arrivals, requireds;
auto &cell_requireds = requireds_cache[cell->type]; pool<Wire*> ports;
for (auto &conn : cell->connections_) { std::stringstream ss;
auto port_wire = inst_module->wire(conn.first); for (auto module : derived) {
if (!port_wire->port_input) if (module->get_bool_attribute(ID(abc9_flop)))
flops.push_back(module);
arrivals.clear();
requireds.clear();
for (auto cell : module->cells()) {
if (cell->type == ID($specify3)) {
auto src = cell->getPort(ID(SRC));
auto dat = cell->getPort(ID(DAT));
auto dst = cell->getPort(ID(DST));
for (const auto &c : src.chunks())
if (!c.wire->port_input)
log_error("Module '%s' contains specify cell '%s' where SRC '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(src));
for (const auto &c : dat.chunks())
if (!c.wire->port_input)
log_error("Module '%s' contains specify cell '%s' where DAT '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(dat));
for (const auto &c : dst.chunks())
if (!c.wire->port_output)
log_error("Module '%s' contains specify cell '%s' where DST '%s' is not a module output.\n", log_id(module), log_id(cell), log_signal(dst));
if (!cell->getParam(ID(EDGE_EN)).as_bool())
continue; continue;
int rise_max = cell->getParam(ID(T_RISE_MAX)).as_int();
int fall_max = cell->getParam(ID(T_FALL_MAX)).as_int();
int max = std::max(rise_max,fall_max);
if (max < 0) {
log_warning("Module '%s' contains specify cell '%s' with T_{RISE,FALL}_MAX < 0 which is currently unsupported. Ignoring.\n", log_id(module), log_id(cell));
continue;
}
for (auto d : dst)
arrivals[d] = std::max(arrivals[d], max);
}
else if (cell->type == ID($specrule)) {
auto type = cell->getParam(ID(TYPE)).decode_string();
if (type != "$setup" && type != "$setuphold")
continue;
auto src = cell->getPort(ID(SRC));
auto dst = cell->getPort(ID(DST));
for (const auto &c : src.chunks())
if (!c.wire->port_input)
log_error("Module '%s' contains specify cell '%s' where SRC '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(src));
for (const auto &c : dst.chunks())
if (!c.wire->port_input)
log_error("Module '%s' contains specify cell '%s' where DST '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(dst));
int setup = cell->getParam(ID(T_LIMIT)).as_int();
if (setup < 0) {
log_warning("Module '%s' contains specify cell '%s' with T_LIMIT < 0 which is currently unsupported. Ignoring.\n", log_id(module), log_id(cell));
continue;
}
for (const auto &s : src)
requireds[s] = std::max(requireds[s], setup);
}
}
auto r = cell_requireds.insert(conn.first); if (arrivals.empty() && requireds.empty())
auto &requireds = r.first->second; continue;
if (r.second) {
auto it = port_wire->attributes.find("\\abc9_required"); ports.clear();
if (it == port_wire->attributes.end()) for (const auto &i : arrivals)
continue; ports.insert(i.first.wire);
if (it->second.flags == 0) { for (auto wire : ports) {
int delay = it->second.as_int(); log_assert(wire->port_output);
requireds.emplace_back(delay); ss.str("");
} if (GetSize(wire) == 1)
wire->attributes[ID(abc9_arrival)] = arrivals.at(SigBit(wire,0));
else {
bool first = true;
for (auto b : SigSpec(wire)) {
if (first)
first = false;
else else
for (const auto &tok : split_tokens(it->second.decode_string())) { ss << " ";
int delay = atoi(tok.c_str()); auto it = arrivals.find(b);
requireds.push_back(delay); if (it == arrivals.end())
} ss << "0";
else
ss << it->second;
} }
wire->attributes[ID(abc9_arrival)] = ss.str();
}
}
if (requireds.empty()) ports.clear();
continue; for (const auto &i : requireds)
ports.insert(i.first.wire);
SigSpec O = module->addWire(NEW_ID, GetSize(conn.second)); for (auto wire : ports) {
auto it = requireds.begin(); log_assert(wire->port_input);
for (int i = 0; i < GetSize(conn.second); ++i) { ss.str("");
#ifndef NDEBUG if (GetSize(wire) == 1)
if (ys_debug(1)) { wire->attributes[ID(abc9_required)] = requireds.at(SigBit(wire,0));
static std::set<std::pair<IdString,IdString>> seen; else {
if (seen.emplace(cell->type, conn.first).second) log("%s.%s abc9_required = %d\n", log_id(cell->type), log_id(conn.first), requireds[i]); bool first = true;
} for (auto b : SigSpec(wire)) {
#endif if (first)
auto box = module->addCell(NEW_ID, ID($__ABC9_DELAY)); first = false;
box->setPort(ID(I), conn.second[i]); else
box->setPort(ID(O), O[i]); ss << " ";
box->setParam(ID(DELAY), *it); auto it = requireds.find(b);
if (requireds.size() > 1) if (it == requireds.end())
it++; ss << "0";
conn.second[i] = O[i]; else
ss << it->second;
} }
wire->attributes[ID(abc9_required)] = ss.str();
} }
} }
} }
int abc9_box_id = design->scratchpad_get_int("abc9_ops.box_id"); // Insert $__ABC9_DELAY cells on all cells that instantiate blackboxes
std::stringstream ss; // with (* abc9_required *) attributes
for (auto flop_module : flops) { dict<IdString,dict<IdString,std::vector<int>>> requireds_cache;
int num_inputs = 0, num_outputs = 0; for (auto cell : cells) {
for (auto port_name : flop_module->ports) { auto module = cell->module;
auto wire = flop_module->wire(port_name); RTLIL::Module* inst_module = module->design->module(cell->type);
log_assert(GetSize(wire) == 1); log_assert(inst_module);
if (wire->port_input) num_inputs++; IdString derived_type = inst_module->derive(design, cell->parameters);
if (wire->port_output) num_outputs++; inst_module = design->module(derived_type);
} log_assert(inst_module);
log_assert(num_outputs == 1);
auto r = flop_module->attributes.insert(ID(abc9_box_id)); auto &cell_requireds = requireds_cache[cell->type];
if (r.second) for (auto &conn : cell->connections_) {
r.first->second = ++abc9_box_id; auto port_wire = inst_module->wire(conn.first);
if (!port_wire->port_input)
ss << log_id(flop_module) << " " << r.first->second.as_int();
ss << " " << (flop_module->get_bool_attribute(ID::whitebox) ? "1" : "0");
ss << " " << num_inputs+1 << " " << num_outputs << std::endl;
ss << "#";
bool first = true;
for (auto port_name : flop_module->ports) {
auto wire = flop_module->wire(port_name);
if (!wire->port_input)
continue; continue;
if (first)
first = false;
else
ss << " ";
ss << log_id(wire);
}
ss << " abc9_ff.Q" << std::endl;
first = true; auto r = cell_requireds.insert(conn.first);
for (auto port_name : flop_module->ports) { auto &requireds = r.first->second;
auto wire = flop_module->wire(port_name); if (r.second) {
if (!wire->port_input) auto it = port_wire->attributes.find("\\abc9_required");
if (it == port_wire->attributes.end())
continue;
if (it->second.flags == 0) {
int delay = it->second.as_int();
requireds.emplace_back(delay);
}
else
for (const auto &tok : split_tokens(it->second.decode_string())) {
int delay = atoi(tok.c_str());
requireds.push_back(delay);
}
}
if (requireds.empty())
continue; continue;
if (first)
first = false; SigSpec O = module->addWire(NEW_ID, GetSize(conn.second));
else auto it = requireds.begin();
ss << " "; for (int i = 0; i < GetSize(conn.second); ++i) {
ss << wire->attributes.at("\\abc9_required", 0).as_int(); #ifndef NDEBUG
if (ys_debug(1)) {
static std::set<std::pair<IdString,IdString>> seen;
if (seen.emplace(cell->type, conn.first).second) log("%s.%s abc9_required = %d\n", log_id(cell->type), log_id(conn.first), requireds[i]);
}
#endif
auto box = module->addCell(NEW_ID, ID($__ABC9_DELAY));
box->setPort(ID(I), conn.second[i]);
box->setPort(ID(O), O[i]);
box->setParam(ID(DELAY), *it);
if (requireds.size() > 1)
it++;
conn.second[i] = O[i];
}
} }
// Last input is 'abc9_ff.Q'
ss << " 0" << std::endl << std::endl;
} }
design->scratchpad_set_string("abc9_ops.box_library.flops", ss.str());
design->scratchpad_set_int("abc9_ops.box_id", abc9_box_id);
} }
void prep_lut(RTLIL::Design *design, int maxlut) void prep_lut(RTLIL::Design *design, int maxlut)
@ -587,7 +605,10 @@ void prep_lut(RTLIL::Design *design, int maxlut)
log_assert(o == d); log_assert(o == d);
int rise_max = cell->getParam(ID(T_RISE_MAX)).as_int(); int rise_max = cell->getParam(ID(T_RISE_MAX)).as_int();
int fall_max = cell->getParam(ID(T_FALL_MAX)).as_int(); int fall_max = cell->getParam(ID(T_FALL_MAX)).as_int();
specify.push_back(std::max(rise_max,fall_max)); int max = std::max(rise_max,fall_max);
if (max < 0)
log_error("Module '%s' contains specify cell '%s' with T_{RISE,FALL}_MAX < 0.\n", log_id(module), log_id(cell));
specify.push_back(max);
} }
if (maxlut && GetSize(specify) > maxlut) if (maxlut && GetSize(specify) > maxlut)
continue; continue;
@ -618,10 +639,57 @@ void write_lut(RTLIL::Module *module, const std::string &dst) {
void prep_box(RTLIL::Design *design) void prep_box(RTLIL::Design *design)
{ {
std::stringstream ss; std::stringstream ss;
ss << design->scratchpad_get_string("abc9_ops.box_library.flops", ss.str()); int abc9_box_id = 1;
dict<IdString,std::vector<IdString>> box_ports;
int abc9_box_id = design->scratchpad_get_int("abc9_ops.box_id");
for (auto module : design->modules()) { for (auto module : design->modules()) {
if (module->get_bool_attribute(ID(abc9_flop))) {
int num_inputs = 0, num_outputs = 0;
for (auto port_name : module->ports) {
auto wire = module->wire(port_name);
log_assert(GetSize(wire) == 1);
if (wire->port_input) num_inputs++;
if (wire->port_output) num_outputs++;
}
log_assert(num_outputs == 1);
auto r = module->attributes.insert(ID(abc9_box_id));
if (r.second)
r.first->second = abc9_box_id++;
ss << log_id(module) << " " << r.first->second.as_int();
ss << " " << (module->get_bool_attribute(ID::whitebox) ? "1" : "0");
ss << " " << num_inputs+1 << " " << num_outputs << std::endl;
ss << "#";
bool first = true;
for (auto port_name : module->ports) {
auto wire = module->wire(port_name);
if (!wire->port_input)
continue;
if (first)
first = false;
else
ss << " ";
ss << log_id(wire);
}
ss << " abc9_ff.Q" << std::endl;
first = true;
for (auto port_name : module->ports) {
auto wire = module->wire(port_name);
if (!wire->port_input)
continue;
if (first)
first = false;
else
ss << " ";
ss << wire->attributes.at("\\abc9_required", 0).as_int();
}
// Last input is 'abc9_ff.Q'
ss << " 0" << std::endl << std::endl;
continue;
}
auto it = module->attributes.find(ID(abc9_box)); auto it = module->attributes.find(ID(abc9_box));
if (it == module->attributes.end()) if (it == module->attributes.end())
continue; continue;
@ -631,7 +699,33 @@ void prep_box(RTLIL::Design *design)
dict<std::pair<SigBit,SigBit>, std::string> table; dict<std::pair<SigBit,SigBit>, std::string> table;
std::vector<SigBit> inputs; std::vector<SigBit> inputs;
std::vector<SigBit> outputs; std::vector<SigBit> outputs;
for (auto port_name : module->ports) {
auto r = box_ports.insert(module->name);
if (r.second) {
// Make carry in the last PI, and carry out the last PO
// since ABC requires it this way
IdString carry_in, carry_out;
for (const auto &port_name : module->ports) {
auto w = module->wire(port_name);
log_assert(w);
if (w->get_bool_attribute("\\abc9_carry")) {
log_assert(w->port_input != w->port_output);
if (w->port_input)
carry_in = port_name;
else if (w->port_output)
carry_out = port_name;
}
else
r.first->second.push_back(port_name);
}
if (carry_in != IdString()) {
r.first->second.push_back(carry_in);
r.first->second.push_back(carry_out);
}
}
for (auto port_name : r.first->second) {
auto wire = module->wire(port_name); auto wire = module->wire(port_name);
if (wire->port_input) if (wire->port_input)
for (int i = 0; i < GetSize(wire); i++) for (int i = 0; i < GetSize(wire); i++)
@ -654,17 +748,29 @@ void prep_box(RTLIL::Design *design)
int rise_max = cell->getParam(ID(T_RISE_MAX)).as_int(); int rise_max = cell->getParam(ID(T_RISE_MAX)).as_int();
int fall_max = cell->getParam(ID(T_FALL_MAX)).as_int(); int fall_max = cell->getParam(ID(T_FALL_MAX)).as_int();
int max = std::max(rise_max,fall_max); int max = std::max(rise_max,fall_max);
for (auto s : src) if (max < 0)
for (auto d : dst) { log_error("Module '%s' contains specify cell '%s' with T_{RISE,FALL}_MAX < 0.\n", log_id(module), log_id(cell));
auto r = table.insert(std::make_pair(s,d)); if (cell->getParam(ID(FULL)).as_bool()) {
for (auto s : src)
for (auto d : dst) {
auto r = table.insert(std::make_pair(s,d));
log_assert(r.second);
r.first->second = std::to_string(max);
}
}
else {
log_assert(GetSize(src) == GetSize(dst));
for (auto i = 0; i < GetSize(src); i++) {
auto r = table.insert(std::make_pair(src[i],dst[i]));
log_assert(r.second); log_assert(r.second);
r.first->second = std::to_string(max); r.first->second = std::to_string(max);
} }
}
} }
auto r = module->attributes.insert(ID(abc9_box_id)); auto r2 = module->attributes.insert(ID(abc9_box_id));
log_assert(r.second); log_assert(r2.second);
r.first->second = ++abc9_box_id;
ss << log_id(module) << " " << abc9_box_id; ss << log_id(module) << " " << abc9_box_id;
r2.first->second = abc9_box_id++;
ss << " " << (module->get_bool_attribute(ID::whitebox) ? "1" : "0"); ss << " " << (module->get_bool_attribute(ID::whitebox) ? "1" : "0");
ss << " " << GetSize(inputs) << " " << GetSize(outputs) << std::endl; ss << " " << GetSize(inputs) << " " << GetSize(outputs) << std::endl;
bool first = true; bool first = true;
@ -700,17 +806,17 @@ void prep_box(RTLIL::Design *design)
ss << std::endl; ss << std::endl;
} }
// ABC expects at least one box
if (ss.tellp() == 0)
ss << "(dummy) 1 0 0 0";
design->scratchpad_set_string("abc9_ops.box_library", ss.str()); design->scratchpad_set_string("abc9_ops.box_library", ss.str());
design->scratchpad_set_int("abc9_ops.box_id", abc9_box_id);
} }
void write_box(RTLIL::Module *module, const std::string &dst) { void write_box(RTLIL::Module *module, const std::string &dst) {
std::ofstream ofs(dst); std::ofstream ofs(dst);
log_assert(ofs.is_open()); log_assert(ofs.is_open());
ofs << module->design->scratchpad_get_string("abc9_ops.box_library"); ofs << module->design->scratchpad_get_string("abc9_ops.box_library");
// ABC expects at least one box
if (ofs.tellp() == 0)
ofs << "(dummy) 1 0 0 0";
ofs.close(); ofs.close();
} }

View File

@ -477,18 +477,14 @@ endmodule
(* abc9_flop, lib_whitebox *) (* abc9_flop, lib_whitebox *)
module FDRE ( module FDRE (
(* abc9_arrival=303 *)
output reg Q, output reg Q,
(* clkbuf_sink *) (* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *) (* invertible_pin = "IS_C_INVERTED" *)
input C, input C,
(* abc9_required=109 *)
input CE, input CE,
(* invertible_pin = "IS_D_INVERTED" *) (* invertible_pin = "IS_D_INVERTED" *)
//(* abc9_required=-46 *) // Negative required times not currently supported
input D, input D,
(* invertible_pin = "IS_R_INVERTED" *) (* invertible_pin = "IS_R_INVERTED" *)
(* abc9_required=404 *)
input R input R
); );
parameter [0:0] INIT = 1'b0; parameter [0:0] INIT = 1'b0;
@ -496,44 +492,58 @@ module FDRE (
parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0;
parameter [0:0] IS_R_INVERTED = 1'b0; parameter [0:0] IS_R_INVERTED = 1'b0;
initial Q <= INIT; initial Q <= INIT;
generate case (|IS_C_INVERTED) generate
case (|IS_C_INVERTED)
1'b0: always @(posedge C) if (R == !IS_R_INVERTED) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; 1'b0: always @(posedge C) if (R == !IS_R_INVERTED) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED;
1'b1: always @(negedge C) if (R == !IS_R_INVERTED) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; 1'b1: always @(negedge C) if (R == !IS_R_INVERTED) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED;
endcase endgenerate endcase
if (!IS_C_INVERTED)
specify
if (CE) (posedge C => (Q : D)) = 303;
//$setup(D , posedge C, -46); // Negative times not currently supported
$setup(CE, posedge C, 109);
$setup(R , posedge C, 404);
endspecify
else
specify
if (CE) (negedge C => (Q : D)) = 303;
//if (CE) $setup(D , negedge C, -46); // Negative times not currently supported
$setup(CE, negedge C, 109);
$setup(R , negedge C, 404);
endspecify
endgenerate
endmodule endmodule
(* abc9_flop, lib_whitebox *) (* abc9_flop, lib_whitebox *)
module FDRE_1 ( module FDRE_1 (
(* abc9_arrival=303 *)
output reg Q, output reg Q,
(* clkbuf_sink *) (* clkbuf_sink *)
input C, input C,
(* abc9_required=109 *)
input CE, input CE,
//(* abc9_required=-46 *) // Negative required times not currently supported
input D, input D,
(* abc9_required=404 *)
input R input R
); );
parameter [0:0] INIT = 1'b0; parameter [0:0] INIT = 1'b0;
initial Q <= INIT; initial Q <= INIT;
always @(negedge C) if (R) Q <= 1'b0; else if (CE) Q <= D; always @(negedge C) if (R) Q <= 1'b0; else if (CE) Q <= D;
specify
if (CE) (negedge C => (Q : D)) = 303;
//if (CE) $setup(D , negedge C, -46); // Negative times not currently supported
$setup(CE, negedge C, 109);
$setup(R , negedge C, 404);
endspecify
endmodule endmodule
(* abc9_flop, lib_whitebox *) (* abc9_flop, lib_whitebox *)
module FDSE ( module FDSE (
(* abc9_arrival=303 *)
output reg Q, output reg Q,
(* clkbuf_sink *) (* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *) (* invertible_pin = "IS_C_INVERTED" *)
input C, input C,
(* abc9_required=109 *)
input CE, input CE,
(* invertible_pin = "IS_D_INVERTED" *) (* invertible_pin = "IS_D_INVERTED" *)
//(* abc9_required=-46 *) // Negative required times not currently supported
input D, input D,
(* invertible_pin = "IS_S_INVERTED" *) (* invertible_pin = "IS_S_INVERTED" *)
(* abc9_required=404 *)
input S input S
); );
parameter [0:0] INIT = 1'b1; parameter [0:0] INIT = 1'b1;
@ -541,28 +551,46 @@ module FDSE (
parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0;
parameter [0:0] IS_S_INVERTED = 1'b0; parameter [0:0] IS_S_INVERTED = 1'b0;
initial Q <= INIT; initial Q <= INIT;
generate case (|IS_C_INVERTED) generate
case (|IS_C_INVERTED)
1'b0: always @(posedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; 1'b0: always @(posedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED;
1'b1: always @(negedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; 1'b1: always @(negedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED;
endcase endgenerate endcase
if (!IS_C_INVERTED)
specify
if (CE) (posedge C => (Q : D)) = 303;
//if (CE) $setup(D , posedge C, -46); // Negative times not currently supported
$setup(CE, posedge C, 109);
$setup(S , posedge C, 404);
endspecify
else
specify
if (CE) (negedge C => (Q : D)) = 303;
//if (CE) $setup(D , negedge C, -46); // Negative times not currently supported
$setup(CE, negedge C, 109);
$setup(S , negedge C, 404);
endspecify
endgenerate
endmodule endmodule
(* abc9_flop, lib_whitebox *) (* abc9_flop, lib_whitebox *)
module FDSE_1 ( module FDSE_1 (
(* abc9_arrival=303 *)
output reg Q, output reg Q,
(* clkbuf_sink *) (* clkbuf_sink *)
input C, input C,
(* abc9_required=109 *)
input CE, input CE,
//(* abc9_required=-46 *) // Negative required times not currently supported
input D, input D,
(* abc9_required=404 *)
input S input S
); );
parameter [0:0] INIT = 1'b1; parameter [0:0] INIT = 1'b1;
initial Q <= INIT; initial Q <= INIT;
always @(negedge C) if (S) Q <= 1'b1; else if (CE) Q <= D; always @(negedge C) if (S) Q <= 1'b1; else if (CE) Q <= D;
specify
if (CE) (negedge C => (Q : D)) = 303;
//if (CE) $setup(D , negedge C, -46); // Negative times not currently supported
$setup(CE, negedge C, 109);
$setup(S , negedge C, 404);
endspecify
endmodule endmodule
module FDRSE ( module FDRSE (
@ -571,7 +599,6 @@ module FDRSE (
(* invertible_pin = "IS_C_INVERTED" *) (* invertible_pin = "IS_C_INVERTED" *)
input C, input C,
(* invertible_pin = "IS_CE_INVERTED" *) (* invertible_pin = "IS_CE_INVERTED" *)
(* abc9_required=109 *)
input CE, input CE,
(* invertible_pin = "IS_D_INVERTED" *) (* invertible_pin = "IS_D_INVERTED" *)
input D, input D,
@ -603,18 +630,14 @@ endmodule
(* abc9_flop, lib_whitebox *) (* abc9_flop, lib_whitebox *)
module FDCE ( module FDCE (
(* abc9_arrival=303 *)
output reg Q, output reg Q,
(* clkbuf_sink *) (* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *) (* invertible_pin = "IS_C_INVERTED" *)
input C, input C,
(* abc9_required=109 *)
input CE, input CE,
(* invertible_pin = "IS_CLR_INVERTED" *) (* invertible_pin = "IS_CLR_INVERTED" *)
(* abc9_required=764 *)
input CLR, input CLR,
(* invertible_pin = "IS_D_INVERTED" *) (* invertible_pin = "IS_D_INVERTED" *)
//(* abc9_required=-46 *) // Negative required times not currently supported
input D input D
); );
parameter [0:0] INIT = 1'b0; parameter [0:0] INIT = 1'b0;
@ -622,46 +645,60 @@ module FDCE (
parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0;
parameter [0:0] IS_CLR_INVERTED = 1'b0; parameter [0:0] IS_CLR_INVERTED = 1'b0;
initial Q <= INIT; initial Q <= INIT;
generate case ({|IS_C_INVERTED, |IS_CLR_INVERTED}) generate
case ({|IS_C_INVERTED, |IS_CLR_INVERTED})
2'b00: always @(posedge C, posedge CLR) if ( CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; 2'b00: always @(posedge C, posedge CLR) if ( CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED;
2'b01: always @(posedge C, negedge CLR) if (!CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; 2'b01: always @(posedge C, negedge CLR) if (!CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED;
2'b10: always @(negedge C, posedge CLR) if ( CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; 2'b10: always @(negedge C, posedge CLR) if ( CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED;
2'b11: always @(negedge C, negedge CLR) if (!CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; 2'b11: always @(negedge C, negedge CLR) if (!CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED;
endcase endgenerate endcase
if (!IS_C_INVERTED)
specify
if (CE) (posedge C => (Q : D)) = 303;
//if (CE) $setup(D , posedge C, -46); // Negative times not currently supported
$setup(CE , posedge C, 109);
$setup(CLR, posedge C, 764);
endspecify
else
specify
if (CE) (negedge C => (Q : D)) = 303;
//if (CE) $setup(D , negedge C, -46); // Negative times not currently supported
$setup(CE , negedge C, 109);
$setup(CLR, negedge C, 764);
endspecify
endgenerate
endmodule endmodule
(* abc9_flop, lib_whitebox *) (* abc9_flop, lib_whitebox *)
module FDCE_1 ( module FDCE_1 (
(* abc9_arrival=303 *)
output reg Q, output reg Q,
(* clkbuf_sink *) (* clkbuf_sink *)
input C, input C,
(* abc9_required=109 *)
input CE, input CE,
(* abc9_required=764 *)
input CLR, input CLR,
//(* abc9_required=-46 *) // Negative required times not currently supported
input D input D
); );
parameter [0:0] INIT = 1'b0; parameter [0:0] INIT = 1'b0;
initial Q <= INIT; initial Q <= INIT;
always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D; always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D;
specify
if (CE) (negedge C => (Q : D)) = 303;
//if (CE) $setup(D , negedge C, -46); // Negative times not currently supported
$setup(CE , negedge C, 109);
$setup(CLR, negedge C, 764);
endspecify
endmodule endmodule
(* abc9_flop, lib_whitebox *) (* abc9_flop, lib_whitebox *)
module FDPE ( module FDPE (
(* abc9_arrival=303 *)
output reg Q, output reg Q,
(* clkbuf_sink *) (* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *) (* invertible_pin = "IS_C_INVERTED" *)
input C, input C,
(* abc9_required=109 *)
input CE, input CE,
(* invertible_pin = "IS_D_INVERTED" *) (* invertible_pin = "IS_D_INVERTED" *)
//(* abc9_required=-46 *) // Negative required times not currently supported
input D, input D,
(* invertible_pin = "IS_PRE_INVERTED" *) (* invertible_pin = "IS_PRE_INVERTED" *)
(* abc9_required=764 *)
input PRE input PRE
); );
parameter [0:0] INIT = 1'b1; parameter [0:0] INIT = 1'b1;
@ -674,25 +711,42 @@ module FDPE (
2'b01: always @(posedge C, negedge PRE) if (!PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; 2'b01: always @(posedge C, negedge PRE) if (!PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED;
2'b10: always @(negedge C, posedge PRE) if ( PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; 2'b10: always @(negedge C, posedge PRE) if ( PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED;
2'b11: always @(negedge C, negedge PRE) if (!PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; 2'b11: always @(negedge C, negedge PRE) if (!PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED;
endcase endgenerate endcase
if (!IS_C_INVERTED)
specify
if (CE) (posedge C => (Q : D)) = 303;
//if (CE) $setup(D , posedge C, -46); // Negative times not currently supported
$setup(CE , posedge C, 109);
$setup(PRE, posedge C, 764);
endspecify
else
specify
if (CE) (negedge C => (Q : D)) = 303;
//if (CE) $setup(D , negedge C, -46); // Negative times not currently supported
$setup(CE , negedge C, 109);
$setup(PRE, negedge C, 764);
endspecify
endgenerate
endmodule endmodule
(* abc9_flop, lib_whitebox *) (* abc9_flop, lib_whitebox *)
module FDPE_1 ( module FDPE_1 (
(* abc9_arrival=303 *)
output reg Q, output reg Q,
(* clkbuf_sink *) (* clkbuf_sink *)
input C, input C,
(* abc9_required=109 *)
input CE, input CE,
//(* abc9_required=-46 *) // Negative required times not currently supported
input D, input D,
(* abc9_required=764 *)
input PRE input PRE
); );
parameter [0:0] INIT = 1'b1; parameter [0:0] INIT = 1'b1;
initial Q <= INIT; initial Q <= INIT;
always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D; always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D;
specify
if (CE) (negedge C => (Q : D)) = 303;
//if (CE) $setup(D , negedge C, -46); // Negative times not currently supported
$setup(CE , negedge C, 109);
$setup(PRE, negedge C, 764);
endspecify
endmodule endmodule
module FDCPE ( module FDCPE (
@ -1303,33 +1357,13 @@ module RAM16X1D_1 (
endmodule endmodule
module RAM32X1D ( module RAM32X1D (
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
(* abc9_arrival=1153 *)
output DPO, SPO, output DPO, SPO,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
(* abc9_required=453 *)
input D, input D,
(* clkbuf_sink *) (* clkbuf_sink *)
(* invertible_pin = "IS_WCLK_INVERTED" *) (* invertible_pin = "IS_WCLK_INVERTED" *)
input WCLK, input WCLK,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
(* abc9_required=654 *)
input WE, input WE,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L800 input A0, A1, A2, A3, A4,
(* abc9_required=245 *)
input A0,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/clBLM_R.sdf#L798
(* abc9_required=208 *)
input A1,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L796
(* abc9_required=147 *)
input A2,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L794
(* abc9_required=68 *)
input A3,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L792
(* abc9_required=66 *)
input A4,
input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4 input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4
); );
parameter INIT = 32'h0; parameter INIT = 32'h0;
@ -1341,35 +1375,61 @@ module RAM32X1D (
assign DPO = mem[dpra]; assign DPO = mem[dpra];
wire clk = WCLK ^ IS_WCLK_INVERTED; wire clk = WCLK ^ IS_WCLK_INVERTED;
always @(posedge clk) if (WE) mem[a] <= D; always @(posedge clk) if (WE) mem[a] <= D;
generate
if (!IS_WCLK_INVERTED)
specify
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
if (WE) (posedge WCLK => (SPO : D)) = 1153;
if (WE) (posedge WCLK => (DPO : D)) = 1153;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
$setup(D , posedge WCLK, 453);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
$setup(WE, posedge WCLK, 654);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L800
$setup(A0, posedge WCLK, 245);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L798
$setup(A1, posedge WCLK, 208);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L796
$setup(A2, posedge WCLK, 147);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L794
$setup(A3, posedge WCLK, 68);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L792
$setup(A4, posedge WCLK, 66);
endspecify
else
specify
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
if (WE) (negedge WCLK => (SPO : D)) = 1153;
if (WE) (negedge WCLK => (DPO : D)) = 1153;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
$setup(D , negedge WCLK, 453);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
$setup(WE, negedge WCLK, 654);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L800
$setup(A0, negedge WCLK, 245);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L798
$setup(A1, negedge WCLK, 208);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L796
$setup(A2, negedge WCLK, 147);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L794
$setup(A3, negedge WCLK, 68);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L792
$setup(A4, negedge WCLK, 66);
endspecify
endgenerate
endmodule endmodule
module RAM32X1D_1 ( module RAM32X1D_1 (
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
(* abc9_arrival=1153 *)
output DPO, SPO, output DPO, SPO,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
(* abc9_required=453 *)
input D, input D,
(* clkbuf_sink *) (* clkbuf_sink *)
(* invertible_pin = "IS_WCLK_INVERTED" *) (* invertible_pin = "IS_WCLK_INVERTED" *)
input WCLK, input WCLK,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
(* abc9_required=654 *)
input WE, input WE,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L800
(* abc9_required=245 *)
input A0, input A0,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/clBLM_R.sdf#L798
(* abc9_required=208 *)
input A1, input A1,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L796
(* abc9_required=147 *)
input A2, input A2,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L794
(* abc9_required=68 *)
input A3, input A3,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L792
(* abc9_required=66 *)
input A4, input A4,
input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4 input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4
); );
@ -1382,39 +1442,35 @@ module RAM32X1D_1 (
assign DPO = mem[dpra]; assign DPO = mem[dpra];
wire clk = WCLK ^ IS_WCLK_INVERTED; wire clk = WCLK ^ IS_WCLK_INVERTED;
always @(negedge clk) if (WE) mem[a] <= D; always @(negedge clk) if (WE) mem[a] <= D;
specify
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
if (WE) (negedge WCLK => (SPO : D)) = 1153;
if (WE) (negedge WCLK => (DPO : D)) = 1153;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
$setup(D , negedge WCLK, 453);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
$setup(WE, negedge WCLK, 654);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L800
$setup(A0, negedge WCLK, 245);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L798
$setup(A1, negedge WCLK, 208);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L796
$setup(A2, negedge WCLK, 147);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L794
$setup(A3, negedge WCLK, 68);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L792
$setup(A4, negedge WCLK, 66);
endspecify
endmodule endmodule
module RAM64X1D ( module RAM64X1D (
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
(* abc9_arrival=1153 *)
output DPO, SPO, output DPO, SPO,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
(* abc9_required=453 *)
input D, input D,
(* clkbuf_sink *) (* clkbuf_sink *)
(* invertible_pin = "IS_WCLK_INVERTED" *) (* invertible_pin = "IS_WCLK_INVERTED" *)
input WCLK, input WCLK,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
(* abc9_required=654 *)
input WE, input WE,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L828 input A0, A1, A2, A3, A4, A5,
(* abc9_required=362 *)
input A0,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L826
(* abc9_required=245 *)
input A1,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L824
(* abc9_required=208 *)
input A2,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L822
(* abc9_required=147 *)
input A3,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L820
(* abc9_required=68 *)
input A4,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818
(* abc9_required=66 *)
input A5,
input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5 input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5
); );
parameter INIT = 64'h0; parameter INIT = 64'h0;
@ -1426,39 +1482,62 @@ module RAM64X1D (
assign DPO = mem[dpra]; assign DPO = mem[dpra];
wire clk = WCLK ^ IS_WCLK_INVERTED; wire clk = WCLK ^ IS_WCLK_INVERTED;
always @(posedge clk) if (WE) mem[a] <= D; always @(posedge clk) if (WE) mem[a] <= D;
generate
if (!IS_WCLK_INVERTED)
specify
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
if (WE) (posedge WCLK => (SPO : D)) = 1153;
if (WE) (posedge WCLK => (DPO : D)) = 1153;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
$setup(D , posedge WCLK, 453);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
$setup(WE, posedge WCLK, 654);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L828
$setup(A0, posedge WCLK, 362);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L826
$setup(A1, posedge WCLK, 245);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L824
$setup(A2, posedge WCLK, 208);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L822
$setup(A3, posedge WCLK, 147);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L820
$setup(A4, posedge WCLK, 68);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818
$setup(A5, posedge WCLK, 66);
endspecify
else
specify
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
if (WE) (negedge WCLK => (SPO : D)) = 1153;
if (WE) (negedge WCLK => (DPO : D)) = 1153;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
$setup(D , negedge WCLK, 453);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
$setup(WE, negedge WCLK, 654);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L828
$setup(A0, negedge WCLK, 362);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L826
$setup(A1, negedge WCLK, 245);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L824
$setup(A2, negedge WCLK, 208);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L822
$setup(A3, negedge WCLK, 147);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L820
$setup(A4, negedge WCLK, 68);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818
$setup(A5, negedge WCLK, 66);
endspecify
endgenerate
endmodule endmodule
module RAM64X1D_1 ( module RAM64X1D_1 (
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
(* abc9_arrival=1153 *)
output DPO, SPO, output DPO, SPO,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
(* abc9_required=453 *)
input D, input D,
(* clkbuf_sink *) (* clkbuf_sink *)
(* invertible_pin = "IS_WCLK_INVERTED" *) (* invertible_pin = "IS_WCLK_INVERTED" *)
input WCLK, input WCLK,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
(* abc9_required=654 *)
input WE, input WE,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L828 input A0, A1, A2, A3, A4, A5,
(* abc9_required=362 *)
input A0,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L826
(* abc9_required=245 *)
input A1,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L824
(* abc9_required=208 *)
input A2,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L822
(* abc9_required=147 *)
input A3,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L820
(* abc9_required=68 *)
input A4,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818
(* abc9_required=66 *)
input A5,
input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5 input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5
); );
parameter INIT = 64'h0; parameter INIT = 64'h0;
@ -1470,21 +1549,35 @@ module RAM64X1D_1 (
assign DPO = mem[dpra]; assign DPO = mem[dpra];
wire clk = WCLK ^ IS_WCLK_INVERTED; wire clk = WCLK ^ IS_WCLK_INVERTED;
always @(negedge clk) if (WE) mem[a] <= D; always @(negedge clk) if (WE) mem[a] <= D;
specify
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
if (WE) (negedge WCLK => (SPO : D)) = 1153;
if (WE) (negedge WCLK => (DPO : D)) = 1153;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
$setup(D , negedge WCLK, 453);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
$setup(WE, negedge WCLK, 654);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L828
$setup(A0, negedge WCLK, 362);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L826
$setup(A1, negedge WCLK, 245);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L824
$setup(A2, negedge WCLK, 208);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L822
$setup(A3, negedge WCLK, 147);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L820
$setup(A4, negedge WCLK, 68);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818
$setup(A5, negedge WCLK, 66);
endspecify
endmodule endmodule
module RAM128X1D ( module RAM128X1D (
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
// plus 208ps to cross MUXF7
(* abc9_arrival=1359 *)
output DPO, SPO, output DPO, SPO,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
(* abc9_required=453 *)
input D, input D,
(* clkbuf_sink *) (* clkbuf_sink *)
(* invertible_pin = "IS_WCLK_INVERTED" *) (* invertible_pin = "IS_WCLK_INVERTED" *)
input WCLK, input WCLK,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
(* abc9_required=654 *)
input WE, input WE,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818-830 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818-830
(* abc9_required="616 362 245 208 147 68 66" *) (* abc9_required="616 362 245 208 147 68 66" *)
@ -1498,6 +1591,46 @@ module RAM128X1D (
assign DPO = mem[DPRA]; assign DPO = mem[DPRA];
wire clk = WCLK ^ IS_WCLK_INVERTED; wire clk = WCLK ^ IS_WCLK_INVERTED;
always @(posedge clk) if (WE) mem[A] <= D; always @(posedge clk) if (WE) mem[A] <= D;
generate
if (!IS_WCLK_INVERTED)
specify
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
// plus 208ps to cross MUXF7
if (WE) (posedge WCLK => (SPO : D)) = 1359;
if (WE) (posedge WCLK => (DPO : D)) = 1359;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
$setup(D , posedge WCLK, 453);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
$setup(WE, posedge WCLK, 654);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818-830
$setup(A[0], posedge WCLK, 616);
$setup(A[1], posedge WCLK, 362);
$setup(A[2], posedge WCLK, 245);
$setup(A[3], posedge WCLK, 208);
$setup(A[4], posedge WCLK, 147);
$setup(A[5], posedge WCLK, 68);
$setup(A[6], posedge WCLK, 66);
endspecify
else
specify
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
// plus 208ps to cross MUXF7
if (WE) (negedge WCLK => (SPO : D)) = 1359;
if (WE) (negedge WCLK => (DPO : D)) = 1359;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
$setup(D , negedge WCLK, 453);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
$setup(WE, negedge WCLK, 654);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818-830
$setup(A[0], negedge WCLK, 616);
$setup(A[1], negedge WCLK, 362);
$setup(A[2], negedge WCLK, 245);
$setup(A[3], negedge WCLK, 208);
$setup(A[4], negedge WCLK, 147);
$setup(A[5], negedge WCLK, 68);
$setup(A[6], negedge WCLK, 66);
endspecify
endgenerate
endmodule endmodule
module RAM256X1D ( module RAM256X1D (
@ -1521,43 +1654,19 @@ endmodule
// Multi port. // Multi port.
module RAM32M ( module RAM32M (
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L889
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L857
(* abc9_arrival="1153 1188" *)
output [1:0] DOA, output [1:0] DOA,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L925
(* abc9_arrival="1161 1187" *)
output [1:0] DOB, output [1:0] DOB,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1025
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L993
(* abc9_arrival="1158 1180" *)
output [1:0] DOC, output [1:0] DOC,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1093
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1061
(* abc9_arrival="1163 1190" *)
output [1:0] DOD, output [1:0] DOD,
input [4:0] ADDRA, ADDRB, ADDRC, input [4:0] ADDRA, ADDRB, ADDRC,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L792-L802
(* abc9_required="245 208 147 68 66" *)
input [4:0] ADDRD, input [4:0] ADDRD,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986-L988
(* abc9_required="453 384" *)
input [1:0] DIA, input [1:0] DIA,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1054-L1056
(* abc9_required="461 354" *)
input [1:0] DIB, input [1:0] DIB,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1122-L1124
(* abc9_required="457 375" *)
input [1:0] DIC, input [1:0] DIC,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1190-L1192
(* abc9_required="310 334" *)
input [1:0] DID, input [1:0] DID,
(* clkbuf_sink *) (* clkbuf_sink *)
(* invertible_pin = "IS_WCLK_INVERTED" *) (* invertible_pin = "IS_WCLK_INVERTED" *)
input WCLK, input WCLK,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
(* abc9_required=654 *)
input WE input WE
); );
parameter [63:0] INIT_A = 64'h0000000000000000; parameter [63:0] INIT_A = 64'h0000000000000000;
@ -1581,6 +1690,87 @@ module RAM32M (
mem_c[2*ADDRD+:2] <= DIC; mem_c[2*ADDRD+:2] <= DIC;
mem_d[2*ADDRD+:2] <= DID; mem_d[2*ADDRD+:2] <= DID;
end end
generate
if (!IS_WCLK_INVERTED)
specify
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L889
if (WE) (posedge WCLK => (DOA[0] : DIA[0])) = 1153;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L857
if (WE) (posedge WCLK => (DOA[1] : DIA[1])) = 1188;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
if (WE) (posedge WCLK => (DOB[0] : DIB[0])) = 1161;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L925
if (WE) (posedge WCLK => (DOB[1] : DIB[1])) = 1187;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L993
if (WE) (posedge WCLK => (DOC[0] : DIC[0])) = 1158;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1025
if (WE) (posedge WCLK => (DOC[1] : DIC[1])) = 1180;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1093
if (WE) (posedge WCLK => (DOD[0] : DID[0])) = 1163;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1061
if (WE) (posedge WCLK => (DOD[1] : DID[1])) = 1190;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
$setup(ADDRD[0], posedge WCLK, 245);
$setup(ADDRD[1], posedge WCLK, 208);
$setup(ADDRD[2], posedge WCLK, 147);
$setup(ADDRD[3], posedge WCLK, 68);
$setup(ADDRD[4], posedge WCLK, 66);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986-L988
$setup(DIA[0], posedge WCLK, 453);
$setup(DIA[1], posedge WCLK, 384);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1054-L1056
$setup(DIB[0], posedge WCLK, 461);
$setup(DIB[1], posedge WCLK, 354);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1122-L1124
$setup(DIC[0], posedge WCLK, 457);
$setup(DIC[1], posedge WCLK, 375);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1190-L1192
$setup(DID[0], posedge WCLK, 310);
$setup(DID[1], posedge WCLK, 334);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
$setup(WE, posedge WCLK, 654);
endspecify
else
specify
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L889
if (WE) (negedge WCLK => (DOA[0] : DIA[0])) = 1153;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L857
if (WE) (negedge WCLK => (DOA[1] : DIA[1])) = 1188;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
if (WE) (negedge WCLK => (DOB[0] : DIB[0])) = 1161;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L925
if (WE) (negedge WCLK => (DOB[1] : DIB[1])) = 1187;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L993
if (WE) (negedge WCLK => (DOC[0] : DIC[0])) = 1158;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1025
if (WE) (negedge WCLK => (DOC[1] : DIC[1])) = 1180;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1093
if (WE) (negedge WCLK => (DOD[0] : DID[0])) = 1163;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1061
if (WE) (negedge WCLK => (DOD[1] : DID[1])) = 1190;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
$setup(ADDRD[0], negedge WCLK, 245);
$setup(ADDRD[1], negedge WCLK, 208);
$setup(ADDRD[2], negedge WCLK, 147);
$setup(ADDRD[3], negedge WCLK, 68);
$setup(ADDRD[4], negedge WCLK, 66);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986-L988
$setup(DIA[0], negedge WCLK, 453);
$setup(DIA[1], negedge WCLK, 384);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1054-L1056
$setup(DIB[0], negedge WCLK, 461);
$setup(DIB[1], negedge WCLK, 354);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1122-L1124
$setup(DIC[0], negedge WCLK, 457);
$setup(DIC[1], negedge WCLK, 375);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1190-L1192
$setup(DID[0], negedge WCLK, 310);
$setup(DID[1], negedge WCLK, 334);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
$setup(WE, posedge WCLK, 654);
endspecify
endgenerate
endmodule endmodule
module RAM32M16 ( module RAM32M16 (
@ -1653,39 +1843,19 @@ module RAM32M16 (
endmodule endmodule
module RAM64M ( module RAM64M (
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L889
(* abc9_arrival=1153 *)
output DOA, output DOA,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
(* abc9_arrival=1161 *)
output DOB, output DOB,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1025
(* abc9_arrival=1158 *)
output DOC, output DOC,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1093
(* abc9_arrival=1163 *)
output DOD, output DOD,
input [5:0] ADDRA, ADDRB, ADDRC, input [5:0] ADDRA, ADDRB, ADDRC,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818-L830
(* abc9_required="362 245 208 147 68 66" *)
input [5:0] ADDRD, input [5:0] ADDRD,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986-L988
(* abc9_required=384 *)
input DIA, input DIA,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1054-L1056
(* abc9_required=354 *)
input DIB, input DIB,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1122-L1124
(* abc9_required=375 *)
input DIC, input DIC,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1190-L1192
(* abc9_required=310 *)
input DID, input DID,
(* clkbuf_sink *) (* clkbuf_sink *)
(* invertible_pin = "IS_WCLK_INVERTED" *) (* invertible_pin = "IS_WCLK_INVERTED" *)
input WCLK, input WCLK,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
(* abc9_required=654 *)
input WE input WE
); );
parameter [63:0] INIT_A = 64'h0000000000000000; parameter [63:0] INIT_A = 64'h0000000000000000;
@ -1709,6 +1879,64 @@ module RAM64M (
mem_c[ADDRD] <= DIC; mem_c[ADDRD] <= DIC;
mem_d[ADDRD] <= DID; mem_d[ADDRD] <= DID;
end end
generate
if (!IS_WCLK_INVERTED)
specify
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L889
if (WE) (posedge WCLK => (DOA : DIA)) = 1153;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
if (WE) (posedge WCLK => (DOB : DIB)) = 1161;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1025
if (WE) (posedge WCLK => (DOC : DIC)) = 1158;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1093
if (WE) (posedge WCLK => (DOD : DID)) = 1163;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818-L830
$setup(ADDRD[0], posedge WCLK, 362);
$setup(ADDRD[1], posedge WCLK, 245);
$setup(ADDRD[2], posedge WCLK, 208);
$setup(ADDRD[3], posedge WCLK, 147);
$setup(ADDRD[4], posedge WCLK, 68);
$setup(ADDRD[5], posedge WCLK, 66);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986-L988
$setup(DIA, posedge WCLK, 384);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1054-L1056
$setup(DIB, posedge WCLK, 354);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1122-L1124
$setup(DIC, posedge WCLK, 375);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1190-L1192
$setup(DID, posedge WCLK, 310);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
$setup(WE, posedge WCLK, 654);
endspecify
else
specify
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L889
if (WE) (negedge WCLK => (DOA : DIA)) = 1153;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
if (WE) (negedge WCLK => (DOB : DIB)) = 1161;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1025
if (WE) (negedge WCLK => (DOC : DIC)) = 1158;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1093
if (WE) (negedge WCLK => (DOD : DID)) = 1163;
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818-L830
$setup(ADDRD[0], negedge WCLK, 362);
$setup(ADDRD[1], negedge WCLK, 245);
$setup(ADDRD[2], negedge WCLK, 208);
$setup(ADDRD[3], negedge WCLK, 147);
$setup(ADDRD[4], negedge WCLK, 68);
$setup(ADDRD[5], negedge WCLK, 66);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986-L988
$setup(DIA, negedge WCLK, 384);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1054-L1056
$setup(DIB, negedge WCLK, 354);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1122-L1124
$setup(DIC, negedge WCLK, 375);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1190-L1192
$setup(DID, negedge WCLK, 310);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
$setup(WE, negedge WCLK, 654);
endspecify
endgenerate
endmodule endmodule
module RAM64M8 ( module RAM64M8 (