-
Notifications
You must be signed in to change notification settings - Fork 75
Simulator upgrades for rohme compatibility (registering now and cancelling) #468
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
Conversation
Rohd needs three kinds of callback: 1. Post to a future time ( Timer( SimDuration(...) , callback ) 2. Post to the next delta ( Timer( SimDuration.zero , callback ) 3. Post to "end of this delta" ( scheduleMicrotask ) Statistically speaking, (1) and (2) are common while (3) is rare. As a result of (2), one time slot may have many delta cycles. Each time slot looks like this: delta 0: - { callbacks originally scheduled for this time slot} - { microtasks scheduled by callbacks in delta 0} delta 1: - { zero time callbacks scheduled in delta 0} - { micro tasks scheduled by callbacks in delta 1 } ... delta n: - { time zero callbacks scheduled by delta n-1 } - { microtasks scheduled in this delta n } The timeslot finishes when there have been no zero delay ( type (2) ) callbacks posted. The following Rohme code uses type (2) zero time delays: await Future.delayed( SimDuration.zero ); print('a'); await Future.delayed( SimDuration.zero ); print('b'); await Future.delayed( SimDuration.zero ); print('c'); Each call to Future.delayed( t ) above actually creates a Timer( current_time + t ). Conceptually, it is very similar to the following SV code: #0; $display("a"); #0; $display("b"); #0; $display("c"); These zero delays are used for example to create mutexs which are fair and deterministic. Mapping from Rohme to Rohd 1. posting to the future is mapped to registerAction( timestamp ) , where timestamps > Simulator.time - added a cancelAction( timestamp , action ) to support cancel ( and therefore suspend / resume ) 2. posting to the next delta is done using registerAction( Simulator.time ) - this creates another complete tickExecute at the current time 3. end of delta ( ie, microtask ) callbacks are mapped to injectAction
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good, thank you for your contribution!
These two issues might be related:
I tried a test like this and it passed: test('simulator reset immediately works ok', () async {
await Simulator.reset();
var actionTaken = false;
Simulator.registerAction(100, () => actionTaken = true);
await Simulator.run();
expect(actionTaken, equals(true));
await Simulator.reset();
}); What symptoms were you seeing? Would you have expected this test to fail? |
Ah ! It's quite likely I was just doing |
Ah I see, yes that might not work right. Fortunately, Dart lint rules can catch this.
I don't believe you can make a constructor |
Description & Motivation
The intention of these changes is to enable Rohme / Rohd interoperability by Layering Rohme on top of the Rohd simulator.
Rohd needs three kinds of callback:
Statistically speaking, (1) and (2) are common while (3) is rare.
As a result of (2), one time slot may have many delta cycles. Each time slot looks like this:
delta 0:
delta 1:
...
delta n:
The timeslot finishes when there have been no zero delay ( type (2) ) callbacks posted.
The following Rohme code uses type (2) zero time delays:
Each call to Future.delayed( t ) above actually creates a Timer( current_time + t ).
Conceptually, it is very similar to the following SV code:
These zero delays are used for example to create mutexs which are fair and deterministic.
Mapping from Rohme to Rohd
Testing
All existing Rohd tests pass as previously. A few new tests have been added in test/simulator_test.dart.
Backwards-compatibility
Given that all current tests pass, there should be no backward compatibility issues.
Documentation
The small number of changes to the Simulator class have been documented inline.
Further Work
Package Organisation
For Rohme to use the Rohd simulator, it has to pull in the entire Rohd package. It would be easier for Rohme if the Rohd simulator was split out into its own package. We could also consider putting the Rohme simulator in this shared package. An external simulator might be useful for other packages which want to share the underlying timing with Rohme and Rohd.
Incremental execution
A feature of the Rohme simulator is that it can run for some time and then run again for a little more time. This might be useful in the future tool integrations where the simulator needs to be started and stopped. It isn't obvious if this feature is supported, or whether it is viable in Rohd ( since there are end-of-simulation events etc ).
Time zero reset
I ran a few experiments with doing Simulator.reset() before running a simulation. It seems that Simulator.reset() only works after a simulation has been run ( eg in a teardown method ). The reason I would like to run it before the simulation runs is that the Rohme simulator is an actual class with a constuctor, so it would be nice to put the reset in the constructor rather than a teardown method. That way a single test.dart can instantiate many Rohme simulators as it moves though the different tests. This might be as simple as doing nothing if a simulation has never been run. Alternatively, we could introduce a 'hasBeenRun' getter into the Rohd simulator so that Rohme could check for it before attempting to call Simulator.reset().