amaranth icon indicating copy to clipboard operation
amaranth copied to clipboard

[RFC] add pre-run simulation hook for cli.main

Open github-4o opened this issue 4 years ago • 1 comments

as far as i can tell, current simulation cli-based workflow for a module is the following: module.py:

main(m, ...)

which gives control to cli.py: https://github.com/nmigen/nmigen/blob/746886ca8ac3b9a8941b540a347452805acbbcf2/nmigen/cli.py#L68-L73 which sets up the simulation environment this (again as far as could see) implies that one needs to have a separate python module that is to be invoked for simulation of module.py. codegen for a module.py is invoked as module.py generate ..., while sim for module.py is invoked as some_module.py simulate ...

suggested solution: pre-run simulation hook defined in module.py, invoked by simulate option in cli.main

  • pros: unified cli interface for both simulation and codegenration via the module.py cli arguments
  • cons: module code bloating as a module will have both hdl-relaed code and testbench-related code in a single file. this may be a problem as testbench code tends to be times larger then uut

github-4o avatar Feb 01 '21 14:02 github-4o

For me, the fact that a single files contains all (code + test) was, among other things, a plus when exploring alternatives to VHDL/Verilog. However it is true that I am at a stage where codesize is very modest.

For the little bits of code I could write, coverage and simulation code seems to require setting up a top module. One could imagine to write a Test/Simulation/Whatever Suite that would look like (disclaimer, heavily inspired by JUnit) :

# imports
from ...

class mySuiteOfStuff:

    @formalVerification
    def shouldVerifyThis(context:VerificationContext): # at least a top module to setup assert/covers etc...
        # update the context

    @formalVerification
    def shouldVerifyThat(c:VerificationContext): # for more concise writing ; and one can have disjointed sets of verifications
        # update the context
        # of course, a new context is regenerated between each call

    @simulation
    def simulateThisCase(context:SimulationContext): # at least a simulator instance and a Module to setup
        # update the context

    @simulation
    def simulateThatCase(c: SimulationContext): # again, several simulation can be defined
        # update the context

    @BeforeAllVerification
    def setupGlobalVerification(...): # did I say that I am heavily inspired by JUnit ?
        # return something ? or update a provided context ?

    @BeforeEachVerification
    def setupOneVerification(...): # remainder the function name is free, the decorator is there to spot the function of interest
        # return something ? or update a provided context ?

    @AfterEachVerification
    def tearDownOneVerification(...) : #....
        #etc...

    @AfterAllVerification
    def tearDownAllVerifications(...) : #...
        # etc...

    # And the same for simulation, but it's so long
    # @{Before|After}{All|Each}Simulation

### Launcher ###
if __name__ == "__main__":
    main(..., suite=mySuiteOfStuff)
    

sporniket avatar Apr 19 '22 12:04 sporniket

We have a more formal RFC process these days and this proposal would have to go through it to be accepted. In general, CLI improvements are desirable; I have a prototype for a new CLI in #904.

whitequark avatar Feb 09 '24 17:02 whitequark