Registers and Logic


           Verilog used the terms wire and reg as a descriptive way to declare wires and registers. The original intent was soon lost in synthesis and verification coding styles, which soon gave way to using terns Nets and Variables in Verilog-2001. The keyword reg remained in SystemVerilog, but was now misleading its intent. SystemVerilog adds the keyword logic as a more descriptive term to remind users that it is not a hardware register. logic and reg are equivalent types.

            SystemVerilog extended the variable type so that, it can be used to connect gates and modules. All variables can be written either by one continuous assignment, or by one or more procedural statements. It shall be an error to have multiple continuous assignments or a mixture of procedural and continuous assignments.

            Now we saw logic and wire are closer. Wire (net) is used when driven by multiple drivers, where as logic is used when it is driven by only one driver. logic just holds the last value assigned to it, while a wire resolves its value based on all the drivers.

For example:
logic abc; 

The following statements are legal assignments to logic abc:

1) assign abc = sel ? 1 : 0;
2) not (abc,pqr),
3) always #10 abc = ~abc;


Previous topic : Enumerations


Enumerations



Previous topic: Literals                     Next topic:  Enumerations


      You'll sometimes be faced with the need for variables that have a limited set of possible values that can be usally referred to by name. For example, the state variable like IDLE,READY,BUZY etx of state machine can only have the all the states defined and Refraining or displaying these states using the state name will be more comfortable. There's a specific facility, called an enumeration in SystemVerilog . Enumerated data types assign a symbolic name to each legal value taken by the data type. Let's create an example using one of the ideas I just mentioned-a state machine .

You can define this as follows:

enum {IDLE,READY,BUZY} states;

This declares an enumerated data type called states, and variables of this type can only have values from the set that appears between the braces, IDLE,READY and BUZY. If you try to set a variable of type states to a value that isn't one of the values specified, it will cause an error. Enumerated data type are strongly typed.

One more advantage of enumerated datatypes is that if you don't initialize then , each one would have a unique value. By defaule they are int types. In the previous examples, IDLE is 0, READY is 1 and BUZY is 2. These values can be printed as values or strings.

The values can be set for some of the names and not set for other names. A name without a value is automatically assigned an increment of the value of the previous name. The value of first name by default is 0.

// c is automatically assigned the increment-value of 8
enum {a=3, b=7, c} alphabet;

// Syntax error: c and d are both assigned 8
enum {a=0, b=7, c, d=8} alphabet;

// a=0, b=7, c=8
enum {a, b=7, c} alphabet;

Enumarated Methods:

SystemVerilog includes a set of specialized methods to enable iterating over the values of enumerated.

The first() method returns the value of the first member of the enumeration.

The last() method returns the value of the last member of the enumeration.

The next() method returns the Nth next enumeration value (default is the next one) starting from the current value of the given variable.

The prev() method returns the Nth previous enumeration value (default is the previous one) starting from the current value of the given variable.

The name() method returns the string representation of the given enumeration value. If the given value is not a member of the enumeration, the name() method returns the empty string.

EXAMPLE : 


ENUM methods
module enum_method;
typedef enum {red,blue,green} colour;
colour c;
initial
begin
c = c.first();
$display(" %s ",c.name);
c = c.next();
$display(" %s ",c.name);
c = c.last();
$display(" %s ",c.name);
c = c.prev();
$display(" %s ",c.name);
end
endmodule

RESULTS : 

red 
blue
green
blue

Enum Numerical Expressions



Elements of enumerated type variables can be used in numerical expressions. The value used in the expression is the numerical value associated with the enumerated value. 

An enum variable or identifier used as part of an expression is automatically cast to the base type of the enum declaration (either explicitly or using int as the default). A cast shall be required for an expression that is assigned to an enum variable where the type of the expression is not equivalent to the enumeration type of the variable.

EXAMPLE:
module enum_method;
typedef enum {red,blue,green} colour;
colour c,d;
int i;
initial
begin
$display("%s",c.name());
d = c;
$display("%s",d.name());
d = colour'(c + 1); // use casting
$display("%s",d.name());
i = d; // automatic casting
$display("%0d",i);
c = colour'(i);
$display("%s",c.name());
end
endmodule 

RESULT 

red 
red
blue
1
blue

TIP: If you want to use X or Z as enum values, then define it using 4-state data type explicitly.

enum integer {IDLE, XX='x, S1='b01, S2='b10} state, next;



Previous topic: Literals                     Next topic:  Enumerations

System verilog literals

Integer And Logic Literals

In verilog , to assign a value to all the bits of vector, user has to specify them explicitly.
reg[31:0] a = 32'hffffffff; 

       System verilog adds the ability to specify unsized literal single bit values with a preceding (').'0, '1, 'X, 'x, 'Z, 'z // sets all bits to this value.

reg[31:0] a = '1;

'x is equivalent to Verilog-2001 'bx
'z is equivalent to Verilog-2001 'bz
'1 is equivalent to making an assignment of all 1's
'0 is equivalent to making an assignment of 0

Time Literals

Time is written in integer or fixed-point format, followed without a space by a time unit (fs ps ns us ms s step).

EXAMPLE
0.1ns
40ps

The time literal is interpreted as a realtime value scaled to the current time unit and rounded to the current time precision.

Array Literals

      Array literals are syntactically similar to C initializers, but with the replicate operator ( {{}} ) allowed.

EXAMPLE
int n[1:2][1:3] = '{'{0,1,2},'{3{4}}};

      The nesting of braces must follow the number of dimensions, unlike in C. However, replicate operators can be nested. The inner pair of braces in a replication is removed. A replication expression only operates within one dimension.

EXAMPLE:
int n[1:2][1:6] = '{2{'{3{4, 5}}}}; // same as '{'{4,5,4,5,4,5},'{4,5,4,5,4,5}}

Structure Literals

       Structure literals are structure assignment patterns or pattern expressions with constant member expressions A structure literal must have a type, which may be either explicitly indicated with a prefix or implicitly indicated by an assignment-like context.
EXAMPLE 
typedef struct {int a; shortreal b;} ab;
ab c;
c = '{0, 0.0}; // structure literal type determined from
// the left-hand context (c)

Nested braces should reflect the structure.
EXAMPLE
ab abarr[1:0] = '{'{1, 1.0}, '{2, 2.0}};

The C-like alternative '{1, 1.0, 2, 2.0} for the preceding example is not allowed.

EXAMPLE: default values
c = '{a:0, b:0.0};
c = '{default:0};
d = ab'{int:1, shortreal:1.0};



Introduction to System Verilog

       SystemVerilog is a combined Hardware Description Language and Hardware Verification Language based on extensions to Verilog. SystemVerilog was created by the donation of the Superlog language to Accellera in 2002. The bulk of the verification functionality is based on the OpenVera language donated by Synopsys. In 2005, SystemVerilog was adopted as IEEE Standard 1800-2005 .

        SystemVerilog's capabilities are unique, but it is significant that these capabilities are combined and offered within a single HDL. There is great value in a common HDL which handles all aspects of the design and verification flow: design description, functional simulation, property specification, and formal verification.



Next topic: Literals

Unsigned N-bit multiplier.

~\Desktop\pract.v.html
module mult (in1,in2,out1);

parameter N=8;

input [N-1:0] in1,in2;
output [2*N-1:0] out1;

assign out1=in1*in2;

endmodule


Verilog code for unsigned 8-bit adder and subtractor

~\Desktop\pracctice.v.html
module add_sub(a,b,oper,res);
        input oper;
        input [7:0] a;
        input [7:0] b;
        output reg [7:0] res;

        always @*
           if (oper == 1’b0)
                res = a + b;
           else
                res = a - b;

        endmodule




Verilog code for unsigned 8-bit adder with carry in and carry out

~\Desktop\pracctice.v.html
module unsigned_adder(a,b,ci,sum,co);

        input [7:0] a;
        input [7:0] b;
        input ci;
        output [7:0] sum;
        output co;

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

        endmodule


Verilog code for unsigned 8-bit adder with carry out

~\Desktop\pracctice.v.html
module unsigned_adder(a,b,sum,co);
        input  [7:0] a;
        input  [7:0] b;
        output [7:0] sum;
        output co;

        assign {co,sum} = a + b;

        endmodule


Verilog code for unsigned 8-bit adder with carry in

~\Desktop\pracctice.v.html
module unsigned_adder(a,b,ci,sum);
        input  [7:0] a;
        input  [7:0] b;
        input       ci;
        output [7:0] sum;

        assign sum = a + b + ci;

        endmodule

N-bit logical shifter

~\Desktop\pract.v.html
module logical_shift (si, sel, so);

        parameter N=8;
//By varying the parameter value you can change the width of shift register

        input  [N-1:0] si;
        input  [1:0] sel;
        output reg [N-1:0] so;

        always @(si or sel)
                case (sel)
                        2’b00   : so = si;
                        2’b01   : so = si << 1;  //shifts by 1-bit
                        2’b10   : so = si << 2;  //shifts by 2-bit
                        default : so = si << 3; //shifts by 3-bit 
                endcase
        endmodule

Verilog code that infers 3:8 decoder

~\Desktop\pracctice.v.html
module decoder (sel, out1);

        input [2:0] sel;
        output reg [7:0] out1;

        always @(sel,out1)
           case (sel)
              3’b000  : out1 = 8’b00000001;
              3’b001  : out1 = 8’b00000010;
              3’b010  : out1 = 8’b00000100;
              3’b011  : out1 = 8’b00001000;
              3’b100  : out1 = 8’b00010000;
              //101,110 and 111 selector values are unused
              default : out1 = 8’bxxxxxxxx;
           endcase

        endmodule

Verilog code for a 3:1 MUX with a 1-bit latch

~\Desktop\pracctice.v.html
module mux (a,b,c,d,sel,out1);

        input a,b,c,d;
        input  [1:0] sel;
        output reg out1;

        always @(*)
           if (sel==2’b00)
                  out1 = a;
           else if (sel == 2’b01)
                  out1 = b;
           else if (sel == 2’b10)
                  out1 = c;

        endmodule

Verilog Code for a 4:1 MUX using a case statement

~\Desktop\pract.v.html
module mux (a,b,c,d,sel,out1);
        input a,b,c,d;
        input [1:0] sel;
        output reg out1;

        always @(*)
          case (sel)
            2’b00   : out1 = a;
            2’b01   : out1 = b;
            2’b10   : out1 = c;
            default : out1 = d;
          endcase
        endmodule

Verilog code for a 4:1 MUX using an If statement

~\Desktop\pract.v.html
module mux (a,b,c,d,sel,out1);
        input a,b,c,d;
        input [1:0] sel;
        output reg out1;

        always @(*)
           if (sel == 2’b00)
              out1 = a;
           else if (sel == 2’b01)
              out1 = b;
           else if (sel == 2’b10)
              out1 = c;
           else
              out1 = d;

        endmodule

Unsigned N-bit comparator

~\Desktop\pract.v.html
module comparator(a, b, cmp);

        parameter N=8;
//  By varing the parameter value you can change the number of bits needed for comparaision

        input [N-1:0] a;
        input [N-1:0] b;

        output cmp;

        assign cmp = (a >= b) ?  1’b1 : 1’b0;

        endmodule


Verilog code for N-bit shift-left/shift-right register with a positive-edge clock, a serial in and parallel out

~\Desktop\pract.v.html
module shift (clk,si,left_right,pout);

        parameter N=8;

        input clk,si,left_right;
        output [N-1:0] pout;
        reg [N-1:0] tmp;

        always @(posedge clk)
           if (left_right == 1’b0)
               tmp <= {tmp[N-2:0],si};
           else
               tmp <= {si,tmp[N-1:1]};

        assign pout = tmp;

        endmodule

Verilog code for N-bit shift-left register with a positive-edge clock, a synchronous parallel load, a serial in and a serial out

~\Desktop\pract.v.html
module shift (clk,sload,si,d,so);

        parameter N=8;

        input clk, si, sload;
        input [N-1:0] d;
        output so;
        reg [N-1:0] tmp;

        always @(posedge clk)
           if (sload)
              tmp <= d;
           else
              tmp <= {tmp[N-2:0], si};

        assign so = tmp[N-1];

        endmodule

Verilog code for N-bit shift-left register with a positive-edge clock, an asynchronous parallel load, serial in and serial out

~\Desktop\pract.v.html
module shift (clk,load,si,din,so);

        parameter N=8;

        input clk,si,load;
        input [N-1:0] din;
        output so;
        reg [N-1:0] tmp;

        always @(posedge clk or posedge load)
          if (load)
             tmp <= din;
          else
             tmp <= {tmp[N-2:0], si};

        assign so = tmp[N];

        endmodule

Verilog code using blocking and nonblocking assignments

~\Desktop\pracctice.v.html
module nonblocking(in1,clk,out1);

input in1,clk;
output reg out1;
reg w1,w2;

//This code refers to a shift register
always @(posedge clk)
begin
            w1    <= in1 ;
            w2    <= w1  ;
            out1  <= w2  ;
end

endmodule


//------------------------------------------------------------------------

module blocking(in1,clk,out1);

input in1,clk;
output reg out1;
reg w1,w2;

//This code refers to a D-ff with in1 as input & out1 as output
always @(posedge clk)
begin
            w1     =  in1;
            w2     =  w1 ;
            out1   =  w2 ;
end

endmodule

Verilog code for serial-in parallel-out 8-bit shift-left register with a positive-edge clock

~\Desktop\pracctice.v.html
module shift (clk, si, po);

        input clk,si;
        output [7:0] po;
        reg    [7:0] temp;

        always @(posedge clk)
          temp <= {temp[6:0],si};

        assign po = temp;

        endmodule