aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2016-06-17 16:31:16 +0200
committerClifford Wolf <clifford@clifford.at>2016-06-17 16:31:16 +0200
commit95757efb25dc51a73b384b475b0fc87d0e11d10e (patch)
treeb0c4518d676e8389629ca96482231616232add14
parent52bb1b968d4bfbbbd84eca88f0e80c486cc1a16e (diff)
downloadyosys-95757efb25dc51a73b384b475b0fc87d0e11d10e.tar.gz
yosys-95757efb25dc51a73b384b475b0fc87d0e11d10e.tar.bz2
yosys-95757efb25dc51a73b384b475b0fc87d0e11d10e.zip
Improved support for $sop cells
-rw-r--r--kernel/celltypes.h18
-rw-r--r--kernel/rtlil.cc2
-rw-r--r--passes/techmap/simplemap.cc31
-rw-r--r--passes/tests/test_cell.cc40
-rw-r--r--techlibs/common/simlib.v6
-rw-r--r--techlibs/common/techmap.v2
6 files changed, 89 insertions, 10 deletions
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::map<RTLIL::IdString, void(*)(RTLIL::Module*, RTL
mappers["$mux"] = simplemap_mux;
mappers["$tribuf"] = simplemap_tribuf;
mappers["$lut"] = simplemap_lut;
+ mappers["$sop"] = simplemap_sop;
mappers["$slice"] = simplemap_slice;
mappers["$concat"] = simplemap_concat;
mappers["$sr"] = simplemap_sr;
diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc
index a8fcac9bc..8b800d414 100644
--- a/passes/tests/test_cell.cc
+++ b/passes/tests/test_cell.cc
@@ -164,6 +164,41 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type,
cell->setParam("\\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