187 ImplicitLocOpBuilder &b)
const {
188 TypeSwitch<Operation *>(op)
190 .Case([&](EqLibOp op) {
193 .Case([&](NeqLibOp op) {
196 .Case([&](LtLibOp op) {
199 .Case([&](LeLibOp op) {
202 .Case([&](GtLibOp op) {
205 .Case([&](GeLibOp op) {
208 .Case([&](SltLibOp op) {
211 .Case([&](SleLibOp op) {
214 .Case([&](SgtLibOp op) {
217 .Case([&](SgeLibOp op) {
221 .Case([&](AddLibOp op) {
222 convertArithBinaryOp<AddLibOp, AddOp>(op, wires, b);
224 .Case([&](SubLibOp op) {
225 convertArithBinaryOp<SubLibOp, SubOp>(op, wires, b);
227 .Case([&](RshLibOp op) {
228 convertArithBinaryOp<RshLibOp, ShrUOp>(op, wires, b);
230 .Case([&](SrshLibOp op) {
231 convertArithBinaryOp<SrshLibOp, ShrSOp>(op, wires, b);
233 .Case([&](LshLibOp op) {
234 convertArithBinaryOp<LshLibOp, ShlOp>(op, wires, b);
236 .Case([&](AndLibOp op) {
237 convertArithBinaryOp<AndLibOp, AndOp>(op, wires, b);
239 .Case([&](OrLibOp op) {
240 convertArithBinaryOp<OrLibOp, OrOp>(op, wires, b);
242 .Case([&](XorLibOp op) {
243 convertArithBinaryOp<XorLibOp, XorOp>(op, wires, b);
245 .Case([&](MuxLibOp op) {
246 auto sel =
wireIn(op.getCond(), op.instanceName(),
247 op.portName(op.getCond()), b);
248 auto tru =
wireIn(op.getTru(), op.instanceName(),
249 op.portName(op.getTru()), b);
250 auto fal =
wireIn(op.getFal(), op.instanceName(),
251 op.portName(op.getFal()), b);
253 auto mux = b.create<MuxOp>(sel, tru, fal);
256 wireOut(mux, op.instanceName(), op.portName(op.getOut()), b);
257 wires.append({sel.getInput(), tru.getInput(), fal.getInput(), out});
260 .Case([&](MultPipeLibOp op) {
261 convertPipelineOp<MultPipeLibOp, comb::MulOp>(op, wires, b);
263 .Case([&](DivUPipeLibOp op) {
264 convertPipelineOp<DivUPipeLibOp, comb::DivUOp>(op, wires, b);
266 .Case([&](DivSPipeLibOp op) {
267 convertPipelineOp<DivSPipeLibOp, comb::DivSOp>(op, wires, b);
269 .Case([&](RemSPipeLibOp op) {
270 convertPipelineOp<RemSPipeLibOp, comb::ModSOp>(op, wires, b);
272 .Case([&](RemUPipeLibOp op) {
273 convertPipelineOp<RemUPipeLibOp, comb::ModUOp>(op, wires, b);
276 .Case([&](RegisterOp op) {
278 wireIn(op.getIn(), op.instanceName(), op.portName(op.getIn()), b);
279 auto writeEn =
wireIn(op.getWriteEn(), op.instanceName(),
280 op.portName(op.getWriteEn()), b);
281 auto clk =
wireIn(op.getClk(), op.instanceName(),
282 op.portName(op.getClk()), b);
283 auto reset =
wireIn(op.getReset(), op.instanceName(),
284 op.portName(op.getReset()), b);
285 auto seqClk = b.create<seq::ToClockOp>(clk);
287 reg(writeEn, seqClk, reset, op.instanceName() +
"_done_reg", b);
289 wireOut(doneReg, op.instanceName(), op.portName(op.getDone()), b);
292 regCe(in, seqClk, clockEn, reset, op.instanceName() +
"_reg", b);
293 auto out =
wireOut(outReg, op.instanceName(),
"", b);
294 wires.append({in.getInput(), writeEn.getInput(), clk.getInput(),
295 reset.getInput(), out, done});
298 .Case([&](SliceLibOp op) {
300 wireIn(op.getIn(), op.instanceName(), op.portName(op.getIn()), b);
301 auto outWidth = op.getOut().getType().getIntOrFloatBitWidth();
303 auto extract = b.create<ExtractOp>(in, 0, outWidth);
306 wireOut(extract, op.instanceName(), op.portName(op.getOut()), b);
307 wires.append({in.getInput(), out});
309 .Case([&](NotLibOp op) {
311 wireIn(op.getIn(), op.instanceName(), op.portName(op.getIn()), b);
313 auto notOp = comb::createOrFoldNot(in, b);
316 wireOut(notOp, op.instanceName(), op.portName(op.getOut()), b);
317 wires.append({in.getInput(), out});
319 .Case([&](WireLibOp op) {
320 auto wire =
wireIn(op.getIn(), op.instanceName(),
"", b);
321 wires.append({wire.getInput(), wire});
323 .Case([&](UndefLibOp op) {
324 auto undef = b.create<sv::ConstantXOp>(op.getType());
325 wires.append({undef});
327 .Case([&](PadLibOp op) {
329 wireIn(op.getIn(), op.instanceName(), op.portName(op.getIn()), b);
330 auto srcWidth = in.getType().getIntOrFloatBitWidth();
331 auto destWidth = op.getOut().getType().getIntOrFloatBitWidth();
333 APInt(destWidth - srcWidth, 0));
335 op.instanceName(), op.portName(op.getOut()), b);
336 wires.append({in.getInput(), padded});
338 .Case([&](ExtSILibOp op) {
340 wireIn(op.getIn(), op.instanceName(), op.portName(op.getIn()), b);
343 op.instanceName(), op.portName(op.getOut()), b);
344 wires.append({in.getInput(), extsi});
346 .Default([](Operation *) {
return SmallVector<Value>(); });
380 ImplicitLocOpBuilder &b)
const {
382 wireIn(op.getClk(), op.instanceName(), op.portName(op.getClk()), b);
384 wireIn(op.getReset(), op.instanceName(), op.portName(op.getReset()), b);
385 auto go =
wireIn(op.getGo(), op.instanceName(), op.portName(op.getGo()), b);
387 wireIn(op.getLeft(), op.instanceName(), op.portName(op.getLeft()), b);
389 wireIn(op.getRight(), op.instanceName(), op.portName(op.getRight()), b);
390 wires.append({clk.getInput(), reset.getInput(), go.getInput(),
391 left.getInput(), right.getInput()});
393 auto doneReg =
reg(go, clk, reset,
394 op.instanceName() +
"_" + op.portName(op.getDone()), b);
396 wireOut(doneReg, op.instanceName(), op.portName(op.getDone()), b);
398 auto targetOp = b.create<TargetOpTy>(left, right,
false);
399 for (
auto &&[targetRes, sourceRes] :
400 llvm::zip(targetOp->getResults(), op.getOutputPorts())) {
401 auto portName = op.portName(sourceRes);
403 auto resReg =
regCe(targetRes, clk, clockEn, reset,
405 wires.push_back(
wireOut(resReg, op.instanceName(), portName, b));
408 wires.push_back(done);