Digital Design Introduction

Introduction to SystemVerilog

Tarik Graba

2022-2024

Hardware Description Languages

Increase the level of abstraction by using Computer Aided-Design (CAD) tools.

Modern Digital designers use Hardware Description Languages (HDL) to describe the behaviour of digital logic circuits.

CAD Tools are then used to:

The transformation of the HDL description into a list of interconnected gates (netlist) is called Logical Synthesis.

As HDLs have been designed for both Simulation and Synthesis, only a subset of these languages can to represent digital hardware. For example, it is useful to have commands to print messages during simulation, but those commands can not be magically transformed into a set of logic gates. This subset is called synthetisable subset of the language.

Also, the intent of the designer is very important. You must think hardware and not software, have an idea of the architecture that you want to get and only use the HDL to describe it.

There are two commonly used HDL with equivalent functionalities (but very different syntaxes) VHDL and Verilog/SystemVerilog. In this course, we will only use SystemVerilog, but the concepts can be easily transposed to VHDL.

SystemVerilog (History)

SystemVerilog Modules

A module is a box that represents a digital bloc component.

module foo( input a,
            input b,
            output c );

// module description

endmodule

Modules are declared with the module keyword. The list of inputs and outputs of the modules (its interface) must also be declared.

NOTE that no SystemVerilog code must appear outside a module.

For multi-bit buses, the square brackets [...] indicate the range.

For example:

input [3:0] A

A is a 4-bit input bus composed of a[3],a[2],a[1] and a[0] bits. a[3] being the most significant bit, and a[0] the least significant one.

A can also be interpreted as a 4-bit unsigned number.

SystemVerilog for Combinational Logic

Continuous Assignments

To describe simple combinational logic we can use concurrent assignment.


module BUF (input i, output o);

 assign o = i;

endmodule

NOTE Continuous assignment are not simple assignment similar to what can be found in standard programming languages. In SystemVerilog, continuous assignment are evaluated continuously and in a concurrent manner. They represent the behaviour of a combinational operator/gate.

SystemVerilog operators are generally similar to the ones that you can find in the C programming language.

The must usual are:

symbol function
& bitwise and
| bitwise or
^ bitwise xor
~ bitwise inversion
symbol function
+ addition operator
- subtraction
symbol function
== equality operator
!= inequality operator
>,< greter, less than
symbol function
&& logical and
|| logical or
! logical inversion
symbol function
:? ternary operator

Exercise:

module FA(
          input a,
          input b,
          input ci,
          output s,
          output co );

   assign s = a ^ b ^ ci;
   assign co = a & b | a & ci | b & ci;

endmodule

Submodules/modules instances

To describe the structure of a digital block, we can instantiate submodule.

module X (input a, output b);
//...
endmodule

module Y(input i, output o);

   // instance of module X
   X X_0(.a(i), .b(o));

endmodule

When instantiating a submodule we must connect its inputs and outputs to signals in the upper module.

Describing the modules hierarchy by instantiating submodules is called structural description.

Internal signals wire

To declare internal signals we use the wire keyword.

module X (input a, output b);
//...
endmodule

module Y(input i, output o);

 wire s;

 X X_0(.a(i), .b(s));
 X X_1(.a(s), .b(o));

endmodule

Signals declared with the wire keyword can be used to connect the inputs/outputs of a module or as the output of continuous assignments.

module FA2(
          input a,
          input b,
          input ci,
          output s,
          output co );

   wire hs, hc;

   assign hs = a ^ b;
   assign hc = a & b;

   assign s = hs ^ ci;
   assign co = hc |  hs & ci;

endmodule

Exercise:

module ADDER(
          input [3:0] a,
          input [3:0] b,
          input ci,
          output [3:0] s,
          output co );

   wire[4:0] c;

   FA FA_0(.a(a[0]), .b(b[0]), .ci(c[0]), .s(s[0]), .co(c[1]));
   FA FA_1(.a(a[1]), .b(b[1]), .ci(c[1]), .s(s[1]), .co(c[2]));
   FA FA_2(.a(a[2]), .b(b[2]), .ci(c[2]), .s(s[2]), .co(c[3]));
   FA FA_3(.a(a[3]), .b(b[3]), .ci(c[3]), .s(s[3]), .co(c[4]));

   assign c[0] = ci;
   assign co = c[4];

endmodule

NOTE FOR LATER This example is given to illustrate structural description in SystemVerilog. For such simple combinational operator, it is recommended to use the arithmetic operators. The corresponding structure will be inferred by synthesis tools.

The 4-bit adder should have been written:

module ADDER(
          input [3:0] a,
          input [3:0] b,
          input ci,
          output [3:0] s,
          output co );

assign {co,s} = a + b + ci;

endmodule

In SystemVerilog {...} is the concatenation operator. Here, {co,s} is a 5-bit bus. The operator expansion rules of SystemVerilog will expand right-hand operators and the addition will be performed on 5-bit.

Processes and Procedural Assignments



module MUX21 ( input a, b,
               input s,
               output o    );

assign o = s & a | ~s & b ;

endmodule

But what about 4-bit buses?


We can use the ternary operator:


module MUX21x4 ( input [3:0] a, b,
                 input s,
                 output[3:0]  o    );

assign o = s? a : b;

endmodule

It would be better if we could express the behaviour in a more explicit manner.

logic signals and processes

NOTE The logic type allows the declaration of variables while the wire type represents nets. Only variables can be modified within a process.

In old Verilog dialect, the logic type was called reg. SystemVerilog added the logic type as a replacement to avoid confusion with Registers (synchronous memorising elements of flip-flops) because we can also describe combinational logic with them.

To describe combinational logic we can use either always@(*) or always_comb. The first one was introduced in Verilog-2001 while the second was introduced later to allow the designer to express its intention. The two constructs can be considered equivalent (differences exist but are beyond what is presented here). They can be interpreted as always if the inputs change, recompute the outputs.

Processes allow the utilization of usual software control sequences (if...else, case…) to describe the behaviour of the combinational logic.



module MUX21x4 ( input [3:0] a, b,
                 input s,
                 output logic [3:0]  o    );

always_comb
   if(s)
      o = a;
   else
      o = b;

endmodule

Note that we have declared o as an output logic to be able to modify it in a process.


Another possibility:


module MUX21x4 ( input [3:0] a, b,
                 input s,
                 output logic [3:0]  o    );

always_comb
   case(s)
      0: o = a;
      1: o = b;
   endcase

endmodule


module MUX41x4 ( input [3:0] a, b, c, d,
                 input [1:0] s,
                 output logic [3:0]  o    );

always_comb
   case(s)
      0: o = a;
      1: o = b;
      2: o = c;
      3: o = d;
   endcase

endmodule

The case statement can be used to describe combinational behaviour by transcribing its truth table.


module DEC21 ( input [1:0] i,
                 output logic [3:0]  o );

always_comb
   case(s)
      0: o = 4'b0001;
      1: o = 4'b0010;
      2: o = 4'b0100;
      3: o = 4'b1000;
   endcase

endmodule

In SystemVerilog you can specify the size (number of bits) and express numbers in different bases. The format is N'Bxxxx where N si the size in bits and B the base.

Examples:

Number Base Size Decimal Value Binary
42 10 32 42 00…101010
6’d42 10 6 42 101010
5’d42 10 5 10 01010
3’b101 2 3 5 101
8’b0101_0101 2 8 85 01010101
’b101 2 ? 5 ……101
8’h55 8 8 85 01010101

Exercise

Seven segments Display

Each segment of a seven segment display is an LED. The seven LEDs have a common power supply (common anode configuration), and their cathode is connected to a signal that we can control (a low logical value will turn-on an LED).

We want to write the SystemVerilog description of a decoder that will be used to display hexadecimal 4-bit numbers in hexadecimal using the seven segment display. This decoder has the following characteristics:

Back to the index