[myhdl-list] Re: how to create records in MyHDL like those in VHDL
Brought to you by:
jandecaluwe
From: Jan D. <ja...@ja...> - 2004-02-16 15:22:44
|
bedros wrote: > Thanks, Jan for you suggestions. > > I tried combining signals using lists and classes and > and worked for simulation, but only signals defined at > top level(CLK, RST) appeared in vcd file. > > Here's my code, so you can run it by yourself and > point to me what I'm doing wrong. Nothing wrong, except expectations :-) Function traceSignals finds the hierarchical regions in a design, and inspect their namespaces for things of type Signal. Those are mapped to a net in the VCD output. So, it doesn't find composite types like lists of Signals, or class instances whose members are Signals. Note that VCD doesn't support such things natively either (far from it), so some kind of heuristic mapping would be needed otherwise. Given what I expect from waveforms (low level debugging before actual verification starts) this wouldn't be worth the trouble in my judgement. The result is that you will only see Signals with a simple name in the VCD output. You could of course always do things like: list_sig = [A, Bvec, state] = [Signal(bool(0)),Signal(intbv()[32:]), Signal(state_t.idle_st) I did find a bug while looking at this. Do you use 0.3 or 0.4? In 0.4, the idea is that the generators at the lowest level can also be hierarchical regions in the VCD output - provided they get a name (this was not the case in 0.3). In 0.4, function _getGens in _extractHierarchy.py is buggy and should be as follows: def _getGens(arg): if type(arg) is GeneratorType: return [arg] elif type(arg) is _AlwaysComb: return [arg.gen] else: l = [] for elt in arg: if type(elt) is GeneratorType: l.append(elt) elif type(elt) is _AlwaysComb: l.append(elt.gen) return l Regards, Jan > > > > # test record > > from myhdl import * > > state_t = enum('idle_st', 'load_st', 'process_st', > 'exit_st') > > class my_record: > def __init__(self): > self.A = Signal(bool(0)) > self.Bvec = Signal(intbv()[32:]) > self.state = Signal(state_t.idle_st) > > #clock generator > def clk_gen(CLK, period=10): > lowTime = int(period / 2) > highTime = period - lowTime > while True: > yield delay(lowTime) > CLK.next = 1 > yield delay(highTime) > CLK.next = 0 > > # Reset generator > def reset_gen(CLK, RST): > RST.next = 1 > yield negedge(CLK) > RST.next = 0 > > def module_list(CLK, RST, list_sig): > > while True: > yield posedge(CLK), RST > > if RST: > list_sig[0].next = 0 > list_sig[1].next = 0x100 > list_sig[2].next = state_t.idle_st > else: > list_sig[0].next = not > list_sig[0].val > list_sig[1].next = list_sig[1].val > +1 > list_sig[2].next = state_t.load_st > > > def module_cls(CLK, RST, my_record): > > while True: > yield posedge(CLK), RST > > if RST: > my_record.A.next = 0 > my_record.Bvec.next = 0x100 > my_record.state.next = state_t.idle_st > else: > my_record.A.next = not > my_record.A.val > my_record.Bvec.next = > my_record.Bvec.val +1 > my_record.state.next = state_t.load_st > > > def top(): > > > # CLK and RST are of boolean type > # clock and reset signals > CLK = Signal(bool(0)) > RST = Signal(bool(0)) > # units to generate the clock and reset > clk_gen_u = clk_gen(CLK) > reset_gen_u = reset_gen(CLK,RST) > > # list of signals > list_sig = [Signal(bool(0)), > Signal(intbv()[32:]), Signal(state_t.idle_st)] > mod_list_u = module_list(CLK, RST, > list_sig) > > # class of signals > my_record_sig = my_record() > > > mod_cls_u = module_cls(CLK, RST, > my_record_sig) > > return clk_gen_u, reset_gen_u, mod_cls_u, > mod_list_u > > def main(): > > top_u = traceSignals(top) > sim = Simulation(top_u) > sim.run(100) > > if __name__ == '__main__': > main() > > > --- Jan Decaluwe <ja...@ja...> wrote: > >>bedros wrote: >> >>>Jan, >>> >>>I got a question for you. I've been playing with >> >>MyHDL >> >>>whenever I have extra time. Everything works fine >> >>for >> >>>me, but I need a way to combine many signals into >> >>one >> >>>record so I can pass it around. >> >>Some up-front remarks. In VHDL, you can create a >>composite >>type and then create a signal with it. In MyHDL, you >>could >>do something similar (using classes), but in >>addition, >>you can also create a composite type consisting of >>signals ... >> >>An example why this is relevant, consider: >> >>s = Signal(intbv()[8:] >> >>then s[i] is not a Signal, but an indexed item from >>the >>signal's current value. You could not use it to wait >>on, or in structure for example. This behavior will >>probably be the most important MyHDL "gotcha" for >>HDL >>users. I found it just too hard and complicated to >>implement it otherwise. >> >>However, it's trivial to create a list of signals: >> >>sl = [Signal(bool()) for i in range(8)] >> >>Now sl[i] is a signal, you can wait on it, use it >>ins structure etc. Note that there's no equivalent >>of this >>in the common HDLs. I think about this capability >>as the "workaround" for the "gotcha" above. >> >>The point is that you have be careful where >>to "place" the Signals in a composite type - they >>should be at the level where you will need >>signal "services". >> >> >>>I tried to create a new class with all my signals >>>instantiated and it worked fine, except I needed >> >>to >> >>>modify your source code to get the VCD waveforms. >> >>Even >> >>>though I used __str__ attribute; I still feel that >>>there should be a better way to do it. I'm new to >> >>both >> >>>MyHDL and Python. >> >>Using __str__ to get VCD output from a custom class >>seems >>the right way to me. We talked about this before - >>perhaps >>you should show me your modifications for me to >>understand >>the problem. >> >>One problem may be that we are struggling with VCD >>format >>limitations. It's a low-level format with not even >>native >>support for enums, and certainly not for composite >>types. >> >> >>>My question is how to make a record of something >>>roughly like this (in vhdl) >>> >>>type pkg_t is (data, address, command); >>> >>>type my_record is record >>> >>> package_type : pkg_t; >>> load : bit_vector(31 downto 0); >>> valid : boolean; >>> >>>end record; >>> >>>I can use enum for pkg_t statement, but how can I >>>create the record? should I use a function, list, >> >>or a >> >>>class? >> >>A class would seem the obvious choice. >> >>Assuming that you want to package signals (see >>above), >>I would expect that something like this should work: >> >>pkg_t = enum('data', 'address', 'command') >> >>class my_record(): >> def __init__(self): >> self.package_type = Signal(pkg_t.data) >> self.load = Signal(intbv()[32:]) >> self.valid = Signal(bool()) >> >>interface = my_record() >> >>Hope this helps, Jan >> >>-- >>Jan Decaluwe - Resources bvba - >>http://jandecaluwe.com >>Losbergenlaan 16, B-3010 Leuven, Belgium >> Python is fun, and now you can design hardware >>with it: >> http://jandecaluwe.com/Tools/MyHDL/Overview.html >> >> >> >> >> > > ------------------------------------------------------- > >>SF.Net is sponsored by: Speed Start Your Linux Apps >>Now. >>Build and deploy apps & Web services for Linux with >>a free DVD software kit from IBM. Click Now! >> > > http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click > >>_______________________________________________ >>myhdl-list mailing list >>myh...@li... >> > > https://lists.sourceforge.net/lists/listinfo/myhdl-list > > > > ------------------------------------------------------- > SF.Net is sponsored by: Speed Start Your Linux Apps Now. > Build and deploy apps & Web services for Linux with > a free DVD software kit from IBM. Click Now! > http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click -- Jan Decaluwe - Resources bvba - http://jandecaluwe.com Losbergenlaan 16, B-3010 Leuven, Belgium Python is fun, and now you can design hardware with it: http://jandecaluwe.com/Tools/MyHDL/Overview.html |