Thread: [myhdl-list] Simplifying Interfaces
Brought to you by:
jandecaluwe
From: Christopher F. <chr...@gm...> - 2012-06-20 03:37:20
|
In one of the MEP-107 threads we had been discussing the current support of attribute conversion. It was pointed out by Oscar that attributes will convert fine as long as a local reference is made. This was interesting because it provides a means with the current release to use objects to simplify interfaces. At first I thought this would be restrictive in the sense that the attributes would only be an intermediate reference, something like the following: In [2]: def top(clock, reset): ...: x,y,z = [Signal(False) for ii in range(3)] ...: class bucket(): pass ...: bb = bucket() ...: bb.x = x ...: bb.y = y ...: bb.z = z ...: g1 = some_module(clock, reset, bb) ...: return g1 ...: In [3]: def some_module(clock, reset, bb): ...: x = bb.x ...: y = bb.y ...: z = bb.z ...: @always(clock.posedge) ...: def hdl(): ...: if not reset: ...: z.next = False ...: else: ...: z.next = x or y ...: return hdl Which converts to the following ... always @(posedge clock) begin: TOP_G1_HDL if ((!reset)) begin z <= 1'b0; end else begin z <= (x || y); end end What I found interesting was the fact that you do not need to start with the individual signals and reference through attributes. The conversion will work in the following case as well. In [11]: def top2(clock, reset): ...: class bucket(): ...: def __init__(self): ...: self.x = Signal(False) ...: self.y = Signal(False) ...: self.z = Signal(False) ...: bb = bucket() ...: g1 = some_module(clock, reset, bb) ...: return g1 The above will convert to always @(posedge clock) begin: TOP2_G1_HDL if ((!reset)) begin g1_z <= 1'b0; end else begin g1_z <= (g1_x || g1_y); end end There doesn't seem to be any restriction in the use of attributes other than they need to be locally referenced (with the current release and development branch). I created a larger example using an embedded bus, wishbone. Using a similar technique you can simplify the interfaces between modules. This example is functional but incomplete. I had a little bit of time and implemented but time was limited and didn't even take the time to look at the wishbone spec (it has been a while since I last used wishbone). There could be some inaccuracies. Using this approach, which is fully supported by conversion with today's releases, a couple simplifications (imo) were achieved. First, the interface was simplified and generalized. As discussed only a single reference was passed to a module. All the signals were encapsulated by the reference. def gpio(wb, out, NumOutputs=1): """Very simple memory mapped peripheral""" Second, now the embedded bus can be very modular. In this case the peripheral doesn't know or care what bus is actually used. In the peripheral it simply requests the registers it needs. This works for basic rw (control) and ro (status) registers (although the current example only uses rw). The ridiculously simple gpio is: def gpio(wb, out, NumInputs=0, NumOutputs=1): """Very simple memory mapped peripheral""" rin = Signal(intbv(0)[8:]) rout = Signal(intbv(0)[8:]) wbdev = wb.AddDevice(Name="GPIO") iReg = wb.AddDeviceRegister(rin, rout, wbdev) @always_comb def hdl_assigns(): out.next = rout[0] return iReg, hdl_assigns The above should probably be changed to have a AddDeviceRwRegister(...) and AddDeviceRoRegister(...). As mentioned, the bus referenced passed could be any bus protocol because the actual bus interfacing is part of the generators in the bus object. The top-level looks something like the following def simple_top(clock, reset, buttons, leds): wb = Wishbone(DataWidth=8, AddressWidth=16) iController = buttons2bus(clock, reset, wb, buttons) outs = [Signal(False) for ii in range(len(leds))] iGpios = [None for ii in range(len(leds))] for ii in range(len(leds)): iGpios[ii] = gpio(wb, outs[ii]) iBus = wb.DeviceBusses() print(wb.Summary()) return iController, iGpios, iBus, hdl_assigns The complete example can be found here https://bitbucket.org/cfelton/examples/src/tip/simple The main file is the simple.py file and the bus is implemented in the wishbone.py. This example is *silly*. It has buttons as inputs and leds as outputs. If a button is pressed it will create a bus access to a gpio (one module per led) and toggle the led. The example was simple to verify (limited inputs and outputs) and I can test it on actual hardware. Feedback and comments welcomed. Chris Felton |
From: Jan D. <ja...@ja...> - 2012-06-22 15:24:41
|
Hi: I don't follow the example completely, but if you - an experienced MyHDL designer - are surprized, then others will be even more so. I wonder if we can come up with an example suited for the MyHDL by Example section, that demonstrates the power of these techniques. The message should be that conversion only deals with code inside generators, in the context of their namespaces. Conversion restrictions only apply to that code. The namespaces are created during elaboration, so it doesn't matter how. On 06/20/2012 05:37 AM, Christopher Felton wrote: > In one of the MEP-107 threads we had been discussing > the current support of attribute conversion. It was > pointed out by Oscar that attributes will convert fine > as long as a local reference is made. This was interesting > because it provides a means with the current release > to use objects to simplify interfaces. > > At first I thought this would be restrictive in the > sense that the attributes would only be an intermediate > reference, something like the following: > > In [2]: def top(clock, reset): > ...: x,y,z = [Signal(False) for ii in range(3)] > ...: class bucket(): pass > ...: bb = bucket() > ...: bb.x = x > ...: bb.y = y > ...: bb.z = z > ...: g1 = some_module(clock, reset, bb) > ...: return g1 > ...: > > In [3]: def some_module(clock, reset, bb): > ...: x = bb.x > ...: y = bb.y > ...: z = bb.z > ...: @always(clock.posedge) > ...: def hdl(): > ...: if not reset: > ...: z.next = False > ...: else: > ...: z.next = x or y > ...: return hdl > > Which converts to the following > > ... > always @(posedge clock) begin: TOP_G1_HDL > if ((!reset)) begin > z<= 1'b0; > end > else begin > z<= (x || y); > end > end > > > What I found interesting was the fact that you do not > need to start with the individual signals and reference > through attributes. The conversion will work in the > following case as well. > > In [11]: def top2(clock, reset): > ...: class bucket(): > ...: def __init__(self): > ...: self.x = Signal(False) > ...: self.y = Signal(False) > ...: self.z = Signal(False) > ...: bb = bucket() > ...: g1 = some_module(clock, reset, bb) > ...: return g1 > > The above will convert to > > always @(posedge clock) begin: TOP2_G1_HDL > if ((!reset)) begin > g1_z<= 1'b0; > end > else begin > g1_z<= (g1_x || g1_y); > end > end > > There doesn't seem to be any restriction in the use of > attributes other than they need to be locally referenced > (with the current release and development branch). > > I created a larger example using an embedded bus, wishbone. > Using a similar technique you can simplify the interfaces > between modules. This example is functional but incomplete. > I had a little bit of time and implemented but time was > limited and didn't even take the time to look at the wishbone > spec (it has been a while since I last used wishbone). > There could be some inaccuracies. > > Using this approach, which is fully supported by conversion > with today's releases, a couple simplifications (imo) were > achieved. > > First, the interface was simplified and generalized. As > discussed only a single reference was passed to a module. > All the signals were encapsulated by the reference. > > def gpio(wb, out, NumOutputs=1): > """Very simple memory mapped peripheral""" > > Second, now the embedded bus can be very modular. In this > case the peripheral doesn't know or care what bus is actually > used. In the peripheral it simply requests the registers it > needs. This works for basic rw (control) and ro (status) > registers (although the current example only uses rw). The ridiculously > simple gpio is: > > def gpio(wb, out, NumInputs=0, NumOutputs=1): > """Very simple memory mapped peripheral""" > rin = Signal(intbv(0)[8:]) > rout = Signal(intbv(0)[8:]) > wbdev = wb.AddDevice(Name="GPIO") > iReg = wb.AddDeviceRegister(rin, rout, wbdev) > > @always_comb > def hdl_assigns(): > out.next = rout[0] > > return iReg, hdl_assigns > > The above should probably be changed to have a > AddDeviceRwRegister(...) and AddDeviceRoRegister(...). > As mentioned, the bus referenced passed could be any bus > protocol because the actual bus interfacing is part of the > generators in the bus object. > > The top-level looks something like the following > > def simple_top(clock, reset, buttons, leds): > > wb = Wishbone(DataWidth=8, AddressWidth=16) > iController = buttons2bus(clock, reset, wb, buttons) > outs = [Signal(False) for ii in range(len(leds))] > iGpios = [None for ii in range(len(leds))] > for ii in range(len(leds)): > iGpios[ii] = gpio(wb, outs[ii]) > > iBus = wb.DeviceBusses() > print(wb.Summary()) > > return iController, iGpios, iBus, hdl_assigns > > The complete example can be found here > https://bitbucket.org/cfelton/examples/src/tip/simple > > The main file is the simple.py file and the bus is > implemented in the wishbone.py. > > This example is *silly*. It has buttons as inputs and leds > as outputs. If a button is pressed it will create a bus > access to a gpio (one module per led) and toggle the led. > The example was simple to verify (limited inputs and outputs) > and I can test it on actual hardware. > > Feedback and comments welcomed. > Chris Felton > > > ------------------------------------------------------------------------------ > Live Security Virtual Conference > Exclusive live event will cover all the ways today's security and > threat landscape has changed and how IT managers can respond. Discussions > will include endpoint security, mobile security and the latest in malware > threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ -- 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: Christopher F. <chr...@gm...> - 2012-06-26 12:23:54
|
On 6/25/2012 3:30 AM, Wesley New wrote: > Firstly, thanks for Chris for bringing this feature to light. It is > definitely one I will employ. > > The only problem I am having is that the ports arent expanded out when I am > using user-defined hdl. > As it isnt creating a flat file, the wrapper doesnt have any wishbone ports. > > For instance see the attached file. > > Initially all I wish to do is to encapsulate the wishbone ports so that I > dont have to type them every time I instantiate a module that has a > wishbone interface > > Regards > > Wesley > You would not be able to use the "object" on the top-level. The outside world (your Verilog or VHDL) wouldn't know how to interface to a /wb/. The top-level has to be the discrete signals everything inside can use the /wb/ to simplify the interface. I haven't tested it with the user defined code, you might have to do and extra step, but it should be possible. Regards, Chris |
From: Christopher F. <chr...@gm...> - 2012-06-27 04:05:35
|
On 6/26/12 7:23 AM, Christopher Felton wrote: > On 6/25/2012 3:30 AM, Wesley New wrote: >> Firstly, thanks for Chris for bringing this feature to light. It is >> definitely one I will employ. >> >> The only problem I am having is that the ports arent expanded out when I am >> using user-defined hdl. >> As it isnt creating a flat file, the wrapper doesnt have any wishbone ports. >> >> For instance see the attached file. >> >> Initially all I wish to do is to encapsulate the wishbone ports so that I >> dont have to type them every time I instantiate a module that has a >> wishbone interface >> >> Regards >> >> Wesley >> > > > You would not be able to use the "object" on the top-level. The outside > world (your Verilog or VHDL) wouldn't know how to interface to a /wb/. > The top-level has to be the discrete signals everything inside can use > the /wb/ to simplify the interface. > > I haven't tested it with the user defined code, you might have to do and > extra step, but it should be possible. > > Regards, > Chris > I added an example that I believe does what you are trying to do. https://bitbucket.org/cfelton/examples/src/tip/stitch The example is a little redonkulous right now, lot of top-level ports that are not used. The top-levels will always need to be the individual signals (best of my knowledge) don't think it is reasonable that the top-level can be something else. Regards, Chris |
From: Christopher F. <chr...@gm...> - 2012-06-26 12:35:49
|
On 6/22/2012 10:24 AM, Jan Decaluwe wrote: > Hi: > > I don't follow the example completely, but if you - > an experienced MyHDL designer - are surprized, then > others will be even more so. > > I wonder if we can come up with an example suited for > the MyHDL by Example section, that demonstrates the power > of these techniques. > > The message should be that conversion only deals with > code inside generators, in the context of their namespaces. > Conversion restrictions only apply to that code. > The namespaces are created during elaboration, so it > doesn't matter how. > I have been trying to think of a good example, an example that isn't too large (too much code to dig through for a cookbook example) and an example that fits nicely, I haven't come up with too many ideas. One example that appears to be used heavily with VHDL records and SV structs is a simple {opcode, address, flags} bundling. But this example on its own wouldn't be functional, it wouldn't do anything. It would be nice to have a small example that does something, I am failing to think of a good example. Anyone else have an idea for an example? I think for the example to be useful, you would want a design that you would use multiple modules and have some interface between. But the interface would be small (limited number of signals in the class) so the the example would be digestible. Regards, Chris |
From: Jan D. <ja...@ja...> - 2012-07-03 11:35:20
|
On 06/26/2012 02:35 PM, Christopher Felton wrote: > On 6/22/2012 10:24 AM, Jan Decaluwe wrote: >> Hi: >> >> I don't follow the example completely, but if you - >> an experienced MyHDL designer - are surprized, then >> others will be even more so. >> >> I wonder if we can come up with an example suited for >> the MyHDL by Example section, that demonstrates the power >> of these techniques. >> >> The message should be that conversion only deals with >> code inside generators, in the context of their namespaces. >> Conversion restrictions only apply to that code. >> The namespaces are created during elaboration, so it >> doesn't matter how. >> > > I have been trying to think of a good example, an example that isn't too > large (too much code to dig through for a cookbook example) and an > example that fits nicely, I haven't come up with too many ideas. > > One example that appears to be used heavily with VHDL records and SV > structs is a simple {opcode, address, flags} bundling. But this example > on its own wouldn't be functional, it wouldn't do anything. > > It would be nice to have a small example that does something, I am > failing to think of a good example. > > Anyone else have an idea for an example? I think for the example to be > useful, you would want a design that you would use multiple modules and > have some interface between. But the interface would be small (limited > number of signals in the class) so the the example would be digestible. Maybe something based on complex numbers, as Tom D has hinted. One could represent them as a class instance, or even as a tuple. -- 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: Wesley N. <we...@sk...> - 2012-07-03 12:34:35
|
Great, I have more in-depth look at this and post some feed back as soon as I get some time. Thanks for the example. :) Wes On Tue, Jul 3, 2012 at 1:34 PM, Jan Decaluwe <ja...@ja...> wrote: > On 06/26/2012 02:35 PM, Christopher Felton wrote: > > On 6/22/2012 10:24 AM, Jan Decaluwe wrote: > >> Hi: > >> > >> I don't follow the example completely, but if you - > >> an experienced MyHDL designer - are surprized, then > >> others will be even more so. > >> > >> I wonder if we can come up with an example suited for > >> the MyHDL by Example section, that demonstrates the power > >> of these techniques. > >> > >> The message should be that conversion only deals with > >> code inside generators, in the context of their namespaces. > >> Conversion restrictions only apply to that code. > >> The namespaces are created during elaboration, so it > >> doesn't matter how. > >> > > > > I have been trying to think of a good example, an example that isn't too > > large (too much code to dig through for a cookbook example) and an > > example that fits nicely, I haven't come up with too many ideas. > > > > One example that appears to be used heavily with VHDL records and SV > > structs is a simple {opcode, address, flags} bundling. But this example > > on its own wouldn't be functional, it wouldn't do anything. > > > > It would be nice to have a small example that does something, I am > > failing to think of a good example. > > > > Anyone else have an idea for an example? I think for the example to be > > useful, you would want a design that you would use multiple modules and > > have some interface between. But the interface would be small (limited > > number of signals in the class) so the the example would be digestible. > > Maybe something based on complex numbers, as Tom D has > hinted. One could represent them as a class instance, > or even as a tuple. > > > -- > 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 > > > > ------------------------------------------------------------------------------ > Live Security Virtual Conference > Exclusive live event will cover all the ways today's security and > threat landscape has changed and how IT managers can respond. Discussions > will include endpoint security, mobile security and the latest in malware > threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > |
From: Christopher F. <chr...@gm...> - 2012-07-04 19:25:14
|
<snip> >> >> Anyone else have an idea for an example? I think for the example to be >> useful, you would want a design that you would use multiple modules and >> have some interface between. But the interface would be small (limited >> number of signals in the class) so the the example would be digestible. > > Maybe something based on complex numbers, as Tom D has > hinted. One could represent them as a class instance, > or even as a tuple. > > I was worried if the complex number example was used some might expect operator overload. I have been waffling if this would be a good example. Regards, Chris |
From: Tom D. <td...@di...> - 2012-07-05 16:29:42
|
On 07/04/2012 02:22 PM, Christopher Felton wrote: > <snip> >>> Anyone else have an idea for an example? I think for the example to be >>> useful, you would want a design that you would use multiple modules and >>> have some interface between. But the interface would be small (limited >>> number of signals in the class) so the the example would be digestible. >> Maybe something based on complex numbers, as Tom D has >> hinted. One could represent them as a class instance, >> or even as a tuple. >> >> > I was worried if the complex number example was used some > might expect operator overload. I have been waffling if > this would be a good example. I think the example would have to show why we would not try to overload operators. |
From: Christopher F. <chr...@gm...> - 2012-07-06 02:57:12
|
On 7/5/12 11:29 AM, Tom Dillon wrote: > > On 07/04/2012 02:22 PM, Christopher Felton wrote: >> <snip> >>>> Anyone else have an idea for an example? I think for the example to be >>>> useful, you would want a design that you would use multiple modules and >>>> have some interface between. But the interface would be small (limited >>>> number of signals in the class) so the the example would be digestible. >>> Maybe something based on complex numbers, as Tom D has >>> hinted. One could represent them as a class instance, >>> or even as a tuple. >>> >>> >> I was worried if the complex number example was used some >> might expect operator overload. I have been waffling if >> this would be a good example. > > I think the example would have to show why we would not try to overload > operators. > I agree, which, IMO, requires a little bit of *ART*. There are many concepts that need to pulled together and succinctly explained. I do not want set incorrect expectations. I don't know if I see a good way to explain that operator overloading is appropriate for a sequence of instructions but not for a hardware description (concurrent processes). Or if it is absent if it will raise questions. I don't if a plain "signal container" example would be a better fit. Regards, Chris |
From: Wesley N. <we...@sk...> - 2014-11-07 15:05:43
|
Did anyone ever come up with a good example of this? Wesley New South African SKA Project +2721 506 7365 www.ska.ac.za On Fri, Jul 6, 2012 at 4:56 AM, Christopher Felton <chr...@gm...> wrote: > On 7/5/12 11:29 AM, Tom Dillon wrote: > > > > On 07/04/2012 02:22 PM, Christopher Felton wrote: > >> <snip> > >>>> Anyone else have an idea for an example? I think for the example to > be > >>>> useful, you would want a design that you would use multiple modules > and > >>>> have some interface between. But the interface would be small > (limited > >>>> number of signals in the class) so the the example would be > digestible. > >>> Maybe something based on complex numbers, as Tom D has > >>> hinted. One could represent them as a class instance, > >>> or even as a tuple. > >>> > >>> > >> I was worried if the complex number example was used some > >> might expect operator overload. I have been waffling if > >> this would be a good example. > > > > I think the example would have to show why we would not try to overload > > operators. > > > > I agree, which, IMO, requires a little bit of *ART*. > There are many concepts that need to pulled together and > succinctly explained. I do not want set incorrect > expectations. > > I don't know if I see a good way to explain that operator > overloading is appropriate for a sequence of instructions > but not for a hardware description (concurrent processes). > Or if it is absent if it will raise questions. > > I don't if a plain "signal container" example would be a > better fit. > > Regards, > Chris > > > > > > ------------------------------------------------------------------------------ > Live Security Virtual Conference > Exclusive live event will cover all the ways today's security and > threat landscape has changed and how IT managers can respond. Discussions > will include endpoint security, mobile security and the latest in malware > threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > |
From: Christopher F. <chr...@gm...> - 2014-11-07 15:28:33
|
On 11/7/2014 9:05 AM, Wesley New wrote: > Did anyone ever come up with a good example of this? > Interfaces have been implemented in 0.9-dev, do you mean has a succinct example been generated as a cookbook or tutorial? I have a basic example here: http://www.fpgarelated.com/showarticle/544.php Regards, Chris > Wesley New > South African SKA Project > +2721 506 7365 > www.ska.ac.za > > > > On Fri, Jul 6, 2012 at 4:56 AM, Christopher Felton <chr...@gm...> > wrote: > >> On 7/5/12 11:29 AM, Tom Dillon wrote: >>> >>> On 07/04/2012 02:22 PM, Christopher Felton wrote: >>>> <snip> >>>>>> Anyone else have an idea for an example? I think for the example to >> be >>>>>> useful, you would want a design that you would use multiple modules >> and >>>>>> have some interface between. But the interface would be small >> (limited >>>>>> number of signals in the class) so the the example would be >> digestible. >>>>> Maybe something based on complex numbers, as Tom D has >>>>> hinted. One could represent them as a class instance, >>>>> or even as a tuple. >>>>> >>>>> >>>> I was worried if the complex number example was used some >>>> might expect operator overload. I have been waffling if >>>> this would be a good example. >>> >>> I think the example would have to show why we would not try to overload >>> operators. >>> >> >> I agree, which, IMO, requires a little bit of *ART*. >> There are many concepts that need to pulled together and >> succinctly explained. I do not want set incorrect >> expectations. >> >> I don't know if I see a good way to explain that operator >> overloading is appropriate for a sequence of instructions >> but not for a hardware description (concurrent processes). >> Or if it is absent if it will raise questions. >> >> I don't if a plain "signal container" example would be a >> better fit. >> >> Regards, >> Chris >> >> >> >> >> >> ------------------------------------------------------------------------------ >> Live Security Virtual Conference >> Exclusive live event will cover all the ways today's security and >> threat landscape has changed and how IT managers can respond. Discussions >> will include endpoint security, mobile security and the latest in malware >> threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ >> _______________________________________________ >> myhdl-list mailing list >> myh...@li... >> https://lists.sourceforge.net/lists/listinfo/myhdl-list >> > > > > ------------------------------------------------------------------------------ > > > > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > |