Reputation: 55
I understand that always
block can be used to implement procedural and sequential logic.
a.
module func(input a, input b , output reg o);
always @(a,b)
o=a&b;
endmodule
b.
module func(input, a, input b, output o);
assign o = a & b;
endmodule
In (a), 'o' is a reg type and in (b) it is a wire. What does this difference mean?
always @(posedge clk or negedge rst)
[...]
But, I'm looking for a more in-depth understanding.
Upvotes: 2
Views: 591
Reputation: 62037
Your (a) and (b) codes are functionally equivalent. This means that they will simulate the same way and they will infer the same logic when synthesized.
They use 2 different styles of modeling: (a) uses a procedural assignment because it uses an always
block, whereas (b) uses a continuous assignment because there is no always
block and it uses the assign
keyword.
In this simple case, there is no "correct" way; they are 2 different styles to achieve the same functionality. For such simple logic, it is preferable to use (b) because it uses less code and it is easier to understand. However, if your combinational logic were more complicated, the procedural approach might be easier to understand.
In (a), the o
signal must be a reg
type since it is assigned inside a procedural logic block. There is no such requirement for continuous assignments. In this case, defining a reg
type does not result in a flip-flop. A reg
only infers a flip-flop when the always
block describes sequential logic
Synthesis tools look for specific types of patterns in Verilog code to infer sequential logic. The following will infer flip-flops with an asynchronous reset:
always @(posedge clk or negedge rst)
if (!rst) ...
else ...
The following will infer flip-flops with a synchronous reset:
always @(posedge clk)
if (!rst) ...
else ...
These are just a couple examples.
Upvotes: 2