mirror of
https://github.com/YosysHQ/yosys
synced 2026-05-25 11:26:22 +00:00
add $priority cell
This commit is contained in:
parent
967b47d984
commit
e166dd4475
9 changed files with 136 additions and 2 deletions
|
|
@ -658,6 +658,25 @@ RTLIL::Const RTLIL::const_bmux(const RTLIL::Const &arg1, const RTLIL::Const &arg
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RTLIL::Const RTLIL::const_priority(const RTLIL::Const &arg)
|
||||||
|
{
|
||||||
|
std::vector<State> t;
|
||||||
|
std::optional<State> first_non_zero = std::nullopt;
|
||||||
|
for (int i = 0; i < GetSize(arg); i++)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
} else {
|
||||||
|
t.push_back(s);
|
||||||
|
}
|
||||||
|
if ((!first_non_zero && s != State::S0) || s == State::Sx) {
|
||||||
|
first_non_zero = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
RTLIL::Const RTLIL::const_demux(const RTLIL::Const &arg1, const RTLIL::Const &arg2)
|
RTLIL::Const RTLIL::const_demux(const RTLIL::Const &arg1, const RTLIL::Const &arg2)
|
||||||
{
|
{
|
||||||
int width = GetSize(arg1);
|
int width = GetSize(arg1);
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@ struct CellTypes
|
||||||
void setup_internals_eval()
|
void setup_internals_eval()
|
||||||
{
|
{
|
||||||
std::vector<RTLIL::IdString> unary_ops = {
|
std::vector<RTLIL::IdString> unary_ops = {
|
||||||
ID($not), ID($pos), ID($buf), ID($neg),
|
ID($not), ID($pos), ID($buf), ID($neg), ID($priority),
|
||||||
ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool),
|
ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool),
|
||||||
ID($logic_not), ID($slice), ID($lut), ID($sop)
|
ID($logic_not), ID($slice), ID($lut), ID($sop)
|
||||||
};
|
};
|
||||||
|
|
@ -509,6 +509,11 @@ struct CellTypes
|
||||||
return default_ret;
|
return default_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cell->type == ID($priority))
|
||||||
|
{
|
||||||
|
return const_priority(arg1);
|
||||||
|
}
|
||||||
|
|
||||||
bool signed_a = cell->parameters.count(ID::A_SIGNED) > 0 && cell->parameters[ID::A_SIGNED].as_bool();
|
bool signed_a = cell->parameters.count(ID::A_SIGNED) > 0 && cell->parameters[ID::A_SIGNED].as_bool();
|
||||||
bool signed_b = cell->parameters.count(ID::B_SIGNED) > 0 && cell->parameters[ID::B_SIGNED].as_bool();
|
bool signed_b = cell->parameters.count(ID::B_SIGNED) > 0 && cell->parameters[ID::B_SIGNED].as_bool();
|
||||||
int result_len = cell->parameters.count(ID::Y_WIDTH) > 0 ? cell->parameters[ID::Y_WIDTH].as_int() : -1;
|
int result_len = cell->parameters.count(ID::Y_WIDTH) > 0 ? cell->parameters[ID::Y_WIDTH].as_int() : -1;
|
||||||
|
|
|
||||||
|
|
@ -259,6 +259,7 @@ X($pmux)
|
||||||
X($pos)
|
X($pos)
|
||||||
X($pow)
|
X($pow)
|
||||||
X($print)
|
X($print)
|
||||||
|
X($priority)
|
||||||
X($recrem)
|
X($recrem)
|
||||||
X($reduce_and)
|
X($reduce_and)
|
||||||
X($reduce_bool)
|
X($reduce_bool)
|
||||||
|
|
|
||||||
|
|
@ -2654,6 +2654,13 @@ namespace {
|
||||||
check_expected();
|
check_expected();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (cell->type.in(ID($priority))) {
|
||||||
|
param(ID::WIDTH);
|
||||||
|
port(ID::A, param(ID::WIDTH));
|
||||||
|
port(ID::Y, param(ID::WIDTH));
|
||||||
|
check_expected();
|
||||||
|
return;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Checklist for adding internal cell types
|
* Checklist for adding internal cell types
|
||||||
* ========================================
|
* ========================================
|
||||||
|
|
@ -3969,6 +3976,14 @@ RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, const RTLIL::SigSp
|
||||||
cell->set_src_attribute(src);
|
cell->set_src_attribute(src);
|
||||||
return cell;
|
return cell;
|
||||||
}
|
}
|
||||||
|
RTLIL::Cell* RTLIL::Module::addPriority(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, const std::string &src)
|
||||||
|
{
|
||||||
|
RTLIL::Cell *cell = addCell(name, ID($priority));
|
||||||
|
cell->setPort(ID::A, sig_a);
|
||||||
|
cell->setPort(ID::Y, sig_y);
|
||||||
|
cell->set_src_attribute(src);
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
RTLIL::Cell* RTLIL::Module::addSrGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
|
RTLIL::Cell* RTLIL::Module::addSrGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
|
||||||
const RTLIL::SigSpec &sig_q, bool set_polarity, bool clr_polarity, const std::string &src)
|
const RTLIL::SigSpec &sig_q, bool set_polarity, bool clr_polarity, const std::string &src)
|
||||||
|
|
@ -4546,7 +4561,7 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == ID($lut) || type == ID($sop)) {
|
if (type == ID($lut) || type == ID($sop) || type == ID($priority)) {
|
||||||
parameters[ID::WIDTH] = GetSize(connections_[ID::A]);
|
parameters[ID::WIDTH] = GetSize(connections_[ID::A]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -848,6 +848,7 @@ namespace RTLIL {
|
||||||
RTLIL::Const const_pmux (const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3);
|
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_bmux (const RTLIL::Const &arg1, const RTLIL::Const &arg2);
|
||||||
RTLIL::Const const_demux (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_bweqx (const RTLIL::Const &arg1, const RTLIL::Const &arg2);
|
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);
|
RTLIL::Const const_bwmux (const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3);
|
||||||
|
|
@ -2262,6 +2263,8 @@ public:
|
||||||
RTLIL::Cell* addAdlatch (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool en_polarity = true, bool arst_polarity = true, const std::string &src = "");
|
RTLIL::Cell* addAdlatch (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool en_polarity = true, bool arst_polarity = true, const std::string &src = "");
|
||||||
RTLIL::Cell* addDlatchsr (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
|
RTLIL::Cell* addDlatchsr (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
|
||||||
|
|
||||||
|
RTLIL::Cell* addPriority (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, const std::string &src = "");
|
||||||
|
|
||||||
RTLIL::Cell* addBufGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_y, const std::string &src = "");
|
RTLIL::Cell* addBufGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_y, const std::string &src = "");
|
||||||
RTLIL::Cell* addNotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_y, const std::string &src = "");
|
RTLIL::Cell* addNotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_y, const std::string &src = "");
|
||||||
RTLIL::Cell* addAndGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
|
RTLIL::Cell* addAndGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
|
||||||
|
|
|
||||||
|
|
@ -430,6 +430,39 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cell->type == ID($priority))
|
||||||
|
{
|
||||||
|
std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), 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;
|
||||||
|
if (a.size()) {
|
||||||
|
tmp = 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]);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (a.size()) {
|
||||||
|
tmp = 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));
|
||||||
|
}
|
||||||
|
undefGating(y, yy, undef_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (cell->type.in(ID($pos), ID($buf), ID($neg)))
|
if (cell->type.in(ID($pos), ID($buf), ID($neg)))
|
||||||
{
|
{
|
||||||
std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
|
std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
|
||||||
|
|
|
||||||
|
|
@ -136,6 +136,21 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
|
||||||
cell->setPort(ID::Y, wire);
|
cell->setPort(ID::Y, wire);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cell_type == ID($priority))
|
||||||
|
{
|
||||||
|
int width = 1 + xorshift32(8 * bloat_factor);
|
||||||
|
|
||||||
|
wire = module->addWire(ID::A);
|
||||||
|
wire->width = width;
|
||||||
|
wire->port_input = true;
|
||||||
|
cell->setPort(ID::A, wire);
|
||||||
|
|
||||||
|
wire = module->addWire(ID::Y);
|
||||||
|
wire->width = width;
|
||||||
|
wire->port_output = true;
|
||||||
|
cell->setPort(ID::Y, wire);
|
||||||
|
}
|
||||||
|
|
||||||
if (cell_type == ID($fa))
|
if (cell_type == ID($fa))
|
||||||
{
|
{
|
||||||
int width = 1 + xorshift32(8 * bloat_factor);
|
int width = 1 + xorshift32(8 * bloat_factor);
|
||||||
|
|
@ -1039,6 +1054,7 @@ struct TestCellPass : public Pass {
|
||||||
cell_types[ID($mux)] = "*";
|
cell_types[ID($mux)] = "*";
|
||||||
cell_types[ID($bmux)] = "*";
|
cell_types[ID($bmux)] = "*";
|
||||||
cell_types[ID($demux)] = "*";
|
cell_types[ID($demux)] = "*";
|
||||||
|
cell_types[ID($priority)] = "*";
|
||||||
// $pmux doesn't work in sat, and is not supported with 'techmap -assert' or
|
// $pmux doesn't work in sat, and is not supported with 'techmap -assert' or
|
||||||
// '-simlib'
|
// '-simlib'
|
||||||
if (nosat && techmap_cmd.compare("aigmap") == 0)
|
if (nosat && techmap_cmd.compare("aigmap") == 0)
|
||||||
|
|
|
||||||
|
|
@ -3250,3 +3250,19 @@ parameter WIDTH = 0;
|
||||||
inout [WIDTH-1:0] Y;
|
inout [WIDTH-1:0] Y;
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
// --------------------------------------------------------
|
||||||
|
//-
|
||||||
|
//- $priority (A, Y)
|
||||||
|
//* group unary
|
||||||
|
//-
|
||||||
|
//- Priority operator. An output bit is set if the input bit at the same index is set and no lower index input bit is set.
|
||||||
|
//-
|
||||||
|
module \$priority (A, Y);
|
||||||
|
parameter WIDTH = 8;
|
||||||
|
input [WIDTH-1:0] A;
|
||||||
|
output [WIDTH-1:0] Y;
|
||||||
|
|
||||||
|
assign Y = A & (~A + 1);
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
|
||||||
|
|
@ -679,3 +679,29 @@ parameter WIDTH = 0;
|
||||||
inout [WIDTH-1:0] Y; // This cell is just a maker, so we leave Y undriven
|
inout [WIDTH-1:0] Y; // This cell is just a maker, so we leave Y undriven
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
(* techmap_celltype = "$priority" *)
|
||||||
|
module \$priority (A, Y);
|
||||||
|
parameter WIDTH = 3;
|
||||||
|
|
||||||
|
(* force_downto *)
|
||||||
|
input [WIDTH-1:0] A;
|
||||||
|
(* force_downto *)
|
||||||
|
output [WIDTH-1:0] Y;
|
||||||
|
|
||||||
|
(* force_downto *)
|
||||||
|
wire [WIDTH-1:0] tmp;
|
||||||
|
|
||||||
|
genvar i;
|
||||||
|
generate
|
||||||
|
if (WIDTH > 0) begin
|
||||||
|
assign tmp[0] = A[0];
|
||||||
|
assign Y[0] = A[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];
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue