This might be a basic question to ask, but I have seen it many places and have not been able to figure out why this is the case.
always #(posedge clk)
a_temp <= so;
assign a = a_temp;
What's the intent of using the extra assign statement here?
There seems to be a common misunderstanding on how verilog types work, that is if a modules port is connected to a wire, which it has to be, then the port should be defined as a wire inside the module. So you often get :
module example (
output wire a_wire
);
reg a_reg;
always #(posedge clk) begin
a_reg <= so;
end
assign a_wire = a_reg;
endmodule
Which could just be:
module example (
output reg a_reg
);
always #(posedge clk) begin
a_reg <= so;
end
endmodule
At the next level of hierarchy a_reg is still connected to a wire.
Interface Spec
Another technique that might be used with more experienced designers is to fix the interface. So that others wiring the block up have a fixed point of reference, and not having to deal with a designers constant name changes. This allows the designer to use the most appropriate (semantic) name for the signal making the code more readable while not being tied to the chosen interface name.
Related
I understand that always block can be used to implement procedural and sequential logic.
Will the gate-level realization of the following two codes be the same? If yes, what is the correct way of describing this continuous-time 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?
What are the required 'always' block properties for the synthesis tool to implement a FF? I know the following will result in a FF:
always #(posedge clk or negedge rst)
[...]
But, I'm looking for a more in-depth understanding.
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 an synchronous reset:
always #(posedge clk)
if (!rst) ...
else ...
These are just a couple examples.
I understand that always block can be used to implement procedural and sequential logic.
Will the gate-level realization of the following two codes be the same? If yes, what is the correct way of describing this continuous-time 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?
What are the required 'always' block properties for the synthesis tool to implement a FF? I know the following will result in a FF:
always #(posedge clk or negedge rst)
[...]
But, I'm looking for a more in-depth understanding.
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 an synchronous reset:
always #(posedge clk)
if (!rst) ...
else ...
These are just a couple examples.
I am new to Verilog language and want to do some practices to get familiar with it. And I encountered this problem on HDLbits: DFF8ar
This problem asks me to create 8 D flip-flops with active-high asynchronous reset. I use a case statement to handle the areset signal:
module top_module (
input clk,
input areset, // active high asynchronous reset
input [7:0] d,
output reg[7:0] q
);
always #(posedge clk or posedge areset) begin
case (areset)
1'b1: q <= 8'b0;
default: q <= d;
endcase
end
endmodule
And to my surprise, the circuit it generated ignores the clk signal:
But, if I switch the case statement to an if-else statement, the result will be correct:
always #(posedge clk or posedge areset) begin
if (areset)
q <= 8'b0;
else q <= d;
end
I don't know the reason behind it even after doing some research. Does if-else statements and case statements have some fundamental difference? Any help is appreciated!
Synthesis places some special restrictions on the normal Verilog language.
Synthesis tools recognize specific Verilog coding patterns, but your case code does not match any of those patterns, whereas your if/else code does. There should be documentation with your tool set that shows what syntax is supported for synthesis. When you ran the synthesis, there may have been warning or error messages; check for any log files.
Although the 2 coding styles may behave the same in simulation, you need to restrict yourself to supported syntax for synthesis.
Let's say there's a code that runs like this
reg [4:0] data;
always # (posedge clk, posedge clr)
begin
if(clr)
data <= 0;
else
data <= data +1;
end
How would this look like in circuit level? My guess is roughly
but then that wouldn't help if Clk goes from 0 to 1 while Clr is 1......
Also, is it good practice to have multiple elements in the sensitivity list? From what I see, there's som overhead going on here..
Verilog excerpt will infer DFF (D Flip-Flop) with async reset. This happens due to the fact that reset signal is a part of sensitivity list.
NOTE1: as per LRM for Verilog, adding the reset to the sensitivity list is what makes the reset asynchronous.
NOTE2: each Verilog procedural block should model only one type of flip-flop. In other words, a designer should not mix resetable (sync or async) flip-flops with follower flip-flops (flops with no resets) in the same procedural block.
Your diagram is incorrect, 'clr' signal will be connected to extra input of the DFF called as CLEAR (it is basically an async reset). I suggest to start with some sort of Verilog tutorial, this is very basic thing and it is well explained in materials that are generally available. To grasp on concept of reset in HDL code I recommend the following material:
http://www.sunburst-design.com/papers/CummingsSNUG2003Boston_Resets.pdf
The schematic is not accurate. 4 D-FF will be implemented for each bit of data declared.
Adding reset (i.e. clr) to sensitivity list will make the ckt async (Verilog LRM).
The D-FF will have an additional clear pin, there will be NO bubble to this pin as your reset (i.e. clr) is active high.
I'm a just starting to learn verilog , and I'm having trouble with some things. I've found a few resources to help, but there are some things which aren't clear and I need specified. I have code for a D Flip-flop below. And I understand how the declaration for in and out work. What I dont get is the register.
When it says out is the variable associated with it.Does this association mean, out is the register along with output? Or does it mean out is also the output for the register?
module DFF(quarter, in, out) ;
parameter n = 1; // width
input quarter ;
input [n-1:0] in ;
output [n-1:0] out ;
reg [n-1:0] out ;
always #(quarter=1)
out = in ;
endmodule
In Verilog there are nets and there are variables. The most common kind of net by far is a wire, which you're probably familiar with. You can declare a variable using var, but most people say reg, because that is how it always has been done.
(In Verilog, but not in SystemVerilog), wires have to be driven by
assign statements
the outputs of instantiated modules
and variables have to be driven from
initial and always blocks.
Your output out is driven from an always block and so must be a variable. The line
reg [n-1:0] out ;
declares the output out as being a variable (rather than a wire).
In fact, you are using an old-fashioned way of specifying inputs and outputs. Since 2001, the way to do it is like this:
module DFF #(parameter n = 1)
(input wire quarter,
input wire [n-1:0] in,
output reg [n-1:0] out);
always #(quarter=1)
out = in ;
endmodule
This is the so-called ANSI form and, I think you would agree, is more sensible. I would advise using this form, not the old-fashioned form you are using.
BTW, you code is a bit strange. I'm not entirely sure what it's supposed to do, but this if you're expecting output to be driven by in when quarter is 1, I'd do it more like this:
module DFF // #(parameter n = 1) // you're not using parameter n
(input wire quarter,
input wire [n-1:0] in,
output reg [n-1:0] out);
always #(*)
if (quarter == 1'b1)
out = in ;
else
// IMPORTANT ! : what is out when quarter != 1 ?
// your current code would synthesise to a latch
// is that what you wanted? (And if so, are you
// sure that's what you wanted)
endmodule
initially verilog was though as a language which does behavioral types of operation on state variables (registers, reg) and connects them via nets. So, reg is a variable which is supposed to keep its value between operations, net is just a connection and has no state associated with it, i.e. wire. reg values can be calculated in procedural blocks, i.e. always block, wires can be connected only (using continuous assignments, assign statements (outside of the always blocks)).
There are different rules for using for regs and wires and different behavior of them in simulation, in particular around multiple drivers. See Matthew's reply for more info.