From 2c7748aab31114f9dc52f5571623bc41c1ef11ed Mon Sep 17 00:00:00 2001 From: Alain Dargelas Date: Sat, 4 Nov 2023 21:14:37 -0700 Subject: [PATCH 1/2] Rewrite rule for for_loop --- templates/SynthSubset.cpp | 39 +++++++++++++++++++++++++++++++++++++++ templates/SynthSubset.h | 3 +++ 2 files changed, 42 insertions(+) diff --git a/templates/SynthSubset.cpp b/templates/SynthSubset.cpp index 470baa99..2b2126ed 100644 --- a/templates/SynthSubset.cpp +++ b/templates/SynthSubset.cpp @@ -352,4 +352,43 @@ bool SynthSubset::reportedParent(const any* object) { return false; } +void SynthSubset::leaveFor_stmt(const for_stmt* object, vpiHandle handle) { + if (const expr* cond = object->VpiCondition()) { + // Rewrite rule for Yosys (Cannot handle non-constant expression in for loop condition besides loop var) + // Transforms: + // for (int i=0; i<32 && found==0; i++) begin + // end + // Into: + // for (int i=0; i<32; i++) begin + // if (found==0) break; + // end + // + + if (cond->UhdmType() == uhdmoperation) { + operation* topOp = (operation*) cond; + if (topOp->VpiOpType() == vpiLogAndOp) { + VectorOfany* operands = topOp->Operands(); + // Assumes lhs is comprator over loop var + // rhs is any expression + any* lhs = operands->at(0); + any* rhs = operands->at(1); + ((for_stmt*)object)->VpiCondition((expr*)lhs); + + if (const any* stmt = object->VpiStmt()) { + if (stmt->UhdmType() == uhdmbegin) { + begin* st = (begin*) stmt; + VectorOfany* stlist = st->Stmts(); + if_stmt* ifstmt = serializer_->MakeIf_stmt(); + stlist->insert(stlist->begin(), ifstmt); + ifstmt->VpiCondition((expr*)rhs); + break_stmt* brk = serializer_->MakeBreak_stmt(); + ifstmt->VpiStmt(brk); + } + } + } + } + } +} + + } // namespace UHDM diff --git a/templates/SynthSubset.h b/templates/SynthSubset.h index ea0fa01e..376fe4b5 100644 --- a/templates/SynthSubset.h +++ b/templates/SynthSubset.h @@ -59,6 +59,9 @@ class SynthSubset final : public VpiListener { void leaveClass_var(const class_var* object, vpiHandle handle) override; + // Apply some rewrite rule for Yosys limitations + void leaveFor_stmt(const for_stmt* object, vpiHandle handle) override; + void reportError(const any* object); void mark(const any* object); bool reportedParent(const any* object); From 8442bc5008a2c2223ca4de24598124ad513eea97 Mon Sep 17 00:00:00 2001 From: Alain Dargelas Date: Sat, 4 Nov 2023 21:24:13 -0700 Subject: [PATCH 2/2] Rewrite rule for for_loop --- templates/SynthSubset.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/templates/SynthSubset.cpp b/templates/SynthSubset.cpp index 2b2126ed..02c70013 100644 --- a/templates/SynthSubset.cpp +++ b/templates/SynthSubset.cpp @@ -373,11 +373,16 @@ void SynthSubset::leaveFor_stmt(const for_stmt* object, vpiHandle handle) { any* lhs = operands->at(0); any* rhs = operands->at(1); ((for_stmt*)object)->VpiCondition((expr*)lhs); - + VectorOfany* stlist = nullptr; if (const any* stmt = object->VpiStmt()) { if (stmt->UhdmType() == uhdmbegin) { begin* st = (begin*) stmt; - VectorOfany* stlist = st->Stmts(); + stlist = st->Stmts(); + } else if (stmt->UhdmType() == uhdmnamed_begin) { + named_begin* st = (named_begin*) stmt; + stlist = st->Stmts(); + } + if (stlist) { if_stmt* ifstmt = serializer_->MakeIf_stmt(); stlist->insert(stlist->begin(), ifstmt); ifstmt->VpiCondition((expr*)rhs);