mirror of https://github.com/YosysHQ/yosys.git
Merge pull request #897 from trcwm/libertyfixes
Liberty parser: Accept ranges [A:B], and ignore missing ';'.
This commit is contained in:
commit
2bb9632944
|
@ -24,6 +24,7 @@
|
||||||
#include <istream>
|
#include <istream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#ifndef FILTERLIB
|
#ifndef FILTERLIB
|
||||||
#include "kernel/log.h"
|
#include "kernel/log.h"
|
||||||
|
@ -86,15 +87,17 @@ int LibertyParser::lexer(std::string &str)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
|
// eat whitespace
|
||||||
do {
|
do {
|
||||||
c = f.get();
|
c = f.get();
|
||||||
} while (c == ' ' || c == '\t' || c == '\r');
|
} while (c == ' ' || c == '\t' || c == '\r');
|
||||||
|
|
||||||
if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_' || c == '-' || c == '+' || c == '.' || c == '[' || c == ']') {
|
// search for identifiers, numbers, plus or minus.
|
||||||
|
if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_' || c == '-' || c == '+' || c == '.') {
|
||||||
str = c;
|
str = c;
|
||||||
while (1) {
|
while (1) {
|
||||||
c = f.get();
|
c = f.get();
|
||||||
if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_' || c == '-' || c == '+' || c == '.' || c == '[' || c == ']')
|
if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_' || c == '-' || c == '+' || c == '.')
|
||||||
str += c;
|
str += c;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
@ -111,6 +114,8 @@ int LibertyParser::lexer(std::string &str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if it wasn't an identifer, number of array range,
|
||||||
|
// maybe it's a string?
|
||||||
if (c == '"') {
|
if (c == '"') {
|
||||||
str = "";
|
str = "";
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -125,9 +130,10 @@ int LibertyParser::lexer(std::string &str)
|
||||||
return 'v';
|
return 'v';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if it wasn't a string, perhaps it's a comment or a forward slash?
|
||||||
if (c == '/') {
|
if (c == '/') {
|
||||||
c = f.get();
|
c = f.get();
|
||||||
if (c == '*') {
|
if (c == '*') { // start of '/*' block comment
|
||||||
int last_c = 0;
|
int last_c = 0;
|
||||||
while (c > 0 && (last_c != '*' || c != '/')) {
|
while (c > 0 && (last_c != '*' || c != '/')) {
|
||||||
last_c = c;
|
last_c = c;
|
||||||
|
@ -136,7 +142,7 @@ int LibertyParser::lexer(std::string &str)
|
||||||
line++;
|
line++;
|
||||||
}
|
}
|
||||||
return lexer(str);
|
return lexer(str);
|
||||||
} else if (c == '/') {
|
} else if (c == '/') { // start of '//' line comment
|
||||||
while (c > 0 && c != '\n')
|
while (c > 0 && c != '\n')
|
||||||
c = f.get();
|
c = f.get();
|
||||||
line++;
|
line++;
|
||||||
|
@ -144,9 +150,10 @@ int LibertyParser::lexer(std::string &str)
|
||||||
}
|
}
|
||||||
f.unget();
|
f.unget();
|
||||||
// fprintf(stderr, "LEX: char >>/<<\n");
|
// fprintf(stderr, "LEX: char >>/<<\n");
|
||||||
return '/';
|
return '/'; // a single '/' charater.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check for a backslash
|
||||||
if (c == '\\') {
|
if (c == '\\') {
|
||||||
c = f.get();
|
c = f.get();
|
||||||
if (c == '\r')
|
if (c == '\r')
|
||||||
|
@ -157,11 +164,15 @@ int LibertyParser::lexer(std::string &str)
|
||||||
return '\\';
|
return '\\';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check for a new line
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
line++;
|
line++;
|
||||||
return 'n';
|
return 'n';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// anything else, such as ';' will get passed
|
||||||
|
// through as literal items.
|
||||||
|
|
||||||
// if (c >= 32 && c < 255)
|
// if (c >= 32 && c < 255)
|
||||||
// fprintf(stderr, "LEX: char >>%c<<\n", c);
|
// fprintf(stderr, "LEX: char >>%c<<\n", c);
|
||||||
// else
|
// else
|
||||||
|
@ -191,12 +202,11 @@ LibertyAst *LibertyParser::parse()
|
||||||
{
|
{
|
||||||
tok = lexer(str);
|
tok = lexer(str);
|
||||||
|
|
||||||
if (tok == ';')
|
// allow both ';' and new lines to
|
||||||
|
// terminate a statement.
|
||||||
|
if ((tok == ';') || (tok == 'n'))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (tok == 'n')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (tok == ':' && ast->value.empty()) {
|
if (tok == ':' && ast->value.empty()) {
|
||||||
tok = lexer(ast->value);
|
tok = lexer(ast->value);
|
||||||
if (tok != 'v')
|
if (tok != 'v')
|
||||||
|
@ -210,7 +220,12 @@ LibertyAst *LibertyParser::parse()
|
||||||
ast->value += str;
|
ast->value += str;
|
||||||
tok = lexer(str);
|
tok = lexer(str);
|
||||||
}
|
}
|
||||||
if (tok == ';')
|
|
||||||
|
// In a liberty file, all key : value pairs should end in ';'
|
||||||
|
// However, there are some liberty files in the wild that
|
||||||
|
// just have a newline. We'll be kind and accept a newline
|
||||||
|
// instead of the ';' too..
|
||||||
|
if ((tok == ';') || (tok == 'n'))
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
error();
|
error();
|
||||||
|
@ -225,6 +240,48 @@ LibertyAst *LibertyParser::parse()
|
||||||
continue;
|
continue;
|
||||||
if (tok == ')')
|
if (tok == ')')
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// FIXME: the AST needs to be extended to store
|
||||||
|
// these vector ranges.
|
||||||
|
if (tok == '[')
|
||||||
|
{
|
||||||
|
// parse vector range [A] or [A:B]
|
||||||
|
std::string arg;
|
||||||
|
tok = lexer(arg);
|
||||||
|
if (tok != 'v')
|
||||||
|
{
|
||||||
|
// expected a vector array index
|
||||||
|
error("Expected a number.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// fixme: check for number A
|
||||||
|
}
|
||||||
|
tok = lexer(arg);
|
||||||
|
// optionally check for : in case of [A:B]
|
||||||
|
// if it isn't we just expect ']'
|
||||||
|
// as we have [A]
|
||||||
|
if (tok == ':')
|
||||||
|
{
|
||||||
|
tok = lexer(arg);
|
||||||
|
if (tok != 'v')
|
||||||
|
{
|
||||||
|
// expected a vector array index
|
||||||
|
error("Expected a number.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// fixme: check for number B
|
||||||
|
tok = lexer(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// expect a closing bracket of array range
|
||||||
|
if (tok != ']')
|
||||||
|
{
|
||||||
|
error("Expected ']' on array range.");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (tok != 'v')
|
if (tok != 'v')
|
||||||
error();
|
error();
|
||||||
ast->args.push_back(arg);
|
ast->args.push_back(arg);
|
||||||
|
@ -255,6 +312,14 @@ void LibertyParser::error()
|
||||||
log_error("Syntax error in liberty file on line %d.\n", line);
|
log_error("Syntax error in liberty file on line %d.\n", line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LibertyParser::error(const std::string &str)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "Syntax error in liberty file on line " << line << ".\n";
|
||||||
|
ss << " " << str << "\n";
|
||||||
|
log_error("%s", ss.str().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
void LibertyParser::error()
|
void LibertyParser::error()
|
||||||
|
@ -263,25 +328,34 @@ void LibertyParser::error()
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LibertyParser::error(const std::string &str)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "Syntax error in liberty file on line " << line << ".\n";
|
||||||
|
ss << " " << str << "\n";
|
||||||
|
printf("%s", ss.str().c_str());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
/**** BEGIN: http://svn.clifford.at/tools/trunk/examples/check.h ****/
|
/**** BEGIN: http://svn.clifford.at/tools/trunk/examples/check.h ****/
|
||||||
|
|
||||||
#define CHECK_NV(result, check) \
|
#define CHECK_NV(result, check) \
|
||||||
do { \
|
do { \
|
||||||
auto _R = (result); \
|
auto _R = (result); \
|
||||||
if (!(_R check)) { \
|
if (!(_R check)) { \
|
||||||
fprintf(stderr, "Error from '%s' (%ld %s) in %s:%d.\n", \
|
fprintf(stderr, "Error from '%s' (%ld %s) in %s:%d.\n", \
|
||||||
#result, (long int)_R, #check, __FILE__, __LINE__); \
|
#result, (long int)_R, #check, __FILE__, __LINE__); \
|
||||||
abort(); \
|
abort(); \
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define CHECK_COND(result) \
|
#define CHECK_COND(result) \
|
||||||
do { \
|
do { \
|
||||||
if (!(result)) { \
|
if (!(result)) { \
|
||||||
fprintf(stderr, "Error from '%s' in %s:%d.\n", \
|
fprintf(stderr, "Error from '%s' in %s:%d.\n", \
|
||||||
#result, __FILE__, __LINE__); \
|
#result, __FILE__, __LINE__); \
|
||||||
abort(); \
|
abort(); \
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
/**** END: http://svn.clifford.at/tools/trunk/examples/check.h ****/
|
/**** END: http://svn.clifford.at/tools/trunk/examples/check.h ****/
|
||||||
|
|
|
@ -46,9 +46,17 @@ namespace Yosys
|
||||||
LibertyAst *ast;
|
LibertyAst *ast;
|
||||||
LibertyParser(std::istream &f) : f(f), line(1), ast(parse()) {}
|
LibertyParser(std::istream &f) : f(f), line(1), ast(parse()) {}
|
||||||
~LibertyParser() { if (ast) delete ast; }
|
~LibertyParser() { if (ast) delete ast; }
|
||||||
|
|
||||||
|
/* lexer return values:
|
||||||
|
'v': identifier, string, array range [...] -> str holds the token string
|
||||||
|
'n': newline
|
||||||
|
anything else is a single character.
|
||||||
|
*/
|
||||||
int lexer(std::string &str);
|
int lexer(std::string &str);
|
||||||
LibertyAst *parse();
|
|
||||||
|
LibertyAst *parse();
|
||||||
void error();
|
void error();
|
||||||
|
void error(const std::string &str);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
*.log
|
||||||
|
test.ys
|
|
@ -0,0 +1,81 @@
|
||||||
|
/********************************************/
|
||||||
|
/* */
|
||||||
|
/* Supergate cell library for Bench marking */
|
||||||
|
/* */
|
||||||
|
/* Symbiotic EDA GmbH / Moseley Instruments */
|
||||||
|
/* Niels A. Moseley */
|
||||||
|
/* */
|
||||||
|
/* Process: none */
|
||||||
|
/* */
|
||||||
|
/* Date : 02-11-2018 */
|
||||||
|
/* Version: 1.0 */
|
||||||
|
/* */
|
||||||
|
/********************************************/
|
||||||
|
|
||||||
|
library(supergate) {
|
||||||
|
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;
|
||||||
|
|
||||||
|
type( IO_bus_3_to_0 ) {
|
||||||
|
base_type : array ;
|
||||||
|
data_type : bit ;
|
||||||
|
bit_width : 4;
|
||||||
|
bit_from : 3 ;
|
||||||
|
bit_to : 0 ;
|
||||||
|
downto : true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell (SRAM) {
|
||||||
|
area : 1 ;
|
||||||
|
memory() {
|
||||||
|
type : ram;
|
||||||
|
address_width : 4;
|
||||||
|
word_width : 4;
|
||||||
|
}
|
||||||
|
pin(CE1) {
|
||||||
|
direction : input;
|
||||||
|
capacitance : 0.021;
|
||||||
|
max_transition : 1.024;
|
||||||
|
switch_pin : true;
|
||||||
|
}
|
||||||
|
bus(I1) {
|
||||||
|
bus_type : IO_bus_3_to_0 ;
|
||||||
|
direction : input;
|
||||||
|
pin (I1[3:0]) {
|
||||||
|
timing() {
|
||||||
|
related_pin : "CE1" ;
|
||||||
|
timing_type : setup_rising ;
|
||||||
|
rise_constraint (scalar) {
|
||||||
|
values("0.0507786");
|
||||||
|
}
|
||||||
|
fall_constraint (scalar) {
|
||||||
|
values("0.0507786");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* end */
|
|
@ -0,0 +1,360 @@
|
||||||
|
/********************************************/
|
||||||
|
/* */
|
||||||
|
/* Supergate cell library for Bench marking */
|
||||||
|
/* */
|
||||||
|
/* Symbiotic EDA GmbH / Moseley Instruments */
|
||||||
|
/* Niels A. Moseley */
|
||||||
|
/* */
|
||||||
|
/* Process: none */
|
||||||
|
/* */
|
||||||
|
/* Date : 02-11-2018 */
|
||||||
|
/* Version: 1.0 */
|
||||||
|
/* */
|
||||||
|
/********************************************/
|
||||||
|
|
||||||
|
library(supergate) {
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* Inverter */
|
||||||
|
cell (inv) {
|
||||||
|
area : 1;
|
||||||
|
pin(A) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
|
||||||
|
pin(Y) {
|
||||||
|
direction : output;
|
||||||
|
function : "A'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tri-state inverter */
|
||||||
|
cell (tri_inv) {
|
||||||
|
area : 4;
|
||||||
|
pin(A) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(S) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(Z) {
|
||||||
|
direction : output;
|
||||||
|
function : "A'";
|
||||||
|
three_State : "S'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cell (buffer) {
|
||||||
|
area : 5;
|
||||||
|
pin(A) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(Y) {
|
||||||
|
direction : output;
|
||||||
|
function : "A";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2-input NAND gate */
|
||||||
|
cell (nand2) {
|
||||||
|
area : 3;
|
||||||
|
pin(A) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(B) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(Y) {
|
||||||
|
direction: output;
|
||||||
|
function : "(A * B)'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2-input NOR gate */
|
||||||
|
cell (nor2) {
|
||||||
|
area : 3;
|
||||||
|
pin(A) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(B) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(Y) {
|
||||||
|
direction: output;
|
||||||
|
function : "(A + B)'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2-input XOR */
|
||||||
|
cell (xor2) {
|
||||||
|
area : 6;
|
||||||
|
pin(A) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(B) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(Y) {
|
||||||
|
direction: output;
|
||||||
|
function : "(A *B') + (A' * B)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2-input inverting MUX */
|
||||||
|
cell (imux2) {
|
||||||
|
area : 5;
|
||||||
|
pin(A) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(B) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(S) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(Y) {
|
||||||
|
direction: output;
|
||||||
|
function : "( (A * S) + (B * S') )'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* D-type flip-flop with asynchronous reset and preset */
|
||||||
|
cell (dff)
|
||||||
|
{
|
||||||
|
area : 6;
|
||||||
|
ff("IQ", "IQN") {
|
||||||
|
next_state : "D";
|
||||||
|
clocked_on : "CLK";
|
||||||
|
clear : "RESET";
|
||||||
|
preset : "PRESET";
|
||||||
|
clear_preset_var1 : L;
|
||||||
|
clear_preset_var2 : L;
|
||||||
|
}
|
||||||
|
pin(D) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(CLK) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(RESET) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(PRESET) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(Q) {
|
||||||
|
direction: output;
|
||||||
|
function : "IQ";
|
||||||
|
timing() {
|
||||||
|
timing_type : rising_edge;
|
||||||
|
intrinsic_rise : 65;
|
||||||
|
intrinsic_fall : 65;
|
||||||
|
rise_resistance : 0;
|
||||||
|
fall_resistance : 0;
|
||||||
|
related_pin : "CLK";
|
||||||
|
}
|
||||||
|
timing () {
|
||||||
|
timing_type : clear;
|
||||||
|
timing_sense : positive_unate;
|
||||||
|
intrinsic_fall : 75;
|
||||||
|
related_pin : "RESET";
|
||||||
|
}
|
||||||
|
timing () {
|
||||||
|
timing_type : preset;
|
||||||
|
timing_sense : negative_unate;
|
||||||
|
intrinsic_rise : 75;
|
||||||
|
related_pin : "PRESET";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pin(QN) {
|
||||||
|
direction: output;
|
||||||
|
function : "IQN";
|
||||||
|
timing() {
|
||||||
|
timing_type : rising_edge;
|
||||||
|
intrinsic_rise : 65;
|
||||||
|
intrinsic_fall : 65;
|
||||||
|
rise_resistance : 0;
|
||||||
|
fall_resistance : 0;
|
||||||
|
related_pin : "CLK";
|
||||||
|
}
|
||||||
|
timing () {
|
||||||
|
timing_type : preset;
|
||||||
|
timing_sense : negative_unate;
|
||||||
|
intrinsic_rise : 75;
|
||||||
|
related_pin : "RESET";
|
||||||
|
}
|
||||||
|
timing () {
|
||||||
|
timing_type : clear;
|
||||||
|
timing_sense : positive_unate;
|
||||||
|
intrinsic_fall : 75;
|
||||||
|
related_pin : "PRESET";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Latch */
|
||||||
|
cell(latch) {
|
||||||
|
area : 5;
|
||||||
|
latch ("IQ","IQN") {
|
||||||
|
enable : "G";
|
||||||
|
data_in : "D";
|
||||||
|
}
|
||||||
|
|
||||||
|
pin(D) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(G) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
|
||||||
|
pin(Q) {
|
||||||
|
direction : output;
|
||||||
|
function : "IQ";
|
||||||
|
internal_node : "Q";
|
||||||
|
|
||||||
|
timing() {
|
||||||
|
timing_type : rising_edge;
|
||||||
|
intrinsic_rise : 65;
|
||||||
|
intrinsic_fall : 65;
|
||||||
|
rise_resistance : 0;
|
||||||
|
fall_resistance : 0;
|
||||||
|
related_pin : "G";
|
||||||
|
}
|
||||||
|
|
||||||
|
timing() {
|
||||||
|
timing_sense : positive_unate;
|
||||||
|
intrinsic_rise : 65;
|
||||||
|
intrinsic_fall : 65;
|
||||||
|
rise_resistance : 0;
|
||||||
|
fall_resistance : 0;
|
||||||
|
related_pin : "D";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pin(QN) {
|
||||||
|
direction : output;
|
||||||
|
function : "IQN";
|
||||||
|
internal_node : "QN";
|
||||||
|
|
||||||
|
timing() {
|
||||||
|
timing_type : rising_edge;
|
||||||
|
intrinsic_rise : 65;
|
||||||
|
intrinsic_fall : 65;
|
||||||
|
rise_resistance : 0;
|
||||||
|
fall_resistance : 0;
|
||||||
|
related_pin : "G";
|
||||||
|
}
|
||||||
|
|
||||||
|
timing() {
|
||||||
|
timing_sense : negative_unate;
|
||||||
|
intrinsic_rise : 65;
|
||||||
|
intrinsic_fall : 65;
|
||||||
|
rise_resistance : 0;
|
||||||
|
fall_resistance : 0;
|
||||||
|
related_pin : "D";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 3 input AND-OR-INVERT gate */
|
||||||
|
cell (aoi211) {
|
||||||
|
area : 3;
|
||||||
|
pin(A) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(B) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(C) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(Y) {
|
||||||
|
direction: output;
|
||||||
|
function : "((A * B) + C)'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 3 input OR-AND-INVERT gate */
|
||||||
|
cell (oai211) {
|
||||||
|
area : 3;
|
||||||
|
pin(A) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(B) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(C) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(Y) {
|
||||||
|
direction: output;
|
||||||
|
function : "((A + B) * C)'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* half adder */
|
||||||
|
cell (halfadder) {
|
||||||
|
area : 5;
|
||||||
|
pin(A) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(B) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(C) {
|
||||||
|
direction : output;
|
||||||
|
function : "(A * B)";
|
||||||
|
}
|
||||||
|
pin(Y) {
|
||||||
|
direction: output;
|
||||||
|
function : "(A *B') + (A' * B)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* full adder */
|
||||||
|
cell (fulladder) {
|
||||||
|
area : 8;
|
||||||
|
pin(A) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(B) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(CI) {
|
||||||
|
direction : input;
|
||||||
|
}
|
||||||
|
pin(CO) {
|
||||||
|
direction : output;
|
||||||
|
function : "(((A * B)+(B * CI))+(CI * A))";
|
||||||
|
}
|
||||||
|
pin(Y) {
|
||||||
|
direction: output;
|
||||||
|
function : "((A^B)^CI)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* end */
|
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
for x in *.lib; do
|
||||||
|
echo "Running $x.."
|
||||||
|
echo "read_verilog small.v" > test.ys
|
||||||
|
echo "synth -top small" >> test.ys
|
||||||
|
echo "dfflibmap -liberty ${x}" >> test.ys
|
||||||
|
../../yosys -ql ${x%.lib}.log -s test.ys
|
||||||
|
done
|
|
@ -0,0 +1,72 @@
|
||||||
|
/********************************************/
|
||||||
|
/* */
|
||||||
|
/* Supergate cell library for Bench marking */
|
||||||
|
/* */
|
||||||
|
/* Symbiotic EDA GmbH / Moseley Instruments */
|
||||||
|
/* Niels A. Moseley */
|
||||||
|
/* */
|
||||||
|
/* Process: none */
|
||||||
|
/* */
|
||||||
|
/* Date : 24-03-2019 */
|
||||||
|
/* Version: 1.0 */
|
||||||
|
/* Version: 1.1 - Removed semicolons in */
|
||||||
|
/* full adder */
|
||||||
|
/* */
|
||||||
|
/********************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
semi colon is missing in full-adder specification
|
||||||
|
some TSMC liberty files are formatted this way..
|
||||||
|
*/
|
||||||
|
|
||||||
|
library(supergate) {
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* full adder */
|
||||||
|
cell (fulladder) {
|
||||||
|
area : 8
|
||||||
|
pin(A) {
|
||||||
|
direction : input
|
||||||
|
}
|
||||||
|
pin(B) {
|
||||||
|
direction : input
|
||||||
|
}
|
||||||
|
pin(CI) {
|
||||||
|
direction : input
|
||||||
|
}
|
||||||
|
pin(CO) {
|
||||||
|
direction : output
|
||||||
|
function : "(((A * B)+(B * CI))+(CI * A))"
|
||||||
|
}
|
||||||
|
pin(Y) {
|
||||||
|
direction: output
|
||||||
|
function : "((A^B)^CI)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* end */
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
/** small, meaningless design to test loading of liberty files */
|
||||||
|
|
||||||
|
module small
|
||||||
|
(
|
||||||
|
input clk,
|
||||||
|
output reg[7:0] count
|
||||||
|
);
|
||||||
|
|
||||||
|
initial count = 0;
|
||||||
|
|
||||||
|
always @ (posedge clk)
|
||||||
|
begin
|
||||||
|
count <= count + 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
Loading…
Reference in New Issue