Liberty file parser now accepts superfluous ;
authorNiels Moseley <n.a.moseley@moseleyinstruments.com>
Wed, 27 Mar 2019 14:15:53 +0000 (15:15 +0100)
committerNiels Moseley <n.a.moseley@moseleyinstruments.com>
Wed, 27 Mar 2019 14:15:53 +0000 (15:15 +0100)
passes/techmap/libparse.cc
tests/liberty/normal.lib
tests/liberty/processdefs.lib [new file with mode: 0644]
tests/liberty/semicolextra.lib [new file with mode: 0644]

index 8eadd87358d06e9ec109a58fa35c4cd6889a88fd..510a24c24e1f2eb4e500eceab063fa0986f7b240 100644 (file)
@@ -155,11 +155,13 @@ int LibertyParser::lexer(std::string &str)
 
        // check for a backslash
        if (c == '\\') {
-               c = f.get();
+               c = f.get();            
                if (c == '\r')
                        c = f.get();
-               if (c == '\n')
+               if (c == '\n') {
+                       line++;
                        return lexer(str);
+               }
                f.unget();
                return '\\';
        }
@@ -186,14 +188,39 @@ LibertyAst *LibertyParser::parse()
 
        int tok = lexer(str);
 
-       while (tok == 'n')
+       // there are liberty files in the while that
+       // have superfluous ';' at the end of
+       // a  { ... }. We simply ignore a ';' here.
+       // and get to the next statement.
+
+       while ((tok == 'n') || (tok == ';'))
                tok = lexer(str);
 
        if (tok == '}' || tok < 0)
                return NULL;
 
-       if (tok != 'v')
-               error();
+       if (tok != 'v') {
+               std::string eReport;
+               switch(tok)
+               {
+               case 'n':
+                       error("Unexpected newline.");
+                       break;
+               case '[':
+               case ']':
+               case '}':
+               case '{':
+               case '\"':
+               case ':':
+                       eReport = "Unexpected '";
+                       eReport += static_cast<char>(tok);
+                       eReport += "'.";
+                       error(eReport);
+                       break;
+               default:
+                       error();
+               }
+       }
 
        LibertyAst *ast = new LibertyAst;
        ast->id = str;
@@ -282,8 +309,28 @@ LibertyAst *LibertyParser::parse()
                                        }
                                        continue;           
                                }
-                               if (tok != 'v')
-                                       error();
+                               if (tok != 'v') {
+                                       std::string eReport;
+                                       switch(tok)
+                                       {
+                                       case 'n':
+                                               error("Unexpected newline.");
+                                               break;
+                                       case '[':
+                                       case ']':
+                                       case '}':
+                                       case '{':
+                                       case '\"':
+                                       case ':':
+                                               eReport = "Unexpected '";
+                                               eReport += static_cast<char>(tok);
+                                               eReport += "'.";
+                                               error(eReport);
+                                               break;
+                                       default:
+                                               error();
+                                       }
+                               }
                                ast->args.push_back(arg);
                        }
                        continue;
index 1474e2b5991259011c7943599516ad52cb78c6ef..4621194dd199ef23973cc13ad60ad83141794af8 100644 (file)
@@ -142,8 +142,7 @@ library(supergate) {
   }
   
   /* D-type flip-flop with asynchronous reset and preset */
-  cell (dff) 
-  {
+  cell (dff) {
     area : 6;
     ff("IQ", "IQN") {
       next_state : "D";
diff --git a/tests/liberty/processdefs.lib b/tests/liberty/processdefs.lib
new file mode 100644 (file)
index 0000000..37a6bba
--- /dev/null
@@ -0,0 +1,48 @@
+/********************************************/
+/*                                          */
+/* Supergate cell library for Bench marking */
+/*                                          */
+/* Symbiotic EDA GmbH / Moseley Instruments */
+/* Niels A. Moseley                         */
+/*                                          */
+/* Process: none                            */
+/*                                          */
+/* Date   : 25-03-2019                      */
+/* Version: 1.0                             */
+/*                                          */
+/********************************************/
+
+library(processdefs) {
+    technology (cmos);
+    revision : 1.0;
+
+    time_unit                     : "1ps";
+    pulling_resistance_unit       : "1kohm";  
+    voltage_unit                  : "1V";
+    current_unit                  : "1uA";  
+
+    capacitive_load_unit(1,ff);
+
+    default_inout_pin_cap         :  7.0;
+    default_input_pin_cap         :  7.0;
+    default_output_pin_cap        :  0.0;
+    default_fanout_load           :  1.0;
+
+    default_wire_load_capacitance : 0.1;
+    default_wire_load_resistance  : 1.0e-3;
+    default_wire_load_area        : 0.0;
+
+    nom_process                   :  1.0;
+    nom_temperature               : 25.0;
+    nom_voltage                   :  1.2;
+
+    delay_model                   : generic_cmos;
+    
+    define_cell_area(bond_pads,pad_slots)
+    input_voltage(cmos) {
+        vil : 0.3 * VDD ;
+        vih : 0.7 * VDD ;
+        vimin : -0.5 ;
+        vimax : VDD + 0.5 ;
+    }
+}
diff --git a/tests/liberty/semicolextra.lib b/tests/liberty/semicolextra.lib
new file mode 100644 (file)
index 0000000..0144fa3
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+
+       Test case for https://www.reddit.com/r/yosys/comments/b5texg/yosys_fails_to_parse_apparentlycorrect_liberty/
+
+       fall_constraint (SETUP_HOLD) formatting.
+
+*/
+
+library(supergate) {
+  technology (cmos);
+  revision : 1.0;
+
+    cell (DFF) {
+        cell_footprint : dff;
+        area : 50;
+        pin(D) {
+            direction : input;
+            capacitance : 0.002;
+            timing() {
+                related_pin : "CK";
+                timing_type : setup_rising;
+
+                fall_constraint (SETUP_HOLD) { values ("0.4000, 0.3000, 0.2000, 0.1000, 0.0000", \
+                    "0.4000, 0.3000, 0.2000, 0.1000, 0.000", \
+                    "0.5000, 0.4000, 0.3000, 0.2000, 0.0000", \
+                    "0.7000, 0.6000, 0.5000, 0.4000, 0.2000", \
+                    "1.0000, 1.0000, 0.9000, 0.8000, 0.6000"); } ;
+            }
+        }      
+
+        pin(CK) {
+            direction : input;
+            clock : true;
+            capacitance : 0.00290;
+        }
+
+        ff(IQ,IQN) {
+            clocked_on : "CK";
+            next_state : "D";
+        }
+        pin(Q) {
+            direction : output;
+            capacitance : 0.003;
+            max_capacitance : 0.3;
+        }
+        cell_leakage_power : 0.3;
+    }
+}