You need to sign in and enrol to submit exercises.
Objectives
This exercise will introduce basic concepts of SystemVerilog as design language:
Declaring modules in SystemVerilog way
RTL design using SystemVerilog
Using a testbench for simulation
Instructions
Next, let's improve the design by making it synchronous and capable of subtraction as well.
Create a file adder_synch.sv and declare a new adder_synch module in it
The module declaration in the previous example was a pretty legacy (but quite common nonetheless) way of doing things and had unwanted redundancy because the ports had to be declared in two places - first in the port list and then declared as input or output.
SystemVerilog has improvements in this so that the port directions and data types can be declared directly in the port list. It's recommended, because redundancy always introduces a change for bugs.
Also, using parameters for signal widths is recommended
As we want to make the adder synchronous, we need clock and reset signals. Add inputs clk and rst_n to your module
As we want to add the subtraction capability, also add a 1-bit input add_sub to your module
Procedures and assigning signals
Procedures are declared with always or initial blocks.
Initial procedures are run only once in the beginning and may not be synthesizable
Always blocks run infinitely and are often timed according to a sensitivity list declared by @
SystemVerilog has new always_comb, always_latch and always_ff procedures, which improve on the old always block by strictly specifying the designer intent
The new procedures guide the compilation and have stricter rules to help preventing coding errors, use them!
Signals can be assigned in blocking or non-blocking manner inside procedures:
<= is a non-blocking assignment. All the values are updated at the same time.
= is blocking assignment. They are processed sequentially like in the usual programming languages.
Try to find a difference between these - what is the value of a?
b <= c;
a <= b;
b = c;
a = b;
Add an always_ff procedure that is sensitive to negative edge of rst_n or positive edge of clk. This results in a synchronized procedure with asynchronous reset.
always_ff @(posedge clk or negedge rst_n) begin
...
end
Handle reset (active low) and normal operation in an if-clause:
if (~rst_n) begin
...
end
else begin
...
end
Fill in the functionality. Do an addition or subtraction based on the add_sub signal
When add_sub = 1, an addition is performed
Remember to clear all output registers on reset
Test with vlog that your design compiles. In the next exercise you will create a simple testbench for simulation.
(Helpful?) Tips / good practices / conventions
Between sessions you lose the "sourced" paths so if you get an error that the run script cannot find the compiler/simulator run the sourcing script as before
Always comment what you're doing in the code! Commenting in SystemVerilog works as in C/C++ i.e. // or /* ... */
Remember to indent the code and use descriptive variable/class names (as in the given code package or some other sensible way..), readibility is nice.