Re: [myhdl-list] MEP - keep hierarchy in conversion
Brought to you by:
jandecaluwe
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 |