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

back+cli: Add FIRRTL, json and dot backends. Add ability to use them with cli.main #469

Closed
wants to merge 4 commits into from

Conversation

pbsds
Copy link

@pbsds pbsds commented Aug 8, 2020

All of these backends enable you to inspect your design more easily, by using netlistsvg, diagrammer and graphviz.

I did try to expand ExamplesTestCase for some coverage on these backends, but it seems like write_firrtl in yosys is unable to create the memory defined in examples/mem.py. Therefore I left the tests out of this PR for now.

…o enable reuse

This change enables adding more yosys backends
This allows us to visualize designs using diagrammer
This allows us to visualize designs using netlistsvg
This allows us to visualize designs with yosys + dot
@whitequark
Copy link
Member

Are you adding these backends with some specific application in mind? They significantly expand our public API (with all the resulting commitment to support), and I don't think this is appropriate at this time; I'd like to help you find a different approach to achieve your goals.

@pbsds
Copy link
Author

pbsds commented Aug 9, 2020

Fair criticism. I made this PR to avoid littering yosys scripts everywhere. My end goal is a live updating graph of the module.

Would a PR which makes cli.main extendable through plugins be of interest instead?

@whitequark
Copy link
Member

I made this PR to avoid littering yosys scripts everywhere. My end goal is a live updating graph of the module.

Sure, I'd like to help you achieve that in a way that would work well with nMigen's approach to API stability. Can you tell me more about the way you're using nMigen and Yosys in your project?

Would a PR which makes cli.main extendable through plugins be of interest instead?

The current design of cli.main is, frankly, largely a mistake (I wrote it so I can say that...) so I'm not that fond of any extensions that further tie us towards it.

@pbsds
Copy link
Author

pbsds commented Aug 9, 2020

I do like the idea of supplying a main function to use with nmigen. I've been drafting a new nMain as i've been exploring the different guides for nmigen, which i intend to add to nmigen at some point.

my current idea draft
class MyModule(Elaboratable):
    def __init__(self, param: int):
        self.param = param
        self.out = Signal()
    ...

# the largest issue is the lack of a consistent cli interface to expect from a given file
if __name__ == "__main__":
    top = MyModule(param=4) # warning: MustUse

    if sys.argv[1] = "build":
        if sys.argv[2] = "icebreaker":
            plat = ICEBreakerPlatform()
            plat.add_resources(...)

        elif sys.argv[2] = "fomu"
            plat = FomuHackerPlatform()
            plat.add_resources(...)

        # `do_program` is usually hard-coded.
        # The folder "build" should also be configurable
        plat.build(top, do_program=True)

    elif sys.argv[1] == "test": # "simulate" already taken in main
        # logic for multiple simulations to select from is manually made
        sim = Simulator(top)

        def my_proc():
            yield ...
        sim.add_sync_process(my_proc)

        with sim.write_vcd("uart.vcd", "uart.gtkw"): # hardcoded filenames, never printed to user
            sim.run()

    else:
        main(top, ports=[ top.out ]) # '-h' doesn't mention the two modes defined above




# === can become: ===




class MyModule(Elaboratable):
    def __init__(self, param):
        self.param = param
        self.out = Signal()
    ...

if __name__ == "__main__":
    platforms, simulations = [], []

    # supporting multiple platforms encourages designing the
    # top-level module in a platform agnostic way

    @platforms.append
    def icebreaker(): # function.__name__ is used by the cli interface in nMain
        plat = ICEBreakerPlatform()
        plat.add_resources(...)
        return plat

    @platforms.append
    def fomu():
        plat = FomuHackerPlatform()
        plat.add_resources(...)
        return plat

    @simulations.append
    def sim_the_foo(sim): # sim = Simulator(design)
        sim.add_clock(1e-6)

        @sim.add_sync_process
        def my_proc():
            yield ...
        # sim could then be automatically run, with configurable filenames

    nMain(
        name = "blinker", # current default is "top", perhaps use design().__class__.__name__ ?
        design = lambda: MyModule(param=4), # avoid MustUse warnings
        ports = lambda x: [ x.out ], # optional, platform.request is a thing
        platforms = platforms, # optional
        simulations = simulations, # optional
    )

When i feel it's ready i could make an issue/PR about it. If you have some ideas i can take into account, that would be great.

Can you tell me more about the way you're using nMigen and Yosys in your project?

I'm very much a beginner with hardware, and therefore I've been having fun with all the points of friction with learning vivado, yosys, chisel3 and nmigen. Therefore i'm currently looking into how to structure a nmigen project.
I've also been playing around with reducing the visual noise of the nmigen dsl, although the ends does not really justify the means in that one.

@pbsds pbsds closed this Aug 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants