WHITESPACE = _{ " " | "\t" | NEWLINE }
WHITESPACE_NONEWLINE = _{ " " | "\t" }
COMMENT = _{ ("/*" ~ (!"*/" ~ ANY)* ~ "*/") | "\\\n" }
main = {
SOI ~
library* ~
&EOI
}
library = {
"library" ~ "(" ~ (str | ident) ~ ")" ~ "{" ~
(((units | properties_library) ~ ";")
| (cell | lut_template)
| unparsed_tokenitem)* ~
"}"
}
unparsed_tokenitem = {
ident ~ (
("(" ~ tokenvalues? ~ ")" ~ (("{" ~ tokentree* ~ "}") | ";"?))
| (":" ~ tokenvalues ~ ";"?))
}
tokenvalues = _{ tokenvalue ~ ("," ~ tokenvalue)* }
tokenvalue = @{ ((ASCII_ALPHANUMERIC | "_" | "." | "-" | "*" | "+" | "|" | "&" | "!" | "'" | "^" | WHITESPACE_NONEWLINE)+) | str }
tokentree = _{
( unparsed_tokenitem
| ("(" ~ tokentree* ~ ")")
| ("{" ~ tokentree* ~ "}")
| ("[" ~ tokentree* ~ "]"))+
}
str = @{ "\"" ~ ((!"\"" ~ !"\\" ~ ANY) | ("\\" ~ ANY))* ~ "\"" }
int = @{ ASCII_DIGIT+ }
ident = @{ (ASCII_ALPHA | "_") ~ (ASCII_ALPHANUMERIC | "_" | "." | "-")* }
float = @{ "-"? ~ ASCII_DIGIT+ ~ ("." ~ ASCII_DIGIT*)? ~
("e" ~ ("+" | "-") ~ ASCII_DIGIT+)?}
ident_group = { "\"" ~ ident+ ~ "\"" }
logic_expr_term_paren = { "(" ~ logic_expr ~ ")" }
logic_expr_term = {
logic_expr_term_paren | int | ident
}
logic_expr_neg = { ("!" ~ logic_expr_term) | (logic_expr_term ~ "'") }
logic_expr_xor = {
(logic_expr_neg | logic_expr_term) ~
("^" ~ (logic_expr_neg | logic_expr_term))*
}
logic_expr_and = {
logic_expr_xor ~
(("&" | "*")? ~ logic_expr_xor)*
}
logic_expr = {
logic_expr_and ~ (("|" | "+") ~ logic_expr_and)*
}
units = {
time_unit
| voltage_unit
| current_unit
| leakage_power_unit
| capacitive_load_unit
| pulling_resistance_unit
}
time_unit = { "time_unit" ~ ":" ~ unitstr }
voltage_unit = { "voltage_unit" ~ ":" ~ unitstr }
current_unit = { "current_unit" ~ ":" ~ unitstr }
leakage_power_unit = { "leakage_power_unit" ~ ":" ~ unitstr }
capacitive_load_unit = { "capacitive_load_unit" ~ unitcap }
pulling_resistance_unit = { "pulling_resistance_unit" ~ ":" ~ unitstr }
unitstr = _{ (float ~ ident) | ("\"" ~ float ~ ident ~ "\"") }
unitcap = _{ "(" ~ float ~ "," ~ ident ~ ")" }
// property = { ident ~ ":" ~ (float | str | ident) }
properties_library = {
default_inout_pin_cap
| default_input_pin_cap
| default_output_pin_cap
| slew_derate_from_library
| input_threshold_pct_fall
| input_threshold_pct_rise
| output_threshold_pct_fall
| output_threshold_pct_rise
| slew_lower_threshold_pct_fall
| slew_lower_threshold_pct_rise
| slew_upper_threshold_pct_fall
| slew_upper_threshold_pct_rise
}
default_inout_pin_cap = { "default_inout_pin_cap" ~ ":" ~ float }
default_input_pin_cap = { "default_input_pin_cap" ~ ":" ~ float }
default_output_pin_cap = { "default_output_pin_cap" ~ ":" ~ float }
slew_derate_from_library = { "slew_derate_from_library" ~ ":" ~ float }
input_threshold_pct_fall = { "input_threshold_pct_fall" ~ ":" ~ float }
input_threshold_pct_rise = { "input_threshold_pct_rise" ~ ":" ~ float }
output_threshold_pct_fall = { "output_threshold_pct_fall" ~ ":" ~ float }
output_threshold_pct_rise = { "output_threshold_pct_rise" ~ ":" ~ float }
slew_lower_threshold_pct_fall = { "slew_lower_threshold_pct_fall" ~ ":" ~ float }
slew_lower_threshold_pct_rise = { "slew_lower_threshold_pct_rise" ~ ":" ~ float }
slew_upper_threshold_pct_fall = { "slew_upper_threshold_pct_fall" ~ ":" ~ float }
slew_upper_threshold_pct_rise = { "slew_upper_threshold_pct_rise" ~ ":" ~ float }
lut_template = {
(&"lu_table_template") ~
ident ~ "(" ~ (str | ident) ~ ")" ~ "{" ~
((lut_variable | lut_index) ~ ";")* ~
"}"
}
lut_variable = { "variable_" ~ int ~ ":" ~ (str | ident) }
lut_index = { "index_" ~ int ~ lut_array }
lut_values = { "values" ~ lut_array }
lut_array = {
"(" ~ ("," | "\\")* ~
(("\"" ~ float ~ ("," ~ float)* ~ "\"") ~ ("," | "\\")*)+
~ ")"
}
cell = {
"cell" ~ "(" ~ (str | ident) ~ ")" ~ "{" ~
(pin | sequential_def | unparsed_tokenitem)* ~
"}"
}
pin = {
"pin" ~ "(" ~ (str | ident) ~ ")" ~ "{" ~
(pin_direction | pin_cap | pin_function | timing | unparsed_tokenitem)* ~
"}"
}
pin_direction = { "direction" ~ ":" ~ (str | ident) ~ ";" }
pin_cap = { pin_cap_type ~ ":" ~ float ~ ";" }
pin_cap_type = { "capacitance" | "fall_capacitance" | "rise_capacitance" }
pin_function = {
("function" | "state_function") ~ ":" ~ // statetable if state function.
(logic_expr | ("\"" ~ logic_expr ~ "\""))
~ ";"
}
timing = {
"timing" ~ "(" ~ ")" ~ "{" ~
((timing_related_pin
| timing_type
| timing_sense) ~ ";"
| nldm_lut
| unparsed_tokenitem)* ~
"}"
}
timing_related_pin = { "related_pin" ~ ":" ~ (str | ident) }
timing_sense = { "timing_sense" ~ ":" ~ ident }
timing_type = { "timing_type" ~ ":" ~ ident }
lut_instance = {
ident ~ "(" ~ (str | ident) ~ ")" ~ "{" ~
((lut_index | lut_values) ~ ";")* ~
"}"
}
nldm_lut = {
(
&"cell_fall"
| &"cell_rise"
| &"fall_transition"
| &"rise_transition"
| &"fall_constraint"
| &"rise_constraint"
) ~ lut_instance
}
sequential_def = {
ff_def | latch_def | statetable_def
}
ff_def = {
"ff" ~ "(" ~ (str | ident) ~ "," ~ (str | ident) ~ ")" ~ "{" ~ ((
seq_def_clocked_on
| seq_def_next_state
| seq_def_clear
| seq_def_preset
| seq_def_clear_preset_var1
| seq_def_clear_preset_var2) ~ ";")* ~
"}"
}
latch_def = {
"latch" ~ "(" ~ (str | ident) ~ "," ~ (str | ident) ~ ")" ~ "{" ~ ((
seq_def_enable
| seq_def_data_in
| seq_def_clear
| seq_def_preset
| seq_def_clear_preset_var1
| seq_def_clear_preset_var2
) ~ ";")* ~
"}"
}
seq_def_clocked_on = {
"clocked_on" ~ ":" ~ (logic_expr | ("\"" ~ logic_expr ~ "\""))
}
seq_def_next_state = {
"next_state" ~ ":" ~ (logic_expr | ("\"" ~ logic_expr ~ "\""))
}
seq_def_enable = {
"enable" ~ ":" ~ (logic_expr | ("\"" ~ logic_expr ~ "\""))
}
seq_def_data_in = {
"data_in" ~ ":" ~ (logic_expr | ("\"" ~ logic_expr ~ "\""))
}
seq_def_clear = {
"clear" ~ ":" ~ (logic_expr | ("\"" ~ logic_expr ~ "\""))
}
seq_def_preset = {
"preset" ~ ":" ~ (logic_expr | ("\"" ~ logic_expr ~ "\""))
}
seq_def_clear_preset_var1 = {
"clear_preset_var1" ~ ":" ~ (
seq_def_clear_preset_var_val
| ("\"" ~ seq_def_clear_preset_var_val ~ "\""))
}
seq_def_clear_preset_var2 = {
"clear_preset_var2" ~ ":" ~ (
seq_def_clear_preset_var_val
| ("\"" ~ seq_def_clear_preset_var_val ~ "\""))
}
seq_def_clear_preset_var_val = { "L" | "H" | "N" | "T" | "X" }
statetable_def = {
"statetable" ~ "(" ~ ident_group ~ "," ~ ident_group ~ ")" ~ "{" ~
"table" ~ ":" ~ "\"" ~
statetable_line ~ ("," ~ statetable_line)* ~
"\"" ~ ";" ~
"}"
}
statetable_line = {
statetable_val+ ~ ":" ~ statetable_val+ ~ ":" ~ statetable_val+
}
statetable_val = {
"L" | "H" | "-" | "L/H" | "H/L" | "R" | "F" | "~R" | "~F" | "X" | "N"
}