Monday, 6 June 2016

Timing Control in Verilog:

There are three constructs that controls the time in verilog. They are
  • Edge based timing control
  • Level based timing control
  • Event based timing control
Above all constructs are not synthesize-able.

Edge based timing control:

  • By using @(posedge or negedge) we can control the time.
  • We can use it any where with in procedural block.
  • It is blocking construct and it blocks until it see the posedge i.e., before this statement if posedge ocuurs then it will wait until it see the next posedge.
Example:
module tb;
  reg x;
  initial begin
    x = 0;
    #10 x = 1;
    #10 x= 0;
  end
  initial begin
    #50 @(posedge x);
    $display("event based control");
  end
endmodule

In above example posedge of x happens at 10th time unit and simulator is waiting for posedge from 50th time unit. So, simulator does n't see the posedge so $display statement will never be executed.

module tb;
  reg x;
  initial begin
    x = 0;
    #10 x = 1;
    #10 x= 0;
  end
  initial begin
    #5 @(posedge x);
    $display("event based control");
  end
endmodule

In above example posedge of x happens at 10th time unit and simulator is waiting for posedge from 5th time unit. So, simulator saw the posedge of x at 10th time unit and execute the $display statement at 10th time unit only.

Level based timing control:

  • By using wait(<exp>) we can control the time.
  • This is a blocking construct that blocks until the given expression becomes true .
  • It is level based because even before the wait statement if the expression is true then wait statement is unblocked i.e., when ever wait statement sees the expression is true then it becomes unblocked.
Example:
module tb;
  reg y;  
  initial begin
    y = 0;
    #20 y = 1;
    #50 y = 0;
  end
  initial begin
    wait(y);
    $display($time, "level based control");
  end
endmodule

Here simulator is waiting for y to trigger to 1 from 0 time unit and at 20th time unit y triggers to 1 then at 20th time unit $display statement is executed.

module tb;
  reg y;  
  initial begin
    y = 0;
    #20 y = 1;
    #50 y = 0;
  end
  initial begin
    #75;
    wait(y);
    $display($time, "level based control");
  end
endmodule

Here simulator is waiting for y to trigger to 1 from 75th time before that i.e., at 20th time unit y triggers to 1. So, simulator does n't saw the true value of y so it blocks $display statement until it sees y becomes true.

Event based timing control:

  • event based control is mainly used for event synchronization.
  • Here we can declare the variables as event type by using event keyword
  • Event variables are not value holders they used to indicate the change in state.
  • @ is used for waiting on event
  • -> is used for triggering an event
  • Here before waiting if triggering happens then it did n't see the change in state.
Example:
module tb;
module tb; 
  event z;
  initial begin
    #15;
    ->z;
  end
  initial begin
    #10;
    @z;
    $display("event based control");
  end
endmodule

Here simulator is waiting for event z to be triggered from 10th time unit and z is triggered at 15th time unit . So, $display is executed in 15th time unit.

module tb;  
  event z;
  initial begin
    #15;
    ->z;
  end
  initial begin
    #20;
    @z;
    $display("event based control");
  end
endmodule

Here simulator is waiting for event z to be triggered from 20th time unit but z is triggered in 15th time unit . So, simulator does n't see the triggering of event z so $display is not executed.


Delays in verilog:

Delays in verilog are not synthesize able, so we use them mainly for verification. In design we generate delays using counters because no gate/flop will not generate 1 sec delay. Assume a gate produce 1 ps delay then in order to generate 1ns delay synthesizer will connect 1000 gates which makes design complex. So, by taking output of counter we generate delays in hardware.

Delays are represented as #1, #2, #3,.....where #1 indicates 1 time unit delay. The value of 1 time unit is mainly depends on `timescale construct. By using `timescale construct we can change the simulator frequency as follows:

Syntax: `timescale <value>/<precision>

Example: `timescale 1ns/1ns
  • Here value should be in multiples of 10 only
  • units of value are ms, ns, ps,.....
  • precision should not be greater than value
  • blindly multiply the value with delay that will give us value of one time unit
  • precision will tell you granularity levels of each clk
Example:
 `timescale 10ns/1ns
 reg y;
 y = 1;
 #10 y = 0;
 #1.26 y = 1;// Rounded to nearest integer i.e., 13

`timescale 1ns/1ns
 reg x;
 x = 0;
 #10 y = 1;
 #1.2 y = 0;//Rounded to nearest integer i.e., 1

There are 2 types of delays they are
  • inter assignment delay
  • intra assignment delay

Inter assignment delay:

Example: 

x = 1;

#10 x = 0; 

Here in current time unit 1st statement is executed and 2nd statement is postponed to 10 time units.

Intra assignment delay:

Example:

x = #10 1;

Here in current time tick x value is evaluated as 1 and it is assigned after 10 time units.

 We can also use delays in continuous assignments in order to avoid glitches.

Example:

assign #10 x = y + z;

Normal assign statement executed when ever there is change in y and z. If we introduce delay in assign statement then even if there is change in y and z before 10 time units it never considers. It considers values of y and z for every 10 time units but it never considers values in between 10 time units.

 

Friday, 3 June 2016

Operators:

An operator is a symbol that tells the compiler to perform specific mathematical or logical functions. Verilog provides the following types of operators:
  • Arithmetic
  • Logical
  • Relational
  • Equality
  • Bit wise
  • Reduction
  • Shift
  • Concatenation
  • Conditional
  • Replication

Arithmetic Operators:

  • +, -, *, /, %, **
  • +, -, *, /, % are synthesize able
  • ** non synthesize able
  • Integer division truncates any fractional part
  • The modulus operator is not allowed for real data type variables. 
  • The result of a modulus operation takes the sign of the first operand.
  • For unsigned arithmetic operations use reg and wire, real and integer for signed arithmetic. 
  • If any bit of operand is x, then the entire result is x.
Examples:
1) 13 % 3 // Evaluates to 1
  16 % 4 // Evaluates to 0
  -7 % 2 // Evaluates to -1, takes sign of the first operand
  7 % -2 // Evaluates to +1, takes sign of the first operand 

2) in1 = 4'b101x;
    in2 = 4'b1010;
    sum = in1 + in2; // sum will be evaluated to the value 4'bx 

Logical Operators:

  • &&, || and !.
  • Expressions connected by && and || are evaluated from left to right
  • The result for these operators is 0 (when false), 1 (when true), and unknown (x - when ambiguous). 
  • The negation operator (!) turns a nonzero or true value of the operand into 0, zero or false value into 1, and ambiguous value of operator results in x (unknown value).
  • The result is a scalar value:
    • 0 if the relation is false
    • 1 if the relation is true
    • x if any of the operands has x (unknown) bits

Example :
reg [3:0] a, b;
a = 4'b1100;
b = 4'b0000;
!a // 0 - false
!b // 1 - true
a && b // 0 - false
a || b // 1 - true

Relational Operators:

  • <, >, <=, >=
  • Output should be a scalar value and it should be
  • 1, if the expression is true
  • 0, if the expression is true
  • x, if there are any unknown or z bits in the operands
Example:
 1'b1 && 1'b1 = 1
 1'b1 && 1'b0 = 0
 1'b1 && 1'bx = x
 1'b1 || 1'b0 = 1
 1'b0 || 1'b0 = 0
 1'b0 || 1'bx = x
 ! 1'b1       = 0
 ! 1'b0       = 1

Equality Operators:

  • logical equality (==), logical inequality (!=), case equality (===), and case inequality (!==) 
  • equality operators return logical value 1 if true, 0 if false.
  • If the operands are of different length then fill msb bit's with 0.
  • The logical equality operators (==, !=) will yield an x if either operand has x or z in its bits.
  • The case equality operators ( ===, !== ) compare both operands bit by bit and compare all bits, including x and z. 
  • The result is 1 ithe operands match exactly, including x and z bits. 
  • The result is 0 if the operands do not match exactly. 
  • Case equality operators never result in an x. 
Example:
  4'bx001 ===  4'bx001 = 1
  4'bx0x1 !=  4'bx001 = x
  4'bz0x1 ===  4'bz0x1 = 1
  4'bz0x1 ==  4'bz001 = x
  4'bx0x1 !==  4'bx001 = 1
  4'bz0x1 !==  4'bz001 = 1
  5       ==   10      = 0
  5       ==   5       = 1
  5       !=   5       = 0
  5       !=   6       = 1

Bit-wise Operators:

  • ~, &, |, ^, xnor (^~, ~^)
  • z is treated as an x in a bitwise operation
  • Truth tables for bit-wise operators are shown below

Example:
  ~4'b0001           = 1110
  ~4'bx001           = x110
  ~4'bz001           = x110
  4'b0001 &  4'b1001 = 0001
  4'b1001 &  4'bx001 = x001
  4'b1001 &  4'bz001 = x001
  4'b0001 |  4'b1001 = 1001
  4'b0001 |  4'bx001 = x001
  4'b0001 |  4'bz001 = x001
  4'b0001 ^  4'b1001 = 1000
  4'b0001 ^  4'bx001 = x000
  4'b0001 ^  4'bz001 = x000
  4'b0001 ~^ 4'b1001 = 0111
  4'b0001 ~^ 4'bx001 = x111
  4'b0001 ~^ 4'bz001 = x111


Reduction Operators:

  •  and (&), nand (~&), or (|), nor (~|), xor (^), and xnor (~^, ^~)
  • Reduction operators take only one operand
  • Reduction operators perform a bitwise operation on a single vector operand and yield a 1-bit result
  • Reduction operators work bit by bit from right to left. 
  • Reduction nand, reduction nor, and reduction xnor are computed by inverting the result of the reduction and, reduction or, and reduction xor, respectively. 
Example:
a = 4'b0101 then
&a = 1'b0
(~& )a =  1'b1
|a = 1'b1
(~|) a = 1'b0
^a = 1'b0
(~^)a = 1'b1

Shift Operators:

  •  right shift ( >>), left shift (<<), arithmetic right shift (>>>), and arithmetic left shift (<<<).
  • During  right shift, left shift and arithmetic left shift when the bits are shifted then the vacant bit positions are filled with zeros.
  • During arithmetic right shift the vacant bit positions are filled with zeros.
Example:
A = 4'b1010;
B = A >> 1;//4'b0101
B = A << 1;//4'b0100

Concatenation Operator:

  • The concatenation operator ( {, } ) appends multiple operands.
  • The operands must be sized. Unsized operands are not allowed because the size of each operand must be known for computation of the size of the result.
  • Concatenations are expressed as operands within braces, with commas separating the operands. 
  • Operands can be scalar nets or registers, vector nets or registers, bit-select, part-select, or sized constants. 
Example:
p = 1'b1, q = 2'b00, s = 2'b10, t = 3'b110
u = {q , r} // 4'b0010
u = {p , q , r , s , 3'b001} // 11'b10010110001
u = {p , q[0], r[1]} // 3'b101 

Replication Operator:

  • Repetitive concatenation of the same number can be expressed by using a replication constant. 
  • A replication constant specifies how many times to replicate the number inside the brackets ( { } )
Example:
reg A;
reg [1:0] B, C;
reg [2:0] D;
A = 1'b1; B = 2'b00; C = 2'b10; D = 3'b110;
Y = { 4{A} } // Result Y is 4'b1111
Y = { 4{A} , 2{B} } // Result Y is 8'b11110000
Y = { 4{A} , 2{B} , C } // Result Y is 8'b1111000010 

Conditional Operator:

The conditional operator(?:) takes three operands.
Syntax: condition_expr ? true_expr : false_expr ;
The condition expression (condition_expr) is first evaluated. If the result is true (logical 1), then the true_expr is evaluated. If the result is false (logical 0), then the false_expr is evaluated. If the result is x (ambiguous), then both true_expr and false_expr are evaluated and their results are compared, bit by bit, to return for each bit position an x if the bits are different and the value of the bits if they are the same. 

Operator Precedence:




Wednesday, 1 June 2016

Modeling a Flop:

Assume that the flop which is going to be modeled is shown in below figure.

Case-1: modeling using assign statement

assign q = ( !rst ) ?  ( clk ? d : q ) : 0;

Here simulation results are matched but synthesis results are mismatched because assign statement is used to model combo logic so in synthesized output we get muxes. This is not correct modeling of flop.

Case-2: modeling using always with BA

always@(posedge clk) begin
  if(rst) q = 0;
  else q = d;
end

Here one always block was there so we get correct simulation and synthesis results. If multiple always block were there and q is assigned to another variable in other always block then we get wrong simulation results because of race condition. This is also not correct modeling of flop.

Case-3: modeling using always with NBA

always@(posedge clk) begin
  if(rst) q <= 0;
  else q <= d;
end

Here both synthesis and simulation results are matched even if there are multiple always blocks. This is the correct way of modeling a flop.

Race Condition:

Race condition is nothing but if two expressions are evaluated in same time unit then depending on the order of evaluation of expressions output value changes.

Example:
always@(posedge clk, negedge rst) begin
  if (rst) a = 0;
  else a = b;
end

always@(posedge clk, negedge rst) begin
  if (rst) b = 1;
  else b = a;
end

Here after reset  if first always block executes first and then second always then a = 1, b = 1. If second one executes first and then first one executes then a = 0, b = 0.

We can avoid the race condition by using NBA as follows:

always@(posedge clk, negedge rst) begin
  if (rst) a <= 0;
  else a <= b;
end

always@(posedge clk, negedge rst) begin
  if (rst) b <= 1;
  else b <= a;
end

Here what ever the order of execution of always block the output is same as a=1,b=0 during first posedge of clock and a=0,b=1 in next posedge of clock i.e., nothing but feedback oscillator.

Causes of race condition:

1) If two always blocks drives same variable.

Example:
always@(posedge clk) begin
  a = 1;
end
always@(posedge clk) begin
  a = 0;
end

2) one always block is dependent on other always block.

Example:
always@(posedge clk) begin
  a = b;
end
always@(posedge clk) begin
  c = a;
end

Tips to avoid Race condition:

1) Never ever drive single variable in multiple always blocks.
2) Use NBA inside always block.

Design of Feedback Oscillator:

The feedback oscillator which is going to be designed as shown below.

Case-1: using NBA

always@(posedge clk, negedge rst) begin
  if (rst) a <= 0;
  else a <= b;
end

always@(posedge clk, negedge rst) begin
  if (rst) b <= 1;
  else b <= a;
end

Here always blocks are executed in any order, when reset = 1 then a = 0,b = 1 and when reset is released then a = 1, b = 0.In next posedge the values of a and b are interchanged and this process continuous until the end of simulation.

Case-2: using BA

always@(posedge clk, negedge rst) begin
  if (rst) a = 0;
  else a = b;
end

always@(posedge clk, negedge rst) begin
  if (rst) b = 1;
  else b = a;
end

Here the values of a and b depends on the order of execution of always blocks i.e., Race condition.

Tuesday, 31 May 2016

Self-Triggered always block:

Case-1: always with BA

Assume the initial value of clock is 0.

always@(clock) begin
  #5 clock =~ clock;
end

Here the assignment is blocking i.e., active event. so, it is executed in current tick i.e., after 5 time units clock becomes 1 ans simulator comes out of the loop and watching event to be triggered but it will never happens because the change occurred when the simulator is with in the always block. so, always block executed only once. It is non self triggered always block.

Case-2: always with NBA

Assume the initial value of clock is 0.

always@(clock) begin
  #5 clock <=~ clock;
end

Here the assignment is non blocking i.e., NBA event. so, the evaluation of R.H.S happens in current tick and assignment happens at the end of tick i.e., clock value is evaluated as 1 and the simulator comes out of always block and watching sensitivity list. At the end of tick 1 is assigned to clock. Here simulator sees the change of sensitivity list so always block executed continuously till the end of simulation. It is self triggered always block. It can be used for clock generation in verification.

Stratified event queues:

Stratified event queue model will help us how the various statements like blocking, non blocking, $display,...etc inside module gets executed.
According to the Verilog IEEE standard, the Verilog event queue is logically segmented into four different regions as shown below.

1) Active events:

Active events include continuous assignments, blocking assignments, evaluation of R.H.S of non blocking assignments, $display statements, evaluation of inputs and updation of outputs of primitive gates and other module instances. The above events can be executed in current simulation time in any order.

2) In active events:

After completing execution of active events, inactive events are processed. Here #0 (zero delay statements ) are scheduled.

3) NBA:

Assignment of evaluated things of R.H.S in active region to L.H.S happens after processing active and inactive events. After assigning a value to a variable that may or may not triggers the other always block. If it triggers then that always block is executed in current simulation time only that's why simulator will go to active after NBA.

4)Monitoring:

After NBA if no always block triggers then monitoring events are evaluated. $strobe, $monitor are monitoring events. if simulator loops from NBA to active 100 times and each loop contains one monitoring statement then 100 monitoring statements are stored in a queue, when the simulator comes out of the loop then all 100 monitoring statements are evaluated.

Example:

always@(x,y) begin
  z = x | y;
  a <= z;
end
always@(a) begin
  w = a;
end

Here if x or y changes then first blocking assignment i.e., z is updated and that is evaluated value on R.H.S of NBA. At the end of tick z is assigned to a that indirectly triggers the other always block. Blocking assignment executed and then simulator advances the time i.e., next time tick.

 Design of Combinational logic using always block

The Combinational circuit which is going to be designed is shown in below figure:

Case-1:

  always@(a,b,c,d) begin
    x = a & b;
    y = c & d;
    f = x & y;
  end

Simulation results:

After applying input2 values then x = 1, y = 0 and f = 0. Here simulation results are matched.

Case-2:

  always@(a,b,c,d) begin
    x <= a & b;
    y <= c & d;
    f <= x & y;
  end

Simulation results

After applying input2 values then x = 1, y = 0 and f = 1. Here we get 'f' based on past values of x and y. Here simulation results are mismatched.

Case-3:

  always@(a,b,c,d,x,y) begin //or always@(*) begin
    x <= a & b;
    y <= c & d;
    f <= x & y;
  end

Simulation results:

First always block executed then x and y are evaluated as 1 and 0, f as 1 which is past output. Here y value is changed so always block get executed one more time then f become 0. Here always block gets executed twice, so simulation time become double i.e., performance degrades.

Synthesis results:

Synthesis results for the above all three cases are same as shown below.



Monday, 30 May 2016

design of sequential logic using always block:

The Sequential circuit which is going to design is shown in following figure.

With Blocking assignments:

Case-1:

always@( posedge clk) begin
    b = a;
    c = b;
    d = c;
end
In above case b,c are treated as temporary signals because after assigning some value to b & c immediately they are assigned to other signals. so there is no need to remember previous values. so b & c are treated as temporary signals.

Simulation results:

Before applying clk 'a' is set to 0 then b = 0, c = 0, d = 0. In this case simulation and synthesis results are mismatched.

Synthesis results:

Case-2:
always@( posedge clk) begin
    d = c;
    c = b;
    b = a;
end

Simulation Results:

In this case b, c are not temporary because before assigning some value to c, c is assigned to d i.e., c need to be retained its previous value only when c is a memory element. similarly b. Simulation results are d = 1, c = 0, b = 0, a = 0. Simulation results and synthesis results are matched.

Note:  while designing seq logic with blocking assignments ordering of statements (i.e., from output to input) is important.

Synthesis Results:

Case-3:


  always@(posedge clk) begin

    b = a;

  end
  always@(posedge clk) begin
    c = b;
  end
  always@(posedge clk) begin
    d = c;
  end

Simulation results:

Simulation results are same as case-2 if they are executed in the same order as they declared. if the order of execution of always blocks changes then output also changes i.e., race condition. Synthesis results are same as case-2. out of case-2 & 3, case-2 is best because of no race condition.

Synthesis results:

With Non-Blocking Assignments:

Case-1:

 always@(posedge clk) begin
    b <= a;
    c <= b;
    d <= c;
  end 

Case-2:

  always@(posedge clk) begin
    d <= c;
    c <= b;
    b <= a;
  end

Case-3:


  always@(posedge clk) begin
    b <= a;
  end
  always@(posedge clk) begin
    c <= b;
  end
  always@(posedge clk) begin
    d <= c;
  end

Simulation results:

Simulation results results for the above all three case are same and their values are a = 0, b = 0, c = 1, d = 0. For evaluation of NBA please refer procedural assignments concept. Synthesis results are also same for the above all three cases as shown below.

Note: NBA gives same simulation and synthesis results for all three combinations of always block. So, it is always preferable that sequential logic is designed NBA only

Synthesis results: