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

Signal update timing and simulation of programmable logic #36

Open
AndreasAlbert opened this issue Apr 16, 2021 · 4 comments
Open

Signal update timing and simulation of programmable logic #36

AndreasAlbert opened this issue Apr 16, 2021 · 4 comments

Comments

@AndreasAlbert
Copy link

Hi,

I'm looking into dspatch as a framework for emulating the behavior of programmable logic on an FPGA. dspatch looks perfect, except for a timing issue I cannot resolve. For example, let's talk about a simple serial circuit of three components:

 ------       ------        -----
|   A  | --> |   B  |  --> |  C  |
 ------       ------        -----

In a realistic FPGA environment with a common clock, B would only be able to process the output of A one clock tick after A produced it, rather than instantly (for most operations, anyway). Similarly, C would have a delay of one tick to B and two ticks to A, etc. From a quick review of the code, it seems to me that such delays are not included in dspatch. Instead, the tick methods of A, B and C are all called on the first clock tick and a signal can propagate from left to right in a single tick. Is that a correct summary?

I considered handling this delay explicitly inside each component, but it seems to me that this is not possible for more complex circuits without rewriting the way Circuit ticks.

@MarcusTomlinson
Copy link
Member

You’re summary is correct, yes.

I considered handling this delay explicitly inside each component, but it seems to me that this is not possible for more complex circuits without rewriting the way Circuit ticks.

This would be my first suggestion. Essentially, in each component’s Process_(), set the output(s) from the result(s) of the previous Process_().

Do you have an example of a complex circuit where this wouldn’t work?

@AndreasAlbert
Copy link
Author

Thanks for getting back to me so quickly!

I am specifically thinking about a circular dependence like this one:

---------------        -------------
| FIFO         |      | CONSUMER    |
| output: data | ---> | input: data |
| input: pop   | <--- | output: pop |
----------------       -------------

If I add an internal delay as we discuss above, it basically boils down to structuring the Process_ method in each of the components like this:

void Process_(SignalBus const & inputs, SignalBus& outputs){
    // Update output bus based on whatever we calculated last tick
    propagate(outputs);

    // Execute the actual logic of this component,
    // output goes into the internal buffer, 
    // will be propagated next tick
    logic(inputs);
}

Now I think I run into trouble with execution order, because I am forcing the two steps to be executed directly after each other for a given component.
The circuit ticks will end up doing more or less this (pseudocode):

for(auto component: components) {
    component.propagate();
    component.logic();
}

When in reality, I would need this:

    for(auto component: components) {
        component.propagate();
    }
    for(auto component: components) {
        component.logic();
    }

@AndreasAlbert
Copy link
Author

One way around this dilemma would be to call propagate only on even ticks and logic on odd ticks. That would make sure that correct ordering is conserved. Only hurdle is that it requires signal states to be persistent between ticks. Currently, the signals are being cleared here, here and possibly elsewhere. @MarcusTomlinson would you be open to having this behavior made configurable? Being able to disable the automatic clearing should suffice.

@MarcusTomlinson
Copy link
Member

@MarcusTomlinson would you be open to having this behavior made configurable? Being able to disable the automatic clearing should suffice.

Sure, sounds fair. Could you PR this?

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

No branches or pull requests

2 participants