Thread: [myhdl-list] Convertible records
Brought to you by:
jandecaluwe
From: Sébastien B. <seb...@mi...> - 2011-09-02 12:19:31
|
Hi, The topic of records has been brought in quite some time ago: http://sourceforge.net/mailarchive/forum.php?thread_name=20040216193128.11905.qmail%40web60309.mail.yahoo.com&forum_name=myhdl-list However, while I managed to get them to work in simulation, they won't convert to VHDL or Verilog. I'm not an expert at Python, so I'm wondering if there is some fundamental issue that prevents this (useful) feature from being implemented, or is it that no one ever got down to it? Or am I just doing it wrong? My example code is below. Best regards, Sébastien from myhdl import * class Binary: def __init__(self): self.a = Signal(intbv()[32:]) self.b = Signal(intbv()[32:]) def Adder(clock, r, operands): @always(clock.posedge) def logic(): r.next = operands.a + operands.b return logic def TB(clock, r, operands): d = delay(10) @always(d) def tb(): operands.a.next = operands.a + 1 operands.b.next = operands.b + 1 clock.next = not clock print r return tb ops = Binary() r = Signal(intbv()[32:]) clock = Signal(bool(0)) dut = Adder(clock, r, ops) tb = TB(clock, r, ops) # this is fine sim = Simulation(dut, tb) sim.run(50) # this last line won't work # myhdl.ConversionError: in file essai.py, line 11: # Unsupported attribute: a toVHDL(Adder, clock, r, ops) |
From: Christopher F. <chr...@gm...> - 2011-09-02 13:45:46
|
On 9/2/2011 7:16 AM, Sébastien Bourdeauducq wrote: > Hi, > > The topic of records has been brought in quite some time ago: > http://sourceforge.net/mailarchive/forum.php?thread_name=20040216193128.11905.qmail%40web60309.mail.yahoo.com&forum_name=myhdl-list > > However, while I managed to get them to work in simulation, they won't > convert to VHDL or Verilog. I'm not an expert at Python, so I'm > wondering if there is some fundamental issue that prevents this (useful) > feature from being implemented, or is it that no one ever got down to > it? Or am I just doing it wrong? > Conversion of a composite type is not supported. The converted will examine the types to be converted and expects, either int or long, Signal, homogeneous list of signals, or a tuple of ints. A class/object that contains signals will not be converted. But the simulator has no problem modeling this convention. Hope this helps, Chris |
From: Sébastien B. <seb...@mi...> - 2011-09-02 13:56:53
|
On 09/02/2011 03:45 PM, Christopher Felton wrote: > A class/object that contains signals will not be converted. How difficult do you think it would be to get that to work? An alternative for me is the conversion of signal lists as parameters to the top functions, but this is not supported either. Which of the two is easier to implement? |
From: Christopher F. <chr...@gm...> - 2011-09-02 14:24:34
|
On 9/2/2011 8:53 AM, Sébastien Bourdeauducq wrote: > On 09/02/2011 03:45 PM, Christopher Felton wrote: >> A class/object that contains signals will not be converted. > > How difficult do you think it would be to get that to work? > > An alternative for me is the conversion of signal lists as parameters to > the top functions, but this is not supported either. > > Which of the two is easier to implement? Correct, neither of these are supported. I don't know how much effort it would require to support these feature. But I wouldn't mind researching this feature, because I recently also had a need to use a record type to convert some VHDL to MyHDL. My basic thought would be to create a type in MyHDL, SignalStruct, and then create long unique variable names in the converted HDL. Example: class MyBus(SignalStruct): def __init__(self): self.addr = Signal(intbv(0)[16:]) self.data = Signal(intbv(0)[8:]) # ... # ... some code bus = MyBus() # ... some generator bus.addr.next = x bus.data.next = y The the converter, when in encountered a SignalStruct in the port list (parameter) or generator it would simple expand the name. // example of converted code bus_addr_mybus_t = x bus_data_mybus_t = y The generated code would be a little obfuscated but I think the generated code should attempt to use the basics of the underlying HDL. This way, the Verilog can be Verilog and not SV. The base class SignalStruct is used to guide the converters and built it can contain helper functions. I am not familiar enough with the backend conversion to determine how much work it would be to find the primitive Signal type from a composite type in the converters. But it seems like a nice enhancement and I would be willing to take it on. But I have a couple other things I am trying to complete currently, it would need to be added to the queue. Regards, Chris Felton |
From: Sébastien B. <seb...@mi...> - 2011-09-02 15:38:47
|
On 09/02/2011 04:24 PM, Christopher Felton wrote: > My basic thought would be to create a type in MyHDL, SignalStruct, and > then create long unique variable names in the converted HDL. > > Example: > > class MyBus(SignalStruct): > def __init__(self): > self.addr = Signal(intbv(0)[16:]) > self.data = Signal(intbv(0)[8:]) > # ... I'm not sure having the base "SignalStruct" would be even necessary. A regular object should be enough (and potentially more flexible), no? i.e. "class MyBus():" could just work as well.. |
From: Christopher F. <chr...@gm...> - 2011-09-02 16:06:48
|
On 9/2/2011 10:35 AM, Sébastien Bourdeauducq wrote: > On 09/02/2011 04:24 PM, Christopher Felton wrote: >> My basic thought would be to create a type in MyHDL, SignalStruct, and >> then create long unique variable names in the converted HDL. >> >> Example: >> >> class MyBus(SignalStruct): >> def __init__(self): >> self.addr = Signal(intbv(0)[16:]) >> self.data = Signal(intbv(0)[8:]) >> # ... > > I'm not sure having the base "SignalStruct" would be even necessary. A > regular object should be enough (and potentially more flexible), no? > > i.e. "class MyBus():" could just work as well.. > Yes, at this point I don't have any justification for having a base class. It is just a gut feeling that have a specific base class will be useful (user shows intent). How the conversion analyzer works now, it looks at free variables (not sure what a free variable is) and checks the type. If the type were to be any class (object) the converter has to do more work to determine if appropriate signals exist in the class. If the converter can check for a particular type (base class) then it knows it has signals and can extract. Make sense? Maybe the AST easily supports this and the base class is not needed. The second part would be that the base class can have helper functions (again, this is a gut and not fully thought out) to help the conversion. Instead of the conversion analyzer having to jump down the class hierarchy, the SignalStruct can return signals (and signals of self object signals :) ). Regards, Chris |
From: Jan L. <jan...@et...> - 2011-09-02 18:45:11
|
Hi all, Am 02.09.2011 um 18:06 schrieb Christopher Felton: > How the conversion analyzer works now, it looks at free variables (not > sure what a free variable is) and checks the type. If the type were > to > be any class (object) the converter has to do more work to determine > if > appropriate signals exist in the class. If the converter can check > for > a particular type (base class) then it knows it has signals and can > extract. Make sense? Maybe the AST easily supports this and the base > class is not needed. maybe it would be a good idea to let the converter "ask" the class how it wants to be converted. In a very simple case something like: class SignalStruct: def __signals__(self): return self.a,self.b Jan -- Jan Langer Professorship Circuit and System Design Chemnitz University of Technology, Reichenhainer Str. 70, 09126 Chemnitz Phone: +49 37209 688001, Fax: +49 371 531-833158, Mobile: +49 162 9847325 http://www.tu-chemnitz.de/etit/sse |
From: Christopher F. <chr...@gm...> - 2011-09-02 19:10:35
|
On 9/2/2011 1:15 PM, Jan Langer wrote: > Hi all, > > Am 02.09.2011 um 18:06 schrieb Christopher Felton: >> How the conversion analyzer works now, it looks at free variables (not >> sure what a free variable is) and checks the type. If the type were >> to >> be any class (object) the converter has to do more work to determine >> if >> appropriate signals exist in the class. If the converter can check >> for >> a particular type (base class) then it knows it has signals and can >> extract. Make sense? Maybe the AST easily supports this and the base >> class is not needed. > > > maybe it would be a good idea to let the converter "ask" the class how > it wants to be converted. In a very simple case something like: > > class SignalStruct: > def __signals__(self): > return self.a,self.b > > Jan > My thought was something like this: class SignalStruct(object): def __init__(self): pass def __signals__(self): return self.__dict__ class MyBus(SignalStruct): def __init__(self): self.addr = Signal(intbv(0)[16:]) self.data = Signal(intbv(0)[8:]) bus = MyBus() bus.__signals__() # This will return the signal objects with the names, the function # can also inspect each of the dict elemets and make sure they are # the correct types. At this point, I think (naively) this is a big chunk. This private function (__signals__) will need to dig deeper for embedded SignalStructs etc. .chris |
From: Sébastien B. <seb...@mi...> - 2011-09-02 19:00:03
|
On 09/02/2011 08:15 PM, Jan Langer wrote: > maybe it would be a good idea to let the converter "ask" the class how > it wants to be converted Can't you infer the list of signals to convert from which ones get actually used? What would be good imo (but with my limited knowledge of Python, I don't know if it's possible) is to simply name signal objects in the generated HDL according to how they were created. For example: class some_class() def __init__(x): self.some_signal = x (...) b = Signal(bool(0)) some_object = some_class(b) toVerilog(some_object.method) => gives a signal named "b" class some_class() def __init__(): self.some_signal = Signal(bool(0)) (...) some_object = some_class() toVerilog(some_object.method) => gives a signal named "some_object_some_signal" (We should adopt a better naming scheme to guarantee the absence of collisions, but you get the idea) This way (I believe) we could happily play with Python objects and still make nicely convertible/synthesizable code. For ports, we can maybe give references to signal objects we want exported to the conversion functions. Any comments? |
From: Christopher F. <chr...@gm...> - 2011-09-02 19:21:26
|
On 9/2/2011 1:57 PM, Sébastien Bourdeauducq wrote: > On 09/02/2011 08:15 PM, Jan Langer wrote: >> maybe it would be a good idea to let the converter "ask" the class how >> it wants to be converted > > Can't you infer the list of signals to convert from which ones get > actually used? > > What would be good imo (but with my limited knowledge of Python, I don't > know if it's possible) is to simply name signal objects in the generated > HDL according to how they were created. For example: > > class some_class() > def __init__(x): > self.some_signal = x I think, similar to the previous examples, we want the class with signals to be declarative and not dynamically building. Not that they can't be, but for a start should limit the discussion to building objects similar to VHDL record and SV struct. (??) The SignalStruct is a basic container of Signals. At least for conversion, modeling you can do all kinds of cool stuff. If you encapsulate an interface (collection of signals) into a class (SignalStruct) you can build in balun circuits :) Think they are also know as transactors or interfaces abstractions. > (...) > b = Signal(bool(0)) > some_object = some_class(b) > toVerilog(some_object.method) > => gives a signal named "b" > > class some_class() > def __init__(): > self.some_signal = Signal(bool(0)) > (...) > some_object = some_class() > toVerilog(some_object.method) > => gives a signal named "some_object_some_signal" > > (We should adopt a better naming scheme to guarantee the absence of > collisions, but you get the idea) > > This way (I believe) we could happily play with Python objects and still > make nicely convertible/synthesizable code. > > For ports, we can maybe give references to signal objects we want > exported to the conversion functions. I think the port can be the class object, for the previous example bus1 = MyBus() bus2 = MyBus() arb = MyBusArb(bus1, bus2) # <-- RTL module The converter will check the types, and will be ok with the port types because it will know how to handle them. Regards, Chris |
From: Sébastien B. <seb...@mi...> - 2011-09-02 19:42:31
|
On 09/02/2011 09:20 PM, Christopher Felton wrote: > should limit the discussion to building > objects similar to VHDL record and SV struct Hmm, this would be of little help for the high level synthesizer I'm trying to develop :-) I tend to think I need dynamically built structures. |
From: Christopher F. <chr...@gm...> - 2011-09-02 19:56:58
|
On 9/2/2011 2:39 PM, Sébastien Bourdeauducq wrote: > On 09/02/2011 09:20 PM, Christopher Felton wrote: >> should limit the discussion to building >> objects similar to VHDL record and SV struct > > Hmm, this would be of little help for the high level synthesizer I'm > trying to develop :-) I tend to think I need dynamically built structures. > Doh, but the first post (start of the conversation) was this simple type? class Binary: def __init__(self): self.a = Signal(intbv()[32:]) self.b = Signal(intbv()[32:]) In general, I don't think it would be a big issue. If something like the SignalStruct was used dynamically. You could add signals as you like. Then the converter would look at the final configuration and still get a list of signals. But I kinda want to wrap my head around the declarative types first (converter issues, etc) without closing the door on the dynamic. I think I am struggling with a use case were dynamic is more useful than the declarative. Regards, Chris |
From: Sébastien B. <seb...@mi...> - 2011-09-02 20:21:27
|
On 09/02/2011 09:56 PM, Christopher Felton wrote: > You could add signals as you > like. Then the converter would look at the final configuration and > still get a list of signals. Well, then it's dynamic :) |
From: Jan L. <jan...@et...> - 2011-09-04 20:50:07
|
Am 02.09.2011 um 21:56 schrieb Christopher Felton: > On 9/2/2011 2:39 PM, Sébastien Bourdeauducq wrote: >> On 09/02/2011 09:20 PM, Christopher Felton wrote: >>> should limit the discussion to building >>> objects similar to VHDL record and SV struct >> >> Hmm, this would be of little help for the high level synthesizer I'm >> trying to develop :-) I tend to think I need dynamically built >> structures. >> > > Doh, but the first post (start of the conversation) was this simple > type? > > class Binary: > def __init__(self): > self.a = Signal(intbv()[32:]) > self.b = Signal(intbv()[32:]) > > In general, I don't think it would be a big issue. If something like > the SignalStruct was used dynamically. You could add signals as you > like. Then the converter would look at the final configuration and > still get a list of signals. > > But I kinda want to wrap my head around the declarative types first > (converter issues, etc) without closing the door on the dynamic. I > think I am struggling with a use case were dynamic is more useful than > the declarative. A dynamic approach on top of a declarative is easily possible. I think we should have a protocol of what the converter expects from a type to be convertible. Then we can define signal types that have dynamic behavior from a users point of view and provide the declarative interface to the converter. The basic data structure used in this interface will probably be the classic intbv. I remember the discussions on the fixed point type. With an approach like the one above, it should be possible to have a very clean fixed point class that shows the user a nice and clean interface where the correct result data type is inferred in expressions and through the declarative interface behind the scene the converter knows how to map the fixed point object to bit vectors. Jan -- Jan Langer Professorship Circuit and System Design Chemnitz University of Technology, Reichenhainer Str. 70, 09126 Chemnitz Phone: +49 37209 688001, Fax: +49 371 531-833158, Mobile: +49 162 9847325 http://www.tu-chemnitz.de/etit/sse |