![]() |
|
|
|||||||
![]() |
VHDL - Signals and variables, concurrent and sequential assignments |
|
|
Thread Tools | Search this Thread |
|
|
#1 |
|
Hi everyone,
I've heard a number of theories about when to use signal assignments or variable assignments for RTL code, and when to use concurrent or sequential VHDL. Does anyone have an opinion on the following 'rules of thumb'? 1) Model combinational logic within a process with a full sensitivity list using variable assignments Coming from a Verilog background, I was told to model combinational logic, using an always@(/*AUTOSENSE*/) procedural block with blocking assignments. The VHDL equivalent of this is using a process with a full sensitivty list, and using variable assignments. However, the variables are only visible from within the process, and thus it is difficult to get the results out to a sequential block (clocked process) bit of code. process(...) variable sum; begin sum := a + b; //how to get this to a process that is clocked?! end process; Once way of getting around this is by assigning the variable to a signal once all combinational logic has finished, however, this breaks the general rule of not mixing blocking and non-blocking (in Verilog), or signal and variable (in VHDL) assignments, and also seems cumbersome. One alternative is to combine the combinational and logic parts - discussed further below. >"In general: > >sequential blocks use non-blocking <= >combinational blocks use blocking =" http://groups-beta.google.com/group/...fd131568d5e217 >"Use non blocking assignments within sequential (clocked) blocks:" http://groups-beta.google.com/group/...b6011c11acbf7/ >"If it's a reg (i.e. it's being assigned in an always block or an >initial block) and you are trying to design synchronous sequential >logic (flip-flops), then use the non-blocking procedural assignment >(<=). >4. If it's a reg (i.e. it's being assigned in an always block or an >initial block) and you are trying to design combinatorial logic, then >use the blocking signal assignment." http://groups-beta.google.com/group/...50bbf691c67e5e Another solution is to migrate all combinational code into the concurrent section of VHDL - but why then, in Verilog, would you write combinational code in procedural blocks rather than using assign statements? I came across the following post discussing the benefits in Verilog: >"If you wanted the latch or combinational logic. I would decide which >construct to use based on the other features available in continuous >assignments vs. procedural assignments. These are delays and >strengths. You can give strengths to wires and not regs (so you would >use the continuous assignment if you wanted this feature)." http://groups-beta.google.com/group/...87510daa47030d Is there any other disadvantages in writing combinational code in concurrent VHDL - perhaps code clarity? The disadvantage mentioned above is not really relevant in RTL. 2) Don't mix signal and variable assignments (blocking and non-blocking) As mentioned above, one solution is to introduce all the combinational logic into a clocked process using variable assignments, and then clock them using signal assignments. This is also suggested in another thread: >"This is the conventional wisdom. I disagree. I prefer to use signal >(non-blocking) assignments _only_ for the purpose of transferring a >variable (register) value to a port or to another process." http://groups-beta.google.com/group/...377484e81b23e9 On the contrary: >"Try looking at a complex always block which uses a mixture of >blocking and non-blocking and it can be a real challange to decipher >what is intended even with a good understanding of the language." http://groups-beta.google.com/group/...a6c4f0df5676eb >"In summary then, one should use non-blocking assignments to >synchronous>signals and blocking assignments in combinational >constructs. Don't mix them together." http://groups-beta.google.com/group/...07296b9fb0cfe1 So in summary: If you are to write combinational logic in a process using variable assignments, thus following rule 1, how do you get the new values to the clocked process? One solution is to write all combinational code in concurrent VHDL - are there any disadvantages in this? Another solution is to combine the combinational and sequential sections of code, but this seems to go against conventional wisdom. I'm sure there are many opinions out there, and I'm interested to see what people think. Thanks Taras Taras_96 |
|
|
|
|
#2 |
|
Posts: n/a
|
>>"This is the conventional wisdom. I disagree. I prefer to use signal
>>(non-blocking) assignments _only_ for the purpose of transferring a >>variable (register) value to a port or to another process." This works fine. I have provided you an example design and testbench that is very easy to read if you want to test the technique on your tools. > On the contrary: >>"Try looking at a complex always block which uses a mixture of >>blocking and non-blocking and it can be a real challange to decipher >>what is intended even with a good understanding of the language." As long as signal assignments are used only as wiring, no confusion will result. > I'm sure there are many opinions out there, and I'm interested to see > what people think. Consider trying some examples on your simulator and judge for yourself. -- Mike Treseler Mike Treseler |
|
|
|
#3 |
|
Posts: n/a
|
Hi Mike
Your 'rule of thumb' works fine - I've implemented a few simple designs already using different assignment conventions, and yours seems to give the clearest code. Just wondering if any of the experts out there have any comments/experiences on any conventions they might have used. As I said, using my judgement your convention seems to give the clearest code, but I'm not an expert (as you can tell by my posts) and thus I don't trust my own judgements Taras Taras_96 |
|
|
|
#4 |
|
Posts: n/a
|
On 10 Apr 2005 21:21:41 -0700, "Taras_96" <> wrote:
>I've heard a number of theories about when to use signal assignments or >variable assignments for RTL code, and when to use concurrent or >sequential VHDL. Does anyone have an opinion on the following 'rules >of thumb'? I have a useful opinion on rules of thumb in general: If you use only your thumb to design things, they are quite helpful. Once you graduate to using all ten fingers, the rules of thumb tend to get consigned to the scrapheap of "things I learned along the way". >1) Model combinational logic within a process with a full sensitivity >list ... In VHDL you have no choice - despite what you say about "concurrent logic" (see below). > ... using variable assignments Assign to variables whenever it aids the noble cause of readability and clarity of expression. >Coming from a Verilog background, I was told to model combinational >logic, using an always@(/*AUTOSENSE*/) ... Yuck. What is (/*AUTOSENSE*/)? (I can guess.) Today, Verilog-2001 always@* is fully supported by all serious tools. > ... procedural block with blocking assignments. Yes, that's entirely appropriate. > The VHDL equivalent of this is using a process with a >full sensitivty list, and using variable assignments. No it isn't. VHDL variables are invisible outside the process that defines them, but this is not true for Verilog regs. > However, the >variables are only visible from within the process, and thus it is >difficult to get the results out to a sequential block (clocked >process) bit of code. So, you need a signal. You have no choice. It is appropriate. >Once way of getting around this is by assigning the variable to a >signal once all combinational logic has finished An excellent idea. > however, this breaks >the general rule of not mixing blocking and non-blocking (in Verilog), >or signal and variable (in VHDL) assignments Please cite a reference to this "general rule". It is neither a rule, nor general. It is a misunderstanding of the rule imposed by almost every Verilog synthesis tool: "never mix blocking and nonblocking assignment TO THE SAME VARIABLE". In VHDL such a "rule" would be meaningless, because you can make variable assignment only to variables, and signal assignment only to signals. Variable assignment to a variable, and signal assignment to a signal, may be freely mixed in a single process, of course. [ mixing var:= and sig<= ] > also seems cumbersome. Why? >>"In general: >> >>sequential blocks use non-blocking <= >>combinational blocks use blocking =" >http://groups-beta.google.com/group/...fd131568d5e217 In Verilog, that's a reasonable starting point. In VHDL it makes no sense. >>"Use non blocking assignments within sequential (clocked) blocks:" >http://groups-beta.google.com/group/...b6011c11acbf7/ In several messages on comp.lang.verilog I have explained at some length why this is pernicious nonsense. Others have responded with entirely valid reasons why they personally choose to follow that guideline even though they know it is not mandatory. Please try to limit the quantity of Verilog baggage you bring to VHDL. VHDL has enough baggage of its own, without adding spurious stuff. >Another solution is to migrate all combinational code into the >concurrent section of VHDL AARGH - As I said in an earlier response to you, there is NO SUCH THING as "the concurrent section of VHDL" in the sense you are using here. The body of an architecture contains a collection of processes. These processes execute independently and concurrently. However, sometimes processes appear in disguise... * a concurrent assignment is in fact a process, sensitive to all signals that appear in the expression that it calculates, containing an assignment to the target signal and nothing else * a component instance is a rather complicated process made up of the collection of processes in the architecture body of the instantiated component .... and so on. > - but why then, in Verilog, would you write >combinational code in procedural blocks rather than using assign >statements? So that you can say more complicated things clearly. >Is there any other disadvantages in writing combinational code in >concurrent VHDL - perhaps code clarity? The disadvantage mentioned >above is not really relevant in RTL. As pointed out above, "concurrent" VHDL is simply a shorthand way of writing a particularly simple kind of process. [...] >So in summary: >If you are to write combinational logic [...] > but this seems to go against conventional wisdom. Conventional wisdom is often deluded, but far worse, it often is transformed (by time and the passage of newsgroup postings) into half-truth and urban myth. Trust it at your peril. -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL, Verilog, SystemC, Perl, Tcl/Tk, Verification, Project Services Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, BH24 1AW, UK Tel: +44 (0)1425 471223 mail: Fax: +44 (0)1425 471573 Web: http://www.doulos.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated. Jonathan Bromley |
|
|
|
#5 |
|
Posts: n/a
|
Taras_96 wrote:
> 1) Model combinational logic within a process with a full sensitivity > list using variable assignments This is because, you would get different simulation results before and after synthesis. A process needs to know, when it should be triggered. > The VHDL equivalent of this is using a process with a > full sensitivty list, and using variable assignments. However, the > variables are only visible from within the process, and thus it is > difficult to get the results out to a sequential block (clocked > process) bit of code. Variables cannot be in sensitivity lists, as they reside /inside/ the process. The sensitivity list lists stuff from outside. This is, where Verilog blocking signal assignments differ from VHDL variables. They are similar (at first sight), but not equal. > process(...) > variable sum; > begin > sum := a + b; //how to get this to a process that is clocked?! > end process; process(clock) variable sum; begin if rising_edge(clock) then sum := a + b; end if; -- do something with sum - assign it to a signal end process; In Verilog you have the edge-condition in the sensitivity list. In VHDL you have a normal sensitivitiy list and the edge-condition inside the process. Note: For the example it would be useful to copy sum to a signal, as sum is a variable and only readable inside this process. > Once way of getting around this is by assigning the variable to a > signal once all combinational logic has finished, however, this breaks > the general rule of not mixing blocking and non-blocking (in Verilog), > or signal and variable (in VHDL) assignments, and also seems > cumbersome. First: Mixing blocking and non-blocking assignments holds only for one variable in a always-satement. Second: Don't think about this rule in VHDL. This is Verilog stuff. Let me give you an example: always @(a,b,sum,flag) begin sum = a+b; if (sum[0] == 1'b1) begin flag_out <= flag; end else begin flag_out <= 1'b0; end //if end //always I mixed blocking and non-blocking assignments in general, but this was nessecary to code it this way. For every signal I used only one assignment type. In VHDL the code could look like: process(a,b,flag) variable sum_var : unsigned(15 downto 0); begin sum_var := a+b; if (sum_var[0] = '1') then flag_out <= flag; else flag_out <= '0'; end if; sum <= sum_var; end process; Ralf Ralf Hildebrandt |
|
|
|
#6 |
|
Posts: n/a
|
Thanks everyone for your suggestions - It's been really helpful
Taras Taras_96 wrote: > Hi everyone, > > I've heard a number of theories about when to use signal assignments or > variable assignments for RTL code, and when to use concurrent or > sequential VHDL. Does anyone have an opinion on the following 'rules > of thumb'? > > 1) Model combinational logic within a process with a full sensitivity > list using variable assignments > > Coming from a Verilog background, I was told to model combinational > logic, using an always@(/*AUTOSENSE*/) procedural block with blocking > assignments. The VHDL equivalent of this is using a process with a > full sensitivty list, and using variable assignments. However, the > variables are only visible from within the process, and thus it is > difficult to get the results out to a sequential block (clocked > process) bit of code. > > process(...) > variable sum; > begin > sum := a + b; //how to get this to a process that is clocked?! > end process; > > Once way of getting around this is by assigning the variable to a > signal once all combinational logic has finished, however, this breaks > the general rule of not mixing blocking and non-blocking (in Verilog), > or signal and variable (in VHDL) assignments, and also seems > cumbersome. One alternative is to combine the combinational and logic > parts - discussed further below. > > >"In general: > > > >sequential blocks use non-blocking <= > >combinational blocks use blocking =" > http://groups-beta.google.com/group/...fd131568d5e217 > > >"Use non blocking assignments within sequential (clocked) blocks:" > http://groups-beta.google.com/group/...b6011c11acbf7/ > > >"If it's a reg (i.e. it's being assigned in an always block or an > >initial block) and you are trying to design synchronous sequential > >logic (flip-flops), then use the non-blocking procedural assignment > >(<=). > >4. If it's a reg (i.e. it's being assigned in an always block or an > >initial block) and you are trying to design combinatorial logic, then > >use the blocking signal assignment." > http://groups-beta.google.com/group/...50bbf691c67e5e > > Another solution is to migrate all combinational code into the > concurrent section of VHDL - but why then, in Verilog, would you write > combinational code in procedural blocks rather than using assign > statements? I came across the following post discussing the benefits > in Verilog: > > >"If you wanted the latch or combinational logic. I would decide which > >construct to use based on the other features available in continuous > >assignments vs. procedural assignments. These are delays and > >strengths. You can give strengths to wires and not regs (so you would > >use the continuous assignment if you wanted this feature)." > http://groups-beta.google.com/group/...87510daa47030d > > Is there any other disadvantages in writing combinational code in > concurrent VHDL - perhaps code clarity? The disadvantage mentioned > above is not really relevant in RTL. > > 2) Don't mix signal and variable assignments (blocking and > non-blocking) > > As mentioned above, one solution is to introduce all the combinational > logic into a clocked process using variable assignments, and then clock > them using signal assignments. This is also suggested in another > thread: > > >"This is the conventional wisdom. I disagree. I prefer to use signal > >(non-blocking) assignments _only_ for the purpose of transferring a > >variable (register) value to a port or to another process." > http://groups-beta.google.com/group/...377484e81b23e9 > > On the contrary: > > >"Try looking at a complex always block which uses a mixture of > >blocking and non-blocking and it can be a real challange to decipher > >what is intended even with a good understanding of the language." > http://groups-beta.google.com/group/...a6c4f0df5676eb > > >"In summary then, one should use non-blocking assignments to > >synchronous>signals and blocking assignments in combinational > >constructs. Don't mix them together." > http://groups-beta.google.com/group/...07296b9fb0cfe1 > > So in summary: > > If you are to write combinational logic in a process using variable > assignments, thus following rule 1, how do you get the new values to > the clocked process? One solution is to write all combinational code > in concurrent VHDL - are there any disadvantages in this? Another > solution is to combine the combinational and sequential sections of > code, but this seems to go against conventional wisdom. > > I'm sure there are many opinions out there, and I'm interested to see > what people think. > > Thanks > > Taras Taras_96 |
|