yosys

Error: Cannot find buffer gate in the library


While attempting to synthesize with Yosys, I am unable to map the logic circuit using only AND, XOR, NOT, and MUX's. This is because I get an error whenever my liberty file excludes BUFX2: Error:

ABC: ** cmd error: aborting 'source <abc-temp-dir>/abc.script'
ABC: Error: Cannot find buffer gate in the library.
ABC: Error: Abc_CommandAbc9Nf(): Mapping into LUTs has failed.
ERROR: Can't open ABC output file `/tmp/yosys-abc-L2LNHN/output.blif'.

BUFX2 in liberty file:

cell (BUFX2) {
  cell_footprint : buf;
  area : 25;
  cell_leakage_power : 0.0660639;
  pin(A)  {
    direction : input;
    capacitance : 0.00933171;
    rise_capacitance : 0.00930577;
    fall_capacitance : 0.00933171;
  }
  pin(Y)  {
    direction : output;
    capacitance : 0;
    rise_capacitance : 0;
    fall_capacitance : 0;
    max_capacitance : 0.975984;
    function : "A";
    timing() {
      related_pin : "A";
      timing_sense : positive_unate;
      cell_rise(delay_template_5x5) {
        index_1 ("0.01, 0.025, 0.05, 0.15, 0.3");
        index_2 ("0.06, 0.18, 0.42, 0.6, 1.2");
        values ( \
          "0.080192, 0.099332, 0.125551, 0.141601, 0.160879", \
          "0.09527, 0.119121, 0.146424, 0.159624, 0.180791", \
          "0.119549, 0.142384, 0.170285, 0.182826, 0.208459", \
          "0.206725, 0.226318, 0.258778, 0.269216, 0.29682", \
          "0.336459, 0.356012, 0.387945, 0.399852, 0.425204");
      }
      cell_fall(delay_template_5x5) {
        index_1 ("0.01, 0.025, 0.05, 0.15, 0.3");
        index_2 ("0.06, 0.18, 0.42, 0.6, 1.2");
        values ( \
          "0.089994, 0.120328, 0.164981, 0.192952, 0.273426", \
          "0.105036, 0.137433, 0.18812, 0.215291, 0.293841", \
          "0.126393, 0.161711, 0.209388, 0.240117, 0.319216", \
          "0.207389, 0.241744, 0.292741, 0.321104, 0.405447", \
          "0.326255, 0.363651, 0.411543, 0.440746, 0.523808");
      }
      fall_transition(delay_template_5x5) {
        index_1 ("0.01, 0.025, 0.05, 0.15, 0.3");
        index_2 ("0.06, 0.18, 0.42, 0.6, 1.2");
        values ( \
          "0.039104, 0.036002, 0.057053, 0.0624, 0.0708", \
          "0.045857, 0.047088, 0.0684, 0.0702, 0.0768", \
          "0.0726, 0.0744, 0.0786, 0.084, 0.0972", \
          "0.165, 0.1656, 0.1668, 0.1692, 0.1764", \
          "0.315, 0.3156, 0.3168, 0.3162, 0.3198");
      }
    }
  }
}

Note that I only get this error when trying to use the command (in yosys) [Must include to see delay time]

abc -liberty asic_cell_yosys_3.lib -constr yosys_timing.constr;

Using the constr file above allows me to see critical path timing delays as illustrated by Clifford in this post.

Setting the area of BUFX2 to an extremely large value like 9999999 still makes Yosys include it in the circuit, even when highly un-optimal.

My goal is trying to optimize depth/critical path timing rather than area/total # of gates, but I can not find a way to do that when

  1. I can't remove the buffer gate from the liberty file [with the .constr file]
  2. All gates which I need to use (AND,XOR,NOT, MUX) require cell_rise, cell_fall, and fall_transition timing constraints which I have included in the file, but do not necessarily know how it works/ effects delay result

To address #2, how should I change the values to reflect XOR gates requiring approximately 0 delay:

cell (XOR2X1) {
area : 1;
  cell_leakage_power : 0.161354;
  pin(A)  {
    direction : input;
    capacitance : 0.0296528;
    rise_capacitance : 0.029651;
    fall_capacitance : 0.0296528;
  }
  pin(B)  {
    direction : input;
    capacitance : 0.0342661;
    rise_capacitance : 0.0339918;
    fall_capacitance : 0.0342661;
  }
  pin(Y)  {
    direction : output;
    capacitance : 0;
    rise_capacitance : 0;
    fall_capacitance : 0;
    max_capacitance : 0.484395;
    function : "(A^B)";
    timing() {
      related_pin : "A";
      timing_sense : non_unate;
      cell_rise(delay_template_5x5) {
        index_1 ("0.005, 0.0125, 0.025, 0.075, 0.15");
        index_2 ("0.06, 0.18, 0.42, 0.6, 1.2");
        values ( \
          "0.084668, 0.100252, 0.11425, 0.123569, 0.136197", \
          "0.097915, 0.113723, 0.126398, 0.138879, 0.150616", \
          "0.119426, 0.133803, 0.150727, 0.160469, 0.175347", \
          "0.200291, 0.21109, 0.234434, 0.245604, 0.260628", \
          "0.324762, 0.343132, 0.359931, 0.370218, 0.387403");
      }

      cell_fall(delay_template_5x5) {
        index_1 ("0.005, 0.0125, 0.025, 0.075, 0.15");
        index_2 ("0.06, 0.18, 0.42, 0.6, 1.2");
        values ( \
          "0.080217, 0.104741, 0.14405, 0.166439, 0.230805", \
          "0.089887, 0.114359, 0.158704, 0.181241, 0.244897", \
          "0.104894, 0.129666, 0.174768, 0.197644, 0.261257", \
          "0.164496, 0.19114, 0.235815, 0.259502, 0.326338", \
          "0.254884, 0.281399, 0.324471, 0.350019, 0.419374");
      }
      fall_transition(delay_template_5x5) {
        index_1 ("0.005, 0.0125, 0.025, 0.075, 0.15");
        index_2 ("0.06, 0.18, 0.42, 0.6, 1.2");
        values ( \
          "0.041331, 0.040781, 0.050767, 0.044749, 0.0696", \
          "0.053453, 0.052285, 0.0624, 0.063, 0.0738", \
          "0.0756, 0.069, 0.078, 0.0792, 0.084", \
          "0.1518, 0.1512, 0.1482, 0.1488, 0.1536", \
          "0.273, 0.273, 0.2682, 0.2652, 0.27");
      }
    }
    timing() {
      related_pin : "B";
      timing_sense : non_unate;
      cell_rise(delay_template_5x5) {
        index_1 ("0.005, 0.0125, 0.025, 0.075, 0.15");
        index_2 ("0.06, 0.18, 0.42, 0.6, 1.2");
        values ( \
          "0.095856, 0.109639, 0.124914, 0.132649, 0.149393", \
          "0.112134, 0.122918, 0.138721, 0.14656, 0.164175", \
          "0.132565, 0.144856, 0.161456, 0.170028, 0.185654", \
          "0.217554, 0.231394, 0.246536, 0.255419, 0.27072", \
          "0.343798, 0.357936, 0.373613, 0.388316, 0.398061");
      }

      cell_fall(delay_template_5x5) {
        index_1 ("0.005, 0.0125, 0.025, 0.075, 0.15");
        index_2 ("0.06, 0.18, 0.42, 0.6, 1.2");
        values ( \
          "0.090864, 0.115106, 0.148564, 0.176005, 0.236451", \
          "0.101631, 0.126046, 0.162396, 0.186432, 0.247857", \
          "0.118398, 0.142704, 0.177128, 0.20129, 0.267362", \
          "0.181148, 0.206, 0.241266, 0.265038, 0.330296", \
          "0.273354, 0.298267, 0.333521, 0.3571, 0.42352");
      }
      fall_transition(delay_template_5x5) {
        index_1 ("0.005, 0.0125, 0.025, 0.075, 0.15");
        index_2 ("0.06, 0.18, 0.42, 0.6, 1.2");
        values ( \
          "0.038733, 0.04056, 0.054628, 0.057339, 0.0624", \
          "0.051463, 0.051355, 0.063, 0.0618, 0.0684", \
          "0.0732, 0.0744, 0.0792, 0.0774, 0.0882", \
          "0.1524, 0.1542, 0.1518, 0.1542, 0.1584", \
          "0.2724, 0.2724, 0.2736, 0.2724, 0.2748");
      }
    }
  }
} 

Thank you.


Solution

  • You can actually achieve point 1 with some trickery.

    Yosys' internal cells start with $, e.g. $_AND_ which you can see if you run abc without any other arguments. One of these internal cells is $_BUF_ which represents a buffer cell. Since to Yosys buffer cells are identical to wires, the opt command will replace all instances of $_BUF_ with simple wires.

    This means you can instantiate $_BUF_ cells by replacing the BUFX2 cell name with "$_BUF_" (the quotes are needed to escape the $), keeping ABC happy because there's a cell buffer, and then after running an opt pass, the buffers have disappeared from your netlist.