mirror of
https://github.com/YosysHQ/yosys
synced 2026-02-14 21:01:50 +00:00
Merge 5a613fc457 into b890b1b43f
This commit is contained in:
commit
a4b29b4179
24 changed files with 641 additions and 107 deletions
|
|
@ -658,6 +658,28 @@ RTLIL::Const RTLIL::const_bmux(const RTLIL::Const &arg1, const RTLIL::Const &arg
|
|||
return t;
|
||||
}
|
||||
|
||||
RTLIL::Const RTLIL::const_priority(const RTLIL::Const &arg, const RTLIL::Const &polarity)
|
||||
{
|
||||
std::vector<RTLIL::State> t;
|
||||
RTLIL::State previous;
|
||||
if (GetSize(arg)) {
|
||||
RTLIL::State s = arg.at(0);
|
||||
t.push_back(s);
|
||||
previous = polarity[0] ? s : const_not(s, Const(), false, false, 1)[0];
|
||||
}
|
||||
for (int i = 1; i < GetSize(arg); i++)
|
||||
{
|
||||
RTLIL::State s = arg.at(i);
|
||||
RTLIL::State is_active = const_xnor(s, polarity[i], false, false, 1)[0];
|
||||
RTLIL::State next = const_or(is_active, previous, false, false, 1)[0];
|
||||
RTLIL::State inactive_polarity = const_not(polarity[i], Const(), false, false, 1)[0];
|
||||
RTLIL::State y = const_mux(s, inactive_polarity, previous)[0];
|
||||
t.push_back(y);
|
||||
previous = next;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
RTLIL::Const RTLIL::const_demux(const RTLIL::Const &arg1, const RTLIL::Const &arg2)
|
||||
{
|
||||
int width = GetSize(arg1);
|
||||
|
|
|
|||
|
|
@ -501,6 +501,27 @@ Aig::Aig(Cell *cell)
|
|||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type == ID($priority))
|
||||
{
|
||||
int width = GetSize(cell->getPort(ID::Y));
|
||||
RTLIL::Const polarity = cell->getParam(ID::POLARITY);
|
||||
vector<int> A = mk.inport_vec(ID::A, width);
|
||||
vector<int> Y;
|
||||
int any_previous_active;
|
||||
if (width) {
|
||||
any_previous_active = polarity[0] ? A[0] : mk.not_gate(A[0]);
|
||||
Y.push_back(A[0]);
|
||||
}
|
||||
for (int i = 1; i < width; i++) {
|
||||
int inactive_val = mk.bool_node(!polarity[i]);
|
||||
Y.push_back(mk.mux_gate(A[i], inactive_val, any_previous_active));
|
||||
int is_active = mk.xnor_gate(inactive_val, A[i]);
|
||||
any_previous_active = mk.or_gate(any_previous_active, is_active);
|
||||
}
|
||||
mk.outport_vec(Y, ID::Y);
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
name.clear();
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ struct CellTypes
|
|||
void setup_internals_eval()
|
||||
{
|
||||
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($logic_not), ID($slice), ID($lut), ID($sop)
|
||||
};
|
||||
|
|
@ -509,6 +509,11 @@ struct CellTypes
|
|||
return default_ret;
|
||||
}
|
||||
|
||||
if (cell->type == ID($priority))
|
||||
{
|
||||
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();
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -259,6 +259,7 @@ X($pmux)
|
|||
X($pos)
|
||||
X($pow)
|
||||
X($print)
|
||||
X($priority)
|
||||
X($recrem)
|
||||
X($reduce_and)
|
||||
X($reduce_bool)
|
||||
|
|
@ -614,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)
|
||||
|
|
|
|||
|
|
@ -2654,6 +2654,14 @@ namespace {
|
|||
check_expected();
|
||||
return;
|
||||
}
|
||||
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();
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Checklist for adding internal cell types
|
||||
* ========================================
|
||||
|
|
@ -3971,6 +3979,14 @@ RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, const RTLIL::SigSp
|
|||
cell->set_src_attribute(src);
|
||||
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,
|
||||
const RTLIL::SigSpec &sig_q, bool set_polarity, bool clr_polarity, const std::string &src)
|
||||
|
|
@ -4548,7 +4564,7 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
|
|||
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]);
|
||||
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_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, 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);
|
||||
|
|
@ -2263,6 +2264,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* 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* 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 = "");
|
||||
|
|
|
|||
|
|
@ -430,6 +430,57 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
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;
|
||||
|
||||
const Const& polarity = cell->getParam(ID::POLARITY);
|
||||
|
||||
std::vector<int> active_so_far;
|
||||
if (a.size()) {
|
||||
active_so_far.push_back(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++) {
|
||||
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(active_so_far.back(), inactive_val, a[i])));
|
||||
active_so_far.push_back(ez->OR(active_so_far.back(), 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()) {
|
||||
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++) {
|
||||
int inactive_val = !polarity[i] ? ez->CONST_TRUE : ez->CONST_FALSE;
|
||||
int is_active = ez->XOR(inactive_val, a[i]);
|
||||
int is_not_inactive = ez->OR(is_active, undef_a[i]);
|
||||
int is_not_active = ez->OR(ez->NOT(is_active), undef_a[i]);
|
||||
|
||||
// $mux
|
||||
int undef_because_s = ez->AND(any_previous_undef, is_not_inactive);
|
||||
int undef_because_a = ez->AND(ez->OR(any_previous_undef, ez->NOT(active_so_far[i-1])), undef_a[i]);
|
||||
int undef = ez->OR(undef_because_s, undef_because_a);
|
||||
ez->assume(ez->IFF(undef_y[i], undef));
|
||||
|
||||
// $or
|
||||
int next_previous_undef_because_previous = ez->AND(any_previous_undef, is_not_active);
|
||||
int next_previous_undef_because_a = ez->AND(ez->NOT(active_so_far[i-1]), undef_a[i]);
|
||||
any_previous_undef = ez->OR(next_previous_undef_because_previous, next_previous_undef_because_a);
|
||||
}
|
||||
undefGating(y, yy, undef_y);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($pos), ID($buf), ID($neg)))
|
||||
{
|
||||
std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue