3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-01-19 00:38:59 +00:00

add POLARITY parameter to $priority cell

This commit is contained in:
Emil J. Tywoniak 2026-01-09 21:02:58 +01:00
parent b72eaf5de5
commit 7f19cf8849
8 changed files with 39 additions and 17 deletions

View file

@ -658,7 +658,7 @@ RTLIL::Const RTLIL::const_bmux(const RTLIL::Const &arg1, const RTLIL::Const &arg
return t;
}
RTLIL::Const RTLIL::const_priority(const RTLIL::Const &arg)
RTLIL::Const RTLIL::const_priority(const RTLIL::Const &arg, const RTLIL::Const &polarity)
{
std::vector<State> t;
std::optional<State> first_non_zero = std::nullopt;
@ -666,11 +666,13 @@ RTLIL::Const RTLIL::const_priority(const RTLIL::Const &arg)
{
RTLIL::State s = arg.at(i);
if (first_non_zero && s != State::Sx) {
t.push_back(*first_non_zero == State::S1 ? State::S0 : *first_non_zero);
auto inactive = polarity[i] == State::S0 ? State::S1 : State::S0;
auto val = *first_non_zero == State::Sx ? State::Sx : inactive;
t.push_back(val);
} else {
t.push_back(s);
}
if ((!first_non_zero && s != State::S0) || s == State::Sx) {
if ((!first_non_zero && s == polarity[i]) || s == State::Sx) {
first_non_zero = s;
}
}

View file

@ -511,7 +511,7 @@ struct CellTypes
if (cell->type == ID($priority))
{
return const_priority(arg1);
return const_priority(arg1, cell->getParam(ID::POLARITY));
}
bool signed_a = cell->parameters.count(ID::A_SIGNED) > 0 && cell->parameters[ID::A_SIGNED].as_bool();

View file

@ -615,6 +615,7 @@ X(PATTERN)
X(PCIN)
X(PIPELINE_16x16_MULT_REG1)
X(PIPELINE_16x16_MULT_REG2)
X(POLARITY)
X(PORTID)
X(PORT_A1_ADDR)
X(PORT_A1_CLK)

View file

@ -2648,6 +2648,7 @@ namespace {
}
if (cell->type.in(ID($priority))) {
param(ID::WIDTH);
param(ID::POLARITY);
port(ID::A, param(ID::WIDTH));
port(ID::Y, param(ID::WIDTH));
check_expected();

View file

@ -848,7 +848,7 @@ namespace RTLIL {
RTLIL::Const const_pmux (const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3);
RTLIL::Const const_bmux (const RTLIL::Const &arg1, const RTLIL::Const &arg2);
RTLIL::Const const_demux (const RTLIL::Const &arg1, const RTLIL::Const &arg2);
RTLIL::Const const_priority (const RTLIL::Const &arg);
RTLIL::Const const_priority (const RTLIL::Const &arg, const RTLIL::Const &polarity);
RTLIL::Const const_bweqx (const RTLIL::Const &arg1, const RTLIL::Const &arg2);
RTLIL::Const const_bwmux (const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3);

View file

@ -436,26 +436,31 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
int tmp;
const Const& polarity = cell->getParam(ID::POLARITY);
int any_previous_active;
if (a.size()) {
tmp = a[0];
any_previous_active = polarity[0] ? a[0] : ez->NOT(a[0]);
ez->assume(ez->IFF(yy[0], a[0]));
}
for (size_t i = 1; i < a.size(); i++) {
ez->assume(ez->IFF(yy[i], ez->AND(a[i], ez->NOT(tmp))));
tmp = ez->OR(tmp, a[i]);
int inactive_val = !polarity[i] ? ez->CONST_TRUE : ez->CONST_FALSE;
int active_val = polarity[i] ? ez->CONST_TRUE : ez->CONST_FALSE;
ez->assume(ez->IFF(yy[i], ez->ITE(any_previous_active, inactive_val, a[i])));
any_previous_active = ez->OR(any_previous_active, ez->IFF(a[i], active_val));
}
if (model_undef) {
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
int any_previous_undef;
if (a.size()) {
tmp = undef_a[0];
any_previous_undef = undef_a[0];
ez->assume(ez->IFF(undef_y[0], undef_a[0]));
}
for (size_t i = 1; i < a.size(); i++) {
tmp = ez->OR(tmp, undef_a[i]);
ez->assume(ez->IFF(undef_y[i], tmp));
any_previous_undef = ez->OR(any_previous_undef, undef_a[i]);
ez->assume(ez->IFF(undef_y[i], any_previous_undef));
}
undefGating(y, yy, undef_y);
}

View file

@ -149,6 +149,13 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
wire->width = width;
wire->port_output = true;
cell->setPort(ID::Y, wire);
RTLIL::SigSpec polarity;
for (int i = 0; i < width; i++)
polarity.append(xorshift32(2) ? State::S1 : State::S0);
cell->setParam(ID::POLARITY, polarity.as_const());
log("polarity: %s\n", log_signal(polarity));
}
if (cell_type == ID($fa))

View file

@ -682,7 +682,8 @@ endmodule
(* techmap_celltype = "$priority" *)
module \$priority (A, Y);
parameter WIDTH = 3;
parameter WIDTH = 0;
parameter POLARITY = 0;
(* force_downto *)
input [WIDTH-1:0] A;
@ -691,16 +692,21 @@ module \$priority (A, Y);
(* force_downto *)
wire [WIDTH-1:0] tmp;
(* force_downto *)
wire [WIDTH-1:0] A_active;
wire [WIDTH-1:0] Y_active;
assign A_active = A ^ ~POLARITY;
assign Y = Y_active ^ ~POLARITY;
genvar i;
generate
if (WIDTH > 0) begin
assign tmp[0] = A[0];
assign Y[0] = A[0];
assign tmp[0] = A_active[0];
assign Y_active[0] = A_active[0];
end
for (i = 1; i < WIDTH; i = i + 1) begin
assign Y[i] = A[i] & ~tmp[i-1];
assign tmp[i] = tmp[i-1] | A[i];
assign Y_active[i] = tmp[i-1] ? 1'b0 : A_active[i];
assign tmp[i] = tmp[i-1] | A_active[i];
end
endgenerate