DVD - Lecture 2b: Verilog Syntax
Introduction to Hardware Description Language and Verilog
In this section, the speaker provides an overview of hardware description language (HDL) and introduces Verilog, explaining its abstractions.
Basics of Hardware Description Language (HDL)
- HDL is used to describe hardware circuits.
- Verilog is a popular HDL used for designing digital systems.
- Verilog allows abstraction of complex circuits into simpler modules.
Primitives in Verilog
- Primitives are basic building blocks in Verilog that represent Boolean logic gates.
- Examples of primitives include AND, OR, NOT gates.
- Primitives are rarely used due to their structural nature and lack of readability.
Signals in Verilog
- Signals in Verilog can have four primary states: 0 (logic zero), 1 (logic one), X (unknown/error), and Z (high impedance).
- Wires and registers are types of signals in Verilog.
- Wires do not retain state, while registers do.
Declaring Wires and Registers
- Wires and registers can represent buses or groups of signals.
- Buses can be declared using square bracket notation, specifying the most significant bit (MSB) and least significant bit (LSB).
- Two-dimensional wires and registers can also be declared using square brackets before and after the signal name.
Differentiating Between Wires and Registers
This section explains the difference between wires and registers in Verilog.
Difference Between Wires and Registers
- Wires do not retain state, while registers do.
- SystemVerilog has improved upon this differentiation concept introduced by Verilog.
Working with Buses in Verilog
This section discusses how to work with buses in Verilog.
Declaring Buses
- Buses can be declared using the square bracket notation, specifying the MSB and LSB.
- Wires and registers can represent buses.
Operators in Verilog
This section introduces different types of operators used in Verilog.
Types of Operators
- Verilog has various operators, including logical (AND, OR), bitwise (AND, OR), and negation (NOT).
- These operators are used to describe Boolean functionality.
Constants in Verilog
This section explains how constants are represented in Verilog.
Constant Encoding
- Constants in Verilog have a specific format.
- They include width, encoding type (binary or hexadecimal), and value.
- Binary constants are denoted by apostrophe b, while hexadecimal constants use apostrophe h.
- Decimal values can also be used for constants.
Procedural Blocks in Verilog
This section highlights the importance of procedural blocks in Verilog.
Procedural Blocks
- Procedural blocks form the heart of Verilog.
- They allow for describing sequential behavior and control flow within modules.
Initial Block and Always Blocks
This section discusses the initial block and always blocks in Verilog, which are used to initialize variables and describe behavior.
Initial Block
- The initial block is used at the beginning of a simulation to execute code once.
- Code inside the initial block starts at T equals zero and is executed only once.
- An example of using the initial block is setting variables
aandbto zero.
Always Blocks
- Always blocks are used to describe behavior in Verilog.
- Statements inside an always block are evaluated when a change in the sensitivity list occurs.
- The sensitivity list determines which signals cause the code inside the block to be evaluated.
- A classic example of an always block is triggering on a positive edge of a clock signal.
Synchronous Reset Flip-Flop
This section explains synchronous reset flip-flops in Verilog.
- A synchronous reset flip-flop is created using an always block triggered by a positive edge of a clock signal.
- If the reset signal is low, the output (
Q) is set to zero, effectively resetting it.
- If the reset signal is not low,
Qtakes on the value of input (D), creating a flip-flop behavior.
Asynchronous Reset Flip-Flop
This section discusses asynchronous reset flip-flops in Verilog.
- An asynchronous reset flip-flop can be created using an always block triggered by either a positive edge of a clock or a negative edge of a reset signal.
- When triggered, if the reset signal is low,
Qis set to zero. Otherwise,Qtakes on the value of input (D).
- Asynchronous resets should be used with caution as they introduce potential timing issues.
Sequential and Combinational Always Blocks
This section explains the difference between sequential and combinational always blocks in Verilog.
Sequential Always Block
- A sequential always block is used to describe flip-flops.
- It is triggered by a clock signal in the sensitivity list, indicating that it represents sequential behavior.
Combinational Always Block
- A combinational always block describes purely combinational logic.
- It does not include any clock signals in the sensitivity list.
- Combinational always blocks are used to describe Boolean functionality.
Describing Combinational Logic
This section discusses how to describe combinational logic using Verilog.
- Combinational logic can be described using an always block with inputs
A,B, andC.
- If any of the inputs change from 0 to 1 or from 1 to 0, the code inside the block is evaluated.
- The output (
out) is set to the result of a three-input AND gate (A && B && C).
Latches are not discussed in this course.
Sensitivity List and Assignments in Verilog
In this section, the speaker discusses the sensitivity list and different types of assignments in Verilog.
Sensitivity List and Always @*
- The sensitivity list in Verilog is used to specify the signals that trigger a process or block of code.
- In Verilog 2001, an update was made to the standard that introduced the use of the
@*operator. This operator automatically includes all signals on the right-hand side of an assignment statement in the sensitivity list.
- Using
always @*, we can write code likealways @* out = A & B & Cwithout explicitly listing each signal in the sensitivity list.
- This approach helps avoid bugs caused by not updating the sensitivity list when adding or removing signals.
Assignments
Assigned Statement
- An assigned statement is used to describe simple expressions or structural elements like gates.
- It is denoted by using
assignkeyword followed by the output signal name and equals sign (=).
- For example, a multiplexer (MUX) can be described using an assign statement as follows:
assign mux_out = cell ? in1 : in0
- Here, if
cellis true,mux_outwill be assigned within1, otherwise it will be assigned within0.
Blocking Procedural Assignment (=)
- Blocking procedural assignment uses the equals sign (
=) for assignment.
- It represents combinational logic where execution occurs sequentially.
- The right-hand side expression is evaluated first, and then assignment takes place before moving to the next statement.
- For example:
- Assuming initially
a = 1, if we have an assignment statement asa = 2; b = a;, at the end of this code,awill be 2 andbwill also be 2.
Non-Blocking Procedural Assignment (<=)
- Non-blocking procedural assignment uses the left-pointing arrow (
<=) for assignment.
- It represents sequential logic where assignments are made at the end of the current time step.
- The right-hand side expression is evaluated at the end of the current time step, after all other statements have been executed.
- For example:
- Assuming initially
a = 1, if we have a non-blocking assignment statement asa <= 2; b <= a;, at the end of this code,awill be updated to 2, butbwill still hold its previous value of 1.
Rules for Assignments
- In combinational always blocks (
always @*), use blocking assignments (=).
- In sequential always blocks, use non-blocking assignments (
<=).
- Do not mix blocking and non-blocking assignments in the same always block.
- Never assign the same variable in more than one always block to avoid shorting signals together.
It is important to follow these rules to ensure proper behavior and avoid confusion or mistakes in Verilog code.
Writing a Module in Verilog and Instantiating Hierarchy
In this section, the speaker discusses how to write a module in Verilog and instantiate hierarchy. They explain the process of creating a hardware block using an example of a mux4 (a multiplexer with four inputs and two outputs).
Writing a Full Mux Module
- A module is used to define a hardware block, such as a mux.
- The mux4 has four inputs (in0, in1, in2, in3) and two outputs (outA, outB).
- The selector for the mux is called cell.
- The module is described using always @( * ) to indicate it is purely combinational (no clock).
- A case statement is used to determine the output based on the value of the selector.
- If none of the cases match, a default statement outputs X's.
Creating an Instance of the Mux Module
- To use the mux module in another module, it needs to be instantiated.
- The instantiation includes giving it a name (e.g., m0) and connecting its ports.
- Ports are connected using dot notation (e.g., .outA(wire_outA)).
- Multiple instances of the same module can be created with different names.
Using Dot Notation for Port Connections
- Dot notation is used to connect ports between modules.
- Each port is specified with its corresponding signal or wire name.
- It's possible to connect multiple signals at once by specifying just the bus name.
System Tasks for Debugging
- Verilog provides system tasks that help with debugging and simulation.
- System tasks start with a dollar sign ($).
- Examples include $display, $monitor, $strobe which print information during simulation execution.
- System tasks use C-style printf format for displaying values.
System Tasks and Variable in Verilog
In this section, the speaker continues discussing system tasks and variables in Verilog. They explain how system tasks can be used to print information during simulation and provide examples of different system tasks.
More Examples of System Tasks
- System tasks are useful for printing information during simulation.
- Examples include $display, $monitor, $strobe.
- These tasks take C-style printf format for displaying values.
Using $display Task
- The $display task is used to print a message or value during simulation.
- It uses C-style printf format with placeholders (%T, %V) for time and variable values.
- Example:
$display("Value of out is %b", out);
Using $monitor Task
- The $monitor task prints a message every time there is a change in the specified parameters.
- It also uses C-style printf format for displaying values.
Using Variables in Verilog
- Variables can be declared and used within modules in Verilog.
- They are useful for storing intermediate values or performing calculations.
- Variables are declared using the
regkeyword.
[t=0:22:55] Writing a Module in Verilog and Instantiating Hierarchy (in English)
This section explains how to write a module in Verilog and instantiate hierarchy. The example of creating a mux4 module is used to illustrate the process.
Writing a Full Mux Module
- A module defines a hardware block, such as a mux.
- The mux4 has four inputs (in0, in1, in2, in3) and two outputs (outA, outB).
- The selector for the mux is called cell.
- The module is purely combinational (no clock) and uses always @* to indicate sensitivity to all inputs.
- A case statement is used to determine the output based on the value of the selector.
- If none of the cases match, a default statement outputs X's.
Creating an Instance of the Mux Module
- To use the mux module in another module, it needs to be instantiated.
- The instantiation includes giving it a name (e.g., m0) and connecting its ports using dot notation.
- Multiple instances of the same module can be created with different names.
Using Dot Notation for Port Connections
- Dot notation is used to connect ports between modules.
- Each port is specified with its corresponding signal or wire name.
- It's possible to connect multiple signals at once by specifying just the bus name.
System Tasks for Debugging
- Verilog provides system tasks that help with debugging and simulation.
- System tasks start with a dollar sign ($).
- Examples include $display, $monitor, $strobe which print information during simulation execution.
- System tasks use C-style printf format for displaying values.