| Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#11
| |||
| |||
| Hi Jonathan Jonathan Bromley <jonathan.bromley@MYCOMPANY.com> writes: >>Why would you want to do that??? > > In ASIC technologies, reset is not free. True in theory. But then, ASIC design rules I am familiar with require that there be not logic in the reset tree. Put differently, a signal declared (to the tool) as reset signal must only be connected to the async reset input of a flip-flop. Deviations from this rule must be justified and documented. Automatic design rule checkers must be told to skip individual "violations". I'd say that *unless* there is a block of significant size in which registers don't require reset, trying to be clever is not likely to save a lot. Regards Marcus -- note that "property" can also be used as syntaxtic sugar to reference a property, breaking the clean design of verilog; [...] (seen on http://www.veripool.com/verilog-mode_news.html) |
|
#12
| |||
| |||
| Hi. Haent had time to dig through the long converstation where this origionated, but myself and a colleague are wondering why not use this template instead? process(clock, reset) begin if reset = '1' then count <= (others => '0'); elsif rising_edge(clock) then count <= count + 1; end if; end process q <= count; msb <= count(7); tc <= '1' when (count = X"FF") else '0'; --(or just use the "and_reduce" function). or am I missing the point? |
|
#13
| |||
| |||
| On Tue, 19 Aug 2008 06:47:14 -0700 (PDT), Tricky wrote: >Haent had time to dig through the long converstation where this >origionated, but myself and a colleague are wondering why not use this >template instead? > >process(clock, reset) > begin > if reset = '1' then > count <= (others => '0'); > > elsif rising_edge(clock) then > count <= count + 1; > > end if; > end process > q <= count; > msb <= count(7); > tc <= '1' when (count = X"FF") else '0'; >or am I missing the point? No, I don't think so. Of course you're right that your code is the same. But it exposes the internal state of the process ("count") as a signal that is global to the architecture; and it splits out the functionality into many processes. For the counter example, none of that matters; for bigger examples, it can have an important impact on encapsulation and readability. I was simply seeking out viable alternatives - and trying to find what *really* works and doesn't work, rather than relying on myth or (in my case) obsolete information. -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK jonathan.bromley@MYCOMPANY.com http://www.MYCOMPANY.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated. |
|
#14
| |||
| |||
| Jonathan Bromley schrieb: > process (clock, reset) > variable count: unsigned(7 downto 0); > begin > if rising_edge(clock) then > count_pipe <= count; -- count_pipe isn't reset > count := count + 1; > end if; > if reset = '1' then > count := (others => '0'); > end if; > end process; We had a discussion about this style some months ago. And nobody found any problems using this style. Unfortunately for Verilog you have to split this process into two always-blocks. Additionally it is a pitfall that the following process looks so similar to your form 3, but creates the unwanted clk-enable for count_pipe: process (clock, reset) variable count: unsigned(7 downto 0); begin if reset = '1' then count := (others => '0'); elsif rising_edge(clock) then count_pipe <= count; -- count_pipe isn't reset count := count + 1; end if; end process; In my company we had a case where this unwanted clk-enable has caused some trouble. Therefore form 3 should be the recommended "synchronous template". It is so easy to forget the unwanted clk-enable - especially if one tries to put everything into one big process. Ralf |
|
#15
| |||
| |||
| On Aug 19, 10:27 am, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com> wrote: > On Tue, 19 Aug 2008 06:47:14 -0700 (PDT), Tricky wrote: > >Haent had time to dig through the long converstation where this > >origionated, but myself and a colleague are wondering why not use this > >template instead? > > >process(clock, reset) > > begin > > if reset = '1' then > > count <= (others => '0'); > > > elsif rising_edge(clock) then > > count <= count + 1; > > > end if; > > end process > > q <= count; > > msb <= count(7); > > tc <= '1' when (count = X"FF") else '0'; > >or am I missing the point? > > No, I don't think so. Of course you're right that > your code is the same. But it exposes the internal > state of the process ("count") as a signal that is > global to the architecture; and it splits out the > functionality into many processes. For the counter > example, none of that matters; for bigger examples, > it can have an important impact on encapsulation > and readability. I was simply seeking out viable > alternatives - and trying to find what *really* > works and doesn't work, rather than relying on > myth or (in my case) obsolete information. > -- > Jonathan Bromley, Consultant I can't say I understand your complaints. "it exposes the internal state of the process ("count") as a signal that is global to the architecture" What is that a problem? One of the issues I have with variables is that they are hard to debug since they can only be viewed when in context, so I prefer a signal that is always viewable. It was a long ago that I worked with signals and maybe the tools I used were not very good. Has that changed? "it splits out the functionality into many processes" Is that really an issue? You are indicating that each concurrent statement is a process. Why would I care about that? I use concurrent statements freely. Is there a reason to restrict them? I want to get work done effectively. I don't care much about finer points of the language or simulation. I want to find ways that make the most effective use of *my* time. I don't see how any of these issues achieve that. I would almost prefer a language that did not offer so much freedom. I can't help but think this offers limited value to the coders and makes life a lot harder for the tool writers. Rick |
|
#16
| |||
| |||
| On Aug 19, 11:58 am, Ralf Hildebrandt <Ralf-Hildebra...@gmx.de> wrote: > Jonathan Bromley schrieb: > > > process (clock, reset) > > variable count: unsigned(7 downto 0); > > begin > > if rising_edge(clock) then > > count_pipe <= count; -- count_pipe isn't reset > > count := count + 1; > > end if; > > if reset = '1' then > > count := (others => '0'); > > end if; > > end process; > > We had a discussion about this style some months ago. And nobody found > any problems using this style. Unfortunately for Verilog you have to > split this process into two always-blocks. > > Additionally it is a pitfall that the following process looks so similar > to your form 3, but creates the unwanted clk-enable for count_pipe: > > process (clock, reset) > variable count: unsigned(7 downto 0); > begin > if reset = '1' then > count := (others => '0'); > elsif rising_edge(clock) then > count_pipe <= count; -- count_pipe isn't reset > count := count + 1; > end if; > end process; > > In my company we had a case where this unwanted clk-enable has caused > some trouble. Therefore form 3 should be the recommended "synchronous > template". It is so easy to forget the unwanted clk-enable - especially > if one tries to put everything into one big process. I don't get it. Where is the unwanted clock enable, do you mean "reset"? If the tool is treating reset in this case as a clock enable, I think you need a new tool vendor. This is the classic inferred register model I have seen from every tool vendor I have used. Rick |
|
#17
| |||
| |||
| On Tue, 19 Aug 2008 14:29:55 -0700 (PDT), rickman wrote: >"it exposes the internal state of the process ("count") as a signal >that is global to the architecture" > >What is that a problem? Encapsulation, and separation of concerns - all the usual stuff that anyone needs to think about as their designs (be they hardware, software or mechanical) get larger. >One of the issues I have with variables is >that they are hard to debug since they can only be viewed when in >context, so I prefer a signal that is always viewable. It was a long >ago that I worked with signals and maybe the tools I used were not >very good. Has that changed? There's no difficulty viewing variables (at least, the static variables that you declare in processes) in any tools I use. Dynamically-created variables - locals of a function or procedure, or automatics in Verilog - may require the use of breakpoints. >"it splits out the functionality into many processes" > >Is that really an issue? It's not a big deal, except that a process is (to my mind) a block of stuff that has a life of its own; it's nice for such blocks to be coherent and decoupled, i.e. to be as far as possible related to one set of concerns and to be a complete implementation of that set of concerns. Inevitably in hardware that ideal is unrealizable, but it's still worth fighting for. Speaking of "blocks", of course the (very under-utilised) VHDL "block" construct allows you to group a bunch of processes, and the signals that link them, without requiring a module (entity) to encapsulate them. >I want to get work done effectively. I don't care much about finer >points of the language or simulation. I want to find ways that make >the most effective use of *my* time. I don't see how any of these >issues achieve that. I am very well aware that you are experienced and productive, so I think it's best for us to agree to differ here and for me to note the very interesting fact that different people think about these issues in very different ways. >I would almost prefer a language that did not offer so much freedom. >I can't help but think this offers limited value to the coders and >makes life a lot harder for the tool writers. Again, perhaps we should agree to differ. Thanks. -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK jonathan.bromley@MYCOMPANY.com http://www.MYCOMPANY.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated. |
|
#18
| |||
| |||
| On Tue, 19 Aug 2008 14:32:28 -0700 (PDT), rickman wrote: >> process (clock, reset) >> variable count: unsigned(7 downto 0); >> begin >> if reset = '1' then >> count := (others => '0'); >> elsif rising_edge(clock) then >> count_pipe <= count; -- count_pipe isn't reset >> count := count + 1; >> end if; >> end process; >I don't get it. Where is the unwanted clock enable, do you mean >"reset"? "reset" is a clock DISABLE for the count_pipe register. Think about what happens when there's a rising edge on clock at a time when reset is held asserted. We activate the process, but we test reset and find it is '1' so we do the reset branch of the logic; this has no effect on count_pipe, which therefore holds its value. >If the tool is treating reset in this case as a clock enable, I think >you need a new tool vendor. This is the classic inferred register >model I have seen from every tool vendor I have used. No, it's not. It's my favourite RTL coding error, in which I add a register to the clocked logic in a process but then forget to add it to the reset branch because it doesn't seem to need resetting from a functional point of view. If the tool did NOT treat "not reset" as a clock enable on the count_pipe register, it would be generating logic that behaved differently from the simulation - and that WOULD be cause for a bug report. Naturally, none of this weakens the arguments that you have already presented for resetting every register in an FPGA design. -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK jonathan.bromley@MYCOMPANY.com http://www.MYCOMPANY.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated. |
|
#19
| |||
| |||
| On Aug 20, 6:00*am, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com> wrote: > On Tue, 19 Aug 2008 14:29:55 -0700 (PDT), rickman wrote: > >"it exposes the internal state of the process ("count") as a signal > >that is global to the architecture" > > >What is that a problem? > > Encapsulation, and separation of concerns - all the > usual stuff that anyone needs to think about as their > designs (be they hardware, software or mechanical) > get larger. > Hierarchy in VHDL is best expressed at the entity level, not process or procedure. As the design gets larger and it becomes apparent that a different (or simply finer grained) breakdown is needed, that should be accomplished by creating new entities. That's where the encapsulation and separation of concerns should occur. Entity/architectures can also generally be reused in some new application without modification, processes and procedures generally can not since they usually need the context that is provided by the entity/architecture. > >One of the issues I have with variables is > >that they are hard to debug since they can only be viewed when in > >context, so I prefer a signal that is always viewable. *It was a long > >ago that I worked with signals and maybe the tools I used were not > >very good. *Has that changed? > > There's no difficulty viewing variables (at least, the static > variables that you declare in processes) in any tools I use. You can't view variables in a wave or list windows after the fact using Modelsim. When something fails in any simulation, the reason for the failure many time is in the past, although sometimes the reason is in the present. The wave and list windows are the available tools for investigating what happened prior to the failure in order to discern what was the root cause. When you use variables extensively you lose at least some of the ability to use those tools to debug. Given that handicap you must turn to other methods such as re-running the simulation to either step through code, or add the variables that you'd like to see to the wave/list windows at sim start (hoping you've guessed correctly at all of the ones you need). At best you're only slightly less productive because of this handicap. Modelsim's log -r /* command is a very powerful debug aid...it get signals, it doesn't pick up variables. > Dynamically-created variables - locals of a function or procedure, > or automatics in Verilog - may require the use of breakpoints. > Again, the use of breakpoints implies that the simulation was restarted so that one can get visibility into what led up to the bad thing. This starts to happen when the use of variables and procedures has clouded things to the point that one can not easily discern what is going wrong given the available information (which is the entire 'signal' history). Don't get me wrong, I do like variables and procedures, but whenever possible I'll use a signal instead of a variable simply for the debug value. > >"it splits out the functionality into many processes" > > >Is that really an issue? > > It's not a big deal, Whew, I was wondering if someone was charging you a fee per process or something. > except that a process is (to my mind) > a block of stuff that has a life of its own; it's nice for > such blocks to be coherent and decoupled, Coherent yes, decoupled no. Anything that is decoupled from the rest of the world is not needed (and a synthesis tool will see to that by optimizing it away). I realize that this extreme of 'decoupled' is more decoupled than what you likely had in mind, but my point is that every process interacts with some input stimulus and provides some output. It interacts with and is therefore coupled to other things. What one really wants to have is good interfaces between these hunks of code (be they multiple processes or multiple entities) rather than some unachievable decoupling. Personally I prefer Altera's Avalon specification as a model interface to use, it provides for handshaking, latency, etc. at a zero (or minimal) logic resource overhead. > i.e. to be as > far as possible related to one set of concerns and to > be a complete implementation of that set of concerns. > Inevitably in hardware that ideal is unrealizable, but > it's still worth fighting for. > But the reason it's unrealizable is because of what I just mentioned above regarding interfaces. Given that every useful process will have some interface to other surrounding code I don't see what the cause is that you would be 'fighting for'. Within an entity, I tend to have multiple clocked processes and concurrent statements. The physical grouping of what signals go in this clocked process versus that clocked process has to do with how closely related the logic is that is required to implement that signal. Things that are unrelated go in separate processes. I'll also tend to try to limit the physical size of a process so that it fits on a screen. The end result is a file where you don't have to scroll back and forth and all around in order to see what is going on. During the design process where you're still working on what the actual logic is, things can freely move (by cut/paste) from one process to another as the realization sets in that the logic for signal 'abc' is very similar after all to that which I have for 'xyz'. This type of situation is also where the limited use of variables is a good thing since I can freely move and modify the code from one process to the other to textually group together the related stuff because, when the code being moved only uses signals, that cut/ paste can always be safely done without mucking up something else in the process that it was cut from. > Speaking of "blocks", of course the (very under-utilised) > VHDL "block" construct allows you to group a bunch of > processes, and the signals that link them, *without > requiring a module (entity) to encapsulate them. > I agree, and would add that the same can also be said for the generate statement...both quite handy ways to create 'local' signals. > > >I would almost prefer a language that did not offer so much freedom. > >I can't help but think this offers limited value to the coders and > >makes life a lot harder for the tool writers. > > Again, perhaps we should agree to differ. > I agree with you (Jonathon). The more skilled you get with VHDL, the more you appreciate all the things that they thought to include (but you still gripe about the odd constraints). Abel is a simple language to learn and use but I wouldn't use it today because VHDL provides much more power for creating not only a design but a self checking testbench of the design within a single language environment. That design and testbench can also be as fully parameterized as I would like it so that they can be reused for some other project down the road. Kevin Jennings |
|
#20
| |||
| |||
| On Aug 18, 5:23*pm, rickman <gnu...@gmail.com> wrote: > On Aug 18, 4:38 pm, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com> > The standard > template is mapped to the global reset quite well by the tools. *In > that context, there is no reason to leave any register uncontrolled on > reset (unless you have some very odd requirements) and failure to do > so can result in unpredictable power up behavior. > I rarely use async resets at all and wouldn't really use any of these forms sticking instead with the simple synchronous process form (putting the "if (reset = '1') then..." at the top for readability). The one exception for async resets being the shift register(s) that take as input the external reset pin and from that generate a reset signal that is synchronous to any clock(s). Using a reset signal that is not synchronized to the clock is a design failure waiting to happen. > > Again, you don't explain the context of your async reset. *If it is > the global reset I see no reason to leave it off of any registers in > your design. * I'd turn it around and say that if there is no functional requirement to reset a register than don't bother spending the time and adding the extra code to do so. Most registers (by quantity) in a design do not have such a requirement since they hold data and do not control anything. Signals that control other things (like an 'enable' bit that turns on/off some function, a state machine) do need resets. > A sync reset is one that is typically used at any time > during operation. *The async reset is typically mapped to the global > reset. *If it does not, IMHO, the async reset does not belong in a > synchronous design. *I avoid the problem by avoiding it! > You're right when you say "the async reset does not belong in a synchronous design"...but I would say that the only exceptions to that being - The reset synchronizer - Any output pins of the top level design that require a specific power up state prior to having a good clock. Kevin Jennings |
![]() |
| Thread Tools | |
| Display Modes | |
In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.