Skip to content

Commit

Permalink
a wild modelop appears
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrew Lenharth committed Dec 31, 2024
1 parent dd2888a commit 5a60636
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 33 deletions.
11 changes: 10 additions & 1 deletion include/circt/Dialect/BLIF/BLIFOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,19 @@ def ModelOp : BLIFOp<"model", [IsolatedFromAbove, RegionKindInterface, SingleBlo
}];

let arguments = (ins SymbolNameAttr:$sym_name,
TypeAttrOf<ModuleType>:$module_type);
TypeAttrOf<ModuleType>:$module_type,
APIntAttr:$clocks);
let results = (outs);
let regions = (region SizedRegion<1>:$body);

let builders = [
OpBuilder<(ins "StringRef":$name,
"ArrayRef<StringRef>":$inputs,
"ArrayRef<StringRef>":$outputs,
"ArrayRef<StringRef>":$clocks)>
];


let extraClassDeclaration = [{
static mlir::RegionKind getRegionKind(unsigned index) {
return mlir::RegionKind::Graph;
Expand Down
2 changes: 2 additions & 0 deletions include/circt/InitAllDialects.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include "circt/Dialect/AIG/AIGDialect.h"
#include "circt/Dialect/Arc/ArcDialect.h"
#include "circt/Dialect/BLIF/BLIFDialect.h"
#include "circt/Dialect/Calyx/CalyxDialect.h"
#include "circt/Dialect/Comb/CombDialect.h"
#include "circt/Dialect/DC/DCDialect.h"
Expand Down Expand Up @@ -58,6 +59,7 @@ inline void registerAllDialects(mlir::DialectRegistry &registry) {
registry.insert<
aig::AIGDialect,
arc::ArcDialect,
blif::BLIFDialect,
calyx::CalyxDialect,
chirrtl::CHIRRTLDialect,
comb::CombDialect,
Expand Down
35 changes: 35 additions & 0 deletions lib/Dialect/BLIF/BLIFOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,41 @@
using namespace circt;
using namespace blif;

void ModelOp::build(mlir::OpBuilder &odsBuilder, mlir::OperationState &odsState,
StringRef name, ArrayRef<StringRef> inputs,
ArrayRef<StringRef> outputs, ArrayRef<StringRef> clocks) {
SmallVector<hw::ModulePort> modulePorts;
auto I1 = odsBuilder.getIntegerType(1);
auto uLoc = odsBuilder.getUnknownLoc();
auto *r = odsState.addRegion();
Block *b = new Block();
r->push_back(b);

for (auto input : inputs) {
modulePorts.push_back(
{odsBuilder.getStringAttr(input), I1, hw::ModulePort::Input});
b->addArgument(I1, uLoc);
}
for (auto output : outputs)
modulePorts.push_back(
{odsBuilder.getStringAttr(output), I1, hw::ModulePort::Output});
for (auto clock : clocks) {
modulePorts.push_back(
{odsBuilder.getStringAttr(clock), I1, hw::ModulePort::Input});
b->addArgument(I1, uLoc);
}
auto moduleType = hw::ModuleType::get(odsBuilder.getContext(), modulePorts);
APInt clockVec(inputs.size() + outputs.size() + clocks.size(), 0);
for (size_t i = inputs.size() + outputs.size();
i < inputs.size() + outputs.size() + clocks.size(); i++)
clockVec.setBit(i);
auto clockAttr = odsBuilder.getIntegerAttr(
odsBuilder.getIntegerType(clockVec.getBitWidth()), clockVec);
odsState.addAttribute("sym_name", odsBuilder.getStringAttr(name));
odsState.addAttribute("module_type", TypeAttr::get(moduleType));
odsState.addAttribute("clocks", clockAttr);
}

namespace mlir {
LogicalResult
convertFromAttribute(SmallVectorImpl<int8_t> &storage, Attribute attr,
Expand Down
36 changes: 29 additions & 7 deletions lib/Dialect/BLIF/Import/BLIFLexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,13 +214,8 @@ BLIFToken BLIFLexer::lexTokenImpl() {
// Handle whitespace.
continue;

case '`':
case '_':
// Handle identifiers.
return lexIdentifierOrKeyword(tokStart);

case '.':
return formToken(BLIFToken::period, tokStart);
return lexPeriodOrKeyword(tokStart);
case ',':
return formToken(BLIFToken::comma, tokStart);
case ':':
Expand Down Expand Up @@ -262,7 +257,7 @@ BLIFToken BLIFLexer::lexTokenImpl() {
// Unknown character, emit an error.
return emitError(tokStart, "unexpected character");

case ';':
case '#':
skipComment();
continue;

Expand Down Expand Up @@ -319,6 +314,33 @@ BLIFToken BLIFLexer::lexFileInfo(const char *tokStart) {
}
}

/// Lex a period or a keyword that starts with a period.
///
/// Period ::= '.'
///
BLIFToken BLIFLexer::lexPeriodOrKeyword(const char *tokStart) {

// Match the rest of the identifier regex: [a-zA-Z_$-]*
while (llvm::isAlpha(*curPtr) || llvm::isDigit(*curPtr) || *curPtr == '_' ||
*curPtr == '$' || *curPtr == '-')
++curPtr;

StringRef spelling(tokStart, curPtr - tokStart);

// See if the identifier is a keyword. By default, it is a period.
BLIFToken::Kind kind = llvm::StringSwitch<BLIFToken::Kind>(spelling)
#define TOK_KEYWORD_DOT(SPELLING) .Case("." #SPELLING, BLIFToken::kw_##SPELLING)
#include "BLIFTokenKinds.def"
.Default(BLIFToken::period);
if (kind != BLIFToken::period) {
++curPtr;
return formToken(kind, tokStart);
}

// Otherwise, this is a period.
return formToken(BLIFToken::period, tokStart);
}

/// Lex an identifier or keyword that starts with a letter.
///
/// LegalStartChar ::= [a-zA-Z_]
Expand Down
3 changes: 2 additions & 1 deletion lib/Dialect/BLIF/Import/BLIFLexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class BLIFToken {
bool isKeyword() const;

bool isModelHeaderKeyword() const {
return true; // isAny(kw_inputs, kw_outputs, kw_names, kw_latch, kw_end);
return isAny(kw_inputs, kw_outputs, kw_clock);
}

/// Given a token containing a string literal, return its value, including
Expand Down Expand Up @@ -134,6 +134,7 @@ class BLIFLexer {
BLIFToken lexNumber(const char *tokStart);
void skipComment();
BLIFToken lexString(const char *tokStart, bool isVerbatim);
BLIFToken lexPeriodOrKeyword(const char *tokStart);

const llvm::SourceMgr &sourceMgr;
const mlir::StringAttr bufferNameIdentifier;
Expand Down
48 changes: 29 additions & 19 deletions lib/Dialect/BLIF/Import/BLIFParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,28 +239,27 @@ ParseResult BLIFParser::parseId(StringAttr &result, const Twine &message) {
return success();
}

ParseResult BLIFParser::parseIdList(SmallVectorImpl<StringRef> &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)
ParseResult BLIFParser::parseIdList(SmallVectorImpl<StringRef> &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();
break;
default:
if (minCount) {
emitError(message);
return failure();
}
return success();
}
return success();
}
}
}


//===----------------------------------------------------------------------===//
// BLIFModelParser
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -418,14 +417,18 @@ namespace {
/// This class implements the parser, namely models
struct BLIFFileParser : public BLIFParser {
explicit BLIFFileParser(BLIFLexer &lexer, ModuleOp mlirModule)
: BLIFParser(mlirModule.getContext(), lexer), mlirModule(mlirModule) {}
: BLIFParser(mlirModule.getContext(), lexer), mlirModule(mlirModule),
builder(UnknownLoc::get(getContext()), getContext()) {
builder.setInsertionPointToStart(mlirModule.getBody());
}

ParseResult parseFile();

private:
ParseResult parseModel();

ModuleOp mlirModule;
ImplicitLocOpBuilder builder;
};

} // end anonymous namespace
Expand All @@ -442,22 +445,29 @@ ParseResult BLIFFileParser::parseModel() {
while (getToken().isModelHeaderKeyword()) {
switch (getToken().getKind()) {
case BLIFToken::kw_inputs:
consumeToken(BLIFToken::kw_inputs);
if (parseIdList(inputs, "expected input list", 1))
return failure();
break;
case BLIFToken::kw_outputs:
consumeToken(BLIFToken::kw_outputs);
if (parseIdList(outputs, "expected output list", 1))
return failure();
break;
case BLIFToken::kw_clock:
consumeToken(BLIFToken::kw_clock);
if (parseIdList(clocks, "expected clock list", 1))
return failure();
break;
default:
return emitError("unexpected token in model header");
break;
}
}
// Create the model
auto m = builder.create<ModelOp>(name, inputs, outputs, clocks);
OpBuilder::InsertionGuard guard(builder);
builder.setInsertionPointToEnd(&m.getBody().back());
builder.create<OutputOp>(ValueRange());

if (/*parseModelBody() ||*/ parseToken(BLIFToken::kw_end, "expected .end"))
return failure();
Expand Down
2 changes: 1 addition & 1 deletion lib/Dialect/BLIF/Import/BLIFTokenKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#if !defined(TOK_MARKER) && !defined(TOK_IDENTIFIER) && \
!defined(TOK_LITERAL) && !defined(TOK_PUNCTUATION) && \
!defined(TOK_KEYWORD) && !defined(TOK_LPKEYWORD) && \
!defined(TOK_LPKEYWORD_PRIM)
!defined(TOK_KEYWORD_DOT)
#error Must define one of the TOK_ macros.
#endif

Expand Down
8 changes: 4 additions & 4 deletions test/Dialect/BLIF/parse-basic.blif
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
; RUN: circt-translate -import-blif -verify-diagnostics -split-input-file %s | circt-opt | FileCheck %s
# 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
#.names a b c
#11 1
.end

;// -----
#// -----

# unamed model
.names a b \
Expand Down

0 comments on commit 5a60636

Please sign in to comment.