Thread: [myhdl-list] Reset functionality "synthesis"
Brought to you by:
jandecaluwe
From: Jan D. <ja...@ja...> - 2012-06-15 14:02:17
|
I think I have a good idea for a "micro-killer feature" - something that one can't do with traditional HDLs, but that makes a designer's life much easier. This was triggered by the latest discussion and work on initial values. Here is a summary of the starting point. I believe all signals/variables should have an initial value in RTL. Ideally, those initial values should be present in the converted Verilog/VHDL also, and we are currently discussing how and when to do so. However, there is the question of the reset functionality at the lower levels. Some people use the fact that signals are not initialized to check whether the reset works properly. With initial values, this is no longer possible (in simulation at least). The idea I have started as follows. Initial values and reset functionality seem related but at a different level. However, I don't see why there can ever be a good reason to use an initial value that is different from the reset value. The question is then if we can use that redundancy to our advantage. In a language like SystemVerilog, there is a dedicated always construct, always_ff, which can be used to check correctness of blocks with flip-flop inference, e.g. whether all flip-flops have a reset. In MyHDL, we could improve by checking that all flip-flops are reset to the initial value. However, I think we can do better. Recall that always_comb already inferres a sensitivity list. What if we introduced a new decorator, always_ff, that would infer the reset structure? The advantages would be: * reset functionality automatically correct by construction * no need to write code dedicated to reset functionality The latter feature is important because reset code tends to take up a lot of lines for non-functional reasons. Also, we would save a level of indentation. For example, suppose we have a wrap-around incrementer as follows: ... count = Signal(modbv(0)[8:]) ... def Inc(count, enable, clock, reset): @always(clock.posedge, reset.negedge) def incLogic(): if reset == 0: count.next = 0 else: if enable: count.next = count + 1 return incLogic With an always_ff decorator, we could rewrite it as follows: def Inc(count, enable, clock, reset): @always_ff(clock.posedge, reset=reset) def incLogic(): if enable: count.next = count + 1 return incLogic and it would do exactly the same as the original. Currently, I think always_ff would have an argument list as follows: always_ff(edge, reset=False, level=0, async=True) The False default for the reset parameter would allow to force the presence of a reset signal. (A block without reset would require reset=None explicitly). The reset level and style can also be specified, with defaults that correspond to the most common case in my opinion. Feedback welcome! -- 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: Tom D. <td...@di...> - 2012-06-15 14:40:17
|
One question, will you still be able to have a register that is not reset and doesn't have an initial value? I often use those in FPGAs when I want a shift register to get optimized to local memory. On 06/15/2012 09:02 AM, Jan Decaluwe wrote: > I think I have a good idea for a "micro-killer feature" - > something that one can't do with traditional HDLs, but > that makes a designer's life much easier. > > This was triggered by the latest discussion and work on > initial values. Here is a summary of the starting point. > > I believe all signals/variables should have an initial > value in RTL. Ideally, those initial values should be > present in the converted Verilog/VHDL also, and we are > currently discussing how and when to do so. > > However, there is the question of the reset functionality > at the lower levels. Some people use the fact that > signals are not initialized to check whether the reset > works properly. With initial values, this is no longer > possible (in simulation at least). > > The idea I have started as follows. Initial values and > reset functionality seem related but at a different level. > However, I don't see why there can ever be a good reason to > use an initial value that is different from the reset value. > The question is then if we can use that redundancy to our > advantage. > > In a language like SystemVerilog, there is a dedicated > always construct, always_ff, which can be used to check > correctness of blocks with flip-flop inference, e.g. > whether all flip-flops have a reset. In MyHDL, we could > improve by checking that all flip-flops are reset to the > initial value. > > However, I think we can do better. Recall that always_comb > already inferres a sensitivity list. What if we introduced > a new decorator, always_ff, that would infer the reset > structure? The advantages would be: > > * reset functionality automatically correct by construction > * no need to write code dedicated to reset functionality > > The latter feature is important because reset code tends > to take up a lot of lines for non-functional reasons. > Also, we would save a level of indentation. > > For example, suppose we have a wrap-around incrementer > as follows: > > ... > count = Signal(modbv(0)[8:]) > ... > def Inc(count, enable, clock, reset): > > @always(clock.posedge, reset.negedge) > def incLogic(): > if reset == 0: > count.next = 0 > else: > if enable: > count.next = count + 1 > > return incLogic > > With an always_ff decorator, we could rewrite it as follows: > > def Inc(count, enable, clock, reset): > > @always_ff(clock.posedge, reset=reset) > def incLogic(): > if enable: > count.next = count + 1 > > return incLogic > > and it would do exactly the same as the original. > > Currently, I think always_ff would have an argument > list as follows: > > always_ff(edge, reset=False, level=0, async=True) > > The False default for the reset parameter would allow > to force the presence of a reset signal. (A block > without reset would require reset=None explicitly). > The reset level and style can also be specified, with > defaults that correspond to the most common case in > my opinion. > > Feedback welcome! > |
From: Jan D. <ja...@ja...> - 2012-06-16 12:05:02
|
On 06/15/2012 04:39 PM, Tom Dillon wrote: > One question, will you still be able to have a register that is not > reset and doesn't have an initial value? > > I often use those in FPGAs when I want a shift register to get > optimized to local memory. For clarity: the present proposal suggest to use initial values in MyHDL as a specification of reset values. This is completely independent from the question whether such initial values should be written out in the converted Verilog or VHDL output code. The proposal would not change any current feature. Everything you can do today would be available unchanged. What you would have is an additional decorator that can be used to infer the reset structure automatically. Even if you don't want a reset, the new decorator would have value, because it permits to specify the absence of a reset explicitly: always_ff(clock.posedge, reset=None) def shift_reg(): reg.next = reg << 1 A reviewer would have no doubt that the absence of the reset is intentional, instead of a potential oversight. What you would not be able to do with this decorator is to mix resettable and non-resettable registers in the same block. But in my view that is not a good idea style-wise anyway. I always factor out such registers in a separate block. -- 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-18 17:18:45
|
<snip> > > However, I think we can do better. Recall that always_comb > already inferres a sensitivity list. What if we introduced > a new decorator, always_ff, that would infer the reset > structure? The advantages would be: > > * reset functionality automatically correct by construction > * no need to write code dedicated to reset functionality > > The latter feature is important because reset code tends > to take up a lot of lines for non-functional reasons. > Also, we would save a level of indentation. > > For example, suppose we have a wrap-around incrementer > as follows: > > ... > count = Signal(modbv(0)[8:]) > ... > def Inc(count, enable, clock, reset): > > @always(clock.posedge, reset.negedge) > def incLogic(): > if reset == 0: > count.next = 0 > else: > if enable: > count.next = count + 1 > > return incLogic > > With an always_ff decorator, we could rewrite it as follows: > > def Inc(count, enable, clock, reset): > > @always_ff(clock.posedge, reset=reset) > def incLogic(): > if enable: > count.next = count + 1 > > return incLogic > > and it would do exactly the same as the original. I really like this idea. I think it can be very useful. If I understand correctly, the initial value of the Signal is used for the /reset/ value? If the above was change to ... count = Signal(modbv(17)[8:]) ... Then the inferred reset logic would be ... if reset == 0: count.next = 17 ... Correct? > > Currently, I think always_ff would have an argument > list as follows: > > always_ff(edge, reset=False, level=0, async=True) > > The False default for the reset parameter would allow > to force the presence of a reset signal. (A block > without reset would require reset=None explicitly). > The reset level and style can also be specified, with > defaults that correspond to the most common case in > my opinion. > > Feedback welcome! > Haven't thought this fully through but would it be better to have the /reset/ properties passes as arguments to the decorator or properties of the Signal? Example if properties used: reset = Signal(False) reset.level = 0 reset.async = True @always_ff(clock.posedge, reset=reset) The property defaults would be the same as you stated. I guess the benefit of this is you could easily change the reset characteristics by only changing a couple lines of code (not all always_ff decorators). Also, I think if the @always_ff is used you have to explicitly state the reset. The reset argument would not have a default value. @always_ff(edge, reset) The @always_ff expects 1 edge and 1 reset. Anything more complicated fall back to the @always. In this case reset=None is a valid option. Regards, Chris |
From: Jan D. <ja...@ja...> - 2012-06-21 16:20:18
|
On 06/18/2012 07:18 PM, Christopher Felton wrote: > <snip> >> >> However, I think we can do better. Recall that always_comb >> already inferres a sensitivity list. What if we introduced >> a new decorator, always_ff, that would infer the reset >> structure? > > > I really like this idea. I think it can be very useful. > If I understand correctly, the initial value of the Signal > is used for the /reset/ value? If the above was change to > > ... > count = Signal(modbv(17)[8:]) > ... > > Then the inferred reset logic would be > > ... > if reset == 0: > count.next = 17 > ... > > Correct? Yes, that is exactly the idea. >> Currently, I think always_ff would have an argument >> list as follows: >> >> always_ff(edge, reset=False, level=0, async=True) >> >> The False default for the reset parameter would allow >> to force the presence of a reset signal. (A block >> without reset would require reset=None explicitly). >> The reset level and style can also be specified, with >> defaults that correspond to the most common case in >> my opinion. >> >> Feedback welcome! >> > > Haven't thought this fully through but would it be better > to have the /reset/ properties passes as arguments to the > decorator or properties of the Signal? Example if properties > used: > > reset = Signal(False) > reset.level = 0 > reset.async = True > > @always_ff(clock.posedge, reset=reset) > > The property defaults would be the same as you stated. Seems a very good idea. Perhaps even introduce a Signal subclass, ResetSignal, to set the properties at construction time and allow type checking in the always_ff decorator: reset = ResetSignal(0, active=0, async=True) # defaults shown > I guess the benefit of this is you could easily change > the reset characteristics by only changing a couple lines > of code (not all always_ff decorators). > > Also, I think if the @always_ff is used you have to > explicitly state the reset. The reset argument would > not have a default value. > > @always_ff(edge, reset) > > The @always_ff expects 1 edge and 1 reset. Anything more > complicated fall back to the @always. In this case > reset=None is a valid option. Right. -- 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-27 04:10:19
|
<snip> >>> >>> Feedback welcome! >>> >> >> Haven't thought this fully through but would it be better >> to have the /reset/ properties passes as arguments to the >> decorator or properties of the Signal? Example if properties >> used: >> >> reset = Signal(False) >> reset.level = 0 >> reset.async = True >> >> @always_ff(clock.posedge, reset=reset) >> >> The property defaults would be the same as you stated. > > Seems a very good idea. Perhaps even introduce a > Signal subclass, ResetSignal, to set the properties > at construction time and allow type checking in the > always_ff decorator: > > reset = ResetSignal(0, active=0, async=True) # defaults shown That seems very reasonable, I like it. This should be a pretty cool addition! Regards, Chris |
From: Jan D. <ja...@ja...> - 2012-07-03 11:58:13
|
On 06/27/2012 06:08 AM, Christopher Felton wrote: > <snip> >>>> >>>> Feedback welcome! >>>> >>> >>> Haven't thought this fully through but would it be better >>> to have the /reset/ properties passes as arguments to the >>> decorator or properties of the Signal? Example if properties >>> used: >>> >>> reset = Signal(False) >>> reset.level = 0 >>> reset.async = True >>> >>> @always_ff(clock.posedge, reset=reset) >>> >>> The property defaults would be the same as you stated. >> >> Seems a very good idea. Perhaps even introduce a >> Signal subclass, ResetSignal, to set the properties >> at construction time and allow type checking in the >> always_ff decorator: >> >> reset = ResetSignal(0, active=0, async=True) # defaults shown > > That seems very reasonable, I like it. This should be a > pretty cool addition! I have gone forward with implementing this, because I am working on a project in which it is immediately useful. I have decided to rename the decorator to always_seq, for sequential, as opposed to combinatorial. always_ff in SystemVerilog means something else, and suggests a much lower level by referring to flip-flops, so reusing this name would be confusing. So now we have always_comb and always_seq, much more logical in RTL coding. The draft implementation is in the public repo. There is a ResetSignal as discussed. Conversion is implemented for VHDL and Verilog. No unit tests yet. I have only tried it for async reset with active level 0, so for other cases there may be bugs. I think this is going to be a great feature. My code becomes so much smaller in one pass, and you get "to the point" immediately instead of being distracted by all those reset assignments. At first, it looks a little suprizing (where are my reset values?) but I think it's a matter of getting used to the concept. Note that you can construct "local" signals close to the generator where they are used, not necessarily all in the beginning. Example usage: ... reset = ResetSignal(0) ... ready = Signal(bool(0)) s0, s1, s2 = [Signal(bool(0) for i in range(3)] @always_seq(clock.posedge, reset=reset) def synchronizer(): s0.next = ready_toggle s1.next = s0 s2.next = s1 ready.next = s2 != s1 When reset goes low, the signals are asynchronously reset to their initial values. -- 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. M. <ang...@gm...> - 2012-07-03 14:33:55
|
On Tue, Jul 3, 2012 at 1:57 PM, Jan Decaluwe <ja...@ja...> wrote: > On 06/27/2012 06:08 AM, Christopher Felton wrote: >> <snip> >>>>> >>>>> Feedback welcome! >>>>> >>>> >>>> Haven't thought this fully through but would it be better >>>> to have the /reset/ properties passes as arguments to the >>>> decorator or properties of the Signal? Example if properties >>>> used: >>>> >>>> reset = Signal(False) >>>> reset.level = 0 >>>> reset.async = True >>>> >>>> @always_ff(clock.posedge, reset=reset) >>>> >>>> The property defaults would be the same as you stated. >>> >>> Seems a very good idea. Perhaps even introduce a >>> Signal subclass, ResetSignal, to set the properties >>> at construction time and allow type checking in the >>> always_ff decorator: >>> >>> reset = ResetSignal(0, active=0, async=True) # defaults shown >> >> That seems very reasonable, I like it. This should be a >> pretty cool addition! > > I have gone forward with implementing this, because I am > working on a project in which it is immediately useful. > > I have decided to rename the decorator to always_seq, for > sequential, as opposed to combinatorial. > > always_ff in SystemVerilog means something else, and suggests > a much lower level by referring to flip-flops, so reusing > this name would be confusing. So now we have always_comb > and always_seq, much more logical in RTL coding. > > The draft implementation is in the public repo. > There is a ResetSignal as discussed. Conversion is implemented > for VHDL and Verilog. > > No unit tests yet. > I have only tried it for async reset with active level 0, > so for other cases there may be bugs. > > I think this is going to be a great feature. My code becomes > so much smaller in one pass, and you get "to the point" > immediately instead of being distracted by all those reset > assignments. At first, it looks a little suprizing > (where are my reset values?) but I think it's a matter of > getting used to the concept. > > Note that you can construct "local" signals close to the > generator where they are used, not necessarily all in > the beginning. > > Example usage: > > ... > reset = ResetSignal(0) > ... > ready = Signal(bool(0)) > s0, s1, s2 = [Signal(bool(0) for i in range(3)] > > @always_seq(clock.posedge, reset=reset) > def synchronizer(): > s0.next = ready_toggle > s1.next = s0 > s2.next = s1 > ready.next = s2 != s1 > > When reset goes low, the signals are asynchronously reset to > their initial values. Jan, how do you choose between synchronous and asynchronous reset? Is asynchronous reset the default? At least for Xilinx FPGAs using synchronous reset is highly recommended over asynchronous reset because most of the bulit-in FPGA devices (such as BRAM blocks and DSP48) do not have asynchronous reset lines but they do have synchronous reset lines). Angel |
From: Jan D. <ja...@ja...> - 2012-07-03 16:31:12
|
On 07/03/2012 04:33 PM, Angel Ezquerra Moreu wrote: > On Tue, Jul 3, 2012 at 1:57 PM, Jan Decaluwe<ja...@ja...> wrote: >> On 06/27/2012 06:08 AM, Christopher Felton wrote: >>> <snip> >>>>>> >>>>>> Feedback welcome! >>>>>> >>>>> >>>>> Haven't thought this fully through but would it be better >>>>> to have the /reset/ properties passes as arguments to the >>>>> decorator or properties of the Signal? Example if properties >>>>> used: >>>>> >>>>> reset = Signal(False) >>>>> reset.level = 0 >>>>> reset.async = True >>>>> >>>>> @always_ff(clock.posedge, reset=reset) >>>>> >>>>> The property defaults would be the same as you stated. >>>> >>>> Seems a very good idea. Perhaps even introduce a >>>> Signal subclass, ResetSignal, to set the properties >>>> at construction time and allow type checking in the >>>> always_ff decorator: >>>> >>>> reset = ResetSignal(0, active=0, async=True) # defaults shown >>> >>> That seems very reasonable, I like it. This should be a >>> pretty cool addition! >> >> I have gone forward with implementing this, because I am >> working on a project in which it is immediately useful. >> >> I have decided to rename the decorator to always_seq, for >> sequential, as opposed to combinatorial. >> >> always_ff in SystemVerilog means something else, and suggests >> a much lower level by referring to flip-flops, so reusing >> this name would be confusing. So now we have always_comb >> and always_seq, much more logical in RTL coding. >> >> The draft implementation is in the public repo. >> There is a ResetSignal as discussed. Conversion is implemented >> for VHDL and Verilog. >> >> No unit tests yet. >> I have only tried it for async reset with active level 0, >> so for other cases there may be bugs. >> >> I think this is going to be a great feature. My code becomes >> so much smaller in one pass, and you get "to the point" >> immediately instead of being distracted by all those reset >> assignments. At first, it looks a little suprizing >> (where are my reset values?) but I think it's a matter of >> getting used to the concept. >> >> Note that you can construct "local" signals close to the >> generator where they are used, not necessarily all in >> the beginning. >> >> Example usage: >> >> ... >> reset = ResetSignal(0) >> ... >> ready = Signal(bool(0)) >> s0, s1, s2 = [Signal(bool(0) for i in range(3)] >> >> @always_seq(clock.posedge, reset=reset) >> def synchronizer(): >> s0.next = ready_toggle >> s1.next = s0 >> s2.next = s1 >> ready.next = s2 != s1 >> >> When reset goes low, the signals are asynchronously reset to >> their initial values. > > Jan, > > how do you choose between synchronous and asynchronous reset? reset = ResetSignal(0, async=False) Note that you can change the reset style (and the active level) for the whole reset tree by merely changing the reset constructor. Changing styles has never been so easy! > Is asynchronous reset the default? Yes. -- 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. <ezq...@gm...> - 2012-07-03 16:40:21
|
On Jul 3, 2012 6:32 PM, "Jan Decaluwe" <ja...@ja...> wrote: > > On 07/03/2012 04:33 PM, Angel Ezquerra Moreu wrote: > > On Tue, Jul 3, 2012 at 1:57 PM, Jan Decaluwe<ja...@ja...> wrote: > >> On 06/27/2012 06:08 AM, Christopher Felton wrote: > >>> <snip> > >>>>>> > >>>>>> Feedback welcome! > >>>>>> > >>>>> > >>>>> Haven't thought this fully through but would it be better > >>>>> to have the /reset/ properties passes as arguments to the > >>>>> decorator or properties of the Signal? Example if properties > >>>>> used: > >>>>> > >>>>> reset = Signal(False) > >>>>> reset.level = 0 > >>>>> reset.async = True > >>>>> > >>>>> @always_ff(clock.posedge, reset=reset) > >>>>> > >>>>> The property defaults would be the same as you stated. > >>>> > >>>> Seems a very good idea. Perhaps even introduce a > >>>> Signal subclass, ResetSignal, to set the properties > >>>> at construction time and allow type checking in the > >>>> always_ff decorator: > >>>> > >>>> reset = ResetSignal(0, active=0, async=True) # defaults shown > >>> > >>> That seems very reasonable, I like it. This should be a > >>> pretty cool addition! > >> > >> I have gone forward with implementing this, because I am > >> working on a project in which it is immediately useful. > >> > >> I have decided to rename the decorator to always_seq, for > >> sequential, as opposed to combinatorial. > >> > >> always_ff in SystemVerilog means something else, and suggests > >> a much lower level by referring to flip-flops, so reusing > >> this name would be confusing. So now we have always_comb > >> and always_seq, much more logical in RTL coding. > >> > >> The draft implementation is in the public repo. > >> There is a ResetSignal as discussed. Conversion is implemented > >> for VHDL and Verilog. > >> > >> No unit tests yet. > >> I have only tried it for async reset with active level 0, > >> so for other cases there may be bugs. > >> > >> I think this is going to be a great feature. My code becomes > >> so much smaller in one pass, and you get "to the point" > >> immediately instead of being distracted by all those reset > >> assignments. At first, it looks a little suprizing > >> (where are my reset values?) but I think it's a matter of > >> getting used to the concept. > >> > >> Note that you can construct "local" signals close to the > >> generator where they are used, not necessarily all in > >> the beginning. > >> > >> Example usage: > >> > >> ... > >> reset = ResetSignal(0) > >> ... > >> ready = Signal(bool(0)) > >> s0, s1, s2 = [Signal(bool(0) for i in range(3)] > >> > >> @always_seq(clock.posedge, reset=reset) > >> def synchronizer(): > >> s0.next = ready_toggle > >> s1.next = s0 > >> s2.next = s1 > >> ready.next = s2 != s1 > >> > >> When reset goes low, the signals are asynchronously reset to > >> their initial values. > > > > Jan, > > > > how do you choose between synchronous and asynchronous reset? > > reset = ResetSignal(0, async=False) > > Note that you can change the reset style (and the > active level) for the whole reset tree by merely > changing the reset constructor. > Changing styles has never been so easy! > > > Is asynchronous reset the default? > > Yes. Jan, given how contentious the asynchronous vs synchronous reset debate is I would argue that there should be no default value in this case, and that the reset type should always be set explicitly. Cheers, Angel |
From: Ben <ben...@gm...> - 2012-07-03 17:04:15
|
On Jul 3, 2012, at 6:40 PM, Angel Ezquerra wrote: >>> how do you choose between synchronous and asynchronous reset? >> >> reset = ResetSignal(0, async=False) >> >> Note that you can change the reset style (and the >> active level) for the whole reset tree by merely >> changing the reset constructor. >> Changing styles has never been so easy! >> >>> Is asynchronous reset the default? >> >> Yes. > > Jan, > > given how contentious the asynchronous vs synchronous reset debate is I would argue that there should be no default value in this case, and that the reset type should always be set explicitly. I second this, and if one get tired of defining the 'synchronousity' at every reset signal, we could define some AsyncResetSignal and SyncResetSignal class that would do it for you ... Best, Benoît |
From: Jan D. <ja...@ja...> - 2012-07-03 18:45:57
|
On 07/03/2012 06:40 PM, Angel Ezquerra wrote: > > Jan, > > given how contentious the asynchronous vs synchronous reset debate is > I would argue that there should be no default value in this case, and > that the reset type should always be set explicitly. I am quite surprized by this, is this really so contentious? In my whole career as a design engineer, I don't recall one single incident about this (many about other issues :-)). Actually, I have *always* used the mixed approach, where you go into reset asynchronously, but come out of it synchronously. In this method, the reset driver comes out of a ff that is reset asychronously with the primary reset, and that also synchronizes the primary reset. For this to work, the ffs in the design should have an asynchronous reset, but that doesn't mean the reset scheme itself is asynchronous, as described. The big advantage of this method is that you don't need the clock to be present to go into reset, only to come out of it. So you avoid power-up issues with clocks and pll's. I thought this was the standard practice, which is why I intuitively made it the default. I'd like to hear more opinions. -- 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: Tom D. <td...@di...> - 2012-07-03 20:15:08
|
On 07/03/2012 01:45 PM, Jan Decaluwe wrote: > On 07/03/2012 06:40 PM, Angel Ezquerra wrote: > >> Jan, >> >> given how contentious the asynchronous vs synchronous reset debate is >> I would argue that there should be no default value in this case, and >> that the reset type should always be set explicitly. > I am quite surprized by this, is this really so contentious? > In my whole career as a design engineer, I don't recall one > single incident about this (many about other issues :-)). > > Actually, I have *always* used the mixed approach, where you > go into reset asynchronously, but come out of it synchronously. > In this method, the reset driver comes out of a ff that > is reset asychronously with the primary reset, and that > also synchronizes the primary reset. > > For this to work, the ffs in the design should have > an asynchronous reset, but that doesn't mean the > reset scheme itself is asynchronous, as described. > The big advantage of this method is that you don't > need the clock to be present to go into reset, > only to come out of it. So you avoid power-up issues > with clocks and pll's. > > I thought this was the standard practice, which is why > I intuitively made it the default. > > I'd like to hear more opinions. I would prefer to have a default value and would vote for async. > |
From: Jan D. <ja...@ja...> - 2012-07-03 21:05:09
|
On 07/03/2012 08:45 PM, Jan Decaluwe wrote: > On 07/03/2012 06:40 PM, Angel Ezquerra wrote: > >> >> Jan, >> >> given how contentious the asynchronous vs synchronous reset debate is >> I would argue that there should be no default value in this case, and >> that the reset type should always be set explicitly. > > I am quite surprized by this, is this really so contentious? > In my whole career as a design engineer, I don't recall one > single incident about this (many about other issues :-)). > > Actually, I have *always* used the mixed approach, where you > go into reset asynchronously, but come out of it synchronously. > In this method, the reset driver comes out of a ff that > is reset asychronously with the primary reset, and that > also synchronizes the primary reset. > > For this to work, the ffs in the design should have > an asynchronous reset, but that doesn't mean the > reset scheme itself is asynchronous, as described. > The big advantage of this method is that you don't > need the clock to be present to go into reset, > only to come out of it. So you avoid power-up issues > with clocks and pll's. > > I thought this was the standard practice, which is why > I intuitively made it the default. > > I'd like to hear more opinions. One more point: if the style is explicit, I think the active level should be also, for consistency. One could argue that it's not that bad, only once as opposed to scattered through the code as currently. But then again, I would think that active low and asynchronous covers 99% of the practical cases ... or not? Undecided. -- 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...> - 2012-07-04 05:57:24
|
On Tue, Jul 3, 2012 at 11:04 PM, Jan Decaluwe <ja...@ja...> wrote: > On 07/03/2012 08:45 PM, Jan Decaluwe wrote: >> On 07/03/2012 06:40 PM, Angel Ezquerra wrote: >> >>> >>> Jan, >>> >>> given how contentious the asynchronous vs synchronous reset debate is >>> I would argue that there should be no default value in this case, and >>> that the reset type should always be set explicitly. >> >> I am quite surprized by this, is this really so contentious? >> In my whole career as a design engineer, I don't recall one >> single incident about this (many about other issues :-)). >> >> Actually, I have *always* used the mixed approach, where you >> go into reset asynchronously, but come out of it synchronously. >> In this method, the reset driver comes out of a ff that >> is reset asychronously with the primary reset, and that >> also synchronizes the primary reset. >> >> For this to work, the ffs in the design should have >> an asynchronous reset, but that doesn't mean the >> reset scheme itself is asynchronous, as described. >> The big advantage of this method is that you don't >> need the clock to be present to go into reset, >> only to come out of it. So you avoid power-up issues >> with clocks and pll's. >> >> I thought this was the standard practice, which is why >> I intuitively made it the default. >> >> I'd like to hear more opinions. > > One more point: if the style is explicit, I think the > active level should be also, for consistency. One could > argue that it's not that bad, only once as opposed to > scattered through the code as currently. > > But then again, I would think that active low and > asynchronous covers 99% of the practical cases ... > or not? > > Undecided. > > -- > Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com That is actually not right for Xilinx FPGAs. The Xilinx manuals actually encourage you to use active high reset because "the SR control port on Xilinx registers is active high. If the RTL code describes active-low set / reset / preset / clear functionality, the synthesis tool will infer an inverter before it can directly drive the control port of a register. You must accomplish this inversion with a lookup table, thus taking up a LUT input. The additional logic that active-low control signals infers may lead to longer runtimes and result in poorer device utilization. It will also affect timing and power." As for the asynchronous vs synchronous reset, I suggest you guys have a look at: http://www.xilinx.com/support/documentation/white_papers/wp231.pdf Particularly, on section "Use of Resets and Performance" it describes why synchronous reset should be used. It summarizes its advice as follows: "Avoid asynchronous reset because it prevents packing of registers into dedicated resources and affects performance, utilization, and tool optimizations." As for the technique that you described to use an asynchronous reset whose deassert is synchronous with the clock, I'm unsure how that would work with a Xilinx FPGA. In our system we have an external, asynchronous (by definition) signal which we register on each our our clock domains, converting it into a synchronous signal which we use as a synchronous reset. So the global reset is asynchronous, but the different module resets are synchronous. So I personally would make both the reset type and the active high/low settings explicit. Given that as you said this will probably be done only once I think it would probably even make the code more readable. Cheers, Angel |
From: Jan D. <ja...@ja...> - 2012-07-04 09:05:40
|
On 07/04/2012 07:57 AM, Angel Ezquerra wrote: > Particularly, on section "Use of Resets and Performance" it describes > why synchronous reset should be used. It summarizes its advice as > follows: > > "Avoid asynchronous reset because it prevents packing of registers > into dedicated > resources and affects performance, utilization, and tool optimizations." I believe what is what Xilinx is doing here is pushing its own problem to designers. Of course I understand that using a synchronous reset or no reset can result in a more "optimal" design. What I don't understand is why a synthesis tool wouldn't be able to prove that some resets in dedicated resources are unnecessary, e.g. in a shift register. As for synchronous reset, my question remains: what if your system is such that you don't have reliable clocks during power-on-reset? Altera agrees, because they document the scheme I described as "preferred when designing an FPGA circuit" here: http://www.altera.com/literature/hb/qts/qts_qii51006.pdf > As for the technique that you described to use an asynchronous reset > whose deassert is synchronous with the clock, I'm unsure how that > would work with a Xilinx FPGA. In our system we have an external, > asynchronous (by definition) signal which we register on each our our > clock domains, converting it into a synchronous signal which we use as > a synchronous reset. So the global reset is asynchronous, but the > different module resets are synchronous. Here is an article from a Xilinx application engineer that describes that technique exactly. It seems Xilinx has caught up with the real world :-) http://www.eetimes.com/design/programmable-logic/4218673/How-do-I-reset-my-FPGA- > So I personally would make both the reset type and the active high/low > settings explicit. Given that as you said this will probably be done > only once I think it would probably even make the code more readable. Yes, I can see that point. And of course, we can turn the whole thing to our advantage by showing that you can switch between the various styles without changing the code, by merely changing the reset constructor. -- 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: Tom D. <td...@di...> - 2012-07-05 16:16:35
|
On 07/04/2012 04:05 AM, Jan Decaluwe wrote: > On 07/04/2012 07:57 AM, Angel Ezquerra wrote: > >> Particularly, on section "Use of Resets and Performance" it describes >> why synchronous reset should be used. It summarizes its advice as >> follows: >> >> "Avoid asynchronous reset because it prevents packing of registers >> into dedicated >> resources and affects performance, utilization, and tool optimizations." > I believe what is what Xilinx is doing here is pushing its own > problem to designers. Of course I understand that using a synchronous > reset or no reset can result in a more "optimal" design. > What I don't understand is why a synthesis tool wouldn't be able > to prove that some resets in dedicated resources are unnecessary, > e.g. in a shift register. Aren't we just talking about the default case? I will still be able to use no reset if I prefer? |
From: Jan D. <ja...@ja...> - 2012-07-06 10:33:25
|
On 07/05/2012 06:16 PM, Tom Dillon wrote: > > On 07/04/2012 04:05 AM, Jan Decaluwe wrote: >> On 07/04/2012 07:57 AM, Angel Ezquerra wrote: >> >>> Particularly, on section "Use of Resets and Performance" it describes >>> why synchronous reset should be used. It summarizes its advice as >>> follows: >>> >>> "Avoid asynchronous reset because it prevents packing of registers >>> into dedicated >>> resources and affects performance, utilization, and tool optimizations." >> I believe what is what Xilinx is doing here is pushing its own >> problem to designers. Of course I understand that using a synchronous >> reset or no reset can result in a more "optimal" design. >> What I don't understand is why a synthesis tool wouldn't be able >> to prove that some resets in dedicated resources are unnecessary, >> e.g. in a shift register. > > Aren't we just talking about the default case? Here we were just speculating about possible synthesis optimizations, nothing very important. > I will still be able to > use no reset if I prefer? Of course. Nothing changes from what you could do previously. There will be more and better options, that's all. -- 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-07-06 03:05:18
|
On 7/5/12 11:16 AM, Tom Dillon wrote: > > On 07/04/2012 04:05 AM, Jan Decaluwe wrote: >> On 07/04/2012 07:57 AM, Angel Ezquerra wrote: >> >>> Particularly, on section "Use of Resets and Performance" it describes >>> why synchronous reset should be used. It summarizes its advice as >>> follows: >>> >>> "Avoid asynchronous reset because it prevents packing of registers >>> into dedicated >>> resources and affects performance, utilization, and tool optimizations." >> I believe what is what Xilinx is doing here is pushing its own >> problem to designers. Of course I understand that using a synchronous >> reset or no reset can result in a more "optimal" design. >> What I don't understand is why a synthesis tool wouldn't be able >> to prove that some resets in dedicated resources are unnecessary, >> e.g. in a shift register. > > Aren't we just talking about the default case? I will still be able to > use no reset if I prefer? > From my understanding (and what I agree with) is that the /@always_seq/ requires a reset. If you don't want a reset you will need to use the /@always(clock.posedge)/. If you use the /@always_seq/ it requires a reset. Regards, Chris |
From: Christopher F. <chr...@gm...> - 2012-07-04 19:21:33
|
<snip> > > I think this is going to be a great feature. My code becomes > so much smaller in one pass, and you get "to the point" > immediately instead of being distracted by all those reset > assignments. At first, it looks a little suprizing > (where are my reset values?) but I think it's a matter of > getting used to the concept. > > Note that you can construct "local" signals close to the > generator where they are used, not necessarily all in > the beginning. > > Example usage: > > ... > reset = ResetSignal(0) > ... > ready = Signal(bool(0)) > s0, s1, s2 = [Signal(bool(0) for i in range(3)] > > @always_seq(clock.posedge, reset=reset) > def synchronizer(): > s0.next = ready_toggle > s1.next = s0 > s2.next = s1 > ready.next = s2 != s1 > > When reset goes low, the signals are asynchronously reset to > their initial values. > I'm getting to this conversation a little late. It sounds like we decided explicitly listing the /level/ and /async/ is preferred. I am ok with this. If it wasn't enforced (I am ambivalent if is should be enforced) I would adopt the style to always list, I like how it looks. reset = ResetSignal(0, level=False, async=True) I use the common async assert, sync release type resets, as well. With the /always_seq/ something that might be worth discussing is the inclusion of clock gating. Clock gating is used frequently in ASIC designs and is becoming more common in FPGA designs. A clock gating description might look like the following with the original @always construct. @always(clock.posedge, reset.negedge) def hld(): if not reset: ... else: if(enable) : # clock gate signal x.next = somethingAwesome or somethingGreat Most @always blocks would have the if-else:if pattern. With the /always_seq/ this could look like @always_seq(clock.posedge, reset=reset, clock_gate=enable) def hdl(): x.next = somethingAwesome or somethingGreat The /clock_gate/ would be optional since it is not as common (required) as a reset. Regards, Chris |
From: Angel E. <ang...@gm...> - 2012-07-04 09:27:48
|
On Wed, Jul 4, 2012 at 11:05 AM, Jan Decaluwe <ja...@ja...> wrote: > On 07/04/2012 07:57 AM, Angel Ezquerra wrote: > >> Particularly, on section "Use of Resets and Performance" it describes >> why synchronous reset should be used. It summarizes its advice as >> follows: >> >> "Avoid asynchronous reset because it prevents packing of registers >> into dedicated >> resources and affects performance, utilization, and tool optimizations." > > I believe what is what Xilinx is doing here is pushing its own > problem to designers. Of course I understand that using a synchronous > reset or no reset can result in a more "optimal" design. > What I don't understand is why a synthesis tool wouldn't be able > to prove that some resets in dedicated resources are unnecessary, > e.g. in a shift register. I guess the synthesis tool tries to implement what the user described in code, even if it does not make much sense. That is, if you try to use an asynchronous reset on a DSP48 block, whose builtin registers do not have one, the synthesis tool must choose between using extra logic or implementing something that is not exactly that the user described. IMHOW it makes sense for it to follow what the user asked (and show a warning, as Xilinx ISE does). > As for synchronous reset, my question remains: what if your system > is such that you don't have reliable clocks during power-on-reset? > > Altera agrees, because they document the scheme I described > as "preferred when designing an FPGA circuit" here: > > http://www.altera.com/literature/hb/qts/qts_qii51006.pdf > >> As for the technique that you described to use an asynchronous reset >> whose deassert is synchronous with the clock, I'm unsure how that >> would work with a Xilinx FPGA. In our system we have an external, >> asynchronous (by definition) signal which we register on each our our >> clock domains, converting it into a synchronous signal which we use as >> a synchronous reset. So the global reset is asynchronous, but the >> different module resets are synchronous. > > Here is an article from a Xilinx application engineer that describes > that technique exactly. It seems Xilinx has caught up with > the real world :-) > > http://www.eetimes.com/design/programmable-logic/4218673/How-do-I-reset-my-FPGA- The funny thing is that one of the quotes on my previous reply came from that very same article :-) If I understand what you and that article are proposing, this scheme is a valid answer to the question that you asked: what if your system is such that you don't have reliable clocks during power-on-reset? To do so, it takes take an external, asynchronous reset, and generate a "synchronous deassert" reset signal that is then used by all the entities on a given clock domain. Is that correct? In a sense, you could say that this is neither a synchronous nor an asynchronous reset, since it is asynchronous when the reset is asserted, but synchronous when deasserted. Once you have this "safe" reset, you feed it into the blocks on the corresponding clock domain where you use it synchronously or asynchronously. Even if it is "clock safe" that does not change the fact that you can still not use an asynchronous reset on a DSP48 block for example, unless you want to pay the price in terms of extra logic and timing. >> So I personally would make both the reset type and the active high/low >> settings explicit. Given that as you said this will probably be done >> only once I think it would probably even make the code more readable. > > Yes, I can see that point. And of course, we can turn the whole > thing to our advantage by showing that you can switch between the > various styles without changing the code, by merely changing the > reset constructor. That is a very good point. I wonder, if you feel that the scheme that you and the article you linked described are such a good practice (and I agree), perhaps the ResetSignal class could somehow support it as well? Angel |
From: Jan D. <ja...@ja...> - 2012-07-04 12:20:48
|
On 07/04/2012 11:27 AM, Angel Ezquerra wrote: > On Wed, Jul 4, 2012 at 11:05 AM, Jan Decaluwe<ja...@ja...> wrote: >> On 07/04/2012 07:57 AM, Angel Ezquerra wrote: >> >>> Particularly, on section "Use of Resets and Performance" it describes >>> why synchronous reset should be used. It summarizes its advice as >>> follows: >>> >>> "Avoid asynchronous reset because it prevents packing of registers >>> into dedicated >>> resources and affects performance, utilization, and tool optimizations." >> >> I believe what is what Xilinx is doing here is pushing its own >> problem to designers. Of course I understand that using a synchronous >> reset or no reset can result in a more "optimal" design. >> What I don't understand is why a synthesis tool wouldn't be able >> to prove that some resets in dedicated resources are unnecessary, >> e.g. in a shift register. > > I guess the synthesis tool tries to implement what the user described > in code, even if it does not make much sense. That is, if you try to > use an asynchronous reset on a DSP48 block, whose builtin registers do > not have one, the synthesis tool must choose between using extra logic > or implementing something that is not exactly that the user described. > IMHOW it makes sense for it to follow what the user asked (and show a > warning, as Xilinx ISE does). I define "what the user described" as the I/O behavior. Within that constraint, a synthesi tool has all the freedom, e.g. by optimizing away redundancy. That's what it does all the time, e.g. when you describe two additions, it doesn't necessarily infer two adders if it can prove exclusivity. Or when a bit of some register is driven by a constant value (not always trivial to spot in arithmetic), it is optimized away. >> As for synchronous reset, my question remains: what if your system >> is such that you don't have reliable clocks during power-on-reset? >> >> Altera agrees, because they document the scheme I described >> as "preferred when designing an FPGA circuit" here: >> >> http://www.altera.com/literature/hb/qts/qts_qii51006.pdf >> >>> As for the technique that you described to use an asynchronous reset >>> whose deassert is synchronous with the clock, I'm unsure how that >>> would work with a Xilinx FPGA. In our system we have an external, >>> asynchronous (by definition) signal which we register on each our our >>> clock domains, converting it into a synchronous signal which we use as >>> a synchronous reset. So the global reset is asynchronous, but the >>> different module resets are synchronous. >> >> Here is an article from a Xilinx application engineer that describes >> that technique exactly. It seems Xilinx has caught up with >> the real world :-) >> >> http://www.eetimes.com/design/programmable-logic/4218673/How-do-I-reset-my-FPGA- > > The funny thing is that one of the quotes on my previous reply came > from that very same article :-) > > If I understand what you and that article are proposing, this scheme > is a valid answer to the question that you asked: what if your system > is such that you don't have reliable clocks during power-on-reset? Yes. > To do so, it takes take an external, asynchronous reset, and generate > a "synchronous deassert" reset signal that is then used by all the > entities on a given clock domain. Is that correct? Yes - with this caveat: that reset signal should feed into the asynchronous reset of a ff for the scheme to work. > In a sense, you could say that this is neither a synchronous nor an > asynchronous reset, since it is asynchronous when the reset is > asserted, but synchronous when deasserted. Correct. The terminology can be confusing as we use synchronous/asynchronous at two levels: global and at the ff level, and the two don't coincide completely. > Once you have this "safe" reset, you feed it into the blocks on the > corresponding clock domain where you use it synchronously or > asynchronously. Even if it is "clock safe" that does not change the > fact that you can still not use an asynchronous reset on a DSP48 block > for example, unless you want to pay the price in terms of extra logic > and timing. When you use it as a synchronous reset at the ff level, you lose the advantage, as the power-on-reset problem is not solved. >>> So I personally would make both the reset type and the active high/low >>> settings explicit. Given that as you said this will probably be done >>> only once I think it would probably even make the code more readable. >> >> Yes, I can see that point. And of course, we can turn the whole >> thing to our advantage by showing that you can switch between the >> various styles without changing the code, by merely changing the >> reset constructor. > > That is a very good point. I start to like it. By require explicit settings, we draw attention to the fact that it is trivial to support various schemes, in contrast to current art. A marketing decision, as it were :-) Also, an active high reset may be more common than the sync style? > I wonder, if you feel that the scheme that you and the article you > linked described are such a good practice (and I agree), perhaps the > ResetSignal class could somehow support it as well? Not sure what you mean. The output of a "reset bridge" as described in the Xilinx article should be a ResetSignal instance, so that is supported. -- 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...> - 2012-07-04 12:39:48
|
On Wed, Jul 4, 2012 at 1:46 PM, Jan Decaluwe <ja...@ja...> wrote: > On 07/04/2012 11:27 AM, Angel Ezquerra wrote: >> On Wed, Jul 4, 2012 at 11:05 AM, Jan Decaluwe<ja...@ja...> wrote: >>> On 07/04/2012 07:57 AM, Angel Ezquerra wrote: >>> >>>> Particularly, on section "Use of Resets and Performance" it describes >>>> why synchronous reset should be used. It summarizes its advice as >>>> follows: >>>> >>>> "Avoid asynchronous reset because it prevents packing of registers >>>> into dedicated >>>> resources and affects performance, utilization, and tool optimizations." >>> >>> I believe what is what Xilinx is doing here is pushing its own >>> problem to designers. Of course I understand that using a synchronous >>> reset or no reset can result in a more "optimal" design. >>> What I don't understand is why a synthesis tool wouldn't be able >>> to prove that some resets in dedicated resources are unnecessary, >>> e.g. in a shift register. >> >> I guess the synthesis tool tries to implement what the user described >> in code, even if it does not make much sense. That is, if you try to >> use an asynchronous reset on a DSP48 block, whose builtin registers do >> not have one, the synthesis tool must choose between using extra logic >> or implementing something that is not exactly that the user described. >> IMHOW it makes sense for it to follow what the user asked (and show a >> warning, as Xilinx ISE does). > > I define "what the user described" as the I/O behavior. Within > that constraint, a synthesi tool has all the freedom, e.g. by > optimizing away redundancy. That's what it does all the time, e.g. > when you describe two additions, it doesn't necessarily infer > two adders if it can prove exclusivity. Or when a bit of some > register is driven by a constant value (not always trivial to > spot in arithmetic), it is optimized away. > >>> As for synchronous reset, my question remains: what if your system >>> is such that you don't have reliable clocks during power-on-reset? >>> >>> Altera agrees, because they document the scheme I described >>> as "preferred when designing an FPGA circuit" here: >>> >>> http://www.altera.com/literature/hb/qts/qts_qii51006.pdf >>> >>>> As for the technique that you described to use an asynchronous reset >>>> whose deassert is synchronous with the clock, I'm unsure how that >>>> would work with a Xilinx FPGA. In our system we have an external, >>>> asynchronous (by definition) signal which we register on each our our >>>> clock domains, converting it into a synchronous signal which we use as >>>> a synchronous reset. So the global reset is asynchronous, but the >>>> different module resets are synchronous. >>> >>> Here is an article from a Xilinx application engineer that describes >>> that technique exactly. It seems Xilinx has caught up with >>> the real world :-) >>> >>> http://www.eetimes.com/design/programmable-logic/4218673/How-do-I-reset-my-FPGA- >> >> The funny thing is that one of the quotes on my previous reply came >> from that very same article :-) >> >> If I understand what you and that article are proposing, this scheme >> is a valid answer to the question that you asked: what if your system >> is such that you don't have reliable clocks during power-on-reset? > > Yes. > >> To do so, it takes take an external, asynchronous reset, and generate >> a "synchronous deassert" reset signal that is then used by all the >> entities on a given clock domain. Is that correct? > > Yes - with this caveat: that reset signal should feed into the > asynchronous reset of a ff for the scheme to work. > >> In a sense, you could say that this is neither a synchronous nor an >> asynchronous reset, since it is asynchronous when the reset is >> asserted, but synchronous when deasserted. > > Correct. > > The terminology can be confusing as we use synchronous/asynchronous > at two levels: global and at the ff level, and the two don't coincide > completely. > >> Once you have this "safe" reset, you feed it into the blocks on the >> corresponding clock domain where you use it synchronously or >> asynchronously. Even if it is "clock safe" that does not change the >> fact that you can still not use an asynchronous reset on a DSP48 block >> for example, unless you want to pay the price in terms of extra logic >> and timing. > > When you use it as a synchronous reset at the ff level, you lose the > advantage, as the power-on-reset problem is not solved. I see. It seems that there is no perfect solution for Xilinx FPGAs then, unless you design your system to somehow guarantee that you'll always get a stable clock before the reset. >>>> So I personally would make both the reset type and the active high/low >>>> settings explicit. Given that as you said this will probably be done >>>> only once I think it would probably even make the code more readable. >>> >>> Yes, I can see that point. And of course, we can turn the whole >>> thing to our advantage by showing that you can switch between the >>> various styles without changing the code, by merely changing the >>> reset constructor. >> >> That is a very good point. > > I start to like it. By require explicit settings, we draw attention > to the fact that it is trivial to support various schemes, in > contrast to current art. A marketing decision, as it were :-) > > Also, an active high reset may be more common than the sync style? Probably. >> I wonder, if you feel that the scheme that you and the article you >> linked described are such a good practice (and I agree), perhaps the >> ResetSignal class could somehow support it as well? > > Not sure what you mean. The output of a "reset bridge" > as described in the Xilinx article should be a ResetSignal > instance, so that is supported. I see. I misunderstood how the ResetSignal would be used in that scenario. Angel |
From: Dan W. <eti...@gm...> - 2012-07-04 13:50:53
|
On Wed, Jul 4, 2012 at 6:46 AM, Jan Decaluwe <ja...@ja...> wrote: > On 07/04/2012 11:27 AM, Angel Ezquerra wrote: >> On Wed, Jul 4, 2012 at 11:05 AM, Jan Decaluwe<ja...@ja...> wrote: >>> On 07/04/2012 07:57 AM, Angel Ezquerra wrote: >>> Yes, I can see that point. And of course, we can turn the whole >>> thing to our advantage by showing that you can switch between the >>> various styles without changing the code, by merely changing the >>> reset constructor. >> >> That is a very good point. > > I start to like it. By require explicit settings, we draw attention > to the fact that it is trivial to support various schemes, in > contrast to current art. A marketing decision, as it were :-) Don't do much FPGA work here, but the explicit specification for the ResetSignal constructor would keep the code more clear; this especially since the active state is no longer specified directly in the @always block as before. I like the active low default, but not "hiding" the exact desired reset behavior and throwing an exception seems the pythonic way. Dan -- SDG www.whiteaudio.com |
From: Jan D. <ja...@ja...> - 2012-07-05 15:27:41
|
On 07/04/2012 09:21 PM, Christopher Felton wrote: >> > > I'm getting to this conversation a little late. It sounds > like we decided explicitly listing the /level/ and /async/ > is preferred. I am ok with this. I think that's how it's going to be. > If it wasn't enforced > (I am ambivalent if is should be enforced) I would adopt > the style to always list, I like how it looks. > > reset = ResetSignal(0, level=False, async=True) Make that 'active' instead of 'level', e.g. active=LOW > I use the common async assert, sync release type resets, > as well. > > With the /always_seq/ something that might be worth discussing > is the inclusion of clock gating. Clock gating is used > frequently in ASIC designs and is becoming more common in > FPGA designs. A clock gating description might look like the > following with the original @always construct. > > @always(clock.posedge, reset.negedge) > def hld(): > if not reset: > ... > else: > if(enable) : # clock gate signal > x.next = somethingAwesome or somethingGreat I guess the intention is that dff's with enables are inferred when available. We should find out what the exact templates are in Verilog and VHDL that support this e.g. probably the enable condition should be and'ed with the clock edge condition in VHDL. -- 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 |