1

Using the following script, I am synthesising to a standard cell library for which I have a lib file, my_library.lib:

read_liberty -lib  my_library.lib
script yosys_readfiles.ys
proc; opt; memory; opt; fsm -norecode; opt
techmap; opt
dfflibmap -liberty my_library.lib
abc -liberty my_library.lib
hilomap -hicell LIB_TIEHI Y -locell LIB_TIELO Y
clean
write_verilog -noattr -noexpr output.v
stat

While this generally works, I found that some of the logic isn't mapped efficiently. For example, I have the following Verilog model of a 4-way multiplexer:

module mux4(
     input  i0,
     input  i1,
     input  i2,
     input  i3,
     input  s0,
     input  s1,
     output z
   );
   reg    zint;
   parameter tdelay = `default_gate_delay;
   always @(i0 or i1 or i2 or i3 or s0 or s1) begin
      case ({s1, s0})
        2'b00:       zint <= i0;
        2'b01:       zint <= i1;    
        2'b10:       zint <= i2;    
        2'b11:       zint <= i3;    
        default:     zint <= i3;
      endcase
   end
   assign z = zint;
endmodule

Yosys synthesised this to the following gate-level netlist:

/* Generated by Yosys 0.5+ (git sha1 f13e387, gcc 5.3.1-8ubuntu2 -O2 -fstack-protector-strong -fPIC -Os) */

module mux4(i0, i1, i2, i3, s0, s1, z);
  wire _00_;
  wire _01_;
  wire _02_;
  wire _03_;
  wire _04_;
  wire _05_;
  input i0;
  input i1;
  input i2;
  input i3;
  input s0;
  input s1;
  output z;
  wire zint;
  NAND3 _06_ (
    .A(s1),
    .B(s0),
    .C(i3),
    .Y(_04_)
  );
  INV _07_ (
    .A(s1),
    .Y(_05_)
  );
  NAND3 _08_ (
    .A(_05_),
    .B(s0),
    .C(i1),
    .Y(_00_)
  );
  INV _09_ (
    .A(s0),
    .Y(_01_)
  );
  NAND3 _10_ (
    .A(_05_),
    .B(_01_),
    .C(i0),
    .Y(_02_)
  );
  NAND3B _11_ (
    .AN(s0),
    .B(s1),
    .C(i2),
    .Y(_03_)
  );
  NAND4 _12_ (
    .A(_02_),
    .B(_00_),
    .C(_03_),
    .D(_04_),
    .Y(z)
  );
  assign zint = z;
endmodule

Since the library I am using already has a MXI4 cell, I would have expected something similar to the following instead:

module mux4(i0, i1, i2, i3, s0, s1, z);
  input i0;
  input i1;
  input i2;
  input i3;
  input s0;
  input s1;
  output z;
  MXI4 _12_ (
    .A(i0),
    .B(i1),
    .C(i2),
    .D(i3),
    .S0(s0),
    .S1(s1),
    .Y(z)
  );
endmodule

I am wondering how I can direct Yosys to use the MXI4 cell instead of the cascaded NAND instances above as this would result in a significant reduction in area. While for this specific cell, I could use the same technique as described in this answer to manually map to the MXI4 cell, but I am concerned that there may be other (more complex) areas of my design where such a manual mapping is either not as obvious and/or infeasible.

One thing I tried was to add the following option to the abc command in my synthesis script, which I found on Reddit:

-script +strash;scorr;ifraig;retime,{D};strash;dch,-f;map,-M,1,{D}

But it didn't solve the problem either. (Also I couldn't find any documentation on some of these ABC commands, any help there would be appreciated as well.)

FriendFX
  • 2,929
  • 1
  • 34
  • 63

1 Answers1

1

The following ABC script should be able to map the MUX4, or it least it is when using the ABC version that is bundled with Yosys 0.7:

abc -liberty my_library.lib -script \
    +strash;ifraig;scorr;dc2;dretime;strash;&get,-n;&dch,-f;&nf,{D};&put

Starting with git commit 8927e19 this is the new default script for abc -liberty.

CliffordVienna
  • 7,995
  • 1
  • 37
  • 57
  • 1
    Brilliant, thanks. I'd also like to confirm this to work under my (Ubuntu-packaged) `Yosys 0.5+ (git sha1 f13e387, gcc 5.3.1-8ubuntu2 -O2 -fstack-protector-strong -fPIC -Os)` version. – FriendFX Feb 01 '17 at 23:20
  • 1
    Do you know any resources describing these (to me somewhat cryptic) ABC commands? – FriendFX Feb 01 '17 at 23:23
  • 1
    Just the help messages: Run `yosys-abc` in interactive mode and type e.g. `&dch -h`. Running `help` gives you the list of all commands, and `help -d` prints the help message for each and every command. You can also run e.g. `yosys-abc -c 'help -d' > abc-help.txt` and spend the rest of the day reading `abc-help.txt`. :) Unfortunately every command and every option is only described by a one-liner, and there are no examples. I usually extrapolate things from ABC scripts the ABC author sends me when I send him questions, as I also did yesterday in response to your post. – CliffordVienna Feb 01 '17 at 23:36
  • 1
    Thanks for the info and for checking with the author of ABC. I just found another case in my current build (with the ABC script in place): A full-adder cell which exists in the library but Yosys used 2 XORs and 2 OAIs instead. Inputs are `A`,`B`,`CI` and outputs are `S` and `CO`. – FriendFX Feb 02 '17 at 00:53
  • 1
    Currently ABC does not support gates with more than one output port. You'd have to write a techmap file that maps Yosys' $alu cells to the full adder cells you have in your gate lib. (As an example for such files, here is the techmap file that mapps $alu cells LUTs and carry-chain cells for ice40 FPGAs: https://github.com/cliffordwolf/yosys/blob/master/techlibs/ice40/arith_map.v) – CliffordVienna Feb 02 '17 at 09:26