yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
maccmap.cc File Reference
#include "kernel/yosys.h"
#include "kernel/macc.h"
+ Include dependency graph for maccmap.cc:

Go to the source code of this file.

Data Structures

struct  MaccmapWorker
 
struct  MaccmapPass
 

Functions

PRIVATE_NAMESPACE_END
YOSYS_NAMESPACE_BEGIN void 
maccmap (RTLIL::Module *module, RTLIL::Cell *cell, bool unmap=false)
 

Variables

MaccmapPass MaccmapPass
 

Function Documentation

void maccmap ( RTLIL::Module module,
RTLIL::Cell cell,
bool  unmap = false 
)

Definition at line 265 of file maccmap.cc.

266 {
267  int width = GetSize(cell->getPort("\\Y"));
268 
269  Macc macc;
270  macc.from_cell(cell);
271 
272  RTLIL::SigSpec all_input_bits;
273  all_input_bits.append(cell->getPort("\\A"));
274  all_input_bits.append(cell->getPort("\\B"));
275 
276  if (all_input_bits.to_sigbit_set().count(RTLIL::Sx)) {
277  module->connect(cell->getPort("\\Y"), RTLIL::SigSpec(RTLIL::Sx, width));
278  return;
279  }
280 
281  for (auto &port : macc.ports)
282  if (GetSize(port.in_b) == 0)
283  log(" %s %s (%d bits, %s)\n", port.do_subtract ? "sub" : "add", log_signal(port.in_a),
284  GetSize(port.in_a), port.is_signed ? "signed" : "unsigned");
285  else
286  log(" %s %s * %s (%dx%d bits, %s)\n", port.do_subtract ? "sub" : "add", log_signal(port.in_a), log_signal(port.in_b),
287  GetSize(port.in_a), GetSize(port.in_b), port.is_signed ? "signed" : "unsigned");
288 
289  if (GetSize(macc.bit_ports) != 0)
290  log(" add bits %s (%d bits)\n", log_signal(macc.bit_ports), GetSize(macc.bit_ports));
291 
292  if (unmap)
293  {
294  typedef std::pair<RTLIL::SigSpec, bool> summand_t;
295  std::vector<summand_t> summands;
296 
297  for (auto &port : macc.ports) {
298  summand_t this_summand;
299  if (GetSize(port.in_b)) {
300  this_summand.first = module->addWire(NEW_ID, width);
301  module->addMul(NEW_ID, port.in_a, port.in_b, this_summand.first, port.is_signed);
302  } else if (GetSize(port.in_a) != width) {
303  this_summand.first = module->addWire(NEW_ID, width);
304  module->addPos(NEW_ID, port.in_a, this_summand.first, port.is_signed);
305  } else {
306  this_summand.first = port.in_a;
307  }
308  this_summand.second = port.do_subtract;
309  summands.push_back(this_summand);
310  }
311 
312  for (auto &bit : macc.bit_ports)
313  summands.push_back(summand_t(bit, false));
314 
315  if (GetSize(summands) == 0)
316  summands.push_back(summand_t(RTLIL::SigSpec(0, width), false));
317 
318  while (GetSize(summands) > 1)
319  {
320  std::vector<summand_t> new_summands;
321  for (int i = 0; i < GetSize(summands); i += 2) {
322  if (i+1 < GetSize(summands)) {
323  summand_t this_summand;
324  this_summand.first = module->addWire(NEW_ID, width);
325  this_summand.second = summands[i].second && summands[i+1].second;
326  if (summands[i].second == summands[i+1].second)
327  module->addAdd(NEW_ID, summands[i].first, summands[i+1].first, this_summand.first);
328  else if (summands[i].second)
329  module->addSub(NEW_ID, summands[i+1].first, summands[i].first, this_summand.first);
330  else if (summands[i+1].second)
331  module->addSub(NEW_ID, summands[i].first, summands[i+1].first, this_summand.first);
332  else
333  log_abort();
334  new_summands.push_back(this_summand);
335  } else
336  new_summands.push_back(summands[i]);
337  }
338  summands.swap(new_summands);
339  }
340 
341  if (summands.front().second)
342  module->addNeg(NEW_ID, summands.front().first, cell->getPort("\\Y"));
343  else
344  module->connect(cell->getPort("\\Y"), summands.front().first);
345  }
346  else
347  {
348  MaccmapWorker worker(module, width);
349 
350  for (auto &port : macc.ports)
351  if (GetSize(port.in_b) == 0)
352  worker.add(port.in_a, port.is_signed, port.do_subtract);
353  else
354  worker.add(port.in_a, port.in_b, port.is_signed, port.do_subtract);
355 
356  for (auto &bit : macc.bit_ports)
357  worker.add(bit, 0);
358 
359  module->connect(cell->getPort("\\Y"), worker.synth());
360  }
361 }
Definition: macc.h:27
std::set< RTLIL::SigBit > to_sigbit_set() const
Definition: rtlil.cc:2909
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
Definition: log.cc:269
RTLIL::Cell * addAdd(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed=false)
#define log_abort()
Definition: log.h:84
RTLIL::Cell * addNeg(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed=false)
void connect(const RTLIL::SigSig &conn)
Definition: rtlil.cc:1278
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const
Definition: rtlil.cc:1809
int GetSize(RTLIL::Wire *wire)
Definition: yosys.cc:334
RTLIL::Wire * addWire(RTLIL::IdString name, int width=1)
Definition: rtlil.cc:1331
#define NEW_ID
Definition: yosys.h:166
RTLIL::Cell * addMul(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed=false)
void from_cell(RTLIL::Cell *cell)
Definition: macc.h:100
RTLIL::Cell * addSub(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed=false)
void log(const char *format,...)
Definition: log.cc:180
void append(const RTLIL::SigSpec &signal)
Definition: rtlil.cc:2523
RTLIL::Cell * addPos(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed=false)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation