myhdl-list Mailing List for MyHDL (Page 60)
Brought to you by:
jandecaluwe
You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(14) |
Nov
(4) |
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(1) |
Feb
(10) |
Mar
(19) |
Apr
(14) |
May
(1) |
Jun
(4) |
Jul
(10) |
Aug
|
Sep
(2) |
Oct
(7) |
Nov
(17) |
Dec
(12) |
2005 |
Jan
(6) |
Feb
(10) |
Mar
(17) |
Apr
(10) |
May
(9) |
Jun
(5) |
Jul
(26) |
Aug
(34) |
Sep
(10) |
Oct
(38) |
Nov
(71) |
Dec
(74) |
2006 |
Jan
(20) |
Feb
(20) |
Mar
(7) |
Apr
(2) |
May
(13) |
Jun
|
Jul
|
Aug
(4) |
Sep
(37) |
Oct
(43) |
Nov
(30) |
Dec
(33) |
2007 |
Jan
(3) |
Feb
|
Mar
|
Apr
|
May
(30) |
Jun
(9) |
Jul
(1) |
Aug
|
Sep
(8) |
Oct
(13) |
Nov
|
Dec
(4) |
2008 |
Jan
(13) |
Feb
(46) |
Mar
(25) |
Apr
(7) |
May
(20) |
Jun
(73) |
Jul
(38) |
Aug
(47) |
Sep
(24) |
Oct
(18) |
Nov
(9) |
Dec
(36) |
2009 |
Jan
(31) |
Feb
(24) |
Mar
(73) |
Apr
(13) |
May
(47) |
Jun
(28) |
Jul
(36) |
Aug
(2) |
Sep
(5) |
Oct
(8) |
Nov
(16) |
Dec
(29) |
2010 |
Jan
(34) |
Feb
(18) |
Mar
(18) |
Apr
(5) |
May
|
Jun
(24) |
Jul
(53) |
Aug
(3) |
Sep
(18) |
Oct
(33) |
Nov
(19) |
Dec
(15) |
2011 |
Jan
(9) |
Feb
(4) |
Mar
(39) |
Apr
(213) |
May
(86) |
Jun
(46) |
Jul
(22) |
Aug
(11) |
Sep
(78) |
Oct
(59) |
Nov
(38) |
Dec
(24) |
2012 |
Jan
(9) |
Feb
(22) |
Mar
(89) |
Apr
(55) |
May
(222) |
Jun
(86) |
Jul
(57) |
Aug
(32) |
Sep
(49) |
Oct
(69) |
Nov
(12) |
Dec
(35) |
2013 |
Jan
(67) |
Feb
(39) |
Mar
(18) |
Apr
(42) |
May
(79) |
Jun
(1) |
Jul
(19) |
Aug
(18) |
Sep
(54) |
Oct
(79) |
Nov
(9) |
Dec
(26) |
2014 |
Jan
(30) |
Feb
(44) |
Mar
(26) |
Apr
(11) |
May
(39) |
Jun
(1) |
Jul
(89) |
Aug
(15) |
Sep
(7) |
Oct
(6) |
Nov
(20) |
Dec
(27) |
2015 |
Jan
(107) |
Feb
(106) |
Mar
(130) |
Apr
(90) |
May
(147) |
Jun
(28) |
Jul
(53) |
Aug
(16) |
Sep
(23) |
Oct
(7) |
Nov
|
Dec
(16) |
2016 |
Jan
(86) |
Feb
(41) |
Mar
(38) |
Apr
(31) |
May
(37) |
Jun
(11) |
Jul
(1) |
Aug
(1) |
Sep
(3) |
Oct
(1) |
Nov
(5) |
Dec
(3) |
2017 |
Jan
|
Feb
(4) |
Mar
(2) |
Apr
(2) |
May
|
Jun
(3) |
Jul
(2) |
Aug
(2) |
Sep
(1) |
Oct
(2) |
Nov
(1) |
Dec
(1) |
2018 |
Jan
(1) |
Feb
(1) |
Mar
(7) |
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2019 |
Jan
(1) |
Feb
|
Mar
(2) |
Apr
(1) |
May
(1) |
Jun
(2) |
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
(3) |
Dec
|
2020 |
Jan
(1) |
Feb
(2) |
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
(1) |
Aug
(1) |
Sep
(1) |
Oct
|
Nov
|
Dec
(3) |
2021 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
(12) |
Dec
(11) |
2022 |
Jan
(7) |
Feb
(2) |
Mar
(1) |
Apr
|
May
|
Jun
(1) |
Jul
(3) |
Aug
(2) |
Sep
(1) |
Oct
|
Nov
|
Dec
(1) |
2023 |
Jan
|
Feb
(1) |
Mar
(1) |
Apr
(3) |
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
(1) |
2024 |
Jan
(1) |
Feb
(2) |
Mar
(4) |
Apr
(2) |
May
(2) |
Jun
(1) |
Jul
|
Aug
(1) |
Sep
(1) |
Oct
|
Nov
|
Dec
(2) |
2025 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Jan D. <ja...@ja...> - 2013-10-02 18:52:58
|
On 10/02/2013 08:12 PM, David Holl wrote: > And on the topic: in contrast to Jan's clever use of user-supplied > code to satiate his needs of hierarchy generation, this partitioning > code does not require the IMHO more significant changes that are > required to pull off his hierarchy scheme. > > (What takes more effort? Injecting an "@partition(...)" / "with > partition(...):"? Or declaring func.verilog_code = """something or > other goes here""" with the requisite top-module convertibility? The > ...verilog_code="""...""" syntax is also "a significant, > non-functional change to the source code" which also provide ample > room for abuse by IP blocks.) The user-defined code option likely takes more effort. And it is indeed also a non-functional code change. The big difference is this: it is trivial to implement it as an optimization *add-on* while keeping the general case intact. Just define the func.verilog_code under parameter control. If not defined, the general case applies. And of course, you can define it differently for different parameters. The vision behind this is the following. Start with the general case, e.g. a description of a specific memory structure. If required, add an optimization for a specific target as an *add-on*, e.g. an implementation for xilinx, altera ... but keep the general case e.g. for an asic. Now you have target-independent code with target-specific optimizations included all in the same code base. Jan -- Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com Python as a HDL: http://www.myhdl.org VHDL development, the modern way: http://www.sigasi.com World-class digital design: http://www.easics.com |
From: Keerthan jai.c <jck...@gm...> - 2013-10-02 18:16:48
|
Name conversion is pretty straight forward (obj.attr -> obj_attr, unless obj_attr already exists as a port). Users who don't like this can simply not use the feature. I don't think this feature should be disabled. I don't think its unreasonable to expect users of advanced features to be aware of some of the implementation details. Making the intf dict available to users as an attribute in the conversion object will greatly simplify cosimulations, without resorting to hacks to prevent unnecessary repetition. Consider writing a test bench for the Mux example in the manual: def test_mux(cosim=False): a, b, z = [Signal(intbv(0)[8:]) for i in range(3)] sel = Signal(intbv(0)[1:]) if cosim: toVerilog(mux, z, a, b, sel) os.system('iverilog -o mux.o mux.v tb_mux.v') dut = Cosimulation('vvp -m ./myhdl.vpi mux.o', z=z, a=a, b=b, sel=sel) #proposed method #dut = Cosimulation('vvp -m ./myhdl.vpi mux.o', **toVerilog.intf) else: dut = mux(z, a, b, sel) @instance def stim(): for i in range(8): a.next, b.next, sel.next = [randrange(i) for i in (8, 8, 2)] yield delay(10) if sel == 1: expected = a else: expected = b assert z == expected Simulation(dut, stim).run() On Wed, Oct 2, 2013 at 12:35 PM, Christopher Felton <chr...@gm...>wrote: > On 10/1/2013 6:12 PM, Keerthan jai.c wrote: > > Conversion of interfaces in the top level makes the arguments for > > cosimulation tricky. > > I think one option to simplify this is to store intf as an attribute in > the > > toVerilog and toVHDL objects. > > You can then pass **toVerilog.intf as the second argument to > Cosimulation. > > > > > > I never thought top-level interface conversion was reasonable. > From my perspective it makes things difficult because, now as > a user you have to know the conversion details (e.g. how the > names are expanded). > > My opinion, is that top-level interfaces conversion should > not be supported. I guess, it would be nice to flag and throw > a nice error message? > > Regards, > Chris > > > > ------------------------------------------------------------------------------ > October Webinars: Code for Performance > Free Intel webinars can help you accelerate application performance. > Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most > from > the latest Intel processors and coprocessors. See abstracts and register > > http://pubads.g.doubleclick.net/gampad/clk?id=60134791&iu=/4140/ostg.clktrk > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > -- have a nice day -jck |
From: David H. <da...@ad...> - 2013-10-02 18:13:10
|
On Wed, Oct 2, 2013 at 11:39 AM, Christopher Felton <chr...@gm...> wrote: > <snip> > That is fair and it is great that folks are experimenting > and presenting ideas! > > But you did solicit feedback: Yep. :) > There was an old thread regarding MEP 110, but I've come up with an > > alternative "solution", and I'm looking for your comments. (call it MEP > > 110-alt?) > > It is a little odd to back track? The idea of preserving > hierarchy has been around awhile, this is a good topic to > debate, bounce around ideas, and see if some form should > be part of myhdl or kept as separate tools. > > I noticed this debate going on for a while, but I hadn't seen a solution that I liked. [such as not requiring top-level convertibility...] So, rather than re-hash all the debate that's gone on before, I cited the most recent [though several months old] email as a way to "tip my hat" to the history, before volunteering this new incarnation to the discussion. In my experience I have had no need for manual placement > or explicit hierarchy control in the lower level formats. > But I have been convinced by others (I can look up the old > threads if needed) that it should be considered. But I am > also under the opinion that the hierarchy conversion can be > a separate function outside the actual conversion. Yep, I kept my changes as minimal as possible in MyHDL's conversion process, and only divert the final stage that actually starts writing to the file. Aside from the file writing, the most relevant code changes merely relay any user-specified tags [for prospective myhdl "extensions"] to the final output code. This relayed data (under ._extData) is never co-mingled or affects conversion. Then during output file writing, I still invoke MyHDL's native routines such as _convertGens(...) wherever appropriate. <snip> You have design hierarchy, it is flattened, and then the tools can organize > arrange as needed. The question seems to be if there needs > to be some sort of steering(?) and where how that should > exist? Exactly. So here, I provide two options for user-directed steering. One is "with ...", and the other is a decorator that may be applied at a [python] module level. I leave it open to debate on what's "better" -- with vs decorator. I don't know what's better. But as MyHDL stands right now, I [previously] had no way to _quickly_ test if hierarchical output could help or not. I might be wrong but I think the current PaR tools will > let you combine "logic" into a placement based on the > behavioral block labels. I would have to spend some time researching it but I think you can tell the placement tool > "place [list of labels] together". > If that is the case, then we'd just need a [friendly?] way to automatically extract the final generated labels of each component. Perhaps the _toVerilog.__call__ function could return a dictionary that map's id(...)'s of @instance's (such as @always & friends) to the final generated names. (Then leave it up to the caller on whatever project-specific requirements they need to fulfill.) Also, it would be great to include in that dict the id(...)'s of all _Signal's as well, to resolve their ._name (or .name for memories... ugh). I haven't experienced MyHDL to predictably preserve consistent naming of my Signals. [ And it gets old quickly to manually update my Xilinx constraints[.ucf] when a reg gets renamed in MyHDL's output. But maybe this is just induced my usage patterns, and either I should submit bug reports or repent from my deviant ways. :) ] On Wed, Oct 2, 2013 at 11:46 AM, Christopher Felton <chr...@gm...>wrote: > > On 10/02/2013 03:53 PM, David Holl wrote: > >> <snip> > >> > >> The only change required to group a set of logic into a partition is to > add: > >> > >> with partition('a_name'): > >> # put your usual logic here ... > > > > I really don't like this. Because, if I include this > in a *block* (IP) in a design. And someone reuses the > block for a different design, it breaks the modularity > of the IP. The designer trying to reuse the block has > to modify the source. In what way is modularity broken? [I'm looking for honest technical details.] I attempted to preserve modularity in that, even if some inner IP block defined a partition (without user knowledge?), it is guaranteed to be contained in a unique Verilog module and never be accidentally merged with other logic, even if the IP block and another partition share the same name. In the worst case, the patch appends _ or _# to guaranteed uniqueness -- and even in that case, the higher-level partitions get first dibs on unique names before nested partitions such as an IP core. --- yeah yeah, a trailing _ wouldn't be appropriate for VHDL, but that's easily fixed.) And, okay... it would be very impolite if some inner IP block employed (* *) Verilog attributes [enabled by this code] to embed vendor-specific junk for chip pin locations or other what not, when not necessary. But by the same argument, what is stopping an inner IP block from using user-defined Verilog or VHDL to achieve the same highly annoying effect? In both cases, I vote for twisting the IP developer's ear until they play nicely. ;) And on the topic: in contrast to Jan's clever use of user-supplied code to satiate his needs of hierarchy generation, this partitioning code does not require the IMHO more significant changes that are required to pull off his hierarchy scheme. (What takes more effort? Injecting an "@partition(...)" / "with partition(...):"? Or declaring func.verilog_code = """something or other goes here""" with the requisite top-module convertibility? The ...verilog_code="""...""" syntax is also "a significant, non-functional change to the source code" which also provide ample room for abuse by IP blocks.) > My opinion, if you need finer control than the design > hierarchy for partitioning it needs to be at a lower > level in the flow. Partitioning at the design module > level is reasonable. > By "module level", would this be acceptable? Changing this module from: def my_special_gizmo(clk, input_data_i, input_valid_i, input_ready_o, output_data_o, output_valid_o, output_ready_i): from myhdl import ... # ... return instances() by adding a decorator into: from myhdl import partition @partition("gizmo") def my_special_gizmo(clk, input_data_i, input_valid_i, input_ready_o, output_data_o, output_valid_o, output_ready_i): from myhdl import ... # ... return instances() in order to generate a partition automatically where it is instantiated? (I'm not sure I prefer the decorator over the "with..." syntax, but the offered code supports both.) > Regards, > Chris Cheers! - David |
From: Christopher F. <chr...@gm...> - 2013-10-02 16:36:00
|
On 10/1/2013 6:12 PM, Keerthan jai.c wrote: > Conversion of interfaces in the top level makes the arguments for > cosimulation tricky. > I think one option to simplify this is to store intf as an attribute in the > toVerilog and toVHDL objects. > You can then pass **toVerilog.intf as the second argument to Cosimulation. > > I never thought top-level interface conversion was reasonable. From my perspective it makes things difficult because, now as a user you have to know the conversion details (e.g. how the names are expanded). My opinion, is that top-level interfaces conversion should not be supported. I guess, it would be nice to flag and throw a nice error message? Regards, Chris |
From: Christopher F. <chr...@gm...> - 2013-10-02 15:47:04
|
On 10/2/2013 9:33 AM, Jan Decaluwe wrote: > On 10/02/2013 03:53 PM, David Holl wrote: >> On Wed, Oct 2, 2013 at 7:33 AM, Jan Decaluwe <ja...@ja... <mailto:ja...@ja...>> wrote: >> >> <snip> >> I am not discussing the concept now, but David's proposed method. >> Let's make this practical. If I understand David's solution, >> one would define a desired output partition by significant, >> non-functional changes to the source code. >> >> >> Nope, sorry but perhaps that is where the confusion lies. >> >> The only change required to group a set of logic into a partition is to add: >> >> with partition('a_name'): >> # put your usual logic here ... > I really don't like this. Because, if I include this in a *block* (IP) in a design. And someone reuses the block for a different design, it breaks the modularity of the IP. The designer trying to reuse the block has to modify the source. My opinion, if you need finer control than the design hierarchy for partitioning it needs to be at a lower level in the flow. Partitioning at the design module level is reasonable. Regards, Chris |
From: Christopher F. <chr...@gm...> - 2013-10-02 15:39:54
|
> >> Do you really want that? > > > I did. So, I created it, and I'm not forcing this patch on anyone. I > offered it in case anyone else finds it useful, just as I found myhdl > useful. > > - David > That is fair and it is great that folks are experimenting and presenting ideas! But you did solicit feedback: > There was an old thread regarding MEP 110, but I've come up with an > alternative "solution", and I'm looking for your comments. (call it MEP > 110-alt?) It is a little odd to back track? The idea of preserving hierarchy has been around awhile, this is a good topic to debate, bounce around ideas, and see if some form should be part of myhdl or kept as separate tools. In my experience I have had no need for manual placement or explicit hierarchy control in the lower level formats. But I have been convinced by others (I can look up the old threads if needed) that it should be considered. But I am also under the opinion that the hierarchy conversion can be a separate function outside the actual conversion. > Decoupling the design hierarchy from the physical hierarchy is exactly what > you want! (above quote from Per) This is what flat conversion gives you? Complete decoupling between design hierarchy and implementation. You have design hierarchy, it is flattened, and then the tools can organize arrange as needed. The question seems to be if there needs to be some sort of steering(?) and where how that should exist? I might be wrong but I think the current PaR tools will let you combine "logic" into a placement based on the behavioral block labels. I would have to spend some time researching it but I think you can tell the placement tool "place [list of labels] together". Regards, Chris Felton |
From: Jan D. <ja...@ja...> - 2013-10-02 14:47:54
|
On 10/02/2013 04:37 PM, Angel Ezquerra wrote: > On Wed, Oct 2, 2013 at 4:32 PM, Jan Decaluwe <ja...@ja...> wrote: >> On 10/02/2013 02:03 PM, Per Karlsson wrote: >>> That is not a problem, it's a feature! :) I'd much rather move around >>> a couple "whit:" than having to actually change the hierarchy. >> >> I don't see why those two options would be the only alternatives. >> >>> Decoupling the design hierarchy from the physical hierarchy is >>> exactly what you want! >> >> That's why physical hierarchy doesn't belong in the source code. > > Jan, > > I think that perhaps I don't understand exactly what you mean. When > you say that the physical hierarchy doesn't belong in the source code, > what is the alternative? If the alternative is to use scripts or some > other means to split your hierarchy, that is not something that I > would consider "outside of the source code". Is that what you mean or > did I misunderstand you? We were discussing design hierarchy versus physical hierarchy In that context, with "the source code" I meant the source code of the design, with the design hierarchy. -- Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com Python as a HDL: http://www.myhdl.org VHDL development, the modern way: http://www.sigasi.com World-class digital design: http://www.easics.com |
From: Angel E. <ang...@gm...> - 2013-10-02 14:38:21
|
On Wed, Oct 2, 2013 at 4:32 PM, Jan Decaluwe <ja...@ja...> wrote: > On 10/02/2013 02:03 PM, Per Karlsson wrote: >> That is not a problem, it's a feature! :) I'd much rather move around >> a couple "whit:" than having to actually change the hierarchy. > > I don't see why those two options would be the only alternatives. > >> Decoupling the design hierarchy from the physical hierarchy is >> exactly what you want! > > That's why physical hierarchy doesn't belong in the source code. Jan, I think that perhaps I don't understand exactly what you mean. When you say that the physical hierarchy doesn't belong in the source code, what is the alternative? If the alternative is to use scripts or some other means to split your hierarchy, that is not something that I would consider "outside of the source code". Is that what you mean or did I misunderstand you? Cheers, Angel |
From: Jan D. <ja...@ja...> - 2013-10-02 14:34:42
|
On 10/02/2013 03:53 PM, David Holl wrote: > On Wed, Oct 2, 2013 at 7:33 AM, Jan Decaluwe <ja...@ja... <mailto:ja...@ja...>> wrote: > > <snip> > I am not discussing the concept now, but David's proposed method. > Let's make this practical. If I understand David's solution, > one would define a desired output partition by significant, > non-functional changes to the source code. > > > Nope, sorry but perhaps that is where the confusion lies. > > The only change required to group a set of logic into a partition is to add: > > with partition('a_name'): > # put your usual logic here ... That is a significant, non-functional change to the source code. No confusion so far. -- Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com Python as a HDL: http://www.myhdl.org VHDL development, the modern way: http://www.sigasi.com World-class digital design: http://www.easics.com |
From: Jan D. <ja...@ja...> - 2013-10-02 14:33:09
|
On 10/02/2013 02:03 PM, Per Karlsson wrote: > That is not a problem, it's a feature! :) I'd much rather move around > a couple "whit:" than having to actually change the hierarchy. I don't see why those two options would be the only alternatives. > Decoupling the design hierarchy from the physical hierarchy is > exactly what you want! That's why physical hierarchy doesn't belong in the source code. -- Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com Python as a HDL: http://www.myhdl.org VHDL development, the modern way: http://www.sigasi.com World-class digital design: http://www.easics.com |
From: David H. <da...@ad...> - 2013-10-02 14:02:07
|
OK... I've refactored the patch and applied it against 0.9-dev in a forked repo: https://bitbucket.org/dholl/myhdl-partition I've consolidated the changes of existing myhdl infrastructure into as few places as possible -- just the minimum to support any conversion extensions (besides this one) --- and put them under a branch called "extension_hooks". Then off that branch, I have my main "partition" branch where the hooks are used to inject the functionality. hg clone https://bitbucket.org/dholl/myhdl-partition cd myhdl-partition hg checkout partition python setup.py build python setup.py install --user -O2 On Tue, Oct 1, 2013 at 11:54 PM, David Holl <da...@ad...> wrote: > dang it. scratch that initial impression where I thought the patch > applied on 0.9-dev. I was actually on the 0.8.1 precursor. damn hg vs > stupid git... (small differences between hg and git: I'm used to "git log" > showing me just the history of the branch I'm on. "hg log" shows the whole > log across branches... ok, so I'll need to read hg's driver's ed handbook > first.) > > > On Tue, Oct 1, 2013 at 11:55 AM, David Holl <da...@ad...> wrote: > >> tl;dr: My patch against 0.8 appears can be applied against the 0.9-dev >> repo, and it satisfies my very limited testing. >> >> The changes in 0.9-dev were not near my hack-n-slash campaign. (I kept >> most of my changes _after_ MyHDL's normal extraction and analysis >> algorithm, with only a few small hooks into signals and generators to >> assist with partition-tagging.) >> >> To test, I first removed the current myhdl-0.8 I had in my Python >> installation, then I followed these steps: >> >> # (I removed my current myhdl-0.8 from my Python installation.) >> hg clone https://bitbucket.org/jandecaluwe/myhdl >> cd myhdl >> gunzip -c ../myhdl-0.8-partitions.patch.gz | patch -p1 >> python setup.py build >> python setup.py install --user -O2 >> >> Then I reran my test_partition.py, and the output is identical. (except >> that the new myhdl is injecting some $signed(...) stuff in 1 place where >> I'm substracting...) >> >> I also reran my pcie designs (with partitions), and that also produced >> identical output. (but again with $signed(...) stuff but in 2 places where >> I'm subtracting...) >> >> >> To confirm I'm using the latest repo, here's the recent log entry: >> hg log | head -8 >> changeset: 1358:324a8d3206fb >> branch: 0.9-dev >> tag: tip >> parent: 1356:db95c2d47119 >> parent: 1357:8de9f8771395 >> user: Jan Decaluwe <ja...@ja...> >> date: Sun Sep 22 19:14:21 2013 +0200 >> summary: Bug fix merge from default >> >> >> And the patch applied fairly cleanly, with only 2 offset changes: >> gunzip -c ../myhdl-0.8-partitions.patch.gz | patch -p1 >> patching file myhdl/_Signal.py >> patching file myhdl/__init__.py >> patching file myhdl/_always.py >> patching file myhdl/_always_comb.py >> Hunk #1 succeeded at 190 (offset 10 lines). >> patching file myhdl/_always_seq.py >> patching file myhdl/_contextdecorator.py >> patching file myhdl/_extractHierarchy.py >> patching file myhdl/_instance.py >> patching file myhdl/_partition.py >> patching file myhdl/conversion/_analyze.py >> Hunk #5 succeeded at 865 (offset 5 lines). >> patching file myhdl/conversion/_toVerilog.py >> >> >> The rest of this email is a quick summary of my changes per file: >> >> __init__.py: include "partition" and "get_current_partition" in the myhdl >> namespace. get_current_partition() may be called from within a partition >> to assign attributes. >> >> For example, to assign attributes using the "with" syntax: >> >> with partition('A') as this_part: # This will be renamed to A0 >> this_part.attr_add('KEEP_HIERARCHY', 'TRUE') >> this_part.attr_add('DONT_TOUCH', 'TRUE') >> >> @always(clk.posedge) >> def clgd(): >> d.next = c + e >> >> And to assign attributes from inside a partition (such as when using the >> "decorator" syntax): >> >> @partition('AES') # <---- partition a la decorator. >> def my_module_bob(...): >> # ... >> this_part = get_current_partition() >> this_part.attr_add('DONT_TOUCH', 'TRUE') >> return instances() >> >> >> _Signal.py: Small change. I radio tag each signal with the current >> partition. (Actually, I originally didn't need to do this, until I tried >> figuring out where to place ConcatSignal drivers (ie, which partition to >> invoke their _toVerilog [or _toVHDL] method). In short, Iw as tired after >> devising the auto-magic placement for every other signal type, so I just >> gave up on auto-placement of ConcatSignals, and instead just use the tagged >> partition to indicate where to place each ConcatSignal's driver. (ie, For >> all other signals, it doesn't matter where you happen to declare them, >> since the output code will auto placed based on the location of any driving >> generator. But for ConcatSignal's, the output code will strictly place >> their driver inside whatever partition you happend to create the >> ConcatSignal in python.) >> >> >> _instance.py: Small change, to support any extension to "monkey patch" >> its way into tagging generators inheriting from _Instantiator. (Actually, >> I should've structured my change to _Signal.py like this one, to open the >> way for any future extensions to also "monkey patch" their way into >> _Signal's and shadow signals...) >> >> >> _always.py: _Always inherits from _Instantiator but does not invoke it's >> constructor. Therefore, I manually invoke the "hookInit" that I created >> inside _Instantiator. >> >> >> _always_comb.py: Same as _always.py. Manually invoke the "hookInit" >> that I created inside _Instantiator. >> >> >> _always_seq.py: Same as _always.py... >> >> >> _extractHierarchy.py: Tweak _HierExtr and _Instance to preserve hookData >> placed via hookInit from _Instantiator. I also tweaked _UserCode and >> _addUserCode to preserve hookData, but I haven't tried any user-defined >> Verilog (or VHDL) to test this. TODO: If anyone has user-defined code, try >> putting it in a partition (perhaps easiest via "with"), and tell me if it >> is placed in the correct Verilog module on output. >> >> >> _contextdecorator.py: New file, from >> http://pypi.python.org/pypi/contextdecorator to support both "with >> partition(...) ..." and "@partition(...)" mechanisms. >> >> >> _partition.py: New file, and is actually pretty short. It defines >> "partition" and "get_current_partition" API, and inject the partition tags >> in the relevant objects such as @always, @always_comb, @always_seq. >> >> >> conversion/_analyze.py: Preserve hookData in _analyzeGens. And >> in _AnalyzeVisitor, I added tree.inmems to mirror record keeping of >> tree.outmems, so that I can verify that memories are only read from the >> same partition in which they're driven. >> >> >> conversion/_toVerilog.py: Thar be dragons. Here is where I added >> toVerilog.partitioned_output, to invoke my alternative Verilog output code >> contained in _write_partitioned_output(...). TODO: I should >> move _write_partitioned_output and its supporting entourage to another >> file. (SigMapping, >> lookup_id, distill_signals_and_memories, _apply_renames, _generate_partitions, _partition2name, _make_unique_names) >> >> >> >> >> >> >> >> On Sun, Sep 29, 2013 at 8:25 PM, Keerthan jai.c <jck...@gm...>wrote: >> >>> David, >>> >>> Just a heads up, the 0.9 dev branch on bitbucket has quite a few changes >>> in the conversion area(MEP 107). You might want to check whether these >>> patches apply on the new branch. >>> >>> >>> On Sun, Sep 29, 2013 at 2:21 PM, David Holl <da...@ad...> wrote: >>> >>>> There was an old thread regarding MEP 110, but I've come up with an >>>> alternative "solution", and I'm looking for your comments. (call it MEP >>>> 110-alt?) >>>> >>>> tl;dr --- If you're interested, >>>> >>>> Introduction: Same as MEP 110. (Especially for floor planning...) >>>> ----------------------- >>>> Analysis: Same as MEP 110. (Yep, everything gets flattened by >>>> default...) >>>> ----------------------- >>>> Proposed Solution: (with implementation) >>>> >>>> I did not follow the proposed solution in MEP 110, because that >>>> would've required that I change [any of] my components to be "top-module >>>> convertible". (I'm using a form of signal containers --similar to MEP >>>> 107-- which which would've required many changes (in my code) to achieve >>>> "top-module convertibility".) >>>> >>>> What I did was I started from the flattened hierarchy in >>>> conversion/_toVerilog.py, but instead of calling the usual >>>> _writeSigDecls, _convertGens, I wrote my own convoluted output code: >>>> ... >>>> if self.partitioned_output: >>>> _write_partitioned_output(self.partitioned_output, >>>> vfile, vpath, self.timescale, h, intf, siglist, memlist, genlist, doc) >>>> else: >>>> _writeFileHeader(vfile, vpath, self.timescale) >>>> _writeModuleHeader(vfile, intf, doc) >>>> _writeSigDecls(vfile, intf, siglist, memlist) >>>> _convertGens(genlist, vfile) >>>> _writeModuleFooter(vfile) >>>> ... >>>> >>>> >>>> To activate this alternative output, just >>>> set toVerilog.partitioned_output=True: >>>> toVerilog.name='test_partition' >>>> toVerilog.partitioned_output=True # the default is False >>>> toVerilog(_test_top, clk, AAA, BBB, ZZZ, TTT, VVV) >>>> >>>> Without any other changes to a hardware description, this alternative >>>> code will produce identical, flattened output. (right down to the arbitrary >>>> ordering of signals and generators...) >>>> >>>> However, you may now group any related logic together, as needed. I >>>> call a group of logic a "partition", and these partitions may be nested. >>>> Instead of the word "partition" you could call it a "module" instead, >>>> since the concept is almost identical to Verilog module's. In the >>>> following description, it will appear that I'm flipping between "partition" >>>> and "module" when really, I'm describing how that partitions in python >>>> impact the created Verilog modules. (but for simplistic purposes, since I >>>> guarantee each "partition" will create a unique Verilog "module", feel free >>>> to call em' what you want...) >>>> >>>> There are 2 ways to assign related hardware into partitions. >>>> ----------------------- >>>> 1) The first is via python's "with" statement. I'll show a few >>>> examples: >>>> >>>> example 1.a) A simple partition... >>>> from myhdl import Signal, partition, ... >>>> >>>> @always(clk.posedge) >>>> def clgc(): >>>> c.next = a + b >>>> >>>> with partition('A'): >>>> @always(clk.posedge) >>>> def clgd(): >>>> d.next = c + e >>>> >>>> @always(clk.posedge) >>>> def clge(): >>>> e.next = a * b >>>> >>>> @always(clk.posedge) >>>> def clgf(): >>>> f.next = more stuff... >>>> >>>> >>>> What "partition" does is annotate all generators (and shadow >>>> signals...) with your text label. Then the "partitioned-output" code uses >>>> these annotations move related logic into a Verilog module, and instantiate >>>> that module from the top-level module. Module ports are automatically >>>> created for any signals that need to cross between modules. >>>> >>>> This code still creates only 1 output .v file containing all modules. >>>> (I didn't care if it was 1 file or multiple files, but for me, 1 file was >>>> "easier" to move/copy around in my opinion.) >>>> >>>> The top module will include all of the signals, except for "e" --- >>>> because in this code, e is only used within partition A. Therefore "e" >>>> will appear as a driven "reg" within a submodule called A. (and that >>>> submodule "A" is instantiated in the top level as "part_A"...) >>>> >>>> >>>> >>>> example 1.b) Partitions may be nested. >>>> >>>> @always(clk.posedge) >>>> def clgc(): >>>> c.next = a + b >>>> >>>> with partition('A'): >>>> @always(clk.posedge) >>>> def clgd(): >>>> d.next = c + e >>>> >>>> with partition('B'): >>>> @always(clk.posedge) >>>> def clge(): >>>> e.next = a * b >>>> >>>> @always(clk.posedge) >>>> def clgf(): >>>> f.next = more stuff... >>>> >>>> >>>> This code will create 3 modules total: the top module, a module called >>>> "A", and a module called "A_B". >>>> >>>> >>>> example 1.c) Partitions having the same name will be renamed to stay >>>> unique! >>>> >>>> If you want related code to be grouped into a partition, all of that >>>> code must be contained in the same python "with" block. For example: >>>> >>>> from myhdl import Signal, partition, ... >>>> >>>> @always(clk.posedge) >>>> def clgc(): >>>> c.next = a + b >>>> >>>> with partition('A'): # This will be renamed to A0 >>>> @always(clk.posedge) >>>> def clgd(): >>>> d.next = c + e >>>> >>>> with partition('A'): # This will be renamed to A1 >>>> @always(clk.posedge) >>>> def clge(): >>>> e.next = a * b >>>> >>>> >>>> Rationale: When you start nesting partitions, partition names are >>>> guaranteed to produce unique module instances and not accidentally group >>>> unrelated logic together. >>>> >>>> >>>> example 1.d) Partitions are nestable across your python function calls, >>>> and renaming will happen to keep sub >>>> >>>> For example, unrelated nested partitions may use the same name without >>>> fear of their logic being accidentally grouped together. >>>> >>>> from myhdl import Signal, partition, ... >>>> >>>> def my_module_alice(...): >>>> # ... >>>> with partition('SM'): >>>> # This happens to enclose a state machine. >>>> # The name SM isn't descriptive enough, but if you >>>> # want descriptive Verilog output, then you should >>>> # use descriptive names. >>>> # ... >>>> # ... >>>> return instances() >>>> >>>> def my_module_bob(...): >>>> # ... >>>> with partition('SM'):# This encloses an unrelated state machine. >>>> # ... >>>> # ... >>>> return instances() >>>> >>>> def top(...): >>>> @always(clk.posedge) >>>> def clgc(): >>>> c.next = a + b >>>> >>>> with partition('CRYPTO'): >>>> alice_inst = alice(...) >>>> bob0_inst = bob(...) >>>> bob1_inst = bob(...) >>>> >>>> with partition('CRYPTO_SM2'): >>>> # I made this CRYPTO_SM2 name, just to be a jerk. >>>> @always(clk.posedge) >>>> def clgd(): >>>> d.next = c + e >>>> >>>> >>>> This code would produce 6 instantiated modules in the generated Verilog >>>> output: >>>> module top(...); >>>> module CRYPTO(...); >>>> module CRYPTO_SM0(...); // this is from alice_inst >>>> module CRYPTO_SM1(...); // this is from bob0_inst >>>> module CRYPTO_SM2(...); // this is from bob1_inst >>>> module CRYPTO_SM2_(...); // renamed CRYPTO_SM2 to not conflict with >>>> CRYPT_SM2 from bob1_inst >>>> >>>> Admittedly, the generated names CRYPTO_SM... in this example aren't >>>> very clear, but the point here is that your python functions (like alice() >>>> and bob()) have a guaranteed means to group logic into a Verilog module >>>> without accidental commingling of unrelated from other modules. >>>> >>>> The "top" module instantates "CRYPTO" and "CRYPTO_SM2_". Then "CRYPTO" >>>> instantiates "CRYPTO_SM0", "CRYPTO_SM1", and "CRYPTO_SM2". >>>> >>>> >>>> example 1.e) Partitions support Verilog 2001 attributes (and if >>>> someone wants to add VHDL support...) >>>> >>>> with partition('A') as this_part: # This will be renamed to A0 >>>> this_part.attr_add('KEEP_HIERARCHY', 'TRUE') >>>> this_part.attr_add('DONT_TOUCH', 'TRUE') >>>> >>>> @always(clk.posedge) >>>> def clgd(): >>>> d.next = c + e >>>> >>>> This will produce output that instantiates module A as: >>>> >>>> (* KEEP_HIERARCHY="TRUE", DONT_TOUCH="TRUE" *) part_A A(clk, c, e, d); >>>> >>>> // The generated module for instance A is called "part_A". >>>> >>>> (MyHDL also has a nifty feature to include doc strings as embedded >>>> comments. I have some back-end support for attaching a string to a >>>> partition, to be output as a comment in the code, but I haven't turned it >>>> on yet.) >>>> >>>> ----------------------- >>>> 2) The second way to group logic into a partition is with a python >>>> decorator. >>>> >>>> example 2) Using decorators in addition to "with" blocks. >>>> >>>> The decorator syntax uses the same rules as the with-blocks. (All >>>> partitions will be unique, and possibly suffixed with a number to maintain >>>> uniqueness in the Verilog code. Partitions may be nested. Use descriptive >>>> names if you want descriptive output.) >>>> >>>> Here, I'll intermix the decorator and with syntax: >>>> >>>> def my_module_alice(...): >>>> # ... >>>> with partition('SM'): >>>> # This happens to enclose a state machine. >>>> # The name SM isn't descriptive enough, but if you >>>> # want descriptive Verilog output, then you should >>>> # use descriptive names. >>>> # ... >>>> # ... >>>> return instances() >>>> >>>> @partition('AES') # <---- partition a la decorator. >>>> def my_module_bob(...): >>>> # ... >>>> with partition('SM'):# This encloses an unrelated state machine. >>>> # ... >>>> # ... >>>> return instances() >>>> >>>> def top(...): >>>> @always(clk.posedge) >>>> def clgc(): >>>> c.next = a + b >>>> >>>> with partition('CRYPTO'): >>>> alice_inst = alice(...) >>>> bob0_inst = bob(...) >>>> bob1_inst = bob(...) >>>> >>>> with partition('CRYPTO_SM2'): >>>> # I made this CRYPTO_SM2 name, just to be a jerk. >>>> @always(clk.posedge) >>>> def clgd(): >>>> d.next = c + e >>>> >>>> The above code will generate ~8 modules: >>>> module top(...); >>>> module CRYPTO(...); >>>> module CRYPTO_SM(...); // this is from alice_inst >>>> module CRYPTO_AES0(...); // decorator on bob() >>>> module CRYPTO_AES0_SM(...); // this is from bob0_inst >>>> module CRYPTO_AES1(...); // decorator on bob() >>>> module CRYPTO_AES1_SM(...); // this is from bob1_inst >>>> module CRYPTO_SM2(...); // renamed CRYPTO_SM2 to not conflict with >>>> CRYPT.SM from bob1_inst >>>> >>>> >>>> ----------------------- END OF EXAMPLES >>>> >>>> Limitations: I hope there aren't any. I put enough care to accomodate >>>> ConcatSignal's, _SliceSignal's, const [undriven] _Signal's, etc... And if >>>> a signal gets pushed into a sub-partition where it is both driven and read, >>>> as well as output from that sub-partition, the generator will automatically >>>> make a separate wire just for the output port, that is driven from your >>>> signal. (This prevents "Output port is read internally..." warnings for >>>> partition-generated modules. I don't do this for the top-level though, to >>>> preserve the same interface as current MyHDL output.) >>>> >>>> Component Conversion: No additional restrictions beyond that of MyHDL. >>>> There is still the same requirement on your top-level to be "top-level >>>> convertible", but there is flexibility for your lower levels. >>>> >>>> Component Parameters: What parameters? All of your parameters were >>>> already digested by python+MyHDL magic, and I'm operating on the flattened >>>> hierarchy. If you invoke the same sub-partition (sub-module) multiple >>>> times, it will be replicated in the output, but every time it appears, it >>>> will use the globally-unique signal names that MyHDL has already assigned. >>>> (ie, I don't change your signal names.) >>>> >>>> Any drawbacks: >>>> This may/will produce larger output code than the proposed solution in >>>> MEP 110. The existing MEP 110 solution will create 1 copy of each module, >>>> and instantiate it multiple times (as long as each instantiation shares the >>>> same port signal widths, etc...). In contrast, this "110.alt" solution >>>> will create a whole copy of a module every time it is instantiated. (But >>>> each copy inherits the unique signal names assigned by MyHDL's flattening >>>> algorithm.) However, the larger output size from this "110.alt" isn't that >>>> much larger than MyHDL's native flat output. (depending on your signal >>>> usage...) >>>> >>>> Benefits: >>>> You can have hierarchical output with minimal changes to your code, >>>> and you control exactly how your logic is partitioned into the hierarchy. >>>> Just sprinkle a few @partition(...) or "with partition(...):" statements >>>> wherever you need in your design. >>>> >>>> Known pitfalls: I have not tried or tested TristateSignal's for >>>> "inout" ports, and I've only tested on a very narrow subset of MyHDL's >>>> feature set. (I was was already bitten by ConcatSignal's, _SliceSignal's, >>>> and lists of signals accidentally being inferred as memories... However, I >>>> expect these areas to work as expected now.) >>>> >>>> >>>> But if anyone is interested, here's the code, and I'm open for feedback. >>>> >>>> I attached patches against myhdl-0.8.tar.gz available from >>>> https://sourceforge.net/projects/myhdl/files/myhdl/0.8/ >>>> >>>> Of the 2 patches, myhdl-0.8-fix_modbv.patch is my poor-man's fix for >>>> modbv, because I needed modbv. This patch is most likely obsoleted by >>>> Jan's real fix in the repo. >>>> >>>> The other patch (myhdl-0.8-partitions.patch) contains my crude first >>>> draft supporting the described hierarchy. Yes, this code is ugly. Don't >>>> look at it yet. It is a quick mock-up of some functionality I really >>>> wanted. But give it a try if you're interested and let me know what it >>>> breaks on... Or if you really want to dive into the code, feel free to do >>>> so. >>>> >>>> On my systems, I apply & install these patches as follows: (gunzip the >>>> .patch files first) >>>> >>>> gunzip myhdl-0.8-fix_modbv.patch.gz >>>> gunzip myhdl-0.8-partitions.patch.gz >>>> tar zxf myhdl-0.8.tar.gz \ >>>> && cd myhdl-0.8 \ >>>> && patch -p1 < ../myhdl-0.8-fix_modbv.patch \ >>>> && patch -p1 < ../myhdl-0.8-partitions.patch \ >>>> && python setup.py build \ >>>> && python setup.py install --user -O2 \ >>>> && cd .. \ >>>> && rm -rf myhdl-0.8 >>>> >>>> This installs myhdl into python's standard location for my home >>>> directory, but feel free to leave off --user to install to the main system >>>> path, or wherever else you want. >>>> >>>> To test drive the functionality, try running test_partition.py. Set >>>> toVerilog.partitioned_output=False >>>> to see the normal output, and >>>> toVerilog.partitioned_output=True >>>> to see the partitioned output. And if you are curious, try >>>> toVerilog.partitioned_output="I promise I will never die." >>>> to enable the partitioned output code, but tell it to ignore the >>>> partition annotations. >>>> >>>> >>>> (typos and all, I'm hitting send...) >>>> >>>> - David >>>> >>>> >>>> >>>> On Wed, May 1, 2013 at 6:44 PM, Oscar Daniel Diaz <osc...@gm...>wrote: >>>> >>>>> El Wed, 01 May 2013 10:55:55 +0200 >>>>> Jan Decaluwe <ja...@ja...> escribió: >>>>> >>>>> > On 04/29/2013 05:25 PM, Oscar Daniel Diaz wrote: >>>>> > >>>>> > > Given that the converter is called recursively several times, >>>>> > > multiple files are generated and its contents are used for >>>>> component >>>>> > > declaration (VHDL). Recursive calls must avoid file replication >>>>> (for >>>>> > > VHDL case means avoid multiple package file generation). This is >>>>> > > done by keeping generated code in memory before pushing to files. >>>>> > > >>>>> > > Attribute "no_component_files" : >>>>> > > * False : all components code is saved to disk as soon as >>>>> > > possible. >>>>> > > * True : discard components code, only save top-module file. >>>>> > >>>>> > Not sure what is meant here exactly. Why would we need component >>>>> > declarations, as opposed to simply using direct instantation? >>>>> > For a case like this, this seems much simpler and less verbose >>>>> > to me. >>>>> >>>>> Since keep hierarchy conversion requires multiple files to generate >>>>> (top-module and components to instantiate), this flag prevents >>>>> generation of those components. Suppose you make some changes only in >>>>> the top-module, this flag allows to only generate top-module file. >>>>> >>>>> When I change from VHDL '87 syntax (doing recursive calls to get >>>>> component declaration) to '93 syntax, that flag would prevent >>>>> those recursive calls. >>>>> >>>>> -- >>>>> Oscar Díaz >>>>> Key Fingerprint = 904B 306C C3C2 7487 650B BFAC EDA2 B702 90E9 9964 >>>>> gpg --keyserver subkeys.pgp.net --recv-keys 90E99964 >>>>> >>>>> >>>>> _______________________________________________ >>>>> myhdl-list mailing list >>>>> myh...@li... >>>>> https://lists.sourceforge.net/lists/listinfo/myhdl-list >>>>> >>>>> >>>> >>>> >>>> ------------------------------------------------------------------------------ >>>> October Webinars: Code for Performance >>>> Free Intel webinars can help you accelerate application performance. >>>> Explore tips for MPI, OpenMP, advanced profiling, and more. Get the >>>> most from >>>> the latest Intel processors and coprocessors. See abstracts and >>>> register > >>>> >>>> http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk >>>> >>>> _______________________________________________ >>>> myhdl-list mailing list >>>> myh...@li... >>>> https://lists.sourceforge.net/lists/listinfo/myhdl-list >>>> >>>> >>> >>> >>> -- >>> have a nice day >>> -jck >>> >>> >>> ------------------------------------------------------------------------------ >>> October Webinars: Code for Performance >>> Free Intel webinars can help you accelerate application performance. >>> Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most >>> from >>> the latest Intel processors and coprocessors. See abstracts and register >>> > >>> >>> http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk >>> _______________________________________________ >>> myhdl-list mailing list >>> myh...@li... >>> https://lists.sourceforge.net/lists/listinfo/myhdl-list >>> >>> >> > |
From: David H. <da...@ad...> - 2013-10-02 13:53:40
|
On Wed, Oct 2, 2013 at 7:33 AM, Jan Decaluwe <ja...@ja...> wrote: > <snip> > I am not discussing the concept now, but David's proposed method. > Let's make this practical. If I understand David's solution, > one would define a desired output partition by significant, > non-functional changes to the source code. > Nope, sorry but perhaps that is where the confusion lies. The only change required to group a set of logic into a partition is to add: with partition('a_name'): # put your usual logic here ... Suppose someone does this for his requirements, and later you > inherit that IP block. Now suppose you need a different kind of > partitioning - your only option would be to make significant, > non-functional changes (hopefully) to the source code. > If I decide I don't like how my partitioning came out, then I move around 1 or 2 "with ..." statements, and I don't spend time sorting out port declarations and other banal book keeping. (But I will glance at the output to verify the resulting port declarations are sane.) As Per pointed out, this provides a "decoupling the design hierarchy from the physical hierarchy". > Do you really want that? I did. So, I created it, and I'm not forcing this patch on anyone. I offered it in case anyone else finds it useful, just as I found myhdl useful. - David |
From: Per K. <bas...@gm...> - 2013-10-02 12:04:03
|
That is not a problem, it's a feature! :) I'd much rather move around a couple "whit:" than having to actually change the hierarchy. Decoupling the design hierarchy from the physical hierarchy is exactly what you want! As for replicating the entire hierarchy, that may actually be a problem. I've ran into tools that can't handle more than a certain depth (I wish I could remember which one), and MyHDL lends itself nicely to creating hardware recursively thus exploding the levels of hierarchy. On Wed, Oct 2, 2013 at 1:33 PM, Jan Decaluwe <ja...@ja...> wrote: [:] > Suppose someone does this for his requirements, and later you > inherit that IP block. Now suppose you need a different kind of > partitioning - your only option would be to make significant, > non-functional changes (hopefully) to the source code. > > Do you really want that? > > -- > Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com > Python as a HDL: http://www.myhdl.org > VHDL development, the modern way: http://www.sigasi.com > World-class digital design: http://www.easics.com > > > ------------------------------------------------------------------------------ > October Webinars: Code for Performance > Free Intel webinars can help you accelerate application performance. > Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most > from > the latest Intel processors and coprocessors. See abstracts and register > > http://pubads.g.doubleclick.net/gampad/clk?id=60134791&iu=/4140/ostg.clktrk > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > |
From: Jan D. <ja...@ja...> - 2013-10-02 11:34:12
|
On 10/02/2013 10:11 AM, Per Karlsson wrote: > Enforcing "top-level convertibility" at all levels of the design > would be a huge step backwards for MyHDL. Obviously, with the user-defined code approach top-level convertibility would only be needed at those levels where you want a hierarchical partioning point. For an application such as floorplanning, this would presumably be at a limited number of places close to the top-level. Furthermore, it is not at all obvious to me that "virtual" top-level convertibility would not be required for the other proposed approaches also. > Encapsulating target dependent design is standard practice, but the > netlist hierarchy is not part of that---mostly. :) The hierarchy is in the MyHDL design - the question is how to extract it (or an alternative one) to the converted output. I am not discussing the concept now, but David's proposed method. Let's make this practical. If I understand David's solution, one would define a desired output partition by significant, non-functional changes to the source code. Suppose someone does this for his requirements, and later you inherit that IP block. Now suppose you need a different kind of partitioning - your only option would be to make significant, non-functional changes (hopefully) to the source code. Do you really want that? -- Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com Python as a HDL: http://www.myhdl.org VHDL development, the modern way: http://www.sigasi.com World-class digital design: http://www.easics.com |
From: Per K. <bas...@gm...> - 2013-10-02 08:11:37
|
Enforcing "top-level convertibility" at all levels of the design would be a huge step backwards for MyHDL. I have not looked into MEP107, it may take away some of that sting, but that will not help a pre-MEP107 design (such as mine). Not even my top module is "top-level convertible", I have a script to wrap it for conversion. Encapsulating target dependent design is standard practice, but the netlist hierarchy is not part of that---mostly. :) (You can never be too careful with those generalizations.) Cheers Per On Wed, Oct 2, 2013 at 9:28 AM, Jan Decaluwe <ja...@ja...> wrote: [...] > Simply convert at various levels, and use user-defined code > (under parameter control) for instantations. > > [...] > I have seen many cases of vendor lock-in with a very high > economical cost that could perfectly have been avoided. > Conversely, my own experience has been to use HDL design > to keep dependencies minimal - with considerable success. > [...] > Jan > > -- > Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com > Python as a HDL: http://www.myhdl.org > VHDL development, the modern way: http://www.sigasi.com > World-class digital design: http://www.easics.com > > > ------------------------------------------------------------------------------ > October Webinars: Code for Performance > Free Intel webinars can help you accelerate application performance. > Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most > from > the latest Intel processors and coprocessors. See abstracts and register > > http://pubads.g.doubleclick.net/gampad/clk?id=60134791&iu=/4140/ostg.clktrk > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > |
From: Jan D. <ja...@ja...> - 2013-10-02 07:29:42
|
On 10/02/2013 08:46 AM, Per Karlsson wrote: > Apart from floorplanning a hierarchical netlist is necessary for > benchmarking (area, power, routing, timing...). It is nigh impossible > to figure out what's going on in your design with a flat netlist. I have nowhere questioned the potential usefulness of hierarchy - merely the usefulness of floorplanning. I would like to hear the opinion of other FPGA experts on this. Ideally based on experiments. I use hierarchy in the output regularly, often for clarity. I use user-defined code for this and I think it works quite well. Simply convert at various levels, and use user-defined code (under parameter control) for instantations. > Finally, worrying about target dependence is missing the mark. > > Every design is target dependent. You can try your best to fit a > range of targets, but there is always a dependence. You go over it very lightly it seems. Of course there will be unavoidable dependencies. But "opening the gates" because of this observation is very unwise. I have seen many cases of vendor lock-in with a very high economical cost that could perfectly have been avoided. Conversely, my own experience has been to use HDL design to keep dependencies minimal - with considerable success. What I am questioning here is not the concept of hierarchical output, but the proposed solution which seems to suggest signifant, non-parametrizable, non-functional source code changes to infer it. I don't like that. Note there are 2 alternative solutions today. One which works with current MyHDL, based on user-defined code. Another is Oscars' proposal which I have not reviewed yet, but which I believe requires no source code changes at all. Both these solutions could probably be improved, but I think they are conceptually much better. Jan -- Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com Python as a HDL: http://www.myhdl.org VHDL development, the modern way: http://www.sigasi.com World-class digital design: http://www.easics.com |
From: Angel E. <ang...@gm...> - 2013-10-02 07:19:36
|
David, I am very experienced with mercurial (I am one of the TortoiseHg devs) so if you need any help please just drop me a line. Cheers, Angel On Wed, Oct 2, 2013 at 5:54 AM, David Holl <da...@ad...> wrote: > dang it. scratch that initial impression where I thought the patch applied > on 0.9-dev. I was actually on the 0.8.1 precursor. damn hg vs stupid > git... (small differences between hg and git: I'm used to "git log" showing > me just the history of the branch I'm on. "hg log" shows the whole log > across branches... ok, so I'll need to read hg's driver's ed handbook > first.) > > > On Tue, Oct 1, 2013 at 11:55 AM, David Holl <da...@ad...> wrote: >> >> tl;dr: My patch against 0.8 appears can be applied against the 0.9-dev >> repo, and it satisfies my very limited testing. >> >> The changes in 0.9-dev were not near my hack-n-slash campaign. (I kept >> most of my changes _after_ MyHDL's normal extraction and analysis algorithm, >> with only a few small hooks into signals and generators to assist with >> partition-tagging.) >> >> To test, I first removed the current myhdl-0.8 I had in my Python >> installation, then I followed these steps: >> >> # (I removed my current myhdl-0.8 from my Python installation.) >> hg clone https://bitbucket.org/jandecaluwe/myhdl >> cd myhdl >> gunzip -c ../myhdl-0.8-partitions.patch.gz | patch -p1 >> python setup.py build >> python setup.py install --user -O2 >> >> Then I reran my test_partition.py, and the output is identical. (except >> that the new myhdl is injecting some $signed(...) stuff in 1 place where I'm >> substracting...) >> >> I also reran my pcie designs (with partitions), and that also produced >> identical output. (but again with $signed(...) stuff but in 2 places where >> I'm subtracting...) >> >> >> To confirm I'm using the latest repo, here's the recent log entry: >> hg log | head -8 >> changeset: 1358:324a8d3206fb >> branch: 0.9-dev >> tag: tip >> parent: 1356:db95c2d47119 >> parent: 1357:8de9f8771395 >> user: Jan Decaluwe <ja...@ja...> >> date: Sun Sep 22 19:14:21 2013 +0200 >> summary: Bug fix merge from default >> >> >> And the patch applied fairly cleanly, with only 2 offset changes: >> gunzip -c ../myhdl-0.8-partitions.patch.gz | patch -p1 >> patching file myhdl/_Signal.py >> patching file myhdl/__init__.py >> patching file myhdl/_always.py >> patching file myhdl/_always_comb.py >> Hunk #1 succeeded at 190 (offset 10 lines). >> patching file myhdl/_always_seq.py >> patching file myhdl/_contextdecorator.py >> patching file myhdl/_extractHierarchy.py >> patching file myhdl/_instance.py >> patching file myhdl/_partition.py >> patching file myhdl/conversion/_analyze.py >> Hunk #5 succeeded at 865 (offset 5 lines). >> patching file myhdl/conversion/_toVerilog.py >> >> >> The rest of this email is a quick summary of my changes per file: >> >> __init__.py: include "partition" and "get_current_partition" in the myhdl >> namespace. get_current_partition() may be called from within a partition to >> assign attributes. >> >> For example, to assign attributes using the "with" syntax: >> >> with partition('A') as this_part: # This will be renamed to A0 >> this_part.attr_add('KEEP_HIERARCHY', 'TRUE') >> this_part.attr_add('DONT_TOUCH', 'TRUE') >> >> @always(clk.posedge) >> def clgd(): >> d.next = c + e >> >> And to assign attributes from inside a partition (such as when using the >> "decorator" syntax): >> >> @partition('AES') # <---- partition a la decorator. >> def my_module_bob(...): >> # ... >> this_part = get_current_partition() >> this_part.attr_add('DONT_TOUCH', 'TRUE') >> return instances() >> >> >> _Signal.py: Small change. I radio tag each signal with the current >> partition. (Actually, I originally didn't need to do this, until I tried >> figuring out where to place ConcatSignal drivers (ie, which partition to >> invoke their _toVerilog [or _toVHDL] method). In short, Iw as tired after >> devising the auto-magic placement for every other signal type, so I just >> gave up on auto-placement of ConcatSignals, and instead just use the tagged >> partition to indicate where to place each ConcatSignal's driver. (ie, For >> all other signals, it doesn't matter where you happen to declare them, since >> the output code will auto placed based on the location of any driving >> generator. But for ConcatSignal's, the output code will strictly place >> their driver inside whatever partition you happend to create the >> ConcatSignal in python.) >> >> >> _instance.py: Small change, to support any extension to "monkey patch" its >> way into tagging generators inheriting from _Instantiator. (Actually, I >> should've structured my change to _Signal.py like this one, to open the way >> for any future extensions to also "monkey patch" their way into _Signal's >> and shadow signals...) >> >> >> _always.py: _Always inherits from _Instantiator but does not invoke it's >> constructor. Therefore, I manually invoke the "hookInit" that I created >> inside _Instantiator. >> >> >> _always_comb.py: Same as _always.py. Manually invoke the "hookInit" that >> I created inside _Instantiator. >> >> >> _always_seq.py: Same as _always.py... >> >> >> _extractHierarchy.py: Tweak _HierExtr and _Instance to preserve hookData >> placed via hookInit from _Instantiator. I also tweaked _UserCode and >> _addUserCode to preserve hookData, but I haven't tried any user-defined >> Verilog (or VHDL) to test this. TODO: If anyone has user-defined code, try >> putting it in a partition (perhaps easiest via "with"), and tell me if it is >> placed in the correct Verilog module on output. >> >> >> _contextdecorator.py: New file, from >> http://pypi.python.org/pypi/contextdecorator to support both "with >> partition(...) ..." and "@partition(...)" mechanisms. >> >> >> _partition.py: New file, and is actually pretty short. It defines >> "partition" and "get_current_partition" API, and inject the partition tags >> in the relevant objects such as @always, @always_comb, @always_seq. >> >> >> conversion/_analyze.py: Preserve hookData in _analyzeGens. And in >> _AnalyzeVisitor, I added tree.inmems to mirror record keeping of >> tree.outmems, so that I can verify that memories are only read from the same >> partition in which they're driven. >> >> >> conversion/_toVerilog.py: Thar be dragons. Here is where I added >> toVerilog.partitioned_output, to invoke my alternative Verilog output code >> contained in _write_partitioned_output(...). TODO: I should move >> _write_partitioned_output and its supporting entourage to another file. >> (SigMapping, lookup_id, distill_signals_and_memories, _apply_renames, >> _generate_partitions, _partition2name, _make_unique_names) >> >> >> >> >> >> >> >> On Sun, Sep 29, 2013 at 8:25 PM, Keerthan jai.c <jck...@gm...> >> wrote: >>> >>> David, >>> >>> Just a heads up, the 0.9 dev branch on bitbucket has quite a few changes >>> in the conversion area(MEP 107). You might want to check whether these >>> patches apply on the new branch. >>> >>> >>> On Sun, Sep 29, 2013 at 2:21 PM, David Holl <da...@ad...> wrote: >>>> >>>> There was an old thread regarding MEP 110, but I've come up with an >>>> alternative "solution", and I'm looking for your comments. (call it MEP >>>> 110-alt?) >>>> >>>> tl;dr --- If you're interested, >>>> >>>> Introduction: Same as MEP 110. (Especially for floor planning...) >>>> ----------------------- >>>> Analysis: Same as MEP 110. (Yep, everything gets flattened by >>>> default...) >>>> ----------------------- >>>> Proposed Solution: (with implementation) >>>> >>>> I did not follow the proposed solution in MEP 110, because that would've >>>> required that I change [any of] my components to be "top-module >>>> convertible". (I'm using a form of signal containers --similar to MEP 107-- >>>> which which would've required many changes (in my code) to achieve >>>> "top-module convertibility".) >>>> >>>> What I did was I started from the flattened hierarchy in >>>> conversion/_toVerilog.py, but instead of calling the usual _writeSigDecls, >>>> _convertGens, I wrote my own convoluted output code: >>>> ... >>>> if self.partitioned_output: >>>> _write_partitioned_output(self.partitioned_output, >>>> vfile, vpath, self.timescale, h, intf, siglist, memlist, genlist, doc) >>>> else: >>>> _writeFileHeader(vfile, vpath, self.timescale) >>>> _writeModuleHeader(vfile, intf, doc) >>>> _writeSigDecls(vfile, intf, siglist, memlist) >>>> _convertGens(genlist, vfile) >>>> _writeModuleFooter(vfile) >>>> ... >>>> >>>> >>>> To activate this alternative output, just set >>>> toVerilog.partitioned_output=True: >>>> toVerilog.name='test_partition' >>>> toVerilog.partitioned_output=True # the default is False >>>> toVerilog(_test_top, clk, AAA, BBB, ZZZ, TTT, VVV) >>>> >>>> Without any other changes to a hardware description, this alternative >>>> code will produce identical, flattened output. (right down to the arbitrary >>>> ordering of signals and generators...) >>>> >>>> However, you may now group any related logic together, as needed. I >>>> call a group of logic a "partition", and these partitions may be nested. >>>> Instead of the word "partition" you could call it a "module" instead, since >>>> the concept is almost identical to Verilog module's. In the following >>>> description, it will appear that I'm flipping between "partition" and >>>> "module" when really, I'm describing how that partitions in python impact >>>> the created Verilog modules. (but for simplistic purposes, since I >>>> guarantee each "partition" will create a unique Verilog "module", feel free >>>> to call em' what you want...) >>>> >>>> There are 2 ways to assign related hardware into partitions. >>>> ----------------------- >>>> 1) The first is via python's "with" statement. I'll show a few >>>> examples: >>>> >>>> example 1.a) A simple partition... >>>> from myhdl import Signal, partition, ... >>>> >>>> @always(clk.posedge) >>>> def clgc(): >>>> c.next = a + b >>>> >>>> with partition('A'): >>>> @always(clk.posedge) >>>> def clgd(): >>>> d.next = c + e >>>> >>>> @always(clk.posedge) >>>> def clge(): >>>> e.next = a * b >>>> >>>> @always(clk.posedge) >>>> def clgf(): >>>> f.next = more stuff... >>>> >>>> >>>> What "partition" does is annotate all generators (and shadow signals...) >>>> with your text label. Then the "partitioned-output" code uses these >>>> annotations move related logic into a Verilog module, and instantiate that >>>> module from the top-level module. Module ports are automatically created >>>> for any signals that need to cross between modules. >>>> >>>> This code still creates only 1 output .v file containing all modules. >>>> (I didn't care if it was 1 file or multiple files, but for me, 1 file was >>>> "easier" to move/copy around in my opinion.) >>>> >>>> The top module will include all of the signals, except for "e" --- >>>> because in this code, e is only used within partition A. Therefore "e" will >>>> appear as a driven "reg" within a submodule called A. (and that submodule >>>> "A" is instantiated in the top level as "part_A"...) >>>> >>>> >>>> >>>> example 1.b) Partitions may be nested. >>>> >>>> @always(clk.posedge) >>>> def clgc(): >>>> c.next = a + b >>>> >>>> with partition('A'): >>>> @always(clk.posedge) >>>> def clgd(): >>>> d.next = c + e >>>> >>>> with partition('B'): >>>> @always(clk.posedge) >>>> def clge(): >>>> e.next = a * b >>>> >>>> @always(clk.posedge) >>>> def clgf(): >>>> f.next = more stuff... >>>> >>>> >>>> This code will create 3 modules total: the top module, a module called >>>> "A", and a module called "A_B". >>>> >>>> >>>> example 1.c) Partitions having the same name will be renamed to stay >>>> unique! >>>> >>>> If you want related code to be grouped into a partition, all of that >>>> code must be contained in the same python "with" block. For example: >>>> >>>> from myhdl import Signal, partition, ... >>>> >>>> @always(clk.posedge) >>>> def clgc(): >>>> c.next = a + b >>>> >>>> with partition('A'): # This will be renamed to A0 >>>> @always(clk.posedge) >>>> def clgd(): >>>> d.next = c + e >>>> >>>> with partition('A'): # This will be renamed to A1 >>>> @always(clk.posedge) >>>> def clge(): >>>> e.next = a * b >>>> >>>> >>>> Rationale: When you start nesting partitions, partition names are >>>> guaranteed to produce unique module instances and not accidentally group >>>> unrelated logic together. >>>> >>>> >>>> example 1.d) Partitions are nestable across your python function calls, >>>> and renaming will happen to keep sub >>>> >>>> For example, unrelated nested partitions may use the same name without >>>> fear of their logic being accidentally grouped together. >>>> >>>> from myhdl import Signal, partition, ... >>>> >>>> def my_module_alice(...): >>>> # ... >>>> with partition('SM'): >>>> # This happens to enclose a state machine. >>>> # The name SM isn't descriptive enough, but if you >>>> # want descriptive Verilog output, then you should >>>> # use descriptive names. >>>> # ... >>>> # ... >>>> return instances() >>>> >>>> def my_module_bob(...): >>>> # ... >>>> with partition('SM'):# This encloses an unrelated state machine. >>>> # ... >>>> # ... >>>> return instances() >>>> >>>> def top(...): >>>> @always(clk.posedge) >>>> def clgc(): >>>> c.next = a + b >>>> >>>> with partition('CRYPTO'): >>>> alice_inst = alice(...) >>>> bob0_inst = bob(...) >>>> bob1_inst = bob(...) >>>> >>>> with partition('CRYPTO_SM2'): >>>> # I made this CRYPTO_SM2 name, just to be a jerk. >>>> @always(clk.posedge) >>>> def clgd(): >>>> d.next = c + e >>>> >>>> >>>> This code would produce 6 instantiated modules in the generated Verilog >>>> output: >>>> module top(...); >>>> module CRYPTO(...); >>>> module CRYPTO_SM0(...); // this is from alice_inst >>>> module CRYPTO_SM1(...); // this is from bob0_inst >>>> module CRYPTO_SM2(...); // this is from bob1_inst >>>> module CRYPTO_SM2_(...); // renamed CRYPTO_SM2 to not conflict with >>>> CRYPT_SM2 from bob1_inst >>>> >>>> Admittedly, the generated names CRYPTO_SM... in this example aren't very >>>> clear, but the point here is that your python functions (like alice() and >>>> bob()) have a guaranteed means to group logic into a Verilog module without >>>> accidental commingling of unrelated from other modules. >>>> >>>> The "top" module instantates "CRYPTO" and "CRYPTO_SM2_". Then "CRYPTO" >>>> instantiates "CRYPTO_SM0", "CRYPTO_SM1", and "CRYPTO_SM2". >>>> >>>> >>>> example 1.e) Partitions support Verilog 2001 attributes (and if someone >>>> wants to add VHDL support...) >>>> >>>> with partition('A') as this_part: # This will be renamed to A0 >>>> this_part.attr_add('KEEP_HIERARCHY', 'TRUE') >>>> this_part.attr_add('DONT_TOUCH', 'TRUE') >>>> >>>> @always(clk.posedge) >>>> def clgd(): >>>> d.next = c + e >>>> >>>> This will produce output that instantiates module A as: >>>> >>>> (* KEEP_HIERARCHY="TRUE", DONT_TOUCH="TRUE" *) part_A A(clk, c, e, d); >>>> >>>> // The generated module for instance A is called "part_A". >>>> >>>> (MyHDL also has a nifty feature to include doc strings as embedded >>>> comments. I have some back-end support for attaching a string to a >>>> partition, to be output as a comment in the code, but I haven't turned it on >>>> yet.) >>>> >>>> ----------------------- >>>> 2) The second way to group logic into a partition is with a python >>>> decorator. >>>> >>>> example 2) Using decorators in addition to "with" blocks. >>>> >>>> The decorator syntax uses the same rules as the with-blocks. (All >>>> partitions will be unique, and possibly suffixed with a number to maintain >>>> uniqueness in the Verilog code. Partitions may be nested. Use descriptive >>>> names if you want descriptive output.) >>>> >>>> Here, I'll intermix the decorator and with syntax: >>>> >>>> def my_module_alice(...): >>>> # ... >>>> with partition('SM'): >>>> # This happens to enclose a state machine. >>>> # The name SM isn't descriptive enough, but if you >>>> # want descriptive Verilog output, then you should >>>> # use descriptive names. >>>> # ... >>>> # ... >>>> return instances() >>>> >>>> @partition('AES') # <---- partition a la decorator. >>>> def my_module_bob(...): >>>> # ... >>>> with partition('SM'):# This encloses an unrelated state machine. >>>> # ... >>>> # ... >>>> return instances() >>>> >>>> def top(...): >>>> @always(clk.posedge) >>>> def clgc(): >>>> c.next = a + b >>>> >>>> with partition('CRYPTO'): >>>> alice_inst = alice(...) >>>> bob0_inst = bob(...) >>>> bob1_inst = bob(...) >>>> >>>> with partition('CRYPTO_SM2'): >>>> # I made this CRYPTO_SM2 name, just to be a jerk. >>>> @always(clk.posedge) >>>> def clgd(): >>>> d.next = c + e >>>> >>>> The above code will generate ~8 modules: >>>> module top(...); >>>> module CRYPTO(...); >>>> module CRYPTO_SM(...); // this is from alice_inst >>>> module CRYPTO_AES0(...); // decorator on bob() >>>> module CRYPTO_AES0_SM(...); // this is from bob0_inst >>>> module CRYPTO_AES1(...); // decorator on bob() >>>> module CRYPTO_AES1_SM(...); // this is from bob1_inst >>>> module CRYPTO_SM2(...); // renamed CRYPTO_SM2 to not conflict with >>>> CRYPT.SM from bob1_inst >>>> >>>> >>>> ----------------------- END OF EXAMPLES >>>> >>>> Limitations: I hope there aren't any. I put enough care to accomodate >>>> ConcatSignal's, _SliceSignal's, const [undriven] _Signal's, etc... And if a >>>> signal gets pushed into a sub-partition where it is both driven and read, as >>>> well as output from that sub-partition, the generator will automatically >>>> make a separate wire just for the output port, that is driven from your >>>> signal. (This prevents "Output port is read internally..." warnings for >>>> partition-generated modules. I don't do this for the top-level though, to >>>> preserve the same interface as current MyHDL output.) >>>> >>>> Component Conversion: No additional restrictions beyond that of MyHDL. >>>> There is still the same requirement on your top-level to be "top-level >>>> convertible", but there is flexibility for your lower levels. >>>> >>>> Component Parameters: What parameters? All of your parameters were >>>> already digested by python+MyHDL magic, and I'm operating on the flattened >>>> hierarchy. If you invoke the same sub-partition (sub-module) multiple >>>> times, it will be replicated in the output, but every time it appears, it >>>> will use the globally-unique signal names that MyHDL has already assigned. >>>> (ie, I don't change your signal names.) >>>> >>>> Any drawbacks: >>>> This may/will produce larger output code than the proposed solution in >>>> MEP 110. The existing MEP 110 solution will create 1 copy of each module, >>>> and instantiate it multiple times (as long as each instantiation shares the >>>> same port signal widths, etc...). In contrast, this "110.alt" solution will >>>> create a whole copy of a module every time it is instantiated. (But each >>>> copy inherits the unique signal names assigned by MyHDL's flattening >>>> algorithm.) However, the larger output size from this "110.alt" isn't that >>>> much larger than MyHDL's native flat output. (depending on your signal >>>> usage...) >>>> >>>> Benefits: >>>> You can have hierarchical output with minimal changes to your code, and >>>> you control exactly how your logic is partitioned into the hierarchy. Just >>>> sprinkle a few @partition(...) or "with partition(...):" statements wherever >>>> you need in your design. >>>> >>>> Known pitfalls: I have not tried or tested TristateSignal's for "inout" >>>> ports, and I've only tested on a very narrow subset of MyHDL's feature set. >>>> (I was was already bitten by ConcatSignal's, _SliceSignal's, and lists of >>>> signals accidentally being inferred as memories... However, I expect these >>>> areas to work as expected now.) >>>> >>>> >>>> But if anyone is interested, here's the code, and I'm open for feedback. >>>> >>>> I attached patches against myhdl-0.8.tar.gz available from >>>> https://sourceforge.net/projects/myhdl/files/myhdl/0.8/ >>>> >>>> Of the 2 patches, myhdl-0.8-fix_modbv.patch is my poor-man's fix for >>>> modbv, because I needed modbv. This patch is most likely obsoleted by Jan's >>>> real fix in the repo. >>>> >>>> The other patch (myhdl-0.8-partitions.patch) contains my crude first >>>> draft supporting the described hierarchy. Yes, this code is ugly. Don't >>>> look at it yet. It is a quick mock-up of some functionality I really >>>> wanted. But give it a try if you're interested and let me know what it >>>> breaks on... Or if you really want to dive into the code, feel free to do >>>> so. >>>> >>>> On my systems, I apply & install these patches as follows: (gunzip the >>>> .patch files first) >>>> >>>> gunzip myhdl-0.8-fix_modbv.patch.gz >>>> gunzip myhdl-0.8-partitions.patch.gz >>>> tar zxf myhdl-0.8.tar.gz \ >>>> && cd myhdl-0.8 \ >>>> && patch -p1 < ../myhdl-0.8-fix_modbv.patch \ >>>> && patch -p1 < ../myhdl-0.8-partitions.patch \ >>>> && python setup.py build \ >>>> && python setup.py install --user -O2 \ >>>> && cd .. \ >>>> && rm -rf myhdl-0.8 >>>> >>>> This installs myhdl into python's standard location for my home >>>> directory, but feel free to leave off --user to install to the main system >>>> path, or wherever else you want. >>>> >>>> To test drive the functionality, try running test_partition.py. Set >>>> toVerilog.partitioned_output=False >>>> to see the normal output, and >>>> toVerilog.partitioned_output=True >>>> to see the partitioned output. And if you are curious, try >>>> toVerilog.partitioned_output="I promise I will never die." >>>> to enable the partitioned output code, but tell it to ignore the >>>> partition annotations. >>>> >>>> >>>> (typos and all, I'm hitting send...) >>>> >>>> - David >>>> >>>> >>>> >>>> On Wed, May 1, 2013 at 6:44 PM, Oscar Daniel Diaz <osc...@gm...> >>>> wrote: >>>>> >>>>> El Wed, 01 May 2013 10:55:55 +0200 >>>>> Jan Decaluwe <ja...@ja...> escribió: >>>>> >>>>> > On 04/29/2013 05:25 PM, Oscar Daniel Diaz wrote: >>>>> > >>>>> > > Given that the converter is called recursively several times, >>>>> > > multiple files are generated and its contents are used for >>>>> > > component >>>>> > > declaration (VHDL). Recursive calls must avoid file replication >>>>> > > (for >>>>> > > VHDL case means avoid multiple package file generation). This is >>>>> > > done by keeping generated code in memory before pushing to files. >>>>> > > >>>>> > > Attribute "no_component_files" : >>>>> > > * False : all components code is saved to disk as soon as >>>>> > > possible. >>>>> > > * True : discard components code, only save top-module file. >>>>> > >>>>> > Not sure what is meant here exactly. Why would we need component >>>>> > declarations, as opposed to simply using direct instantation? >>>>> > For a case like this, this seems much simpler and less verbose >>>>> > to me. >>>>> >>>>> Since keep hierarchy conversion requires multiple files to generate >>>>> (top-module and components to instantiate), this flag prevents >>>>> generation of those components. Suppose you make some changes only in >>>>> the top-module, this flag allows to only generate top-module file. >>>>> >>>>> When I change from VHDL '87 syntax (doing recursive calls to get >>>>> component declaration) to '93 syntax, that flag would prevent >>>>> those recursive calls. >>>>> >>>>> -- >>>>> Oscar Díaz >>>>> Key Fingerprint = 904B 306C C3C2 7487 650B BFAC EDA2 B702 90E9 9964 >>>>> gpg --keyserver subkeys.pgp.net --recv-keys 90E99964 >>>>> >>>>> >>>>> _______________________________________________ >>>>> myhdl-list mailing list >>>>> myh...@li... >>>>> https://lists.sourceforge.net/lists/listinfo/myhdl-list >>>>> >>>> >>>> >>>> >>>> ------------------------------------------------------------------------------ >>>> October Webinars: Code for Performance >>>> Free Intel webinars can help you accelerate application performance. >>>> Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most >>>> from >>>> the latest Intel processors and coprocessors. See abstracts and register >>>> > >>>> >>>> http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk >>>> >>>> _______________________________________________ >>>> myhdl-list mailing list >>>> myh...@li... >>>> https://lists.sourceforge.net/lists/listinfo/myhdl-list >>>> >>> >>> >>> >>> -- >>> have a nice day >>> -jck >>> >>> >>> ------------------------------------------------------------------------------ >>> October Webinars: Code for Performance >>> Free Intel webinars can help you accelerate application performance. >>> Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most >>> from >>> the latest Intel processors and coprocessors. See abstracts and register >>> > >>> >>> http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk >>> _______________________________________________ >>> myhdl-list mailing list >>> myh...@li... >>> https://lists.sourceforge.net/lists/listinfo/myhdl-list >>> >> > > > ------------------------------------------------------------------------------ > October Webinars: Code for Performance > Free Intel webinars can help you accelerate application performance. > Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most > from > the latest Intel processors and coprocessors. See abstracts and register > > http://pubads.g.doubleclick.net/gampad/clk?id=60134791&iu=/4140/ostg.clktrk > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > |
From: Per K. <bas...@gm...> - 2013-10-02 06:47:08
|
Floorplanning is essential. (I could stop here, but I'm in a chatty mood.) Yes, you can do a simple million gate ASIC without floorplanning. But is it more than two decades since a million gate ASIC was anything to write home about. A couple of guys in a garage can do hundred million to trillion gate designs. Sure, they cannot tape it out without doing some serious growing up financially, but how is that going to happen if they cannot show that their design is going to work? Apart from floorplanning a hierarchical netlist is necessary for benchmarking (area, power, routing, timing...). It is nigh impossible to figure out what's going on in your design with a flat netlist. Saying "back-end tools need to improve", is like putting off getting a bike because soon we are all gonna have flying cars. Back end tools have needed to improve for decades. (And they have, but designs have grown faster.) Finally, worrying about target dependence is missing the mark. Every design is target dependent. You can try your best to fit a range of targets, but there is always a dependence. Secondly, the hierarchy is not the floorplan. The hierarchy is just the partition into lego bricks, and thus not very target dependent. The floorplan is how you fit them together. Cheers Per On Wed, Oct 2, 2013 at 12:44 AM, Angel Ezquerra <ang...@gm...>wrote: > I cannot comment on the ASIC side, but on the FPGA side it is a common > recommendation to properly organize your code into entities to improve > the map and/or plan and route results. I believe that it is also > necessary to be able to do incremental builds and what they call > "Partial Reconfiguration", which "is the ability to dynamically modify > blocks of logic by downloading partial bit files while the remaining > logic continues to operate without interruption". > > I'm not saying this is something that Xilinx could not improve (I > really think they could and they should). However, I would not hold my > breath hoping for Xilinx tools to improve in this regard. They are a > little better now, but their tools used to be and still are to a long > extent very rudimentary and finicky. My guess is that they have a lot > of other things that they must improve before getting to this. > > I also think that being able to control how the generated code is > split into files and entities would be nice, particularly if you had > to debug some generation issue. It might also help when adding > chipscope probes. > > Finally, it would make it easier to include generated VHDL or Verilog > files into version control. In general I don't think that generated > VHDL and Verilog files should be put into version control, because > they are derived files that can be generated from the MyHDL sources. > However, some projects have policies that require all VHDL or Verilog > code to be included on the source repository. In those cases having a > single big generated VHDL file is a pain because it changes with every > modification of any of the MyHDL files, and it is hard to tell what > changed in that big single file. If multiple files were generated, > only some of those files would usually change, making it easier to > tell what changed in a given version. > > So I think that there are a few sensible reasons for wanting the > ability to split the generated design into files and entities. > > Cheers, > > Angel > > > On Tue, Oct 1, 2013 at 9:45 PM, Jan Decaluwe <ja...@ja...> wrote: > > A few helicopter-view comments on this. > > > > I still have an issue with floorplanning being that important. > > Afaik we can do million-gate ASICs without floorplanning at > > all. It seems to me an ideal problem for full automation by > > layout tools. > > > > To put it differently, if one really needs floorplanning, I > > would think it applies to very large projects with big > > budgets - more than enough to actually pay someone to > > solve this in MyHDL (me for example :-)). > > > > Of course, FPGAs may be be different. But I still > > would think it's a matter of back-end tools that need > > to improve in the first place - not our task. > > > > So - are we really sure floorplanning actually makes > > a difference? > > > > If it does, I certainly would not want a solution that > > influences the source code significantly, as I think this > > solution is suggesting. It has nothing to do with functionality. > > Instead it would make source code target-dependent, as > > the floorplanning solution for one target may not be right > > or required for another one. > > > > Jan > > > > On 09/29/2013 08:21 PM, David Holl wrote: > >> There was an old thread regarding MEP 110, but I've come up with an > alternative "solution", and I'm looking for your comments. (call it MEP > 110-alt?) > >> > >> tl;dr --- If you're interested, > >> > >> Introduction: Same as MEP 110. (Especially for floor planning...) > >> ----------------------- > >> Analysis: Same as MEP 110. (Yep, everything gets flattened by > default...) > >> ----------------------- > >> Proposed Solution: (with implementation) > >> > >> I did not follow the proposed solution in MEP 110, because that > would've required that I change [any of] my components to be "top-module > convertible". (I'm using a form of signal containers --similar to MEP > 107-- which which would've required many changes (in my code) to achieve > "top-module convertibility".) > >> > >> What I did was I started from the flattened hierarchy in > conversion/_toVerilog.py, but instead of calling the usual _writeSigDecls, > _convertGens, I wrote my own convoluted output code: > >> ... > >> if self.partitioned_output: > >> _write_partitioned_output(self.partitioned_output, > vfile, vpath, self.timescale, h, intf, siglist, memlist, genlist, doc) > >> else: > >> _writeFileHeader(vfile, vpath, self.timescale) > >> _writeModuleHeader(vfile, intf, doc) > >> _writeSigDecls(vfile, intf, siglist, memlist) > >> _convertGens(genlist, vfile) > >> _writeModuleFooter(vfile) > >> ... > >> > >> > >> To activate this alternative output, just set > toVerilog.partitioned_output=True: > >> toVerilog.name='test_partition' > >> toVerilog.partitioned_output=True # the default is False > >> toVerilog(_test_top, clk, AAA, BBB, ZZZ, TTT, VVV) > >> > >> Without any other changes to a hardware description, this alternative > code will produce identical, flattened output. (right down to the arbitrary > ordering of signals and generators...) > >> > >> However, you may now group any related logic together, as needed. I > call a group of logic a "partition", and these partitions may be nested. > Instead of the word "partition" you could call it a "module" instead, > since the concept is almost identical to Verilog module's. In the > following description, it will appear that I'm flipping between "partition" > and "module" when really, I'm describing how that partitions in python > impact the created Verilog modules. (but for simplistic purposes, since I > guarantee each "partition" will create a unique Verilog "module", feel free > to call em' what you want...) > >> > >> There are 2 ways to assign related hardware into partitions. > >> ----------------------- > >> 1) The first is via python's "with" statement. I'll show a few > examples: > >> > >> example 1.a) A simple partition... > >> from myhdl import Signal, partition, ... > >> > >> @always(clk.posedge) > >> def clgc(): > >> c.next = a + b > >> > >> with partition('A'): > >> @always(clk.posedge) > >> def clgd(): > >> d.next = c + e > >> > >> @always(clk.posedge) > >> def clge(): > >> e.next = a * b > >> > >> @always(clk.posedge) > >> def clgf(): > >> f.next = more stuff... > >> > >> > >> What "partition" does is annotate all generators (and shadow > signals...) with your text label. Then the "partitioned-output" code uses > these annotations move related logic into a Verilog module, and instantiate > that module from the top-level module. Module ports are automatically > created for any signals that need to cross between modules. > >> > >> This code still creates only 1 output .v file containing all modules. > (I didn't care if it was 1 file or multiple files, but for me, 1 file was > "easier" to move/copy around in my opinion.) > >> > >> The top module will include all of the signals, except for "e" --- > because in this code, e is only used within partition A. Therefore "e" > will appear as a driven "reg" within a submodule called A. (and that > submodule "A" is instantiated in the top level as "part_A"...) > >> > >> > >> > >> example 1.b) Partitions may be nested. > >> > >> @always(clk.posedge) > >> def clgc(): > >> c.next = a + b > >> > >> with partition('A'): > >> @always(clk.posedge) > >> def clgd(): > >> d.next = c + e > >> > >> with partition('B'): > >> @always(clk.posedge) > >> def clge(): > >> e.next = a * b > >> > >> @always(clk.posedge) > >> def clgf(): > >> f.next = more stuff... > >> > >> > >> This code will create 3 modules total: the top module, a module called > "A", and a module called "A_B". > >> > >> > >> example 1.c) Partitions having the same name will be renamed to stay > unique! > >> > >> If you want related code to be grouped into a partition, all of that > code must be contained in the same python "with" block. For example: > >> > >> from myhdl import Signal, partition, ... > >> > >> @always(clk.posedge) > >> def clgc(): > >> c.next = a + b > >> > >> with partition('A'): # This will be renamed to A0 > >> @always(clk.posedge) > >> def clgd(): > >> d.next = c + e > >> > >> with partition('A'): # This will be renamed to A1 > >> @always(clk.posedge) > >> def clge(): > >> e.next = a * b > >> > >> > >> Rationale: When you start nesting partitions, partition names are > guaranteed to produce unique module instances and not accidentally group > unrelated logic together. > >> > >> > >> example 1.d) Partitions are nestable across your python function calls, > and renaming will happen to keep sub > >> > >> For example, unrelated nested partitions may use the same name without > fear of their logic being accidentally grouped together. > >> > >> from myhdl import Signal, partition, ... > >> > >> def my_module_alice(...): > >> # ... > >> with partition('SM'): > >> # This happens to enclose a state machine. > >> # The name SM isn't descriptive enough, but if you > >> # want descriptive Verilog output, then you should > >> # use descriptive names. > >> # ... > >> # ... > >> return instances() > >> > >> def my_module_bob(...): > >> # ... > >> with partition('SM'):# This encloses an unrelated state machine. > >> # ... > >> # ... > >> return instances() > >> > >> def top(...): > >> @always(clk.posedge) > >> def clgc(): > >> c.next = a + b > >> > >> with partition('CRYPTO'): > >> alice_inst = alice(...) > >> bob0_inst = bob(...) > >> bob1_inst = bob(...) > >> > >> with partition('CRYPTO_SM2'): > >> # I made this CRYPTO_SM2 name, just to be a jerk. > >> @always(clk.posedge) > >> def clgd(): > >> d.next = c + e > >> > >> > >> This code would produce 6 instantiated modules in the generated Verilog > output: > >> module top(...); > >> module CRYPTO(...); > >> module CRYPTO_SM0(...); // this is from alice_inst > >> module CRYPTO_SM1(...); // this is from bob0_inst > >> module CRYPTO_SM2(...); // this is from bob1_inst > >> module CRYPTO_SM2_(...); // renamed CRYPTO_SM2 to not conflict with > CRYPT_SM2 from bob1_inst > >> > >> Admittedly, the generated names CRYPTO_SM... in this example aren't > very clear, but the point here is that your python functions (like alice() > and bob()) have a guaranteed means to group logic into a Verilog module > without accidental commingling of unrelated from other modules. > >> > >> The "top" module instantates "CRYPTO" and "CRYPTO_SM2_". Then "CRYPTO" > instantiates "CRYPTO_SM0", "CRYPTO_SM1", and "CRYPTO_SM2". > >> > >> > >> example 1.e) Partitions support Verilog 2001 attributes (and if > someone wants to add VHDL support...) > >> > >> with partition('A') as this_part: # This will be renamed to A0 > >> this_part.attr_add('KEEP_HIERARCHY', 'TRUE') > >> this_part.attr_add('DONT_TOUCH', 'TRUE') > >> > >> @always(clk.posedge) > >> def clgd(): > >> d.next = c + e > >> > >> This will produce output that instantiates module A as: > >> > >> (* KEEP_HIERARCHY="TRUE", DONT_TOUCH="TRUE" *) part_A A(clk, c, e, d); > >> > >> // The generated module for instance A is called "part_A". > >> > >> (MyHDL also has a nifty feature to include doc strings as embedded > comments. I have some back-end support for attaching a string to a > partition, to be output as a comment in the code, but I haven't turned it > on yet.) > >> > >> ----------------------- > >> 2) The second way to group logic into a partition is with a python > decorator. > >> > >> example 2) Using decorators in addition to "with" blocks. > >> > >> The decorator syntax uses the same rules as the with-blocks. (All > partitions will be unique, and possibly suffixed with a number to maintain > uniqueness in the Verilog code. Partitions may be nested. Use descriptive > names if you want descriptive output.) > >> > >> Here, I'll intermix the decorator and with syntax: > >> > >> def my_module_alice(...): > >> # ... > >> with partition('SM'): > >> # This happens to enclose a state machine. > >> # The name SM isn't descriptive enough, but if you > >> # want descriptive Verilog output, then you should > >> # use descriptive names. > >> # ... > >> # ... > >> return instances() > >> > >> @partition('AES') # <---- partition a la decorator. > >> def my_module_bob(...): > >> # ... > >> with partition('SM'):# This encloses an unrelated state machine. > >> # ... > >> # ... > >> return instances() > >> > >> def top(...): > >> @always(clk.posedge) > >> def clgc(): > >> c.next = a + b > >> > >> with partition('CRYPTO'): > >> alice_inst = alice(...) > >> bob0_inst = bob(...) > >> bob1_inst = bob(...) > >> > >> with partition('CRYPTO_SM2'): > >> # I made this CRYPTO_SM2 name, just to be a jerk. > >> @always(clk.posedge) > >> def clgd(): > >> d.next = c + e > >> > >> The above code will generate ~8 modules: > >> module top(...); > >> module CRYPTO(...); > >> module CRYPTO_SM(...); // this is from alice_inst > >> module CRYPTO_AES0(...); // decorator on bob() > >> module CRYPTO_AES0_SM(...); // this is from bob0_inst > >> module CRYPTO_AES1(...); // decorator on bob() > >> module CRYPTO_AES1_SM(...); // this is from bob1_inst > >> module CRYPTO_SM2(...); // renamed CRYPTO_SM2 to not conflict with > CRYPT.SM <http://CRYPT.SM> from bob1_inst > >> > >> > >> ----------------------- END OF EXAMPLES > >> > >> Limitations: I hope there aren't any. I put enough care to accomodate > ConcatSignal's, _SliceSignal's, const [undriven] _Signal's, etc... And if > a signal gets pushed into a sub-partition where it is both driven and read, > as well as output from that sub-partition, the generator will automatically > make a separate wire just for the output port, that is driven from your > signal. (This prevents "Output port is read internally..." warnings for > partition-generated modules. I don't do this for the top-level though, to > preserve the same interface as current MyHDL output.) > >> > >> Component Conversion: No additional restrictions beyond that of MyHDL. > There is still the same requirement on your top-level to be "top-level > convertible", but there is flexibility for your lower levels. > >> > >> Component Parameters: What parameters? All of your parameters were > already digested by python+MyHDL magic, and I'm operating on the flattened > hierarchy. If you invoke the same sub-partition (sub-module) multiple > times, it will be replicated in the output, but every time it appears, it > will use the globally-unique signal names that MyHDL has already assigned. > (ie, I don't change your signal names.) > >> > >> Any drawbacks: > >> This may/will produce larger output code than the proposed solution in > MEP 110. The existing MEP 110 solution will create 1 copy of each module, > and instantiate it multiple times (as long as each instantiation shares the > same port signal widths, etc...). In contrast, this "110.alt" solution > will create a whole copy of a module every time it is instantiated. (But > each copy inherits the unique signal names assigned by MyHDL's flattening > algorithm.) However, the larger output size from this "110.alt" isn't that > much larger than MyHDL's native flat output. (depending on your signal > usage...) > >> > >> Benefits: > >> You can have hierarchical output with minimal changes to your code, and > you control exactly how your logic is partitioned into the hierarchy. Just > sprinkle a few @partition(...) or "with partition(...):" statements > wherever you need in your design. > >> > >> Known pitfalls: I have not tried or tested TristateSignal's for > "inout" ports, and I've only tested on a very narrow subset of MyHDL's > feature set. (I was was already bitten by ConcatSignal's, _SliceSignal's, > and lists of signals accidentally being inferred as memories... However, I > expect these areas to work as expected now.) > >> > >> > >> But if anyone is interested, here's the code, and I'm open for feedback. > >> > >> I attached patches against myhdl-0.8.tar.gz available from > >> https://sourceforge.net/projects/myhdl/files/myhdl/0.8/ > >> > >> Of the 2 patches, myhdl-0.8-fix_modbv.patch is my poor-man's fix for > modbv, because I needed modbv. This patch is most likely obsoleted by > Jan's real fix in the repo. > >> > >> The other patch (myhdl-0.8-partitions.patch) contains my crude first > draft supporting the described hierarchy. Yes, this code is ugly. Don't > look at it yet. It is a quick mock-up of some functionality I really > wanted. But give it a try if you're interested and let me know what it > breaks on... Or if you really want to dive into the code, feel free to do > so. > >> > >> On my systems, I apply & install these patches as follows: (gunzip the > .patch files first) > >> > >> gunzip myhdl-0.8-fix_modbv.patch.gz > >> gunzip myhdl-0.8-partitions.patch.gz > >> tar zxf myhdl-0.8.tar.gz \ > >> && cd myhdl-0.8 \ > >> && patch -p1 < ../myhdl-0.8-fix_modbv.patch \ > >> && patch -p1 < ../myhdl-0.8-partitions.patch \ > >> && python setup.py build \ > >> && python setup.py install --user -O2 \ > >> && cd .. \ > >> && rm -rf myhdl-0.8 > >> > >> This installs myhdl into python's standard location for my home > directory, but feel free to leave off --user to install to the main system > path, or wherever else you want. > >> > >> To test drive the functionality, try running test_partition.py. Set > >> toVerilog.partitioned_output=False > >> to see the normal output, and > >> toVerilog.partitioned_output=True > >> to see the partitioned output. And if you are curious, try > >> toVerilog.partitioned_output="I promise I will never die." > >> to enable the partitioned output code, but tell it to ignore the > partition annotations. > >> > >> > >> (typos and all, I'm hitting send...) > >> > >> - David > >> > >> > >> > >> On Wed, May 1, 2013 at 6:44 PM, Oscar Daniel Diaz <osc...@gm...<mailto: > osc...@gm...>> wrote: > >> > >> El Wed, 01 May 2013 10:55:55 +0200 > >> Jan Decaluwe <ja...@ja... <mailto:ja...@ja...>> > escribió: > >> > >> > On 04/29/2013 05:25 PM, Oscar Daniel Diaz wrote: > >> > > >> > > Given that the converter is called recursively several times, > >> > > multiple files are generated and its contents are used for > component > >> > > declaration (VHDL). Recursive calls must avoid file > replication (for > >> > > VHDL case means avoid multiple package file generation). This > is > >> > > done by keeping generated code in memory before pushing to > files. > >> > > > >> > > Attribute "no_component_files" : > >> > > * False : all components code is saved to disk as soon as > >> > > possible. > >> > > * True : discard components code, only save top-module file. > >> > > >> > Not sure what is meant here exactly. Why would we need component > >> > declarations, as opposed to simply using direct instantation? > >> > For a case like this, this seems much simpler and less verbose > >> > to me. > >> > >> Since keep hierarchy conversion requires multiple files to generate > >> (top-module and components to instantiate), this flag prevents > >> generation of those components. Suppose you make some changes only > in > >> the top-module, this flag allows to only generate top-module file. > >> > >> When I change from VHDL '87 syntax (doing recursive calls to get > >> component declaration) to '93 syntax, that flag would prevent > >> those recursive calls. > >> > >> -- > >> Oscar Díaz > >> Key Fingerprint = 904B 306C C3C2 7487 650B BFAC EDA2 B702 90E9 9964 > >> gpg --keyserver subkeys.pgp.net <http://subkeys.pgp.net> > --recv-keys 90E99964 > >> > >> > >> _______________________________________________ > >> myhdl-list mailing list > >> myh...@li... <mailto: > myh...@li...> > >> https://lists.sourceforge.net/lists/listinfo/myhdl-list > >> > >> > >> > >> > >> > ------------------------------------------------------------------------------ > >> October Webinars: Code for Performance > >> Free Intel webinars can help you accelerate application performance. > >> Explore tips for MPI, OpenMP, advanced profiling, and more. Get the > most from > >> the latest Intel processors and coprocessors. See abstracts and > register > > >> > http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk > >> > >> > >> > >> _______________________________________________ > >> myhdl-list mailing list > >> myh...@li... > >> https://lists.sourceforge.net/lists/listinfo/myhdl-list > >> > > > > > > -- > > Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com > > Python as a HDL: http://www.myhdl.org > > VHDL development, the modern way: http://www.sigasi.com > > World-class digital design: http://www.easics.com > > > > > ------------------------------------------------------------------------------ > > October Webinars: Code for Performance > > Free Intel webinars can help you accelerate application performance. > > Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most > from > > the latest Intel processors and coprocessors. See abstracts and register > > > > > http://pubads.g.doubleclick.net/gampad/clk?id=60134791&iu=/4140/ostg.clktrk > > _______________________________________________ > > myhdl-list mailing list > > myh...@li... > > https://lists.sourceforge.net/lists/listinfo/myhdl-list > > > ------------------------------------------------------------------------------ > October Webinars: Code for Performance > Free Intel webinars can help you accelerate application performance. > Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most > from > the latest Intel processors and coprocessors. See abstracts and register > > http://pubads.g.doubleclick.net/gampad/clk?id=60134791&iu=/4140/ostg.clktrk > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > |
From: David H. <da...@ad...> - 2013-10-02 05:46:18
|
dang it. scratch that initial impression where I thought the patch applied on 0.9-dev. I was actually on the 0.8.1 precursor. damn hg vs stupid git... (small differences between hg and git: I'm used to "git log" showing me just the history of the branch I'm on. "hg log" shows the whole log across branches... ok, so I'll need to read hg's driver's ed handbook first.) On Tue, Oct 1, 2013 at 11:55 AM, David Holl <da...@ad...> wrote: > tl;dr: My patch against 0.8 appears can be applied against the 0.9-dev > repo, and it satisfies my very limited testing. > > The changes in 0.9-dev were not near my hack-n-slash campaign. (I kept > most of my changes _after_ MyHDL's normal extraction and analysis > algorithm, with only a few small hooks into signals and generators to > assist with partition-tagging.) > > To test, I first removed the current myhdl-0.8 I had in my Python > installation, then I followed these steps: > > # (I removed my current myhdl-0.8 from my Python installation.) > hg clone https://bitbucket.org/jandecaluwe/myhdl > cd myhdl > gunzip -c ../myhdl-0.8-partitions.patch.gz | patch -p1 > python setup.py build > python setup.py install --user -O2 > > Then I reran my test_partition.py, and the output is identical. (except > that the new myhdl is injecting some $signed(...) stuff in 1 place where > I'm substracting...) > > I also reran my pcie designs (with partitions), and that also produced > identical output. (but again with $signed(...) stuff but in 2 places where > I'm subtracting...) > > > To confirm I'm using the latest repo, here's the recent log entry: > hg log | head -8 > changeset: 1358:324a8d3206fb > branch: 0.9-dev > tag: tip > parent: 1356:db95c2d47119 > parent: 1357:8de9f8771395 > user: Jan Decaluwe <ja...@ja...> > date: Sun Sep 22 19:14:21 2013 +0200 > summary: Bug fix merge from default > > > And the patch applied fairly cleanly, with only 2 offset changes: > gunzip -c ../myhdl-0.8-partitions.patch.gz | patch -p1 > patching file myhdl/_Signal.py > patching file myhdl/__init__.py > patching file myhdl/_always.py > patching file myhdl/_always_comb.py > Hunk #1 succeeded at 190 (offset 10 lines). > patching file myhdl/_always_seq.py > patching file myhdl/_contextdecorator.py > patching file myhdl/_extractHierarchy.py > patching file myhdl/_instance.py > patching file myhdl/_partition.py > patching file myhdl/conversion/_analyze.py > Hunk #5 succeeded at 865 (offset 5 lines). > patching file myhdl/conversion/_toVerilog.py > > > The rest of this email is a quick summary of my changes per file: > > __init__.py: include "partition" and "get_current_partition" in the myhdl > namespace. get_current_partition() may be called from within a partition > to assign attributes. > > For example, to assign attributes using the "with" syntax: > > with partition('A') as this_part: # This will be renamed to A0 > this_part.attr_add('KEEP_HIERARCHY', 'TRUE') > this_part.attr_add('DONT_TOUCH', 'TRUE') > > @always(clk.posedge) > def clgd(): > d.next = c + e > > And to assign attributes from inside a partition (such as when using the > "decorator" syntax): > > @partition('AES') # <---- partition a la decorator. > def my_module_bob(...): > # ... > this_part = get_current_partition() > this_part.attr_add('DONT_TOUCH', 'TRUE') > return instances() > > > _Signal.py: Small change. I radio tag each signal with the current > partition. (Actually, I originally didn't need to do this, until I tried > figuring out where to place ConcatSignal drivers (ie, which partition to > invoke their _toVerilog [or _toVHDL] method). In short, Iw as tired after > devising the auto-magic placement for every other signal type, so I just > gave up on auto-placement of ConcatSignals, and instead just use the tagged > partition to indicate where to place each ConcatSignal's driver. (ie, For > all other signals, it doesn't matter where you happen to declare them, > since the output code will auto placed based on the location of any driving > generator. But for ConcatSignal's, the output code will strictly place > their driver inside whatever partition you happend to create the > ConcatSignal in python.) > > > _instance.py: Small change, to support any extension to "monkey patch" its > way into tagging generators inheriting from _Instantiator. (Actually, I > should've structured my change to _Signal.py like this one, to open the way > for any future extensions to also "monkey patch" their way into _Signal's > and shadow signals...) > > > _always.py: _Always inherits from _Instantiator but does not invoke it's > constructor. Therefore, I manually invoke the "hookInit" that I created > inside _Instantiator. > > > _always_comb.py: Same as _always.py. Manually invoke the "hookInit" that > I created inside _Instantiator. > > > _always_seq.py: Same as _always.py... > > > _extractHierarchy.py: Tweak _HierExtr and _Instance to preserve hookData > placed via hookInit from _Instantiator. I also tweaked _UserCode and > _addUserCode to preserve hookData, but I haven't tried any user-defined > Verilog (or VHDL) to test this. TODO: If anyone has user-defined code, try > putting it in a partition (perhaps easiest via "with"), and tell me if it > is placed in the correct Verilog module on output. > > > _contextdecorator.py: New file, from > http://pypi.python.org/pypi/contextdecorator to support both "with > partition(...) ..." and "@partition(...)" mechanisms. > > > _partition.py: New file, and is actually pretty short. It defines > "partition" and "get_current_partition" API, and inject the partition tags > in the relevant objects such as @always, @always_comb, @always_seq. > > > conversion/_analyze.py: Preserve hookData in _analyzeGens. And > in _AnalyzeVisitor, I added tree.inmems to mirror record keeping of > tree.outmems, so that I can verify that memories are only read from the > same partition in which they're driven. > > > conversion/_toVerilog.py: Thar be dragons. Here is where I added > toVerilog.partitioned_output, to invoke my alternative Verilog output code > contained in _write_partitioned_output(...). TODO: I should > move _write_partitioned_output and its supporting entourage to another > file. (SigMapping, > lookup_id, distill_signals_and_memories, _apply_renames, _generate_partitions, _partition2name, _make_unique_names) > > > > > > > > On Sun, Sep 29, 2013 at 8:25 PM, Keerthan jai.c <jck...@gm...>wrote: > >> David, >> >> Just a heads up, the 0.9 dev branch on bitbucket has quite a few changes >> in the conversion area(MEP 107). You might want to check whether these >> patches apply on the new branch. >> >> >> On Sun, Sep 29, 2013 at 2:21 PM, David Holl <da...@ad...> wrote: >> >>> There was an old thread regarding MEP 110, but I've come up with an >>> alternative "solution", and I'm looking for your comments. (call it MEP >>> 110-alt?) >>> >>> tl;dr --- If you're interested, >>> >>> Introduction: Same as MEP 110. (Especially for floor planning...) >>> ----------------------- >>> Analysis: Same as MEP 110. (Yep, everything gets flattened by >>> default...) >>> ----------------------- >>> Proposed Solution: (with implementation) >>> >>> I did not follow the proposed solution in MEP 110, because that would've >>> required that I change [any of] my components to be "top-module >>> convertible". (I'm using a form of signal containers --similar to MEP >>> 107-- which which would've required many changes (in my code) to achieve >>> "top-module convertibility".) >>> >>> What I did was I started from the flattened hierarchy in >>> conversion/_toVerilog.py, but instead of calling the usual >>> _writeSigDecls, _convertGens, I wrote my own convoluted output code: >>> ... >>> if self.partitioned_output: >>> _write_partitioned_output(self.partitioned_output, >>> vfile, vpath, self.timescale, h, intf, siglist, memlist, genlist, doc) >>> else: >>> _writeFileHeader(vfile, vpath, self.timescale) >>> _writeModuleHeader(vfile, intf, doc) >>> _writeSigDecls(vfile, intf, siglist, memlist) >>> _convertGens(genlist, vfile) >>> _writeModuleFooter(vfile) >>> ... >>> >>> >>> To activate this alternative output, just >>> set toVerilog.partitioned_output=True: >>> toVerilog.name='test_partition' >>> toVerilog.partitioned_output=True # the default is False >>> toVerilog(_test_top, clk, AAA, BBB, ZZZ, TTT, VVV) >>> >>> Without any other changes to a hardware description, this alternative >>> code will produce identical, flattened output. (right down to the arbitrary >>> ordering of signals and generators...) >>> >>> However, you may now group any related logic together, as needed. I >>> call a group of logic a "partition", and these partitions may be nested. >>> Instead of the word "partition" you could call it a "module" instead, >>> since the concept is almost identical to Verilog module's. In the >>> following description, it will appear that I'm flipping between "partition" >>> and "module" when really, I'm describing how that partitions in python >>> impact the created Verilog modules. (but for simplistic purposes, since I >>> guarantee each "partition" will create a unique Verilog "module", feel free >>> to call em' what you want...) >>> >>> There are 2 ways to assign related hardware into partitions. >>> ----------------------- >>> 1) The first is via python's "with" statement. I'll show a few examples: >>> >>> example 1.a) A simple partition... >>> from myhdl import Signal, partition, ... >>> >>> @always(clk.posedge) >>> def clgc(): >>> c.next = a + b >>> >>> with partition('A'): >>> @always(clk.posedge) >>> def clgd(): >>> d.next = c + e >>> >>> @always(clk.posedge) >>> def clge(): >>> e.next = a * b >>> >>> @always(clk.posedge) >>> def clgf(): >>> f.next = more stuff... >>> >>> >>> What "partition" does is annotate all generators (and shadow signals...) >>> with your text label. Then the "partitioned-output" code uses these >>> annotations move related logic into a Verilog module, and instantiate that >>> module from the top-level module. Module ports are automatically created >>> for any signals that need to cross between modules. >>> >>> This code still creates only 1 output .v file containing all modules. >>> (I didn't care if it was 1 file or multiple files, but for me, 1 file was >>> "easier" to move/copy around in my opinion.) >>> >>> The top module will include all of the signals, except for "e" --- >>> because in this code, e is only used within partition A. Therefore "e" >>> will appear as a driven "reg" within a submodule called A. (and that >>> submodule "A" is instantiated in the top level as "part_A"...) >>> >>> >>> >>> example 1.b) Partitions may be nested. >>> >>> @always(clk.posedge) >>> def clgc(): >>> c.next = a + b >>> >>> with partition('A'): >>> @always(clk.posedge) >>> def clgd(): >>> d.next = c + e >>> >>> with partition('B'): >>> @always(clk.posedge) >>> def clge(): >>> e.next = a * b >>> >>> @always(clk.posedge) >>> def clgf(): >>> f.next = more stuff... >>> >>> >>> This code will create 3 modules total: the top module, a module called >>> "A", and a module called "A_B". >>> >>> >>> example 1.c) Partitions having the same name will be renamed to stay >>> unique! >>> >>> If you want related code to be grouped into a partition, all of that >>> code must be contained in the same python "with" block. For example: >>> >>> from myhdl import Signal, partition, ... >>> >>> @always(clk.posedge) >>> def clgc(): >>> c.next = a + b >>> >>> with partition('A'): # This will be renamed to A0 >>> @always(clk.posedge) >>> def clgd(): >>> d.next = c + e >>> >>> with partition('A'): # This will be renamed to A1 >>> @always(clk.posedge) >>> def clge(): >>> e.next = a * b >>> >>> >>> Rationale: When you start nesting partitions, partition names are >>> guaranteed to produce unique module instances and not accidentally group >>> unrelated logic together. >>> >>> >>> example 1.d) Partitions are nestable across your python function calls, >>> and renaming will happen to keep sub >>> >>> For example, unrelated nested partitions may use the same name without >>> fear of their logic being accidentally grouped together. >>> >>> from myhdl import Signal, partition, ... >>> >>> def my_module_alice(...): >>> # ... >>> with partition('SM'): >>> # This happens to enclose a state machine. >>> # The name SM isn't descriptive enough, but if you >>> # want descriptive Verilog output, then you should >>> # use descriptive names. >>> # ... >>> # ... >>> return instances() >>> >>> def my_module_bob(...): >>> # ... >>> with partition('SM'):# This encloses an unrelated state machine. >>> # ... >>> # ... >>> return instances() >>> >>> def top(...): >>> @always(clk.posedge) >>> def clgc(): >>> c.next = a + b >>> >>> with partition('CRYPTO'): >>> alice_inst = alice(...) >>> bob0_inst = bob(...) >>> bob1_inst = bob(...) >>> >>> with partition('CRYPTO_SM2'): >>> # I made this CRYPTO_SM2 name, just to be a jerk. >>> @always(clk.posedge) >>> def clgd(): >>> d.next = c + e >>> >>> >>> This code would produce 6 instantiated modules in the generated Verilog >>> output: >>> module top(...); >>> module CRYPTO(...); >>> module CRYPTO_SM0(...); // this is from alice_inst >>> module CRYPTO_SM1(...); // this is from bob0_inst >>> module CRYPTO_SM2(...); // this is from bob1_inst >>> module CRYPTO_SM2_(...); // renamed CRYPTO_SM2 to not conflict with >>> CRYPT_SM2 from bob1_inst >>> >>> Admittedly, the generated names CRYPTO_SM... in this example aren't very >>> clear, but the point here is that your python functions (like alice() and >>> bob()) have a guaranteed means to group logic into a Verilog module without >>> accidental commingling of unrelated from other modules. >>> >>> The "top" module instantates "CRYPTO" and "CRYPTO_SM2_". Then "CRYPTO" >>> instantiates "CRYPTO_SM0", "CRYPTO_SM1", and "CRYPTO_SM2". >>> >>> >>> example 1.e) Partitions support Verilog 2001 attributes (and if someone >>> wants to add VHDL support...) >>> >>> with partition('A') as this_part: # This will be renamed to A0 >>> this_part.attr_add('KEEP_HIERARCHY', 'TRUE') >>> this_part.attr_add('DONT_TOUCH', 'TRUE') >>> >>> @always(clk.posedge) >>> def clgd(): >>> d.next = c + e >>> >>> This will produce output that instantiates module A as: >>> >>> (* KEEP_HIERARCHY="TRUE", DONT_TOUCH="TRUE" *) part_A A(clk, c, e, d); >>> >>> // The generated module for instance A is called "part_A". >>> >>> (MyHDL also has a nifty feature to include doc strings as embedded >>> comments. I have some back-end support for attaching a string to a >>> partition, to be output as a comment in the code, but I haven't turned it >>> on yet.) >>> >>> ----------------------- >>> 2) The second way to group logic into a partition is with a python >>> decorator. >>> >>> example 2) Using decorators in addition to "with" blocks. >>> >>> The decorator syntax uses the same rules as the with-blocks. (All >>> partitions will be unique, and possibly suffixed with a number to maintain >>> uniqueness in the Verilog code. Partitions may be nested. Use descriptive >>> names if you want descriptive output.) >>> >>> Here, I'll intermix the decorator and with syntax: >>> >>> def my_module_alice(...): >>> # ... >>> with partition('SM'): >>> # This happens to enclose a state machine. >>> # The name SM isn't descriptive enough, but if you >>> # want descriptive Verilog output, then you should >>> # use descriptive names. >>> # ... >>> # ... >>> return instances() >>> >>> @partition('AES') # <---- partition a la decorator. >>> def my_module_bob(...): >>> # ... >>> with partition('SM'):# This encloses an unrelated state machine. >>> # ... >>> # ... >>> return instances() >>> >>> def top(...): >>> @always(clk.posedge) >>> def clgc(): >>> c.next = a + b >>> >>> with partition('CRYPTO'): >>> alice_inst = alice(...) >>> bob0_inst = bob(...) >>> bob1_inst = bob(...) >>> >>> with partition('CRYPTO_SM2'): >>> # I made this CRYPTO_SM2 name, just to be a jerk. >>> @always(clk.posedge) >>> def clgd(): >>> d.next = c + e >>> >>> The above code will generate ~8 modules: >>> module top(...); >>> module CRYPTO(...); >>> module CRYPTO_SM(...); // this is from alice_inst >>> module CRYPTO_AES0(...); // decorator on bob() >>> module CRYPTO_AES0_SM(...); // this is from bob0_inst >>> module CRYPTO_AES1(...); // decorator on bob() >>> module CRYPTO_AES1_SM(...); // this is from bob1_inst >>> module CRYPTO_SM2(...); // renamed CRYPTO_SM2 to not conflict with >>> CRYPT.SM from bob1_inst >>> >>> >>> ----------------------- END OF EXAMPLES >>> >>> Limitations: I hope there aren't any. I put enough care to accomodate >>> ConcatSignal's, _SliceSignal's, const [undriven] _Signal's, etc... And if >>> a signal gets pushed into a sub-partition where it is both driven and read, >>> as well as output from that sub-partition, the generator will automatically >>> make a separate wire just for the output port, that is driven from your >>> signal. (This prevents "Output port is read internally..." warnings for >>> partition-generated modules. I don't do this for the top-level though, to >>> preserve the same interface as current MyHDL output.) >>> >>> Component Conversion: No additional restrictions beyond that of MyHDL. >>> There is still the same requirement on your top-level to be "top-level >>> convertible", but there is flexibility for your lower levels. >>> >>> Component Parameters: What parameters? All of your parameters were >>> already digested by python+MyHDL magic, and I'm operating on the flattened >>> hierarchy. If you invoke the same sub-partition (sub-module) multiple >>> times, it will be replicated in the output, but every time it appears, it >>> will use the globally-unique signal names that MyHDL has already assigned. >>> (ie, I don't change your signal names.) >>> >>> Any drawbacks: >>> This may/will produce larger output code than the proposed solution in >>> MEP 110. The existing MEP 110 solution will create 1 copy of each module, >>> and instantiate it multiple times (as long as each instantiation shares the >>> same port signal widths, etc...). In contrast, this "110.alt" solution >>> will create a whole copy of a module every time it is instantiated. (But >>> each copy inherits the unique signal names assigned by MyHDL's flattening >>> algorithm.) However, the larger output size from this "110.alt" isn't that >>> much larger than MyHDL's native flat output. (depending on your signal >>> usage...) >>> >>> Benefits: >>> You can have hierarchical output with minimal changes to your code, >>> and you control exactly how your logic is partitioned into the hierarchy. >>> Just sprinkle a few @partition(...) or "with partition(...):" statements >>> wherever you need in your design. >>> >>> Known pitfalls: I have not tried or tested TristateSignal's for "inout" >>> ports, and I've only tested on a very narrow subset of MyHDL's feature set. >>> (I was was already bitten by ConcatSignal's, _SliceSignal's, and lists of >>> signals accidentally being inferred as memories... However, I expect these >>> areas to work as expected now.) >>> >>> >>> But if anyone is interested, here's the code, and I'm open for feedback. >>> >>> I attached patches against myhdl-0.8.tar.gz available from >>> https://sourceforge.net/projects/myhdl/files/myhdl/0.8/ >>> >>> Of the 2 patches, myhdl-0.8-fix_modbv.patch is my poor-man's fix for >>> modbv, because I needed modbv. This patch is most likely obsoleted by >>> Jan's real fix in the repo. >>> >>> The other patch (myhdl-0.8-partitions.patch) contains my crude first >>> draft supporting the described hierarchy. Yes, this code is ugly. Don't >>> look at it yet. It is a quick mock-up of some functionality I really >>> wanted. But give it a try if you're interested and let me know what it >>> breaks on... Or if you really want to dive into the code, feel free to do >>> so. >>> >>> On my systems, I apply & install these patches as follows: (gunzip the >>> .patch files first) >>> >>> gunzip myhdl-0.8-fix_modbv.patch.gz >>> gunzip myhdl-0.8-partitions.patch.gz >>> tar zxf myhdl-0.8.tar.gz \ >>> && cd myhdl-0.8 \ >>> && patch -p1 < ../myhdl-0.8-fix_modbv.patch \ >>> && patch -p1 < ../myhdl-0.8-partitions.patch \ >>> && python setup.py build \ >>> && python setup.py install --user -O2 \ >>> && cd .. \ >>> && rm -rf myhdl-0.8 >>> >>> This installs myhdl into python's standard location for my home >>> directory, but feel free to leave off --user to install to the main system >>> path, or wherever else you want. >>> >>> To test drive the functionality, try running test_partition.py. Set >>> toVerilog.partitioned_output=False >>> to see the normal output, and >>> toVerilog.partitioned_output=True >>> to see the partitioned output. And if you are curious, try >>> toVerilog.partitioned_output="I promise I will never die." >>> to enable the partitioned output code, but tell it to ignore the >>> partition annotations. >>> >>> >>> (typos and all, I'm hitting send...) >>> >>> - David >>> >>> >>> >>> On Wed, May 1, 2013 at 6:44 PM, Oscar Daniel Diaz <osc...@gm...>wrote: >>> >>>> El Wed, 01 May 2013 10:55:55 +0200 >>>> Jan Decaluwe <ja...@ja...> escribió: >>>> >>>> > On 04/29/2013 05:25 PM, Oscar Daniel Diaz wrote: >>>> > >>>> > > Given that the converter is called recursively several times, >>>> > > multiple files are generated and its contents are used for component >>>> > > declaration (VHDL). Recursive calls must avoid file replication (for >>>> > > VHDL case means avoid multiple package file generation). This is >>>> > > done by keeping generated code in memory before pushing to files. >>>> > > >>>> > > Attribute "no_component_files" : >>>> > > * False : all components code is saved to disk as soon as >>>> > > possible. >>>> > > * True : discard components code, only save top-module file. >>>> > >>>> > Not sure what is meant here exactly. Why would we need component >>>> > declarations, as opposed to simply using direct instantation? >>>> > For a case like this, this seems much simpler and less verbose >>>> > to me. >>>> >>>> Since keep hierarchy conversion requires multiple files to generate >>>> (top-module and components to instantiate), this flag prevents >>>> generation of those components. Suppose you make some changes only in >>>> the top-module, this flag allows to only generate top-module file. >>>> >>>> When I change from VHDL '87 syntax (doing recursive calls to get >>>> component declaration) to '93 syntax, that flag would prevent >>>> those recursive calls. >>>> >>>> -- >>>> Oscar Díaz >>>> Key Fingerprint = 904B 306C C3C2 7487 650B BFAC EDA2 B702 90E9 9964 >>>> gpg --keyserver subkeys.pgp.net --recv-keys 90E99964 >>>> >>>> >>>> _______________________________________________ >>>> myhdl-list mailing list >>>> myh...@li... >>>> https://lists.sourceforge.net/lists/listinfo/myhdl-list >>>> >>>> >>> >>> >>> ------------------------------------------------------------------------------ >>> October Webinars: Code for Performance >>> Free Intel webinars can help you accelerate application performance. >>> Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most >>> from >>> the latest Intel processors and coprocessors. See abstracts and register >>> > >>> >>> http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk >>> >>> _______________________________________________ >>> myhdl-list mailing list >>> myh...@li... >>> https://lists.sourceforge.net/lists/listinfo/myhdl-list >>> >>> >> >> >> -- >> have a nice day >> -jck >> >> >> ------------------------------------------------------------------------------ >> October Webinars: Code for Performance >> Free Intel webinars can help you accelerate application performance. >> Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most >> from >> the latest Intel processors and coprocessors. See abstracts and register > >> >> http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk >> _______________________________________________ >> myhdl-list mailing list >> myh...@li... >> https://lists.sourceforge.net/lists/listinfo/myhdl-list >> >> > |
From: Keerthan jai.c <jck...@gm...> - 2013-10-01 23:13:02
|
Conversion of interfaces in the top level makes the arguments for cosimulation tricky. I think one option to simplify this is to store intf as an attribute in the toVerilog and toVHDL objects. You can then pass **toVerilog.intf as the second argument to Cosimulation. On Sat, Sep 14, 2013 at 6:58 AM, Jan Decaluwe <ja...@ja...> wrote: > On 09/14/2013 12:08 PM, Keerthan jai.c wrote: > > Jan, could you elaborate on the dynamically set attributes case? > > None of the tests in conversion/toVerilog seem to be failing for me. > > jand@gamay:~/dev/myhdl/myhdl/test/conversion/toVerilog$ py.test > test_newcustom.py > ========================================================================== > test session starts > ========================================================================== > platform linux2 -- Python 2.6.5 -- pytest-2.0.1 > collected 7 items > > test_newcustom.py .F..... > > > -- > Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com > Python as a HDL: http://www.myhdl.org > VHDL development, the modern way: http://www.sigasi.com > World-class digital design: http://www.easics.com > > > ------------------------------------------------------------------------------ > LIMITED TIME SALE - Full Year of Microsoft Training For Just $49.99! > 1,500+ hours of tutorials including VisualStudio 2012, Windows 8, > SharePoint > 2013, SQL 2012, MVC 4, more. BEST VALUE: New Multi-Library Power Pack > includes > Mobile, Cloud, Java, and UX Design. Lowest price ever! Ends 9/22/13. > http://pubads.g.doubleclick.net/gampad/clk?id=64545871&iu=/4140/ostg.clktrk > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > -- have a nice day -jck |
From: Angel E. <ang...@gm...> - 2013-10-01 22:44:29
|
I cannot comment on the ASIC side, but on the FPGA side it is a common recommendation to properly organize your code into entities to improve the map and/or plan and route results. I believe that it is also necessary to be able to do incremental builds and what they call "Partial Reconfiguration", which "is the ability to dynamically modify blocks of logic by downloading partial bit files while the remaining logic continues to operate without interruption". I'm not saying this is something that Xilinx could not improve (I really think they could and they should). However, I would not hold my breath hoping for Xilinx tools to improve in this regard. They are a little better now, but their tools used to be and still are to a long extent very rudimentary and finicky. My guess is that they have a lot of other things that they must improve before getting to this. I also think that being able to control how the generated code is split into files and entities would be nice, particularly if you had to debug some generation issue. It might also help when adding chipscope probes. Finally, it would make it easier to include generated VHDL or Verilog files into version control. In general I don't think that generated VHDL and Verilog files should be put into version control, because they are derived files that can be generated from the MyHDL sources. However, some projects have policies that require all VHDL or Verilog code to be included on the source repository. In those cases having a single big generated VHDL file is a pain because it changes with every modification of any of the MyHDL files, and it is hard to tell what changed in that big single file. If multiple files were generated, only some of those files would usually change, making it easier to tell what changed in a given version. So I think that there are a few sensible reasons for wanting the ability to split the generated design into files and entities. Cheers, Angel On Tue, Oct 1, 2013 at 9:45 PM, Jan Decaluwe <ja...@ja...> wrote: > A few helicopter-view comments on this. > > I still have an issue with floorplanning being that important. > Afaik we can do million-gate ASICs without floorplanning at > all. It seems to me an ideal problem for full automation by > layout tools. > > To put it differently, if one really needs floorplanning, I > would think it applies to very large projects with big > budgets - more than enough to actually pay someone to > solve this in MyHDL (me for example :-)). > > Of course, FPGAs may be be different. But I still > would think it's a matter of back-end tools that need > to improve in the first place - not our task. > > So - are we really sure floorplanning actually makes > a difference? > > If it does, I certainly would not want a solution that > influences the source code significantly, as I think this > solution is suggesting. It has nothing to do with functionality. > Instead it would make source code target-dependent, as > the floorplanning solution for one target may not be right > or required for another one. > > Jan > > On 09/29/2013 08:21 PM, David Holl wrote: >> There was an old thread regarding MEP 110, but I've come up with an alternative "solution", and I'm looking for your comments. (call it MEP 110-alt?) >> >> tl;dr --- If you're interested, >> >> Introduction: Same as MEP 110. (Especially for floor planning...) >> ----------------------- >> Analysis: Same as MEP 110. (Yep, everything gets flattened by default...) >> ----------------------- >> Proposed Solution: (with implementation) >> >> I did not follow the proposed solution in MEP 110, because that would've required that I change [any of] my components to be "top-module convertible". (I'm using a form of signal containers --similar to MEP 107-- which which would've required many changes (in my code) to achieve "top-module convertibility".) >> >> What I did was I started from the flattened hierarchy in conversion/_toVerilog.py, but instead of calling the usual _writeSigDecls, _convertGens, I wrote my own convoluted output code: >> ... >> if self.partitioned_output: >> _write_partitioned_output(self.partitioned_output, vfile, vpath, self.timescale, h, intf, siglist, memlist, genlist, doc) >> else: >> _writeFileHeader(vfile, vpath, self.timescale) >> _writeModuleHeader(vfile, intf, doc) >> _writeSigDecls(vfile, intf, siglist, memlist) >> _convertGens(genlist, vfile) >> _writeModuleFooter(vfile) >> ... >> >> >> To activate this alternative output, just set toVerilog.partitioned_output=True: >> toVerilog.name='test_partition' >> toVerilog.partitioned_output=True # the default is False >> toVerilog(_test_top, clk, AAA, BBB, ZZZ, TTT, VVV) >> >> Without any other changes to a hardware description, this alternative code will produce identical, flattened output. (right down to the arbitrary ordering of signals and generators...) >> >> However, you may now group any related logic together, as needed. I call a group of logic a "partition", and these partitions may be nested. Instead of the word "partition" you could call it a "module" instead, since the concept is almost identical to Verilog module's. In the following description, it will appear that I'm flipping between "partition" and "module" when really, I'm describing how that partitions in python impact the created Verilog modules. (but for simplistic purposes, since I guarantee each "partition" will create a unique Verilog "module", feel free to call em' what you want...) >> >> There are 2 ways to assign related hardware into partitions. >> ----------------------- >> 1) The first is via python's "with" statement. I'll show a few examples: >> >> example 1.a) A simple partition... >> from myhdl import Signal, partition, ... >> >> @always(clk.posedge) >> def clgc(): >> c.next = a + b >> >> with partition('A'): >> @always(clk.posedge) >> def clgd(): >> d.next = c + e >> >> @always(clk.posedge) >> def clge(): >> e.next = a * b >> >> @always(clk.posedge) >> def clgf(): >> f.next = more stuff... >> >> >> What "partition" does is annotate all generators (and shadow signals...) with your text label. Then the "partitioned-output" code uses these annotations move related logic into a Verilog module, and instantiate that module from the top-level module. Module ports are automatically created for any signals that need to cross between modules. >> >> This code still creates only 1 output .v file containing all modules. (I didn't care if it was 1 file or multiple files, but for me, 1 file was "easier" to move/copy around in my opinion.) >> >> The top module will include all of the signals, except for "e" --- because in this code, e is only used within partition A. Therefore "e" will appear as a driven "reg" within a submodule called A. (and that submodule "A" is instantiated in the top level as "part_A"...) >> >> >> >> example 1.b) Partitions may be nested. >> >> @always(clk.posedge) >> def clgc(): >> c.next = a + b >> >> with partition('A'): >> @always(clk.posedge) >> def clgd(): >> d.next = c + e >> >> with partition('B'): >> @always(clk.posedge) >> def clge(): >> e.next = a * b >> >> @always(clk.posedge) >> def clgf(): >> f.next = more stuff... >> >> >> This code will create 3 modules total: the top module, a module called "A", and a module called "A_B". >> >> >> example 1.c) Partitions having the same name will be renamed to stay unique! >> >> If you want related code to be grouped into a partition, all of that code must be contained in the same python "with" block. For example: >> >> from myhdl import Signal, partition, ... >> >> @always(clk.posedge) >> def clgc(): >> c.next = a + b >> >> with partition('A'): # This will be renamed to A0 >> @always(clk.posedge) >> def clgd(): >> d.next = c + e >> >> with partition('A'): # This will be renamed to A1 >> @always(clk.posedge) >> def clge(): >> e.next = a * b >> >> >> Rationale: When you start nesting partitions, partition names are guaranteed to produce unique module instances and not accidentally group unrelated logic together. >> >> >> example 1.d) Partitions are nestable across your python function calls, and renaming will happen to keep sub >> >> For example, unrelated nested partitions may use the same name without fear of their logic being accidentally grouped together. >> >> from myhdl import Signal, partition, ... >> >> def my_module_alice(...): >> # ... >> with partition('SM'): >> # This happens to enclose a state machine. >> # The name SM isn't descriptive enough, but if you >> # want descriptive Verilog output, then you should >> # use descriptive names. >> # ... >> # ... >> return instances() >> >> def my_module_bob(...): >> # ... >> with partition('SM'):# This encloses an unrelated state machine. >> # ... >> # ... >> return instances() >> >> def top(...): >> @always(clk.posedge) >> def clgc(): >> c.next = a + b >> >> with partition('CRYPTO'): >> alice_inst = alice(...) >> bob0_inst = bob(...) >> bob1_inst = bob(...) >> >> with partition('CRYPTO_SM2'): >> # I made this CRYPTO_SM2 name, just to be a jerk. >> @always(clk.posedge) >> def clgd(): >> d.next = c + e >> >> >> This code would produce 6 instantiated modules in the generated Verilog output: >> module top(...); >> module CRYPTO(...); >> module CRYPTO_SM0(...); // this is from alice_inst >> module CRYPTO_SM1(...); // this is from bob0_inst >> module CRYPTO_SM2(...); // this is from bob1_inst >> module CRYPTO_SM2_(...); // renamed CRYPTO_SM2 to not conflict with CRYPT_SM2 from bob1_inst >> >> Admittedly, the generated names CRYPTO_SM... in this example aren't very clear, but the point here is that your python functions (like alice() and bob()) have a guaranteed means to group logic into a Verilog module without accidental commingling of unrelated from other modules. >> >> The "top" module instantates "CRYPTO" and "CRYPTO_SM2_". Then "CRYPTO" instantiates "CRYPTO_SM0", "CRYPTO_SM1", and "CRYPTO_SM2". >> >> >> example 1.e) Partitions support Verilog 2001 attributes (and if someone wants to add VHDL support...) >> >> with partition('A') as this_part: # This will be renamed to A0 >> this_part.attr_add('KEEP_HIERARCHY', 'TRUE') >> this_part.attr_add('DONT_TOUCH', 'TRUE') >> >> @always(clk.posedge) >> def clgd(): >> d.next = c + e >> >> This will produce output that instantiates module A as: >> >> (* KEEP_HIERARCHY="TRUE", DONT_TOUCH="TRUE" *) part_A A(clk, c, e, d); >> >> // The generated module for instance A is called "part_A". >> >> (MyHDL also has a nifty feature to include doc strings as embedded comments. I have some back-end support for attaching a string to a partition, to be output as a comment in the code, but I haven't turned it on yet.) >> >> ----------------------- >> 2) The second way to group logic into a partition is with a python decorator. >> >> example 2) Using decorators in addition to "with" blocks. >> >> The decorator syntax uses the same rules as the with-blocks. (All partitions will be unique, and possibly suffixed with a number to maintain uniqueness in the Verilog code. Partitions may be nested. Use descriptive names if you want descriptive output.) >> >> Here, I'll intermix the decorator and with syntax: >> >> def my_module_alice(...): >> # ... >> with partition('SM'): >> # This happens to enclose a state machine. >> # The name SM isn't descriptive enough, but if you >> # want descriptive Verilog output, then you should >> # use descriptive names. >> # ... >> # ... >> return instances() >> >> @partition('AES') # <---- partition a la decorator. >> def my_module_bob(...): >> # ... >> with partition('SM'):# This encloses an unrelated state machine. >> # ... >> # ... >> return instances() >> >> def top(...): >> @always(clk.posedge) >> def clgc(): >> c.next = a + b >> >> with partition('CRYPTO'): >> alice_inst = alice(...) >> bob0_inst = bob(...) >> bob1_inst = bob(...) >> >> with partition('CRYPTO_SM2'): >> # I made this CRYPTO_SM2 name, just to be a jerk. >> @always(clk.posedge) >> def clgd(): >> d.next = c + e >> >> The above code will generate ~8 modules: >> module top(...); >> module CRYPTO(...); >> module CRYPTO_SM(...); // this is from alice_inst >> module CRYPTO_AES0(...); // decorator on bob() >> module CRYPTO_AES0_SM(...); // this is from bob0_inst >> module CRYPTO_AES1(...); // decorator on bob() >> module CRYPTO_AES1_SM(...); // this is from bob1_inst >> module CRYPTO_SM2(...); // renamed CRYPTO_SM2 to not conflict with CRYPT.SM <http://CRYPT.SM> from bob1_inst >> >> >> ----------------------- END OF EXAMPLES >> >> Limitations: I hope there aren't any. I put enough care to accomodate ConcatSignal's, _SliceSignal's, const [undriven] _Signal's, etc... And if a signal gets pushed into a sub-partition where it is both driven and read, as well as output from that sub-partition, the generator will automatically make a separate wire just for the output port, that is driven from your signal. (This prevents "Output port is read internally..." warnings for partition-generated modules. I don't do this for the top-level though, to preserve the same interface as current MyHDL output.) >> >> Component Conversion: No additional restrictions beyond that of MyHDL. There is still the same requirement on your top-level to be "top-level convertible", but there is flexibility for your lower levels. >> >> Component Parameters: What parameters? All of your parameters were already digested by python+MyHDL magic, and I'm operating on the flattened hierarchy. If you invoke the same sub-partition (sub-module) multiple times, it will be replicated in the output, but every time it appears, it will use the globally-unique signal names that MyHDL has already assigned. (ie, I don't change your signal names.) >> >> Any drawbacks: >> This may/will produce larger output code than the proposed solution in MEP 110. The existing MEP 110 solution will create 1 copy of each module, and instantiate it multiple times (as long as each instantiation shares the same port signal widths, etc...). In contrast, this "110.alt" solution will create a whole copy of a module every time it is instantiated. (But each copy inherits the unique signal names assigned by MyHDL's flattening algorithm.) However, the larger output size from this "110.alt" isn't that much larger than MyHDL's native flat output. (depending on your signal usage...) >> >> Benefits: >> You can have hierarchical output with minimal changes to your code, and you control exactly how your logic is partitioned into the hierarchy. Just sprinkle a few @partition(...) or "with partition(...):" statements wherever you need in your design. >> >> Known pitfalls: I have not tried or tested TristateSignal's for "inout" ports, and I've only tested on a very narrow subset of MyHDL's feature set. (I was was already bitten by ConcatSignal's, _SliceSignal's, and lists of signals accidentally being inferred as memories... However, I expect these areas to work as expected now.) >> >> >> But if anyone is interested, here's the code, and I'm open for feedback. >> >> I attached patches against myhdl-0.8.tar.gz available from >> https://sourceforge.net/projects/myhdl/files/myhdl/0.8/ >> >> Of the 2 patches, myhdl-0.8-fix_modbv.patch is my poor-man's fix for modbv, because I needed modbv. This patch is most likely obsoleted by Jan's real fix in the repo. >> >> The other patch (myhdl-0.8-partitions.patch) contains my crude first draft supporting the described hierarchy. Yes, this code is ugly. Don't look at it yet. It is a quick mock-up of some functionality I really wanted. But give it a try if you're interested and let me know what it breaks on... Or if you really want to dive into the code, feel free to do so. >> >> On my systems, I apply & install these patches as follows: (gunzip the .patch files first) >> >> gunzip myhdl-0.8-fix_modbv.patch.gz >> gunzip myhdl-0.8-partitions.patch.gz >> tar zxf myhdl-0.8.tar.gz \ >> && cd myhdl-0.8 \ >> && patch -p1 < ../myhdl-0.8-fix_modbv.patch \ >> && patch -p1 < ../myhdl-0.8-partitions.patch \ >> && python setup.py build \ >> && python setup.py install --user -O2 \ >> && cd .. \ >> && rm -rf myhdl-0.8 >> >> This installs myhdl into python's standard location for my home directory, but feel free to leave off --user to install to the main system path, or wherever else you want. >> >> To test drive the functionality, try running test_partition.py. Set >> toVerilog.partitioned_output=False >> to see the normal output, and >> toVerilog.partitioned_output=True >> to see the partitioned output. And if you are curious, try >> toVerilog.partitioned_output="I promise I will never die." >> to enable the partitioned output code, but tell it to ignore the partition annotations. >> >> >> (typos and all, I'm hitting send...) >> >> - David >> >> >> >> On Wed, May 1, 2013 at 6:44 PM, Oscar Daniel Diaz <osc...@gm... <mailto:osc...@gm...>> wrote: >> >> El Wed, 01 May 2013 10:55:55 +0200 >> Jan Decaluwe <ja...@ja... <mailto:ja...@ja...>> escribió: >> >> > On 04/29/2013 05:25 PM, Oscar Daniel Diaz wrote: >> > >> > > Given that the converter is called recursively several times, >> > > multiple files are generated and its contents are used for component >> > > declaration (VHDL). Recursive calls must avoid file replication (for >> > > VHDL case means avoid multiple package file generation). This is >> > > done by keeping generated code in memory before pushing to files. >> > > >> > > Attribute "no_component_files" : >> > > * False : all components code is saved to disk as soon as >> > > possible. >> > > * True : discard components code, only save top-module file. >> > >> > Not sure what is meant here exactly. Why would we need component >> > declarations, as opposed to simply using direct instantation? >> > For a case like this, this seems much simpler and less verbose >> > to me. >> >> Since keep hierarchy conversion requires multiple files to generate >> (top-module and components to instantiate), this flag prevents >> generation of those components. Suppose you make some changes only in >> the top-module, this flag allows to only generate top-module file. >> >> When I change from VHDL '87 syntax (doing recursive calls to get >> component declaration) to '93 syntax, that flag would prevent >> those recursive calls. >> >> -- >> Oscar Díaz >> Key Fingerprint = 904B 306C C3C2 7487 650B BFAC EDA2 B702 90E9 9964 >> gpg --keyserver subkeys.pgp.net <http://subkeys.pgp.net> --recv-keys 90E99964 >> >> >> _______________________________________________ >> myhdl-list mailing list >> myh...@li... <mailto:myh...@li...> >> https://lists.sourceforge.net/lists/listinfo/myhdl-list >> >> >> >> >> ------------------------------------------------------------------------------ >> October Webinars: Code for Performance >> Free Intel webinars can help you accelerate application performance. >> Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from >> the latest Intel processors and coprocessors. See abstracts and register > >> http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk >> >> >> >> _______________________________________________ >> myhdl-list mailing list >> myh...@li... >> https://lists.sourceforge.net/lists/listinfo/myhdl-list >> > > > -- > Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com > Python as a HDL: http://www.myhdl.org > VHDL development, the modern way: http://www.sigasi.com > World-class digital design: http://www.easics.com > > ------------------------------------------------------------------------------ > October Webinars: Code for Performance > Free Intel webinars can help you accelerate application performance. > Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from > the latest Intel processors and coprocessors. See abstracts and register > > http://pubads.g.doubleclick.net/gampad/clk?id=60134791&iu=/4140/ostg.clktrk > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list |
From: Jan D. <ja...@ja...> - 2013-10-01 19:46:01
|
A few helicopter-view comments on this. I still have an issue with floorplanning being that important. Afaik we can do million-gate ASICs without floorplanning at all. It seems to me an ideal problem for full automation by layout tools. To put it differently, if one really needs floorplanning, I would think it applies to very large projects with big budgets - more than enough to actually pay someone to solve this in MyHDL (me for example :-)). Of course, FPGAs may be be different. But I still would think it's a matter of back-end tools that need to improve in the first place - not our task. So - are we really sure floorplanning actually makes a difference? If it does, I certainly would not want a solution that influences the source code significantly, as I think this solution is suggesting. It has nothing to do with functionality. Instead it would make source code target-dependent, as the floorplanning solution for one target may not be right or required for another one. Jan On 09/29/2013 08:21 PM, David Holl wrote: > There was an old thread regarding MEP 110, but I've come up with an alternative "solution", and I'm looking for your comments. (call it MEP 110-alt?) > > tl;dr --- If you're interested, > > Introduction: Same as MEP 110. (Especially for floor planning...) > ----------------------- > Analysis: Same as MEP 110. (Yep, everything gets flattened by default...) > ----------------------- > Proposed Solution: (with implementation) > > I did not follow the proposed solution in MEP 110, because that would've required that I change [any of] my components to be "top-module convertible". (I'm using a form of signal containers --similar to MEP 107-- which which would've required many changes (in my code) to achieve "top-module convertibility".) > > What I did was I started from the flattened hierarchy in conversion/_toVerilog.py, but instead of calling the usual _writeSigDecls, _convertGens, I wrote my own convoluted output code: > ... > if self.partitioned_output: > _write_partitioned_output(self.partitioned_output, vfile, vpath, self.timescale, h, intf, siglist, memlist, genlist, doc) > else: > _writeFileHeader(vfile, vpath, self.timescale) > _writeModuleHeader(vfile, intf, doc) > _writeSigDecls(vfile, intf, siglist, memlist) > _convertGens(genlist, vfile) > _writeModuleFooter(vfile) > ... > > > To activate this alternative output, just set toVerilog.partitioned_output=True: > toVerilog.name='test_partition' > toVerilog.partitioned_output=True # the default is False > toVerilog(_test_top, clk, AAA, BBB, ZZZ, TTT, VVV) > > Without any other changes to a hardware description, this alternative code will produce identical, flattened output. (right down to the arbitrary ordering of signals and generators...) > > However, you may now group any related logic together, as needed. I call a group of logic a "partition", and these partitions may be nested. Instead of the word "partition" you could call it a "module" instead, since the concept is almost identical to Verilog module's. In the following description, it will appear that I'm flipping between "partition" and "module" when really, I'm describing how that partitions in python impact the created Verilog modules. (but for simplistic purposes, since I guarantee each "partition" will create a unique Verilog "module", feel free to call em' what you want...) > > There are 2 ways to assign related hardware into partitions. > ----------------------- > 1) The first is via python's "with" statement. I'll show a few examples: > > example 1.a) A simple partition... > from myhdl import Signal, partition, ... > > @always(clk.posedge) > def clgc(): > c.next = a + b > > with partition('A'): > @always(clk.posedge) > def clgd(): > d.next = c + e > > @always(clk.posedge) > def clge(): > e.next = a * b > > @always(clk.posedge) > def clgf(): > f.next = more stuff... > > > What "partition" does is annotate all generators (and shadow signals...) with your text label. Then the "partitioned-output" code uses these annotations move related logic into a Verilog module, and instantiate that module from the top-level module. Module ports are automatically created for any signals that need to cross between modules. > > This code still creates only 1 output .v file containing all modules. (I didn't care if it was 1 file or multiple files, but for me, 1 file was "easier" to move/copy around in my opinion.) > > The top module will include all of the signals, except for "e" --- because in this code, e is only used within partition A. Therefore "e" will appear as a driven "reg" within a submodule called A. (and that submodule "A" is instantiated in the top level as "part_A"...) > > > > example 1.b) Partitions may be nested. > > @always(clk.posedge) > def clgc(): > c.next = a + b > > with partition('A'): > @always(clk.posedge) > def clgd(): > d.next = c + e > > with partition('B'): > @always(clk.posedge) > def clge(): > e.next = a * b > > @always(clk.posedge) > def clgf(): > f.next = more stuff... > > > This code will create 3 modules total: the top module, a module called "A", and a module called "A_B". > > > example 1.c) Partitions having the same name will be renamed to stay unique! > > If you want related code to be grouped into a partition, all of that code must be contained in the same python "with" block. For example: > > from myhdl import Signal, partition, ... > > @always(clk.posedge) > def clgc(): > c.next = a + b > > with partition('A'): # This will be renamed to A0 > @always(clk.posedge) > def clgd(): > d.next = c + e > > with partition('A'): # This will be renamed to A1 > @always(clk.posedge) > def clge(): > e.next = a * b > > > Rationale: When you start nesting partitions, partition names are guaranteed to produce unique module instances and not accidentally group unrelated logic together. > > > example 1.d) Partitions are nestable across your python function calls, and renaming will happen to keep sub > > For example, unrelated nested partitions may use the same name without fear of their logic being accidentally grouped together. > > from myhdl import Signal, partition, ... > > def my_module_alice(...): > # ... > with partition('SM'): > # This happens to enclose a state machine. > # The name SM isn't descriptive enough, but if you > # want descriptive Verilog output, then you should > # use descriptive names. > # ... > # ... > return instances() > > def my_module_bob(...): > # ... > with partition('SM'):# This encloses an unrelated state machine. > # ... > # ... > return instances() > > def top(...): > @always(clk.posedge) > def clgc(): > c.next = a + b > > with partition('CRYPTO'): > alice_inst = alice(...) > bob0_inst = bob(...) > bob1_inst = bob(...) > > with partition('CRYPTO_SM2'): > # I made this CRYPTO_SM2 name, just to be a jerk. > @always(clk.posedge) > def clgd(): > d.next = c + e > > > This code would produce 6 instantiated modules in the generated Verilog output: > module top(...); > module CRYPTO(...); > module CRYPTO_SM0(...); // this is from alice_inst > module CRYPTO_SM1(...); // this is from bob0_inst > module CRYPTO_SM2(...); // this is from bob1_inst > module CRYPTO_SM2_(...); // renamed CRYPTO_SM2 to not conflict with CRYPT_SM2 from bob1_inst > > Admittedly, the generated names CRYPTO_SM... in this example aren't very clear, but the point here is that your python functions (like alice() and bob()) have a guaranteed means to group logic into a Verilog module without accidental commingling of unrelated from other modules. > > The "top" module instantates "CRYPTO" and "CRYPTO_SM2_". Then "CRYPTO" instantiates "CRYPTO_SM0", "CRYPTO_SM1", and "CRYPTO_SM2". > > > example 1.e) Partitions support Verilog 2001 attributes (and if someone wants to add VHDL support...) > > with partition('A') as this_part: # This will be renamed to A0 > this_part.attr_add('KEEP_HIERARCHY', 'TRUE') > this_part.attr_add('DONT_TOUCH', 'TRUE') > > @always(clk.posedge) > def clgd(): > d.next = c + e > > This will produce output that instantiates module A as: > > (* KEEP_HIERARCHY="TRUE", DONT_TOUCH="TRUE" *) part_A A(clk, c, e, d); > > // The generated module for instance A is called "part_A". > > (MyHDL also has a nifty feature to include doc strings as embedded comments. I have some back-end support for attaching a string to a partition, to be output as a comment in the code, but I haven't turned it on yet.) > > ----------------------- > 2) The second way to group logic into a partition is with a python decorator. > > example 2) Using decorators in addition to "with" blocks. > > The decorator syntax uses the same rules as the with-blocks. (All partitions will be unique, and possibly suffixed with a number to maintain uniqueness in the Verilog code. Partitions may be nested. Use descriptive names if you want descriptive output.) > > Here, I'll intermix the decorator and with syntax: > > def my_module_alice(...): > # ... > with partition('SM'): > # This happens to enclose a state machine. > # The name SM isn't descriptive enough, but if you > # want descriptive Verilog output, then you should > # use descriptive names. > # ... > # ... > return instances() > > @partition('AES') # <---- partition a la decorator. > def my_module_bob(...): > # ... > with partition('SM'):# This encloses an unrelated state machine. > # ... > # ... > return instances() > > def top(...): > @always(clk.posedge) > def clgc(): > c.next = a + b > > with partition('CRYPTO'): > alice_inst = alice(...) > bob0_inst = bob(...) > bob1_inst = bob(...) > > with partition('CRYPTO_SM2'): > # I made this CRYPTO_SM2 name, just to be a jerk. > @always(clk.posedge) > def clgd(): > d.next = c + e > > The above code will generate ~8 modules: > module top(...); > module CRYPTO(...); > module CRYPTO_SM(...); // this is from alice_inst > module CRYPTO_AES0(...); // decorator on bob() > module CRYPTO_AES0_SM(...); // this is from bob0_inst > module CRYPTO_AES1(...); // decorator on bob() > module CRYPTO_AES1_SM(...); // this is from bob1_inst > module CRYPTO_SM2(...); // renamed CRYPTO_SM2 to not conflict with CRYPT.SM <http://CRYPT.SM> from bob1_inst > > > ----------------------- END OF EXAMPLES > > Limitations: I hope there aren't any. I put enough care to accomodate ConcatSignal's, _SliceSignal's, const [undriven] _Signal's, etc... And if a signal gets pushed into a sub-partition where it is both driven and read, as well as output from that sub-partition, the generator will automatically make a separate wire just for the output port, that is driven from your signal. (This prevents "Output port is read internally..." warnings for partition-generated modules. I don't do this for the top-level though, to preserve the same interface as current MyHDL output.) > > Component Conversion: No additional restrictions beyond that of MyHDL. There is still the same requirement on your top-level to be "top-level convertible", but there is flexibility for your lower levels. > > Component Parameters: What parameters? All of your parameters were already digested by python+MyHDL magic, and I'm operating on the flattened hierarchy. If you invoke the same sub-partition (sub-module) multiple times, it will be replicated in the output, but every time it appears, it will use the globally-unique signal names that MyHDL has already assigned. (ie, I don't change your signal names.) > > Any drawbacks: > This may/will produce larger output code than the proposed solution in MEP 110. The existing MEP 110 solution will create 1 copy of each module, and instantiate it multiple times (as long as each instantiation shares the same port signal widths, etc...). In contrast, this "110.alt" solution will create a whole copy of a module every time it is instantiated. (But each copy inherits the unique signal names assigned by MyHDL's flattening algorithm.) However, the larger output size from this "110.alt" isn't that much larger than MyHDL's native flat output. (depending on your signal usage...) > > Benefits: > You can have hierarchical output with minimal changes to your code, and you control exactly how your logic is partitioned into the hierarchy. Just sprinkle a few @partition(...) or "with partition(...):" statements wherever you need in your design. > > Known pitfalls: I have not tried or tested TristateSignal's for "inout" ports, and I've only tested on a very narrow subset of MyHDL's feature set. (I was was already bitten by ConcatSignal's, _SliceSignal's, and lists of signals accidentally being inferred as memories... However, I expect these areas to work as expected now.) > > > But if anyone is interested, here's the code, and I'm open for feedback. > > I attached patches against myhdl-0.8.tar.gz available from > https://sourceforge.net/projects/myhdl/files/myhdl/0.8/ > > Of the 2 patches, myhdl-0.8-fix_modbv.patch is my poor-man's fix for modbv, because I needed modbv. This patch is most likely obsoleted by Jan's real fix in the repo. > > The other patch (myhdl-0.8-partitions.patch) contains my crude first draft supporting the described hierarchy. Yes, this code is ugly. Don't look at it yet. It is a quick mock-up of some functionality I really wanted. But give it a try if you're interested and let me know what it breaks on... Or if you really want to dive into the code, feel free to do so. > > On my systems, I apply & install these patches as follows: (gunzip the .patch files first) > > gunzip myhdl-0.8-fix_modbv.patch.gz > gunzip myhdl-0.8-partitions.patch.gz > tar zxf myhdl-0.8.tar.gz \ > && cd myhdl-0.8 \ > && patch -p1 < ../myhdl-0.8-fix_modbv.patch \ > && patch -p1 < ../myhdl-0.8-partitions.patch \ > && python setup.py build \ > && python setup.py install --user -O2 \ > && cd .. \ > && rm -rf myhdl-0.8 > > This installs myhdl into python's standard location for my home directory, but feel free to leave off --user to install to the main system path, or wherever else you want. > > To test drive the functionality, try running test_partition.py. Set > toVerilog.partitioned_output=False > to see the normal output, and > toVerilog.partitioned_output=True > to see the partitioned output. And if you are curious, try > toVerilog.partitioned_output="I promise I will never die." > to enable the partitioned output code, but tell it to ignore the partition annotations. > > > (typos and all, I'm hitting send...) > > - David > > > > On Wed, May 1, 2013 at 6:44 PM, Oscar Daniel Diaz <osc...@gm... <mailto:osc...@gm...>> wrote: > > El Wed, 01 May 2013 10:55:55 +0200 > Jan Decaluwe <ja...@ja... <mailto:ja...@ja...>> escribió: > > > On 04/29/2013 05:25 PM, Oscar Daniel Diaz wrote: > > > > > Given that the converter is called recursively several times, > > > multiple files are generated and its contents are used for component > > > declaration (VHDL). Recursive calls must avoid file replication (for > > > VHDL case means avoid multiple package file generation). This is > > > done by keeping generated code in memory before pushing to files. > > > > > > Attribute "no_component_files" : > > > * False : all components code is saved to disk as soon as > > > possible. > > > * True : discard components code, only save top-module file. > > > > Not sure what is meant here exactly. Why would we need component > > declarations, as opposed to simply using direct instantation? > > For a case like this, this seems much simpler and less verbose > > to me. > > Since keep hierarchy conversion requires multiple files to generate > (top-module and components to instantiate), this flag prevents > generation of those components. Suppose you make some changes only in > the top-module, this flag allows to only generate top-module file. > > When I change from VHDL '87 syntax (doing recursive calls to get > component declaration) to '93 syntax, that flag would prevent > those recursive calls. > > -- > Oscar Díaz > Key Fingerprint = 904B 306C C3C2 7487 650B BFAC EDA2 B702 90E9 9964 > gpg --keyserver subkeys.pgp.net <http://subkeys.pgp.net> --recv-keys 90E99964 > > > _______________________________________________ > myhdl-list mailing list > myh...@li... <mailto:myh...@li...> > https://lists.sourceforge.net/lists/listinfo/myhdl-list > > > > > ------------------------------------------------------------------------------ > October Webinars: Code for Performance > Free Intel webinars can help you accelerate application performance. > Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from > the latest Intel processors and coprocessors. See abstracts and register > > http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk > > > > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > -- Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com Python as a HDL: http://www.myhdl.org VHDL development, the modern way: http://www.sigasi.com World-class digital design: http://www.easics.com |
From: David H. <da...@ad...> - 2013-10-01 15:55:35
|
tl;dr: My patch against 0.8 appears can be applied against the 0.9-dev repo, and it satisfies my very limited testing. The changes in 0.9-dev were not near my hack-n-slash campaign. (I kept most of my changes _after_ MyHDL's normal extraction and analysis algorithm, with only a few small hooks into signals and generators to assist with partition-tagging.) To test, I first removed the current myhdl-0.8 I had in my Python installation, then I followed these steps: # (I removed my current myhdl-0.8 from my Python installation.) hg clone https://bitbucket.org/jandecaluwe/myhdl cd myhdl gunzip -c ../myhdl-0.8-partitions.patch.gz | patch -p1 python setup.py build python setup.py install --user -O2 Then I reran my test_partition.py, and the output is identical. (except that the new myhdl is injecting some $signed(...) stuff in 1 place where I'm substracting...) I also reran my pcie designs (with partitions), and that also produced identical output. (but again with $signed(...) stuff but in 2 places where I'm subtracting...) To confirm I'm using the latest repo, here's the recent log entry: hg log | head -8 changeset: 1358:324a8d3206fb branch: 0.9-dev tag: tip parent: 1356:db95c2d47119 parent: 1357:8de9f8771395 user: Jan Decaluwe <ja...@ja...> date: Sun Sep 22 19:14:21 2013 +0200 summary: Bug fix merge from default And the patch applied fairly cleanly, with only 2 offset changes: gunzip -c ../myhdl-0.8-partitions.patch.gz | patch -p1 patching file myhdl/_Signal.py patching file myhdl/__init__.py patching file myhdl/_always.py patching file myhdl/_always_comb.py Hunk #1 succeeded at 190 (offset 10 lines). patching file myhdl/_always_seq.py patching file myhdl/_contextdecorator.py patching file myhdl/_extractHierarchy.py patching file myhdl/_instance.py patching file myhdl/_partition.py patching file myhdl/conversion/_analyze.py Hunk #5 succeeded at 865 (offset 5 lines). patching file myhdl/conversion/_toVerilog.py The rest of this email is a quick summary of my changes per file: __init__.py: include "partition" and "get_current_partition" in the myhdl namespace. get_current_partition() may be called from within a partition to assign attributes. For example, to assign attributes using the "with" syntax: with partition('A') as this_part: # This will be renamed to A0 this_part.attr_add('KEEP_HIERARCHY', 'TRUE') this_part.attr_add('DONT_TOUCH', 'TRUE') @always(clk.posedge) def clgd(): d.next = c + e And to assign attributes from inside a partition (such as when using the "decorator" syntax): @partition('AES') # <---- partition a la decorator. def my_module_bob(...): # ... this_part = get_current_partition() this_part.attr_add('DONT_TOUCH', 'TRUE') return instances() _Signal.py: Small change. I radio tag each signal with the current partition. (Actually, I originally didn't need to do this, until I tried figuring out where to place ConcatSignal drivers (ie, which partition to invoke their _toVerilog [or _toVHDL] method). In short, Iw as tired after devising the auto-magic placement for every other signal type, so I just gave up on auto-placement of ConcatSignals, and instead just use the tagged partition to indicate where to place each ConcatSignal's driver. (ie, For all other signals, it doesn't matter where you happen to declare them, since the output code will auto placed based on the location of any driving generator. But for ConcatSignal's, the output code will strictly place their driver inside whatever partition you happend to create the ConcatSignal in python.) _instance.py: Small change, to support any extension to "monkey patch" its way into tagging generators inheriting from _Instantiator. (Actually, I should've structured my change to _Signal.py like this one, to open the way for any future extensions to also "monkey patch" their way into _Signal's and shadow signals...) _always.py: _Always inherits from _Instantiator but does not invoke it's constructor. Therefore, I manually invoke the "hookInit" that I created inside _Instantiator. _always_comb.py: Same as _always.py. Manually invoke the "hookInit" that I created inside _Instantiator. _always_seq.py: Same as _always.py... _extractHierarchy.py: Tweak _HierExtr and _Instance to preserve hookData placed via hookInit from _Instantiator. I also tweaked _UserCode and _addUserCode to preserve hookData, but I haven't tried any user-defined Verilog (or VHDL) to test this. TODO: If anyone has user-defined code, try putting it in a partition (perhaps easiest via "with"), and tell me if it is placed in the correct Verilog module on output. _contextdecorator.py: New file, from http://pypi.python.org/pypi/contextdecorator to support both "with partition(...) ..." and "@partition(...)" mechanisms. _partition.py: New file, and is actually pretty short. It defines "partition" and "get_current_partition" API, and inject the partition tags in the relevant objects such as @always, @always_comb, @always_seq. conversion/_analyze.py: Preserve hookData in _analyzeGens. And in _AnalyzeVisitor, I added tree.inmems to mirror record keeping of tree.outmems, so that I can verify that memories are only read from the same partition in which they're driven. conversion/_toVerilog.py: Thar be dragons. Here is where I added toVerilog.partitioned_output, to invoke my alternative Verilog output code contained in _write_partitioned_output(...). TODO: I should move _write_partitioned_output and its supporting entourage to another file. (SigMapping, lookup_id, distill_signals_and_memories, _apply_renames, _generate_partitions, _partition2name, _make_unique_names) On Sun, Sep 29, 2013 at 8:25 PM, Keerthan jai.c <jck...@gm...>wrote: > David, > > Just a heads up, the 0.9 dev branch on bitbucket has quite a few changes > in the conversion area(MEP 107). You might want to check whether these > patches apply on the new branch. > > > On Sun, Sep 29, 2013 at 2:21 PM, David Holl <da...@ad...> wrote: > >> There was an old thread regarding MEP 110, but I've come up with an >> alternative "solution", and I'm looking for your comments. (call it MEP >> 110-alt?) >> >> tl;dr --- If you're interested, >> >> Introduction: Same as MEP 110. (Especially for floor planning...) >> ----------------------- >> Analysis: Same as MEP 110. (Yep, everything gets flattened by >> default...) >> ----------------------- >> Proposed Solution: (with implementation) >> >> I did not follow the proposed solution in MEP 110, because that would've >> required that I change [any of] my components to be "top-module >> convertible". (I'm using a form of signal containers --similar to MEP >> 107-- which which would've required many changes (in my code) to achieve >> "top-module convertibility".) >> >> What I did was I started from the flattened hierarchy in >> conversion/_toVerilog.py, but instead of calling the usual >> _writeSigDecls, _convertGens, I wrote my own convoluted output code: >> ... >> if self.partitioned_output: >> _write_partitioned_output(self.partitioned_output, vfile, >> vpath, self.timescale, h, intf, siglist, memlist, genlist, doc) >> else: >> _writeFileHeader(vfile, vpath, self.timescale) >> _writeModuleHeader(vfile, intf, doc) >> _writeSigDecls(vfile, intf, siglist, memlist) >> _convertGens(genlist, vfile) >> _writeModuleFooter(vfile) >> ... >> >> >> To activate this alternative output, just >> set toVerilog.partitioned_output=True: >> toVerilog.name='test_partition' >> toVerilog.partitioned_output=True # the default is False >> toVerilog(_test_top, clk, AAA, BBB, ZZZ, TTT, VVV) >> >> Without any other changes to a hardware description, this alternative >> code will produce identical, flattened output. (right down to the arbitrary >> ordering of signals and generators...) >> >> However, you may now group any related logic together, as needed. I call >> a group of logic a "partition", and these partitions may be nested. >> Instead of the word "partition" you could call it a "module" instead, >> since the concept is almost identical to Verilog module's. In the >> following description, it will appear that I'm flipping between "partition" >> and "module" when really, I'm describing how that partitions in python >> impact the created Verilog modules. (but for simplistic purposes, since I >> guarantee each "partition" will create a unique Verilog "module", feel free >> to call em' what you want...) >> >> There are 2 ways to assign related hardware into partitions. >> ----------------------- >> 1) The first is via python's "with" statement. I'll show a few examples: >> >> example 1.a) A simple partition... >> from myhdl import Signal, partition, ... >> >> @always(clk.posedge) >> def clgc(): >> c.next = a + b >> >> with partition('A'): >> @always(clk.posedge) >> def clgd(): >> d.next = c + e >> >> @always(clk.posedge) >> def clge(): >> e.next = a * b >> >> @always(clk.posedge) >> def clgf(): >> f.next = more stuff... >> >> >> What "partition" does is annotate all generators (and shadow signals...) >> with your text label. Then the "partitioned-output" code uses these >> annotations move related logic into a Verilog module, and instantiate that >> module from the top-level module. Module ports are automatically created >> for any signals that need to cross between modules. >> >> This code still creates only 1 output .v file containing all modules. (I >> didn't care if it was 1 file or multiple files, but for me, 1 file was >> "easier" to move/copy around in my opinion.) >> >> The top module will include all of the signals, except for "e" --- >> because in this code, e is only used within partition A. Therefore "e" >> will appear as a driven "reg" within a submodule called A. (and that >> submodule "A" is instantiated in the top level as "part_A"...) >> >> >> >> example 1.b) Partitions may be nested. >> >> @always(clk.posedge) >> def clgc(): >> c.next = a + b >> >> with partition('A'): >> @always(clk.posedge) >> def clgd(): >> d.next = c + e >> >> with partition('B'): >> @always(clk.posedge) >> def clge(): >> e.next = a * b >> >> @always(clk.posedge) >> def clgf(): >> f.next = more stuff... >> >> >> This code will create 3 modules total: the top module, a module called >> "A", and a module called "A_B". >> >> >> example 1.c) Partitions having the same name will be renamed to stay >> unique! >> >> If you want related code to be grouped into a partition, all of that code >> must be contained in the same python "with" block. For example: >> >> from myhdl import Signal, partition, ... >> >> @always(clk.posedge) >> def clgc(): >> c.next = a + b >> >> with partition('A'): # This will be renamed to A0 >> @always(clk.posedge) >> def clgd(): >> d.next = c + e >> >> with partition('A'): # This will be renamed to A1 >> @always(clk.posedge) >> def clge(): >> e.next = a * b >> >> >> Rationale: When you start nesting partitions, partition names are >> guaranteed to produce unique module instances and not accidentally group >> unrelated logic together. >> >> >> example 1.d) Partitions are nestable across your python function calls, >> and renaming will happen to keep sub >> >> For example, unrelated nested partitions may use the same name without >> fear of their logic being accidentally grouped together. >> >> from myhdl import Signal, partition, ... >> >> def my_module_alice(...): >> # ... >> with partition('SM'): >> # This happens to enclose a state machine. >> # The name SM isn't descriptive enough, but if you >> # want descriptive Verilog output, then you should >> # use descriptive names. >> # ... >> # ... >> return instances() >> >> def my_module_bob(...): >> # ... >> with partition('SM'):# This encloses an unrelated state machine. >> # ... >> # ... >> return instances() >> >> def top(...): >> @always(clk.posedge) >> def clgc(): >> c.next = a + b >> >> with partition('CRYPTO'): >> alice_inst = alice(...) >> bob0_inst = bob(...) >> bob1_inst = bob(...) >> >> with partition('CRYPTO_SM2'): >> # I made this CRYPTO_SM2 name, just to be a jerk. >> @always(clk.posedge) >> def clgd(): >> d.next = c + e >> >> >> This code would produce 6 instantiated modules in the generated Verilog >> output: >> module top(...); >> module CRYPTO(...); >> module CRYPTO_SM0(...); // this is from alice_inst >> module CRYPTO_SM1(...); // this is from bob0_inst >> module CRYPTO_SM2(...); // this is from bob1_inst >> module CRYPTO_SM2_(...); // renamed CRYPTO_SM2 to not conflict with >> CRYPT_SM2 from bob1_inst >> >> Admittedly, the generated names CRYPTO_SM... in this example aren't very >> clear, but the point here is that your python functions (like alice() and >> bob()) have a guaranteed means to group logic into a Verilog module without >> accidental commingling of unrelated from other modules. >> >> The "top" module instantates "CRYPTO" and "CRYPTO_SM2_". Then "CRYPTO" >> instantiates "CRYPTO_SM0", "CRYPTO_SM1", and "CRYPTO_SM2". >> >> >> example 1.e) Partitions support Verilog 2001 attributes (and if someone >> wants to add VHDL support...) >> >> with partition('A') as this_part: # This will be renamed to A0 >> this_part.attr_add('KEEP_HIERARCHY', 'TRUE') >> this_part.attr_add('DONT_TOUCH', 'TRUE') >> >> @always(clk.posedge) >> def clgd(): >> d.next = c + e >> >> This will produce output that instantiates module A as: >> >> (* KEEP_HIERARCHY="TRUE", DONT_TOUCH="TRUE" *) part_A A(clk, c, e, d); >> >> // The generated module for instance A is called "part_A". >> >> (MyHDL also has a nifty feature to include doc strings as embedded >> comments. I have some back-end support for attaching a string to a >> partition, to be output as a comment in the code, but I haven't turned it >> on yet.) >> >> ----------------------- >> 2) The second way to group logic into a partition is with a python >> decorator. >> >> example 2) Using decorators in addition to "with" blocks. >> >> The decorator syntax uses the same rules as the with-blocks. (All >> partitions will be unique, and possibly suffixed with a number to maintain >> uniqueness in the Verilog code. Partitions may be nested. Use descriptive >> names if you want descriptive output.) >> >> Here, I'll intermix the decorator and with syntax: >> >> def my_module_alice(...): >> # ... >> with partition('SM'): >> # This happens to enclose a state machine. >> # The name SM isn't descriptive enough, but if you >> # want descriptive Verilog output, then you should >> # use descriptive names. >> # ... >> # ... >> return instances() >> >> @partition('AES') # <---- partition a la decorator. >> def my_module_bob(...): >> # ... >> with partition('SM'):# This encloses an unrelated state machine. >> # ... >> # ... >> return instances() >> >> def top(...): >> @always(clk.posedge) >> def clgc(): >> c.next = a + b >> >> with partition('CRYPTO'): >> alice_inst = alice(...) >> bob0_inst = bob(...) >> bob1_inst = bob(...) >> >> with partition('CRYPTO_SM2'): >> # I made this CRYPTO_SM2 name, just to be a jerk. >> @always(clk.posedge) >> def clgd(): >> d.next = c + e >> >> The above code will generate ~8 modules: >> module top(...); >> module CRYPTO(...); >> module CRYPTO_SM(...); // this is from alice_inst >> module CRYPTO_AES0(...); // decorator on bob() >> module CRYPTO_AES0_SM(...); // this is from bob0_inst >> module CRYPTO_AES1(...); // decorator on bob() >> module CRYPTO_AES1_SM(...); // this is from bob1_inst >> module CRYPTO_SM2(...); // renamed CRYPTO_SM2 to not conflict with >> CRYPT.SM from bob1_inst >> >> >> ----------------------- END OF EXAMPLES >> >> Limitations: I hope there aren't any. I put enough care to accomodate >> ConcatSignal's, _SliceSignal's, const [undriven] _Signal's, etc... And if >> a signal gets pushed into a sub-partition where it is both driven and read, >> as well as output from that sub-partition, the generator will automatically >> make a separate wire just for the output port, that is driven from your >> signal. (This prevents "Output port is read internally..." warnings for >> partition-generated modules. I don't do this for the top-level though, to >> preserve the same interface as current MyHDL output.) >> >> Component Conversion: No additional restrictions beyond that of MyHDL. >> There is still the same requirement on your top-level to be "top-level >> convertible", but there is flexibility for your lower levels. >> >> Component Parameters: What parameters? All of your parameters were >> already digested by python+MyHDL magic, and I'm operating on the flattened >> hierarchy. If you invoke the same sub-partition (sub-module) multiple >> times, it will be replicated in the output, but every time it appears, it >> will use the globally-unique signal names that MyHDL has already assigned. >> (ie, I don't change your signal names.) >> >> Any drawbacks: >> This may/will produce larger output code than the proposed solution in >> MEP 110. The existing MEP 110 solution will create 1 copy of each module, >> and instantiate it multiple times (as long as each instantiation shares the >> same port signal widths, etc...). In contrast, this "110.alt" solution >> will create a whole copy of a module every time it is instantiated. (But >> each copy inherits the unique signal names assigned by MyHDL's flattening >> algorithm.) However, the larger output size from this "110.alt" isn't that >> much larger than MyHDL's native flat output. (depending on your signal >> usage...) >> >> Benefits: >> You can have hierarchical output with minimal changes to your code, >> and you control exactly how your logic is partitioned into the hierarchy. >> Just sprinkle a few @partition(...) or "with partition(...):" statements >> wherever you need in your design. >> >> Known pitfalls: I have not tried or tested TristateSignal's for "inout" >> ports, and I've only tested on a very narrow subset of MyHDL's feature set. >> (I was was already bitten by ConcatSignal's, _SliceSignal's, and lists of >> signals accidentally being inferred as memories... However, I expect these >> areas to work as expected now.) >> >> >> But if anyone is interested, here's the code, and I'm open for feedback. >> >> I attached patches against myhdl-0.8.tar.gz available from >> https://sourceforge.net/projects/myhdl/files/myhdl/0.8/ >> >> Of the 2 patches, myhdl-0.8-fix_modbv.patch is my poor-man's fix for >> modbv, because I needed modbv. This patch is most likely obsoleted by >> Jan's real fix in the repo. >> >> The other patch (myhdl-0.8-partitions.patch) contains my crude first >> draft supporting the described hierarchy. Yes, this code is ugly. Don't >> look at it yet. It is a quick mock-up of some functionality I really >> wanted. But give it a try if you're interested and let me know what it >> breaks on... Or if you really want to dive into the code, feel free to do >> so. >> >> On my systems, I apply & install these patches as follows: (gunzip the >> .patch files first) >> >> gunzip myhdl-0.8-fix_modbv.patch.gz >> gunzip myhdl-0.8-partitions.patch.gz >> tar zxf myhdl-0.8.tar.gz \ >> && cd myhdl-0.8 \ >> && patch -p1 < ../myhdl-0.8-fix_modbv.patch \ >> && patch -p1 < ../myhdl-0.8-partitions.patch \ >> && python setup.py build \ >> && python setup.py install --user -O2 \ >> && cd .. \ >> && rm -rf myhdl-0.8 >> >> This installs myhdl into python's standard location for my home >> directory, but feel free to leave off --user to install to the main system >> path, or wherever else you want. >> >> To test drive the functionality, try running test_partition.py. Set >> toVerilog.partitioned_output=False >> to see the normal output, and >> toVerilog.partitioned_output=True >> to see the partitioned output. And if you are curious, try >> toVerilog.partitioned_output="I promise I will never die." >> to enable the partitioned output code, but tell it to ignore the >> partition annotations. >> >> >> (typos and all, I'm hitting send...) >> >> - David >> >> >> >> On Wed, May 1, 2013 at 6:44 PM, Oscar Daniel Diaz <osc...@gm...>wrote: >> >>> El Wed, 01 May 2013 10:55:55 +0200 >>> Jan Decaluwe <ja...@ja...> escribió: >>> >>> > On 04/29/2013 05:25 PM, Oscar Daniel Diaz wrote: >>> > >>> > > Given that the converter is called recursively several times, >>> > > multiple files are generated and its contents are used for component >>> > > declaration (VHDL). Recursive calls must avoid file replication (for >>> > > VHDL case means avoid multiple package file generation). This is >>> > > done by keeping generated code in memory before pushing to files. >>> > > >>> > > Attribute "no_component_files" : >>> > > * False : all components code is saved to disk as soon as >>> > > possible. >>> > > * True : discard components code, only save top-module file. >>> > >>> > Not sure what is meant here exactly. Why would we need component >>> > declarations, as opposed to simply using direct instantation? >>> > For a case like this, this seems much simpler and less verbose >>> > to me. >>> >>> Since keep hierarchy conversion requires multiple files to generate >>> (top-module and components to instantiate), this flag prevents >>> generation of those components. Suppose you make some changes only in >>> the top-module, this flag allows to only generate top-module file. >>> >>> When I change from VHDL '87 syntax (doing recursive calls to get >>> component declaration) to '93 syntax, that flag would prevent >>> those recursive calls. >>> >>> -- >>> Oscar Díaz >>> Key Fingerprint = 904B 306C C3C2 7487 650B BFAC EDA2 B702 90E9 9964 >>> gpg --keyserver subkeys.pgp.net --recv-keys 90E99964 >>> >>> >>> _______________________________________________ >>> myhdl-list mailing list >>> myh...@li... >>> https://lists.sourceforge.net/lists/listinfo/myhdl-list >>> >>> >> >> >> ------------------------------------------------------------------------------ >> October Webinars: Code for Performance >> Free Intel webinars can help you accelerate application performance. >> Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most >> from >> the latest Intel processors and coprocessors. See abstracts and register > >> >> http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk >> >> _______________________________________________ >> myhdl-list mailing list >> myh...@li... >> https://lists.sourceforge.net/lists/listinfo/myhdl-list >> >> > > > -- > have a nice day > -jck > > > ------------------------------------------------------------------------------ > October Webinars: Code for Performance > Free Intel webinars can help you accelerate application performance. > Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most > from > the latest Intel processors and coprocessors. See abstracts and register > > http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > > |
From: Per K. <bas...@gm...> - 2013-10-01 09:30:26
|
Hi! I haven't tried your patch out (we're still at 0.7 plus some patches), but I'd just like to offer some encouragement! What you are proposing would be very useful, I think! /Per On Sun, Sep 29, 2013 at 8:21 PM, David Holl <da...@ad...> wrote: > There was an old thread regarding MEP 110, but I've come up with an > alternative "solution", and I'm looking for your comments. (call it MEP > 110-alt?) > > tl;dr --- If you're interested, > > Introduction: Same as MEP 110. (Especially for floor planning...) > ----------------------- > Analysis: Same as MEP 110. (Yep, everything gets flattened by default...) > ----------------------- > Proposed Solution: (with implementation) > > I did not follow the proposed solution in MEP 110, because that would've > required that I change [any of] my components to be "top-module > convertible". (I'm using a form of signal containers --similar to MEP > 107-- which which would've required many changes (in my code) to achieve > "top-module convertibility".) > > What I did was I started from the flattened hierarchy in > conversion/_toVerilog.py, but instead of calling the usual > _writeSigDecls, _convertGens, I wrote my own convoluted output code: > ... > if self.partitioned_output: > _write_partitioned_output(self.partitioned_output, vfile, > vpath, self.timescale, h, intf, siglist, memlist, genlist, doc) > else: > _writeFileHeader(vfile, vpath, self.timescale) > _writeModuleHeader(vfile, intf, doc) > _writeSigDecls(vfile, intf, siglist, memlist) > _convertGens(genlist, vfile) > _writeModuleFooter(vfile) > ... > > > To activate this alternative output, just > set toVerilog.partitioned_output=True: > toVerilog.name='test_partition' > toVerilog.partitioned_output=True # the default is False > toVerilog(_test_top, clk, AAA, BBB, ZZZ, TTT, VVV) > > Without any other changes to a hardware description, this alternative code > will produce identical, flattened output. (right down to the arbitrary > ordering of signals and generators...) > > However, you may now group any related logic together, as needed. I call > a group of logic a "partition", and these partitions may be nested. > Instead of the word "partition" you could call it a "module" instead, > since the concept is almost identical to Verilog module's. In the > following description, it will appear that I'm flipping between "partition" > and "module" when really, I'm describing how that partitions in python > impact the created Verilog modules. (but for simplistic purposes, since I > guarantee each "partition" will create a unique Verilog "module", feel free > to call em' what you want...) > > There are 2 ways to assign related hardware into partitions. > ----------------------- > 1) The first is via python's "with" statement. I'll show a few examples: > > example 1.a) A simple partition... > from myhdl import Signal, partition, ... > > @always(clk.posedge) > def clgc(): > c.next = a + b > > with partition('A'): > @always(clk.posedge) > def clgd(): > d.next = c + e > > @always(clk.posedge) > def clge(): > e.next = a * b > > @always(clk.posedge) > def clgf(): > f.next = more stuff... > > > What "partition" does is annotate all generators (and shadow signals...) > with your text label. Then the "partitioned-output" code uses these > annotations move related logic into a Verilog module, and instantiate that > module from the top-level module. Module ports are automatically created > for any signals that need to cross between modules. > > This code still creates only 1 output .v file containing all modules. (I > didn't care if it was 1 file or multiple files, but for me, 1 file was > "easier" to move/copy around in my opinion.) > > The top module will include all of the signals, except for "e" --- because > in this code, e is only used within partition A. Therefore "e" will appear > as a driven "reg" within a submodule called A. (and that submodule "A" is > instantiated in the top level as "part_A"...) > > > > example 1.b) Partitions may be nested. > > @always(clk.posedge) > def clgc(): > c.next = a + b > > with partition('A'): > @always(clk.posedge) > def clgd(): > d.next = c + e > > with partition('B'): > @always(clk.posedge) > def clge(): > e.next = a * b > > @always(clk.posedge) > def clgf(): > f.next = more stuff... > > > This code will create 3 modules total: the top module, a module called > "A", and a module called "A_B". > > > example 1.c) Partitions having the same name will be renamed to stay > unique! > > If you want related code to be grouped into a partition, all of that code > must be contained in the same python "with" block. For example: > > from myhdl import Signal, partition, ... > > @always(clk.posedge) > def clgc(): > c.next = a + b > > with partition('A'): # This will be renamed to A0 > @always(clk.posedge) > def clgd(): > d.next = c + e > > with partition('A'): # This will be renamed to A1 > @always(clk.posedge) > def clge(): > e.next = a * b > > > Rationale: When you start nesting partitions, partition names are > guaranteed to produce unique module instances and not accidentally group > unrelated logic together. > > > example 1.d) Partitions are nestable across your python function calls, > and renaming will happen to keep sub > > For example, unrelated nested partitions may use the same name without > fear of their logic being accidentally grouped together. > > from myhdl import Signal, partition, ... > > def my_module_alice(...): > # ... > with partition('SM'): > # This happens to enclose a state machine. > # The name SM isn't descriptive enough, but if you > # want descriptive Verilog output, then you should > # use descriptive names. > # ... > # ... > return instances() > > def my_module_bob(...): > # ... > with partition('SM'):# This encloses an unrelated state machine. > # ... > # ... > return instances() > > def top(...): > @always(clk.posedge) > def clgc(): > c.next = a + b > > with partition('CRYPTO'): > alice_inst = alice(...) > bob0_inst = bob(...) > bob1_inst = bob(...) > > with partition('CRYPTO_SM2'): > # I made this CRYPTO_SM2 name, just to be a jerk. > @always(clk.posedge) > def clgd(): > d.next = c + e > > > This code would produce 6 instantiated modules in the generated Verilog > output: > module top(...); > module CRYPTO(...); > module CRYPTO_SM0(...); // this is from alice_inst > module CRYPTO_SM1(...); // this is from bob0_inst > module CRYPTO_SM2(...); // this is from bob1_inst > module CRYPTO_SM2_(...); // renamed CRYPTO_SM2 to not conflict with > CRYPT_SM2 from bob1_inst > > Admittedly, the generated names CRYPTO_SM... in this example aren't very > clear, but the point here is that your python functions (like alice() and > bob()) have a guaranteed means to group logic into a Verilog module without > accidental commingling of unrelated from other modules. > > The "top" module instantates "CRYPTO" and "CRYPTO_SM2_". Then "CRYPTO" > instantiates "CRYPTO_SM0", "CRYPTO_SM1", and "CRYPTO_SM2". > > > example 1.e) Partitions support Verilog 2001 attributes (and if someone > wants to add VHDL support...) > > with partition('A') as this_part: # This will be renamed to A0 > this_part.attr_add('KEEP_HIERARCHY', 'TRUE') > this_part.attr_add('DONT_TOUCH', 'TRUE') > > @always(clk.posedge) > def clgd(): > d.next = c + e > > This will produce output that instantiates module A as: > > (* KEEP_HIERARCHY="TRUE", DONT_TOUCH="TRUE" *) part_A A(clk, c, e, d); > > // The generated module for instance A is called "part_A". > > (MyHDL also has a nifty feature to include doc strings as embedded > comments. I have some back-end support for attaching a string to a > partition, to be output as a comment in the code, but I haven't turned it > on yet.) > > ----------------------- > 2) The second way to group logic into a partition is with a python > decorator. > > example 2) Using decorators in addition to "with" blocks. > > The decorator syntax uses the same rules as the with-blocks. (All > partitions will be unique, and possibly suffixed with a number to maintain > uniqueness in the Verilog code. Partitions may be nested. Use descriptive > names if you want descriptive output.) > > Here, I'll intermix the decorator and with syntax: > > def my_module_alice(...): > # ... > with partition('SM'): > # This happens to enclose a state machine. > # The name SM isn't descriptive enough, but if you > # want descriptive Verilog output, then you should > # use descriptive names. > # ... > # ... > return instances() > > @partition('AES') # <---- partition a la decorator. > def my_module_bob(...): > # ... > with partition('SM'):# This encloses an unrelated state machine. > # ... > # ... > return instances() > > def top(...): > @always(clk.posedge) > def clgc(): > c.next = a + b > > with partition('CRYPTO'): > alice_inst = alice(...) > bob0_inst = bob(...) > bob1_inst = bob(...) > > with partition('CRYPTO_SM2'): > # I made this CRYPTO_SM2 name, just to be a jerk. > @always(clk.posedge) > def clgd(): > d.next = c + e > > The above code will generate ~8 modules: > module top(...); > module CRYPTO(...); > module CRYPTO_SM(...); // this is from alice_inst > module CRYPTO_AES0(...); // decorator on bob() > module CRYPTO_AES0_SM(...); // this is from bob0_inst > module CRYPTO_AES1(...); // decorator on bob() > module CRYPTO_AES1_SM(...); // this is from bob1_inst > module CRYPTO_SM2(...); // renamed CRYPTO_SM2 to not conflict with > CRYPT.SM from bob1_inst > > > ----------------------- END OF EXAMPLES > > Limitations: I hope there aren't any. I put enough care to accomodate > ConcatSignal's, _SliceSignal's, const [undriven] _Signal's, etc... And if > a signal gets pushed into a sub-partition where it is both driven and read, > as well as output from that sub-partition, the generator will automatically > make a separate wire just for the output port, that is driven from your > signal. (This prevents "Output port is read internally..." warnings for > partition-generated modules. I don't do this for the top-level though, to > preserve the same interface as current MyHDL output.) > > Component Conversion: No additional restrictions beyond that of MyHDL. > There is still the same requirement on your top-level to be "top-level > convertible", but there is flexibility for your lower levels. > > Component Parameters: What parameters? All of your parameters were > already digested by python+MyHDL magic, and I'm operating on the flattened > hierarchy. If you invoke the same sub-partition (sub-module) multiple > times, it will be replicated in the output, but every time it appears, it > will use the globally-unique signal names that MyHDL has already assigned. > (ie, I don't change your signal names.) > > Any drawbacks: > This may/will produce larger output code than the proposed solution in MEP > 110. The existing MEP 110 solution will create 1 copy of each module, and > instantiate it multiple times (as long as each instantiation shares the > same port signal widths, etc...). In contrast, this "110.alt" solution > will create a whole copy of a module every time it is instantiated. (But > each copy inherits the unique signal names assigned by MyHDL's flattening > algorithm.) However, the larger output size from this "110.alt" isn't that > much larger than MyHDL's native flat output. (depending on your signal > usage...) > > Benefits: > You can have hierarchical output with minimal changes to your code, > and you control exactly how your logic is partitioned into the hierarchy. > Just sprinkle a few @partition(...) or "with partition(...):" statements > wherever you need in your design. > > Known pitfalls: I have not tried or tested TristateSignal's for "inout" > ports, and I've only tested on a very narrow subset of MyHDL's feature set. > (I was was already bitten by ConcatSignal's, _SliceSignal's, and lists of > signals accidentally being inferred as memories... However, I expect these > areas to work as expected now.) > > > But if anyone is interested, here's the code, and I'm open for feedback. > > I attached patches against myhdl-0.8.tar.gz available from > https://sourceforge.net/projects/myhdl/files/myhdl/0.8/ > > Of the 2 patches, myhdl-0.8-fix_modbv.patch is my poor-man's fix for > modbv, because I needed modbv. This patch is most likely obsoleted by > Jan's real fix in the repo. > > The other patch (myhdl-0.8-partitions.patch) contains my crude first draft > supporting the described hierarchy. Yes, this code is ugly. Don't look at > it yet. It is a quick mock-up of some functionality I really wanted. But > give it a try if you're interested and let me know what it breaks on... Or > if you really want to dive into the code, feel free to do so. > > On my systems, I apply & install these patches as follows: (gunzip the > .patch files first) > > gunzip myhdl-0.8-fix_modbv.patch.gz > gunzip myhdl-0.8-partitions.patch.gz > tar zxf myhdl-0.8.tar.gz \ > && cd myhdl-0.8 \ > && patch -p1 < ../myhdl-0.8-fix_modbv.patch \ > && patch -p1 < ../myhdl-0.8-partitions.patch \ > && python setup.py build \ > && python setup.py install --user -O2 \ > && cd .. \ > && rm -rf myhdl-0.8 > > This installs myhdl into python's standard location for my home directory, > but feel free to leave off --user to install to the main system path, or > wherever else you want. > > To test drive the functionality, try running test_partition.py. Set > toVerilog.partitioned_output=False > to see the normal output, and > toVerilog.partitioned_output=True > to see the partitioned output. And if you are curious, try > toVerilog.partitioned_output="I promise I will never die." > to enable the partitioned output code, but tell it to ignore the partition > annotations. > > > (typos and all, I'm hitting send...) > > - David > > > > On Wed, May 1, 2013 at 6:44 PM, Oscar Daniel Diaz <osc...@gm...>wrote: > >> El Wed, 01 May 2013 10:55:55 +0200 >> Jan Decaluwe <ja...@ja...> escribió: >> >> > On 04/29/2013 05:25 PM, Oscar Daniel Diaz wrote: >> > >> > > Given that the converter is called recursively several times, >> > > multiple files are generated and its contents are used for component >> > > declaration (VHDL). Recursive calls must avoid file replication (for >> > > VHDL case means avoid multiple package file generation). This is >> > > done by keeping generated code in memory before pushing to files. >> > > >> > > Attribute "no_component_files" : >> > > * False : all components code is saved to disk as soon as >> > > possible. >> > > * True : discard components code, only save top-module file. >> > >> > Not sure what is meant here exactly. Why would we need component >> > declarations, as opposed to simply using direct instantation? >> > For a case like this, this seems much simpler and less verbose >> > to me. >> >> Since keep hierarchy conversion requires multiple files to generate >> (top-module and components to instantiate), this flag prevents >> generation of those components. Suppose you make some changes only in >> the top-module, this flag allows to only generate top-module file. >> >> When I change from VHDL '87 syntax (doing recursive calls to get >> component declaration) to '93 syntax, that flag would prevent >> those recursive calls. >> >> -- >> Oscar Díaz >> Key Fingerprint = 904B 306C C3C2 7487 650B BFAC EDA2 B702 90E9 9964 >> gpg --keyserver subkeys.pgp.net --recv-keys 90E99964 >> >> >> _______________________________________________ >> myhdl-list mailing list >> myh...@li... >> https://lists.sourceforge.net/lists/listinfo/myhdl-list >> >> > > > ------------------------------------------------------------------------------ > October Webinars: Code for Performance > Free Intel webinars can help you accelerate application performance. > Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most > from > the latest Intel processors and coprocessors. See abstracts and register > > http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > > |
From: Keerthan jai.c <jck...@gm...> - 2013-09-30 00:26:05
|
David, Just a heads up, the 0.9 dev branch on bitbucket has quite a few changes in the conversion area(MEP 107). You might want to check whether these patches apply on the new branch. On Sun, Sep 29, 2013 at 2:21 PM, David Holl <da...@ad...> wrote: > There was an old thread regarding MEP 110, but I've come up with an > alternative "solution", and I'm looking for your comments. (call it MEP > 110-alt?) > > tl;dr --- If you're interested, > > Introduction: Same as MEP 110. (Especially for floor planning...) > ----------------------- > Analysis: Same as MEP 110. (Yep, everything gets flattened by default...) > ----------------------- > Proposed Solution: (with implementation) > > I did not follow the proposed solution in MEP 110, because that would've > required that I change [any of] my components to be "top-module > convertible". (I'm using a form of signal containers --similar to MEP > 107-- which which would've required many changes (in my code) to achieve > "top-module convertibility".) > > What I did was I started from the flattened hierarchy in > conversion/_toVerilog.py, but instead of calling the usual > _writeSigDecls, _convertGens, I wrote my own convoluted output code: > ... > if self.partitioned_output: > _write_partitioned_output(self.partitioned_output, vfile, > vpath, self.timescale, h, intf, siglist, memlist, genlist, doc) > else: > _writeFileHeader(vfile, vpath, self.timescale) > _writeModuleHeader(vfile, intf, doc) > _writeSigDecls(vfile, intf, siglist, memlist) > _convertGens(genlist, vfile) > _writeModuleFooter(vfile) > ... > > > To activate this alternative output, just > set toVerilog.partitioned_output=True: > toVerilog.name='test_partition' > toVerilog.partitioned_output=True # the default is False > toVerilog(_test_top, clk, AAA, BBB, ZZZ, TTT, VVV) > > Without any other changes to a hardware description, this alternative code > will produce identical, flattened output. (right down to the arbitrary > ordering of signals and generators...) > > However, you may now group any related logic together, as needed. I call > a group of logic a "partition", and these partitions may be nested. > Instead of the word "partition" you could call it a "module" instead, > since the concept is almost identical to Verilog module's. In the > following description, it will appear that I'm flipping between "partition" > and "module" when really, I'm describing how that partitions in python > impact the created Verilog modules. (but for simplistic purposes, since I > guarantee each "partition" will create a unique Verilog "module", feel free > to call em' what you want...) > > There are 2 ways to assign related hardware into partitions. > ----------------------- > 1) The first is via python's "with" statement. I'll show a few examples: > > example 1.a) A simple partition... > from myhdl import Signal, partition, ... > > @always(clk.posedge) > def clgc(): > c.next = a + b > > with partition('A'): > @always(clk.posedge) > def clgd(): > d.next = c + e > > @always(clk.posedge) > def clge(): > e.next = a * b > > @always(clk.posedge) > def clgf(): > f.next = more stuff... > > > What "partition" does is annotate all generators (and shadow signals...) > with your text label. Then the "partitioned-output" code uses these > annotations move related logic into a Verilog module, and instantiate that > module from the top-level module. Module ports are automatically created > for any signals that need to cross between modules. > > This code still creates only 1 output .v file containing all modules. (I > didn't care if it was 1 file or multiple files, but for me, 1 file was > "easier" to move/copy around in my opinion.) > > The top module will include all of the signals, except for "e" --- because > in this code, e is only used within partition A. Therefore "e" will appear > as a driven "reg" within a submodule called A. (and that submodule "A" is > instantiated in the top level as "part_A"...) > > > > example 1.b) Partitions may be nested. > > @always(clk.posedge) > def clgc(): > c.next = a + b > > with partition('A'): > @always(clk.posedge) > def clgd(): > d.next = c + e > > with partition('B'): > @always(clk.posedge) > def clge(): > e.next = a * b > > @always(clk.posedge) > def clgf(): > f.next = more stuff... > > > This code will create 3 modules total: the top module, a module called > "A", and a module called "A_B". > > > example 1.c) Partitions having the same name will be renamed to stay > unique! > > If you want related code to be grouped into a partition, all of that code > must be contained in the same python "with" block. For example: > > from myhdl import Signal, partition, ... > > @always(clk.posedge) > def clgc(): > c.next = a + b > > with partition('A'): # This will be renamed to A0 > @always(clk.posedge) > def clgd(): > d.next = c + e > > with partition('A'): # This will be renamed to A1 > @always(clk.posedge) > def clge(): > e.next = a * b > > > Rationale: When you start nesting partitions, partition names are > guaranteed to produce unique module instances and not accidentally group > unrelated logic together. > > > example 1.d) Partitions are nestable across your python function calls, > and renaming will happen to keep sub > > For example, unrelated nested partitions may use the same name without > fear of their logic being accidentally grouped together. > > from myhdl import Signal, partition, ... > > def my_module_alice(...): > # ... > with partition('SM'): > # This happens to enclose a state machine. > # The name SM isn't descriptive enough, but if you > # want descriptive Verilog output, then you should > # use descriptive names. > # ... > # ... > return instances() > > def my_module_bob(...): > # ... > with partition('SM'):# This encloses an unrelated state machine. > # ... > # ... > return instances() > > def top(...): > @always(clk.posedge) > def clgc(): > c.next = a + b > > with partition('CRYPTO'): > alice_inst = alice(...) > bob0_inst = bob(...) > bob1_inst = bob(...) > > with partition('CRYPTO_SM2'): > # I made this CRYPTO_SM2 name, just to be a jerk. > @always(clk.posedge) > def clgd(): > d.next = c + e > > > This code would produce 6 instantiated modules in the generated Verilog > output: > module top(...); > module CRYPTO(...); > module CRYPTO_SM0(...); // this is from alice_inst > module CRYPTO_SM1(...); // this is from bob0_inst > module CRYPTO_SM2(...); // this is from bob1_inst > module CRYPTO_SM2_(...); // renamed CRYPTO_SM2 to not conflict with > CRYPT_SM2 from bob1_inst > > Admittedly, the generated names CRYPTO_SM... in this example aren't very > clear, but the point here is that your python functions (like alice() and > bob()) have a guaranteed means to group logic into a Verilog module without > accidental commingling of unrelated from other modules. > > The "top" module instantates "CRYPTO" and "CRYPTO_SM2_". Then "CRYPTO" > instantiates "CRYPTO_SM0", "CRYPTO_SM1", and "CRYPTO_SM2". > > > example 1.e) Partitions support Verilog 2001 attributes (and if someone > wants to add VHDL support...) > > with partition('A') as this_part: # This will be renamed to A0 > this_part.attr_add('KEEP_HIERARCHY', 'TRUE') > this_part.attr_add('DONT_TOUCH', 'TRUE') > > @always(clk.posedge) > def clgd(): > d.next = c + e > > This will produce output that instantiates module A as: > > (* KEEP_HIERARCHY="TRUE", DONT_TOUCH="TRUE" *) part_A A(clk, c, e, d); > > // The generated module for instance A is called "part_A". > > (MyHDL also has a nifty feature to include doc strings as embedded > comments. I have some back-end support for attaching a string to a > partition, to be output as a comment in the code, but I haven't turned it > on yet.) > > ----------------------- > 2) The second way to group logic into a partition is with a python > decorator. > > example 2) Using decorators in addition to "with" blocks. > > The decorator syntax uses the same rules as the with-blocks. (All > partitions will be unique, and possibly suffixed with a number to maintain > uniqueness in the Verilog code. Partitions may be nested. Use descriptive > names if you want descriptive output.) > > Here, I'll intermix the decorator and with syntax: > > def my_module_alice(...): > # ... > with partition('SM'): > # This happens to enclose a state machine. > # The name SM isn't descriptive enough, but if you > # want descriptive Verilog output, then you should > # use descriptive names. > # ... > # ... > return instances() > > @partition('AES') # <---- partition a la decorator. > def my_module_bob(...): > # ... > with partition('SM'):# This encloses an unrelated state machine. > # ... > # ... > return instances() > > def top(...): > @always(clk.posedge) > def clgc(): > c.next = a + b > > with partition('CRYPTO'): > alice_inst = alice(...) > bob0_inst = bob(...) > bob1_inst = bob(...) > > with partition('CRYPTO_SM2'): > # I made this CRYPTO_SM2 name, just to be a jerk. > @always(clk.posedge) > def clgd(): > d.next = c + e > > The above code will generate ~8 modules: > module top(...); > module CRYPTO(...); > module CRYPTO_SM(...); // this is from alice_inst > module CRYPTO_AES0(...); // decorator on bob() > module CRYPTO_AES0_SM(...); // this is from bob0_inst > module CRYPTO_AES1(...); // decorator on bob() > module CRYPTO_AES1_SM(...); // this is from bob1_inst > module CRYPTO_SM2(...); // renamed CRYPTO_SM2 to not conflict with > CRYPT.SM from bob1_inst > > > ----------------------- END OF EXAMPLES > > Limitations: I hope there aren't any. I put enough care to accomodate > ConcatSignal's, _SliceSignal's, const [undriven] _Signal's, etc... And if > a signal gets pushed into a sub-partition where it is both driven and read, > as well as output from that sub-partition, the generator will automatically > make a separate wire just for the output port, that is driven from your > signal. (This prevents "Output port is read internally..." warnings for > partition-generated modules. I don't do this for the top-level though, to > preserve the same interface as current MyHDL output.) > > Component Conversion: No additional restrictions beyond that of MyHDL. > There is still the same requirement on your top-level to be "top-level > convertible", but there is flexibility for your lower levels. > > Component Parameters: What parameters? All of your parameters were > already digested by python+MyHDL magic, and I'm operating on the flattened > hierarchy. If you invoke the same sub-partition (sub-module) multiple > times, it will be replicated in the output, but every time it appears, it > will use the globally-unique signal names that MyHDL has already assigned. > (ie, I don't change your signal names.) > > Any drawbacks: > This may/will produce larger output code than the proposed solution in MEP > 110. The existing MEP 110 solution will create 1 copy of each module, and > instantiate it multiple times (as long as each instantiation shares the > same port signal widths, etc...). In contrast, this "110.alt" solution > will create a whole copy of a module every time it is instantiated. (But > each copy inherits the unique signal names assigned by MyHDL's flattening > algorithm.) However, the larger output size from this "110.alt" isn't that > much larger than MyHDL's native flat output. (depending on your signal > usage...) > > Benefits: > You can have hierarchical output with minimal changes to your code, > and you control exactly how your logic is partitioned into the hierarchy. > Just sprinkle a few @partition(...) or "with partition(...):" statements > wherever you need in your design. > > Known pitfalls: I have not tried or tested TristateSignal's for "inout" > ports, and I've only tested on a very narrow subset of MyHDL's feature set. > (I was was already bitten by ConcatSignal's, _SliceSignal's, and lists of > signals accidentally being inferred as memories... However, I expect these > areas to work as expected now.) > > > But if anyone is interested, here's the code, and I'm open for feedback. > > I attached patches against myhdl-0.8.tar.gz available from > https://sourceforge.net/projects/myhdl/files/myhdl/0.8/ > > Of the 2 patches, myhdl-0.8-fix_modbv.patch is my poor-man's fix for > modbv, because I needed modbv. This patch is most likely obsoleted by > Jan's real fix in the repo. > > The other patch (myhdl-0.8-partitions.patch) contains my crude first draft > supporting the described hierarchy. Yes, this code is ugly. Don't look at > it yet. It is a quick mock-up of some functionality I really wanted. But > give it a try if you're interested and let me know what it breaks on... Or > if you really want to dive into the code, feel free to do so. > > On my systems, I apply & install these patches as follows: (gunzip the > .patch files first) > > gunzip myhdl-0.8-fix_modbv.patch.gz > gunzip myhdl-0.8-partitions.patch.gz > tar zxf myhdl-0.8.tar.gz \ > && cd myhdl-0.8 \ > && patch -p1 < ../myhdl-0.8-fix_modbv.patch \ > && patch -p1 < ../myhdl-0.8-partitions.patch \ > && python setup.py build \ > && python setup.py install --user -O2 \ > && cd .. \ > && rm -rf myhdl-0.8 > > This installs myhdl into python's standard location for my home directory, > but feel free to leave off --user to install to the main system path, or > wherever else you want. > > To test drive the functionality, try running test_partition.py. Set > toVerilog.partitioned_output=False > to see the normal output, and > toVerilog.partitioned_output=True > to see the partitioned output. And if you are curious, try > toVerilog.partitioned_output="I promise I will never die." > to enable the partitioned output code, but tell it to ignore the partition > annotations. > > > (typos and all, I'm hitting send...) > > - David > > > > On Wed, May 1, 2013 at 6:44 PM, Oscar Daniel Diaz <osc...@gm...>wrote: > >> El Wed, 01 May 2013 10:55:55 +0200 >> Jan Decaluwe <ja...@ja...> escribió: >> >> > On 04/29/2013 05:25 PM, Oscar Daniel Diaz wrote: >> > >> > > Given that the converter is called recursively several times, >> > > multiple files are generated and its contents are used for component >> > > declaration (VHDL). Recursive calls must avoid file replication (for >> > > VHDL case means avoid multiple package file generation). This is >> > > done by keeping generated code in memory before pushing to files. >> > > >> > > Attribute "no_component_files" : >> > > * False : all components code is saved to disk as soon as >> > > possible. >> > > * True : discard components code, only save top-module file. >> > >> > Not sure what is meant here exactly. Why would we need component >> > declarations, as opposed to simply using direct instantation? >> > For a case like this, this seems much simpler and less verbose >> > to me. >> >> Since keep hierarchy conversion requires multiple files to generate >> (top-module and components to instantiate), this flag prevents >> generation of those components. Suppose you make some changes only in >> the top-module, this flag allows to only generate top-module file. >> >> When I change from VHDL '87 syntax (doing recursive calls to get >> component declaration) to '93 syntax, that flag would prevent >> those recursive calls. >> >> -- >> Oscar Díaz >> Key Fingerprint = 904B 306C C3C2 7487 650B BFAC EDA2 B702 90E9 9964 >> gpg --keyserver subkeys.pgp.net --recv-keys 90E99964 >> >> >> _______________________________________________ >> myhdl-list mailing list >> myh...@li... >> https://lists.sourceforge.net/lists/listinfo/myhdl-list >> >> > > > ------------------------------------------------------------------------------ > October Webinars: Code for Performance > Free Intel webinars can help you accelerate application performance. > Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most > from > the latest Intel processors and coprocessors. See abstracts and register > > http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > > -- have a nice day -jck |