Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mistral: improve ALM packing in LABs #1170

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 83 additions & 3 deletions mistral/lab.cc
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,15 @@ void Arch::update_alm_input_count(uint32_t lab, uint8_t alm)
alm_data.unique_input_count = total_inputs;
}

const std::array<int, 6> tdmux_set = {
0, // A
1, // B
0, // C
1, // D
2, // E
3, // F
};

bool Arch::check_lab_input_count(uint32_t lab) const
{
// There are only 46 TD signals available to route signals from general routing to the ALM input. Currently, we
Expand All @@ -544,10 +553,75 @@ bool Arch::check_lab_input_count(uint32_t lab) const
// currently perfunctory place and route algorithms to achieve satisfactory runtimes.
int count = 0;
auto &lab_data = labs.at(lab);
for (int i = 0; i < 10; i++) {
count += lab_data.alms.at(i).unique_input_count;
pool<std::pair<IdString, int>> unique_inputs;

for (int alm = 0; alm < 10; alm++) {
// TODO: duplication with above
auto &alm_data = labs.at(lab).alms.at(alm);
// Get cells into an array for fast access
std::array<const CellInfo *, 2> luts{getBoundBelCell(alm_data.lut_bels[0]), getBoundBelCell(alm_data.lut_bels[1])};
std::array<const CellInfo *, 4> ffs{getBoundBelCell(alm_data.ff_bels[0]), getBoundBelCell(alm_data.ff_bels[1]),
getBoundBelCell(alm_data.ff_bels[2]), getBoundBelCell(alm_data.ff_bels[3])};
for (int i = 0; i < 2; i++) {
if (!luts[i])
continue;

for (int j = 0; j < luts[i]->combInfo.lut_input_count; j++)
if (luts[i]->combInfo.lut_in[j]) {
// LD routing outputs

const pool<int> ld_set_c = {1, 2, 4, 7};

const pool<int> ld_inputs_a = {2, 3, 4, 5, 10, 13, 14};
const pool<int> ld_inputs_b = {0, 1, 7, 9, 12, 18};
const pool<int> ld_inputs_c = {6, 8, 11, 16, 17};
const pool<int> ld_inputs_d = {15, 19};

// could this be driven by LD?
if (luts[i]->combInfo.lut_in[j]->driver.cell->bel.pos == alm_data.lut_bels[i].pos) {
auto dst_lut = 2 * alm + i;
auto& data = bel_data(luts[i]->combInfo.lut_in[j]->driver.cell->bel);
auto& src_alm_data = labs.at(data.lab_data.lab).alms.at(data.lab_data.alm);
bool ok = false;
int src_lut = 2 * data.lab_data.alm;
if (data.type == id_MISTRAL_MCOMB || data.type == id_MISTRAL_COMB) {
src_lut += data.lab_data.idx;
ok = true;
}
if (data.type == id_MISTRAL_FF && data.lab_data.idx & 1 == 1) {
src_lut += (data.lab_data.idx - 1) / 2;
ok = true;
}
if (ok && dst_lut & 1 == 0 && ld_inputs_a.count(src_lut))
continue;
if (ok && dst_lut & 1 == 1 && ld_inputs_b.count(src_lut))
continue;
if (ok && ld_set_c.count(dst_lut) && ld_inputs_c.count(src_lut))
continue;
if (ok && !ld_set_c.count(dst_lut) && ld_inputs_d.count(src_lut))
continue;
}

unique_inputs.insert(std::make_pair(luts[i]->combInfo.lut_in[j]->name, tdmux_set.at(j)));
}
}
for (int i = 0; i < 4; i++) {
const CellInfo *ff = ffs[i];
if (!ff)
continue;
if (ff->ffInfo.sdata) {
unique_inputs.insert(std::make_pair(ff->ffInfo.sdata->name, tdmux_set.at(4)));
unique_inputs.insert(std::make_pair(ff->ffInfo.sdata->name, tdmux_set.at(5)));
}
// FF input doesn't consume routing resources if driven by associated LUT
if (ff->ffInfo.datain && (!luts[i / 2] || ff->ffInfo.datain != luts[i / 2]->combInfo.comb_out)) {
unique_inputs.insert(std::make_pair(ff->ffInfo.datain->name, tdmux_set.at(4)));
unique_inputs.insert(std::make_pair(ff->ffInfo.datain->name, tdmux_set.at(5)));
}
}
}
return (count <= 42);

return (unique_inputs.size() <= 42);
}

bool Arch::check_mlab_groups(uint32_t lab) const
Expand Down Expand Up @@ -690,12 +764,18 @@ bool Arch::is_lab_ctrlset_legal(uint32_t lab) const
void Arch::lab_pre_route()
{
log_info("Preparing LABs for routing...\n");
int labs_used = 0;
for (uint32_t lab = 0; lab < labs.size(); lab++) {
bool lab_used = false;
assign_control_sets(lab);
for (uint8_t alm = 0; alm < 10; alm++) {
reassign_alm_inputs(lab, alm);
lab_used |= labs.at(lab).alms.at(alm).unique_input_count > 0;
}
if (lab_used)
labs_used++;
}
log_info(" %d LABs used\n", labs_used);
}

void Arch::assign_control_sets(uint32_t lab)
Expand Down