diff --git a/include/circt/InitAllTranslations.h b/include/circt/InitAllTranslations.h index 314faa8b175e..1bf8b8db965f 100644 --- a/include/circt/InitAllTranslations.h +++ b/include/circt/InitAllTranslations.h @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "circt/Dialect/Arc/ModelInfoExport.h" +#include "circt/Dialect/BLIF/BLIFParser.h" #include "circt/Dialect/Calyx/CalyxEmitter.h" #include "circt/Dialect/ESI/ESIDialect.h" #include "circt/Dialect/FIRRTL/FIREmitter.h" @@ -32,6 +33,7 @@ namespace circt { inline void registerAllTranslations() { static bool initOnce = []() { arc::registerArcModelInfoTranslation(); + blif::registerFromBLIFFileTranslation(); calyx::registerToCalyxTranslation(); firrtl::registerFromFIRFileTranslation(); firrtl::registerToFIRFileTranslation(); diff --git a/lib/Dialect/BLIF/Import/BLIFLexer.cpp b/lib/Dialect/BLIF/Import/BLIFLexer.cpp index 03fda407a993..99f0ea108bb0 100644 --- a/lib/Dialect/BLIF/Import/BLIFLexer.cpp +++ b/lib/Dialect/BLIF/Import/BLIFLexer.cpp @@ -256,10 +256,6 @@ BLIFToken BLIFLexer::lexTokenImpl() { return lexFileInfo(tokStart); // Unknown character, emit an error. return emitError(tokStart, "unexpected character"); - case '%': - if (*curPtr == '[') - return lexInlineAnnotation(tokStart); - return emitError(tokStart, "unexpected character following '%'"); case '|': if (*curPtr == '}') return ++curPtr, formToken(BLIFToken::r_brace_bar, tokStart); diff --git a/lib/Dialect/BLIF/Import/BLIFParser.cpp b/lib/Dialect/BLIF/Import/BLIFParser.cpp index 951d15f1838e..823d0e3f882e 100644 --- a/lib/Dialect/BLIF/Import/BLIFParser.cpp +++ b/lib/Dialect/BLIF/Import/BLIFParser.cpp @@ -160,8 +160,8 @@ struct BLIFParser { ParseResult parseIdOrNil(StringRef &result, const Twine &message); ParseResult parseIdOrNil(StringAttr &result, const Twine &message); - ParseResult parseIdList(SmallVectorImpl &result, - const Twine &message); + ParseResult parseIdList(SmallVectorImpl &result, + const Twine &message, unsigned minCount = 0); private: BLIFParser(const BLIFParser &) = delete; @@ -239,6 +239,28 @@ ParseResult BLIFParser::parseId(StringAttr &result, const Twine &message) { return success(); } + ParseResult BLIFParser::parseIdList(SmallVectorImpl &result, + const Twine &message, unsigned minCount) { + while(true) { + switch (getToken().getKind()) { + // The most common case is an identifier. + case BLIFToken::identifier: + result.push_back(getTokenSpelling()); + consumeToken(); + if (minCount) + --minCount; + break; + default: + if (minCount) { + emitError(message); + return failure(); + } + return success(); + } + } +} + + //===----------------------------------------------------------------------===// // BLIFModelParser //===----------------------------------------------------------------------===// @@ -292,9 +314,9 @@ Value BLIFModelParser::getReferencedModel(SMLoc loc, StringRef modelName) { ParseResult BLIFModelParser::parseLogicGate() { auto startTok = consumeToken(BLIFToken::kw_names); auto loc = startTok.getLoc(); - SmallVector inputs; + SmallVector inputs; std::string output; - if (parseIdList(inputs, "expected input list")) + if (parseIdList(inputs, "expected input list", 1)) return failure(); output = inputs.back(); inputs.pop_back(); @@ -413,22 +435,22 @@ struct BLIFFileParser : public BLIFParser { ParseResult BLIFFileParser::parseModel() { StringAttr name; auto modLoc = getToken().getLoc(); - SmallVector inputs, outputs, clocks; + SmallVector inputs, outputs, clocks; consumeToken(BLIFToken::kw_model); if (parseId(name, "expected model name")) return failure(); while (getToken().isModelHeaderKeyword()) { switch (getToken().getKind()) { case BLIFToken::kw_inputs: - if (parseIdList(inputs, "expected input list")) + if (parseIdList(inputs, "expected input list", 1)) return failure(); break; case BLIFToken::kw_outputs: - if (parseIdList(outputs, "expected output list")) + if (parseIdList(outputs, "expected output list", 1)) return failure(); break; case BLIFToken::kw_clock: - if (parseIdList(clocks, "expected clock list")) + if (parseIdList(clocks, "expected clock list", 1)) return failure(); break; default: diff --git a/test/Dialect/BLIF/parse-basic.blif b/test/Dialect/BLIF/parse-basic.blif new file mode 100644 index 000000000000..10ba2ad8b81f --- /dev/null +++ b/test/Dialect/BLIF/parse-basic.blif @@ -0,0 +1,16 @@ +; RUN: circt-translate -import-blif -verify-diagnostics -split-input-file %s | circt-opt | FileCheck %s + +.model simple +.inputs a B +.outputs c +.names a b c +11 1 +.end + +;// ----- + +# unamed model +.names a b \ +c # test \ +11 1 + diff --git a/test/lit.cfg.py b/test/lit.cfg.py index 6ff8c38100cd..791317c1f457 100644 --- a/test/lit.cfg.py +++ b/test/lit.cfg.py @@ -22,7 +22,7 @@ config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell) # suffixes: A list of file extensions to treat as test files. -config.suffixes = ['.td', '.mlir', '.ll', '.fir', '.sv'] +config.suffixes = ['.td', '.mlir', '.ll', '.blif', '.fir', '.sv'] # test_source_root: The root path where tests are located. config.test_source_root = os.path.dirname(__file__)