Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support NBAs to arrays inside loops #5092

Merged
merged 1 commit into from
May 3, 2024

Conversation

gezalore
Copy link
Member

@gezalore gezalore commented May 1, 2024

--- Patch 3 of 3 towards supporting NBAs to arrays inside loops. ---

Depends on #5091

For NBAs that might execute a dynamic number of times in a single
evaluation (specifically: those that assign to array elements inside
loops), we introduce a new run-time VlNBACommitQueue data-structure
(currently a vector), which stores all pending updates and the necessary
info to reconstruct the LHS reference of the AstAssignDly at run-time.

All variables needing a commit queue has their corresponding unique
commit queue.

All NBAs to a variable that requires a commit queue go through the
commit queue. This is necessary to preserve update order in sequential
code, e.g.:
a[7] <= 10
for (int i = 1 ; i < 10; ++i) a[i] <= i;
a[2] <= 10
needs to end with array elements 1..9 being 1, 10, 3, 4, 5, 6, 7, 8, 9.

This enables supporting common forms of NBAs to arrays on the left hand
side of <= in non-suspendable/non-fork code. (Suspendable/fork
implementation is unclear to me so I left it unchanged, see #5084).

Any NBA that does not need a commit queue (i.e.: those that were
supported before), use the same scheme as before, and this patch should
have no effect on the generated code for those NBAs.

@gezalore
Copy link
Member Author

gezalore commented May 1, 2024

@wsnyder could you please review #5090, #5091, #5092 (this), either individually or as a whole, whichever is convenient.

@gezalore gezalore changed the title Delay support loop array nbas Support NBAs to arrays inside loops May 1, 2024
@gezalore gezalore force-pushed the delay-support-loop-array-nbas branch 3 times, most recently from 940380d to 579e4fe Compare May 1, 2024 23:24
Copy link
Member

@wsnyder wsnyder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I worry about the include templates. Templates can do nasty things to compile time. Can Verilator instead do some of this?

Have you thought how this would be extended to more complicated types, e.g. array of queues of arrays of structs?

test_regress/t/t_nba_commit_queue.v Outdated Show resolved Hide resolved
test_regress/t/t_order_blkloopinit_bad.out Show resolved Hide resolved
include/verilated_types.h Outdated Show resolved Hide resolved
src/V3AstNodeDType.h Outdated Show resolved Hide resolved
src/V3Delayed.cpp Outdated Show resolved Hide resolved
src/V3Delayed.cpp Outdated Show resolved Hide resolved
include/verilated_types.h Outdated Show resolved Hide resolved
include/verilated_types.h Outdated Show resolved Hide resolved
Comment on lines 1632 to 1633
VL_ATTR_ALWINLINE static typename std::enable_if<!IsVlWide<T_Elem>::value, T_Elem>::type
bAnd(const T_Elem& a, const T_Elem& b) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be in VlWide?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The commit template needs to be well formed for both wide a non-wide, so if you put it in VlWide, you need to add it as operator&/operartor|/operator~, but I don't think we want those operators available on VlWide as they are prone to abuse.

@gezalore
Copy link
Member Author

gezalore commented May 2, 2024

I worry about the include templates. Templates can do nasty things to compile time.

If you don't instantiate them, it should cost very little, especially with PCH.

Can Verilator instead do some of this?

I removed the type traits from VlUnpacked and passed the extra derived info to the VlNBACommitQueue template directly. This means the only time the C++ compiler will
need to instantiate a new template is when a commit queue is actually required (i.e.:
it should never happen in code that compiled before, only in new code this enables).

As for eliminating the templates completely, yes, Verilator in theory could code
generate these, but we are missing several internal functions, including representation,
which I don't want to invent at this point (see below).

Have you thought how this would be extended to more complicated types, e.g. array of queues of arrays of structs?

Yes, the general scheme is that you generate a closure, and enqueue that to the commit queue,
which when invoked applies the delayed update to the target data-structure:

struct NBAClosureX {
    // Pointer to closure code
    void (*fptr)(NBAClosureX*, TargetVarType*);
    // RHS value to apply
    DataType rhs;
    // Capture all members requried to perform the update,
    // e.g. array indices, selLSB/selWidth, etc.
    size_t indices[Rank];
    size_t selLsb;
    size_t selWidth;
    // Whatever else 'fptr' needs
}

void NBAClosureX_code(NBAClosureX* ctxp, TargetVarType* targetp) {
    // Generate code here that applies the update captured in 'ctxp' to 'targetp'
    reconstructLhs(ctxp) = ctxp->rhs;
}

An NBA is then lowered into this:

void Vfoo__eval_blah(Vfoo*vlSelf) {
    // At site of NBA
    NBAClosureX* ctxp = new NBAClosureX;
    ctxp->fptr = NBAClosureX_code;
    //
    ctxp->rhs = RHSOfTheNBA;
    // Populate the captured variables to 'ctxp'
    ctxp->indices[0] = ... // this is VdlyDim0 today
    ctxp->indices[1] = ... // this is VdlyDim1 today
    ctxp->selLhb = ... // this is 
    // etc.
    VdlyCommitQueue__targetVar.enqueue(ctxp);


    // In the 'post' block
    VdlyCommitQueue__targetVar.commit(targetVar);
}

And of course 'commit' is just:

void VdlyCommitQueue__targetVar::commit(TargetVarType* targetp) {
    for (NBAClosureX* ctxp : m_pending) ctxp->fptrp(ctxp, targetp);
    m_pending.clear();
}

Needless to say, that is a lot of work that is not necessary to support the common synthesisable/RTL case of memories (which is the case this patch enables).

@gezalore gezalore force-pushed the delay-support-loop-array-nbas branch 2 times, most recently from 8b56988 to cf55b6d Compare May 2, 2024 10:39
@gezalore
Copy link
Member Author

gezalore commented May 2, 2024

Done as requested. Please take another look.

docs/guide/warnings.rst Outdated Show resolved Hide resolved
test_regress/t/t_nba_commit_queue.v Outdated Show resolved Hide resolved
include/verilated_types.h Outdated Show resolved Hide resolved
src/V3Delayed.cpp Show resolved Hide resolved
src/V3Delayed.cpp Outdated Show resolved Hide resolved
For NBAs that might execute a dynamic number of times in a single
evaluation (specifically: those that assign to array elements inside
loops), we introduce a new run-time VlNBACommitQueue data-structure
(currently a vector), which stores all pending updates and the necessary
info to reconstruct the LHS reference of the AstAssignDly at run-time.

All variables needing a commit queue has their corresponding unique
commit queue.

All NBAs to a variable that requires a commit queue go through the
commit queue. This is necessary to preserve update order in sequential
code, e.g.:
 a[7] <= 10
 for (int i = 1 ; i < 10; ++i) a[i] <= i;
 a[2] <= 10
needs to end with array elements 1..9 being 1, 10, 3, 4, 5, 6, 7, 8, 9.

This enables supporting common forms of NBAs to arrays on the left hand
side of <= in non-suspendable/non-fork code. (Suspendable/fork
implementation is unclear to me so I left it unchanged, see verilator#5084).

Any NBA that does not need a commit queue (i.e.: those that were
supported before), use the same scheme as before, and this patch should
have no effect on the generated code for those NBAs.
@gezalore gezalore force-pushed the delay-support-loop-array-nbas branch from 3dfc78a to f15eda2 Compare May 3, 2024 09:31
@gezalore
Copy link
Member Author

gezalore commented May 3, 2024

Good to go if you are happy with it.

@wsnyder wsnyder merged commit 80b08b7 into verilator:master May 3, 2024
46 checks passed
@gezalore gezalore deleted the delay-support-loop-array-nbas branch May 3, 2024 12:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants