P
Patrick Maupin
Guest
On Apr 20, 5:14 pm, Jan Decaluwe <j...@jandecaluwe.com> wrote:
variable semantics provided by blocking assignments, in the context of
a clocked always block", but I don't think that translates into
"Verilog RTL designers can't even use variables."
What it *does* translate into is "The cleanest way to write Verilog is
somewhat verbose, in that it requires you to separate your
combinatorial logic from your sequential logic."
Basically, this method of thinking/coding requires two variables for
each sequential variable. It's really handy to have a nice naming
convention, like next_x is the variable that will be placed into x on
the next clock.
So you have your definitions:
reg y, next_y;
reg [5:0] x, next_x;
and your combinatorial block:
always @* begin
next_x = x + 1;
next_y = x == 0;
end
and your sequential block:
always @(posedge clk or negedge rstn)
if (!rstn) begin
x <= 0;
y <= 0;
end else begin
x <= next_x;
y <= next_y;
end
The declaration of registers and the sequential block both become,
pretty much, boilerplate code with this method of coding -- all the
action happens in the combinatorial block. I am actually, slowly, in
my spare time, working on a project that will create a lot of the
boilerplate for coding in this method.
How does this help? It's more about a human's ability to mentally
manage complexity than anything else. In the sequential block, every
line must be 'xxx' <= next_'xxx'. Very easy to verify. In the
combinatorial block, 'next_' must appear on the lhs, and only on the
lhs, of any assignment involving a sequential variable. Nothing keeps
you from using if, case statements, etc. in the combinatorial block,
and it's very easy to think about, because you see two variables
simultaneously -- what is 'x' right now, and what will 'x' be after
the next clock.
I have worked at several companies and with several individuals where
this coding style is used. I did not invent it; as far as I know it
was probably invented at multiple places independently. It works
quite well, but is, as I mentioned, a bit verbose. There is no reason
to use it for extremely simple modules, but OTOH, the breakover point
where it is better to use it comes much sooner than you might think.
Regards,
Pat
Well, the guidelines absolutely _do_ "forbid the use of traditionalOn Apr 20, 11:46 pm, Patrick Maupin <pmau...@gmail.com> wrote:
http://sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf
The infamous Guideline #5 bans variable semantics from always blocks
with sequential logic. It must be the Worst Guideline ever for RTL
designers.
The result is not wizardry but ignorance.
How are we supposed to "raise the abstraction level" if Verilog RTL
designers
can't even use variables?
I didn't notice this post until today. I think you are completely
misreading the guidelines if you think they mean "Verilog RTL
designers can't even use variables"
I use that line as a shorthand for "Guideline #5 combined with
Guideline #1, if taken seriously, forbids the use of traditional
variable semantics provided by blocking assignments, in the
context of a clocked always block".
No matter how absurd I hope this sounds to you, that's really
what it says.
variable semantics provided by blocking assignments, in the context of
a clocked always block", but I don't think that translates into
"Verilog RTL designers can't even use variables."
What it *does* translate into is "The cleanest way to write Verilog is
somewhat verbose, in that it requires you to separate your
combinatorial logic from your sequential logic."
Basically, this method of thinking/coding requires two variables for
each sequential variable. It's really handy to have a nice naming
convention, like next_x is the variable that will be placed into x on
the next clock.
So you have your definitions:
reg y, next_y;
reg [5:0] x, next_x;
and your combinatorial block:
always @* begin
next_x = x + 1;
next_y = x == 0;
end
and your sequential block:
always @(posedge clk or negedge rstn)
if (!rstn) begin
x <= 0;
y <= 0;
end else begin
x <= next_x;
y <= next_y;
end
The declaration of registers and the sequential block both become,
pretty much, boilerplate code with this method of coding -- all the
action happens in the combinatorial block. I am actually, slowly, in
my spare time, working on a project that will create a lot of the
boilerplate for coding in this method.
How does this help? It's more about a human's ability to mentally
manage complexity than anything else. In the sequential block, every
line must be 'xxx' <= next_'xxx'. Very easy to verify. In the
combinatorial block, 'next_' must appear on the lhs, and only on the
lhs, of any assignment involving a sequential variable. Nothing keeps
you from using if, case statements, etc. in the combinatorial block,
and it's very easy to think about, because you see two variables
simultaneously -- what is 'x' right now, and what will 'x' be after
the next clock.
I have worked at several companies and with several individuals where
this coding style is used. I did not invent it; as far as I know it
was probably invented at multiple places independently. It works
quite well, but is, as I mentioned, a bit verbose. There is no reason
to use it for extremely simple modules, but OTOH, the breakover point
where it is better to use it comes much sooner than you might think.
Regards,
Pat