Liberty file parser now accepts superfluous ;

This commit is contained in:
Niels Moseley 2019-03-27 15:15:53 +01:00
parent 7682629b79
commit 487cb45b87
4 changed files with 151 additions and 9 deletions

View File

@ -155,11 +155,13 @@ int LibertyParser::lexer(std::string &str)
// check for a backslash // check for a backslash
if (c == '\\') { if (c == '\\') {
c = f.get(); c = f.get();
if (c == '\r') if (c == '\r')
c = f.get(); c = f.get();
if (c == '\n') if (c == '\n') {
line++;
return lexer(str); return lexer(str);
}
f.unget(); f.unget();
return '\\'; return '\\';
} }
@ -186,14 +188,39 @@ LibertyAst *LibertyParser::parse()
int tok = lexer(str); 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); tok = lexer(str);
if (tok == '}' || tok < 0) if (tok == '}' || tok < 0)
return NULL; return NULL;
if (tok != 'v') if (tok != 'v') {
error(); 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; LibertyAst *ast = new LibertyAst;
ast->id = str; ast->id = str;
@ -282,8 +309,28 @@ LibertyAst *LibertyParser::parse()
} }
continue; continue;
} }
if (tok != 'v') if (tok != 'v') {
error(); 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); ast->args.push_back(arg);
} }
continue; continue;

View File

@ -142,8 +142,7 @@ library(supergate) {
} }
/* D-type flip-flop with asynchronous reset and preset */ /* D-type flip-flop with asynchronous reset and preset */
cell (dff) cell (dff) {
{
area : 6; area : 6;
ff("IQ", "IQN") { ff("IQ", "IQN") {
next_state : "D"; next_state : "D";

View File

@ -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 ;
}
}

View File

@ -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;
}
}