mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-12 20:18:20 +00:00
Added $lut support in test_cell, techmap, satgen
This commit is contained in:
parent
2a1b08aeb3
commit
8649b57b6f
|
@ -1768,8 +1768,7 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
|
||||||
type.substr(0, 9) == "$verific$" || type.substr(0, 7) == "$array:" || type.substr(0, 8) == "$extern:")
|
type.substr(0, 9) == "$verific$" || type.substr(0, 7) == "$array:" || type.substr(0, 8) == "$extern:")
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (type == "$mux" || type == "$pmux")
|
if (type == "$mux" || type == "$pmux") {
|
||||||
{
|
|
||||||
parameters["\\WIDTH"] = SIZE(connections_["\\Y"]);
|
parameters["\\WIDTH"] = SIZE(connections_["\\Y"]);
|
||||||
if (type == "$pmux")
|
if (type == "$pmux")
|
||||||
parameters["\\S_WIDTH"] = SIZE(connections_["\\S"]);
|
parameters["\\S_WIDTH"] = SIZE(connections_["\\S"]);
|
||||||
|
@ -1777,7 +1776,12 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool signedness_ab = type != "$slice" && type != "$concat";
|
if (type == "$lut") {
|
||||||
|
parameters["\\WIDTH"] = SIZE(connections_["\\A"]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool signedness_ab = !type.in("$slice", "$concat");
|
||||||
|
|
||||||
if (connections_.count("\\A")) {
|
if (connections_.count("\\A")) {
|
||||||
if (signedness_ab) {
|
if (signedness_ab) {
|
||||||
|
|
|
@ -841,6 +841,56 @@ struct SatGen
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cell->type == "$lut")
|
||||||
|
{
|
||||||
|
std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep);
|
||||||
|
std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep);
|
||||||
|
|
||||||
|
std::vector<int> lut;
|
||||||
|
for (auto bit : cell->getParam("\\LUT").bits)
|
||||||
|
lut.push_back(bit == RTLIL::S1 ? ez->TRUE : ez->FALSE);
|
||||||
|
while (SIZE(lut) < (1 << SIZE(a)))
|
||||||
|
lut.push_back(ez->FALSE);
|
||||||
|
lut.resize(1 << SIZE(a));
|
||||||
|
|
||||||
|
if (model_undef)
|
||||||
|
{
|
||||||
|
std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep);
|
||||||
|
std::vector<int> t(lut), u(SIZE(t), ez->FALSE);
|
||||||
|
|
||||||
|
for (int i = SIZE(a)-1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
std::vector<int> t0(t.begin(), t.begin() + SIZE(t)/2);
|
||||||
|
std::vector<int> t1(t.begin() + SIZE(t)/2, t.end());
|
||||||
|
|
||||||
|
std::vector<int> u0(u.begin(), u.begin() + SIZE(u)/2);
|
||||||
|
std::vector<int> u1(u.begin() + SIZE(u)/2, u.end());
|
||||||
|
|
||||||
|
t = ez->vec_ite(a[i], t1, t0);
|
||||||
|
u = ez->vec_ite(undef_a[i], ez->vec_or(ez->vec_xor(t0, t1), ez->vec_or(u0, u1)), ez->vec_ite(a[i], u1, u0));
|
||||||
|
}
|
||||||
|
|
||||||
|
log_assert(SIZE(t) == 1);
|
||||||
|
log_assert(SIZE(u) == 1);
|
||||||
|
undefGating(y, t, u);
|
||||||
|
ez->assume(ez->vec_eq(importUndefSigSpec(cell->getPort("\\Y"), timestep), u));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::vector<int> t = lut;
|
||||||
|
for (int i = SIZE(a)-1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
std::vector<int> t0(t.begin(), t.begin() + SIZE(t)/2);
|
||||||
|
std::vector<int> t1(t.begin() + SIZE(t)/2, t.end());
|
||||||
|
t = ez->vec_ite(a[i], t1, t0);
|
||||||
|
}
|
||||||
|
|
||||||
|
log_assert(SIZE(t) == 1);
|
||||||
|
ez->assume(ez->vec_eq(y, t));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (cell->type == "$slice")
|
if (cell->type == "$slice")
|
||||||
{
|
{
|
||||||
RTLIL::SigSpec a = cell->getPort("\\A");
|
RTLIL::SigSpec a = cell->getPort("\\A");
|
||||||
|
@ -903,4 +953,3 @@ struct SatGen
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -30,20 +30,41 @@ static uint32_t xorshift32(uint32_t limit) {
|
||||||
return xorshift32_state % limit;
|
return xorshift32_state % limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void create_gold_module(RTLIL::Design *design, std::string cell_type, std::string cell_type_flags)
|
static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, std::string cell_type_flags)
|
||||||
{
|
{
|
||||||
RTLIL::Module *module = design->addModule("\\gold");
|
RTLIL::Module *module = design->addModule("\\gold");
|
||||||
RTLIL::Cell *cell = module->addCell("\\UUT", cell_type);
|
RTLIL::Cell *cell = module->addCell("\\UUT", cell_type);
|
||||||
|
RTLIL::Wire *wire;
|
||||||
|
|
||||||
|
if (cell_type == "$lut")
|
||||||
|
{
|
||||||
|
int width = 1 + xorshift32(6);
|
||||||
|
|
||||||
|
wire = module->addWire("\\A");
|
||||||
|
wire->width = width;
|
||||||
|
wire->port_input = true;
|
||||||
|
cell->setPort("\\A", wire);
|
||||||
|
|
||||||
|
wire = module->addWire("\\Y");
|
||||||
|
wire->port_output = true;
|
||||||
|
cell->setPort("\\Y", wire);
|
||||||
|
|
||||||
|
RTLIL::SigSpec config;
|
||||||
|
for (int i = 0; i < (1 << width); i++)
|
||||||
|
config.append(xorshift32(2) ? RTLIL::S1 : RTLIL::S0);
|
||||||
|
|
||||||
|
cell->setParam("\\LUT", config.as_const());
|
||||||
|
}
|
||||||
|
|
||||||
if (cell_type_flags.find('A') != std::string::npos) {
|
if (cell_type_flags.find('A') != std::string::npos) {
|
||||||
RTLIL::Wire *wire = module->addWire("\\A");
|
wire = module->addWire("\\A");
|
||||||
wire->width = 1 + xorshift32(8);
|
wire->width = 1 + xorshift32(8);
|
||||||
wire->port_input = true;
|
wire->port_input = true;
|
||||||
cell->setPort("\\A", wire);
|
cell->setPort("\\A", wire);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cell_type_flags.find('B') != std::string::npos) {
|
if (cell_type_flags.find('B') != std::string::npos) {
|
||||||
RTLIL::Wire *wire = module->addWire("\\B");
|
wire = module->addWire("\\B");
|
||||||
if (cell_type_flags.find('h') != std::string::npos)
|
if (cell_type_flags.find('h') != std::string::npos)
|
||||||
wire->width = 1 + xorshift32(6);
|
wire->width = 1 + xorshift32(6);
|
||||||
else
|
else
|
||||||
|
@ -67,7 +88,7 @@ static void create_gold_module(RTLIL::Design *design, std::string cell_type, std
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cell_type_flags.find('Y') != std::string::npos) {
|
if (cell_type_flags.find('Y') != std::string::npos) {
|
||||||
RTLIL::Wire *wire = module->addWire("\\Y");
|
wire = module->addWire("\\Y");
|
||||||
wire->width = 1 + xorshift32(8);
|
wire->width = 1 + xorshift32(8);
|
||||||
wire->port_output = true;
|
wire->port_output = true;
|
||||||
cell->setPort("\\Y", wire);
|
cell->setPort("\\Y", wire);
|
||||||
|
@ -188,9 +209,11 @@ struct TestCellPass : public Pass {
|
||||||
// cell_types["$pmux"] = "A";
|
// cell_types["$pmux"] = "A";
|
||||||
// cell_types["$slice"] = "A";
|
// cell_types["$slice"] = "A";
|
||||||
// cell_types["$concat"] = "A";
|
// cell_types["$concat"] = "A";
|
||||||
// cell_types["$lut"] = "A";
|
|
||||||
// cell_types["$assert"] = "A";
|
// cell_types["$assert"] = "A";
|
||||||
|
|
||||||
|
cell_types["$lut"] = "*";
|
||||||
|
// cell_types["$alu"] = "*";
|
||||||
|
|
||||||
for (; argidx < SIZE(args); argidx++)
|
for (; argidx < SIZE(args); argidx++)
|
||||||
{
|
{
|
||||||
if (args[argidx].rfind("-", 0) == 0)
|
if (args[argidx].rfind("-", 0) == 0)
|
||||||
|
|
|
@ -841,3 +841,20 @@ module \$pmux (A, B, S, Y);
|
||||||
assign Y = |S ? Y_B : A;
|
assign Y = |S ? Y_B : A;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------
|
||||||
|
// LUTs
|
||||||
|
// --------------------------------------------------------
|
||||||
|
|
||||||
|
`ifndef NOLUT
|
||||||
|
module \$lut (A, Y);
|
||||||
|
parameter WIDTH = 1;
|
||||||
|
parameter LUT = 0;
|
||||||
|
|
||||||
|
input [WIDTH-1:0] A;
|
||||||
|
output Y;
|
||||||
|
|
||||||
|
assign Y = LUT[A];
|
||||||
|
endmodule
|
||||||
|
`endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue