From: Clifford Wolf Date: Fri, 17 Jun 2016 14:31:16 +0000 (+0200) Subject: Improved support for $sop cells X-Git-Tag: yosys-0.7~200 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=95757efb25dc51a73b384b475b0fc87d0e11d10e;p=yosys.git Improved support for $sop cells --- diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 41dd51ed8..cf7bc2dcf 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -366,21 +366,33 @@ struct CellTypes while (GetSize(t) < width*depth*2) t.push_back(RTLIL::S0); + RTLIL::State default_ret = State::S0; + for (int i = 0; i < depth; i++) { bool match = true; + bool match_x = true; for (int j = 0; j < width; j++) { RTLIL::State a = arg1.bits.at(j); - if (t.at(2*width*i + 2*j + 0) == State::S1 && a == State::S1) match = false; - if (t.at(2*width*i + 2*j + 1) == State::S1 && a == State::S0) match = false; + if (t.at(2*width*i + 2*j + 0) == State::S1) { + if (a == State::S1) match_x = false; + if (a != State::S0) match = false; + } + if (t.at(2*width*i + 2*j + 1) == State::S1) { + if (a == State::S0) match_x = false; + if (a != State::S1) match = false; + } } if (match) return State::S1; + + if (match_x) + default_ret = State::Sx; } - return State::S0; + return default_ret; } bool signed_a = cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters["\\A_SIGNED"].as_bool(); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 3b1df4406..bcd87d3ff 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -2142,7 +2142,7 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) return; } - if (type == "$lut") { + if (type == "$lut" || type == "$sop") { parameters["\\WIDTH"] = GetSize(connections_["\\A"]); return; } diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index 777e80142..0fb647344 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -321,6 +321,36 @@ void simplemap_lut(RTLIL::Module *module, RTLIL::Cell *cell) module->connect(cell->getPort("\\Y"), lut_data); } +void simplemap_sop(RTLIL::Module *module, RTLIL::Cell *cell) +{ + SigSpec ctrl = cell->getPort("\\A"); + SigSpec table = cell->getParam("\\TABLE"); + + int width = cell->getParam("\\WIDTH").as_int(); + int depth = cell->getParam("\\DEPTH").as_int(); + table.extend_u0(2 * width * depth); + + SigSpec products; + + for (int i = 0; i < depth; i++) { + SigSpec in, pat; + for (int j = 0; j < width; j++) { + if (table[2*i*width + 2*j + 0] == State::S1) { + in.append(ctrl[j]); + pat.append(State::S0); + } + if (table[2*i*width + 2*j + 1] == State::S1) { + in.append(ctrl[j]); + pat.append(State::S1); + } + } + + products.append(GetSize(in) > 0 ? module->Eq(NEW_ID, in, pat) : State::S1); + } + + module->connect(cell->getPort("\\Y"), module->ReduceOr(NEW_ID, products)); +} + void simplemap_slice(RTLIL::Module *module, RTLIL::Cell *cell) { int offset = cell->parameters.at("\\OFFSET").as_int(); @@ -498,6 +528,7 @@ void simplemap_get_mappers(std::mapsetParam("\\LUT", config.as_const()); } + if (cell_type == "$sop") + { + int width = 1 + xorshift32(8); + int depth = 1 + xorshift32(8); + + 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 < width*depth; i++) + switch (xorshift32(3)) { + case 0: + config.append(RTLIL::S1); + config.append(RTLIL::S0); + break; + case 1: + config.append(RTLIL::S0); + config.append(RTLIL::S1); + break; + case 2: + config.append(RTLIL::S0); + config.append(RTLIL::S0); + break; + } + + cell->setParam("\\DEPTH", depth); + cell->setParam("\\TABLE", config.as_const()); + } + if (cell_type_flags.find('A') != std::string::npos) { wire = module->addWire("\\A"); wire->width = 1 + xorshift32(8); @@ -534,7 +569,7 @@ struct TestCellPass : public Pass { log(" pass this option to techmap.\n"); log("\n"); log(" -simlib\n"); - log(" use \"techmap -map +/simlib.v -max_iter 2 -autoproc\"\n"); + log(" use \"techmap -D SIMLIB_NOCHECKS -map +/simlib.v -max_iter 2 -autoproc\"\n"); log("\n"); log(" -aigmap\n"); log(" instead of calling \"techmap\", call \"aigmap\"\n"); @@ -604,7 +639,7 @@ struct TestCellPass : public Pass { continue; } if (args[argidx] == "-simlib") { - techmap_cmd = "techmap -map +/simlib.v -max_iter 2 -autoproc"; + techmap_cmd = "techmap -D SIMLIB_NOCHECKS -map +/simlib.v -max_iter 2 -autoproc"; continue; } if (args[argidx] == "-aigmap") { @@ -697,6 +732,7 @@ struct TestCellPass : public Pass { // cell_types["$assert"] = "A"; cell_types["$lut"] = "*"; + cell_types["$sop"] = "*"; cell_types["$alu"] = "ABSY"; cell_types["$lcu"] = "*"; cell_types["$macc"] = "*"; diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 493292582..342555024 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -1340,7 +1340,7 @@ wire [WIDTH-1:0] pos_clr = CLR_POLARITY ? CLR : ~CLR; genvar i; generate - for (i = 0; i < WIDTH; i = i+1) begin:bit + for (i = 0; i < WIDTH; i = i+1) begin:bitslices always @(posedge pos_set[i], posedge pos_clr[i]) if (pos_clr[i]) Q[i] <= 0; @@ -1409,7 +1409,7 @@ wire [WIDTH-1:0] pos_clr = CLR_POLARITY ? CLR : ~CLR; genvar i; generate - for (i = 0; i < WIDTH; i = i+1) begin:bit + for (i = 0; i < WIDTH; i = i+1) begin:bitslices always @(posedge pos_set[i], posedge pos_clr[i], posedge pos_clk) if (pos_clr[i]) Q[i] <= 0; @@ -1485,7 +1485,7 @@ wire [WIDTH-1:0] pos_clr = CLR_POLARITY ? CLR : ~CLR; genvar i; generate - for (i = 0; i < WIDTH; i = i+1) begin:bit + for (i = 0; i < WIDTH; i = i+1) begin:bitslices always @* if (pos_clr[i]) Q[i] = 0; diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index a623bb516..90c4ed7eb 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -452,7 +452,7 @@ endmodule `ifndef NOLUT (* techmap_simplemap *) -(* techmap_celltype = "$lut" *) +(* techmap_celltype = "$lut $sop" *) module _90_lut; endmodule `endif