Friday, November 21, 2025

Check duty cycle of a clock

 High time check:

@(posedge clk) (1, start_t = $realtime) |-> @(negedge clk) ($realtime - start_t == half_period);


Low time check:
@(negedge clk) (1, start_t = $realtime) |-> @(posedge clk) ($realtime - start_t == half_period);

Write a system verilog assertion to check clock of 50 MHz

 // Code your testbench here


// or browse Examples


module clk_check;


     timeunit 1ns;     


   timeprecision 100ps;  


realtime clk_period = 20.0/1.0ns; 


bit clk, RESET_N, ENABLE;


  property T_clk(real clk_period);


time current_time;


// disable iff(!RESET_N || !ENABLE)


(('1,current_time=$realtime) |=>


         (clk_period <= $realtime-(current_time-0.001ns))  &&


         (clk_period >= $realtime-(current_time + 0.001ns))); 


endproperty


 


assert_period:assert property (@(posedge clk)T_clk(clk_period))


$display("%t TB_INFO : clk  correct",$realtime); 


else


$warning("%t TB_INFO : clk not correct",$realtime);


initial forever #10 clk=!clk; 


initial begin 


$display("START CHECKING ");


repeat(10) @(posedge clk); 


// $display("%t %t TB_INFO : clk  correct",$realtime, $realtime);


$finish; 


end


   


endmodule : clk_check 

Thursday, November 20, 2025

Check that when A goes HIGH , B goes HIGH for 1 to 3 cycles within the next 10 cycles

 $rose(A) |-> B[=1:3] throughout 1'b[*10]

Generate Non overlapping addresses

 Start address 

 End address 

Cannot be over lapping.

class a;

      rand   bit [31:0]  start_address[] ;

      rand   bit [31:0]  end_address[] ;

      rand   int size ; 

      //100 -1000

      //1000-5000

  constraint c1 {

        foreach(start_address[i]) start_address[i] != end_address[i] ;

    }                      


  constraint c2 {

    foreach(start_address[i]) 

      foreach(start_address[j])

        if(i!=j) 

          !(start_address[j] inside {[start_address[i]:end_address[i]]}); }                      

  constraint c3 {

    foreach(end_address[i]) 

      foreach(end_address[j])

        if(i!=j) 

             !(end_address[j] inside {[start_address[i]:end_address[i]]}) ;}                 

  endclass


module top ;

  a a1;

  initial begin 

    a1 = new();

    a1.start_address= new[20];

    a1.end_address = new[20];

    repeat (20) begin

      a1.randomize();

      //foreach(a1.start_address[i])

      $display("start addr = %p ", a1.start_address );

        $display("end addr = %p",  a1.end_address );

    end 

  end

  

endmodule


    

Wednesday, November 19, 2025

flight scheduler - SV randomization

 Q. How many combinations can be there for the below scenario?

There are 3 flights and 8 passengers (a,b,c,d,e,f,g,h) 

1.a and b should always be together 

2. each flight needs to fly . minimum passengers that can go in an flights are = 1 , 

Maximum passengers that can go in an flights are = 4 .

Answer : 

Instaed of manually thinking of all scenarios , we can write in in system verilog . (using constarints) .

1. create an enum of passengers 

 typedef enum {a,b,c,d,e,f,g,h} passenger ;

2. create a queue called flight like this :

    passenger flight[]; 

// Code your testbench here

// or browse Examples

class FlightScheduler;

  // Passenger list

  typedef enum {a, b, c, d, e, f, g, h} passengers_t;


  // The flights array stores the flight allocation for each passenger

  rand passengers_t flights[8]; // Array of flight assignments for 8 passengers

  rand int flight_count[3];     // Number of passengers on each flight (0, 1, 2)


  constraint flight_constraints {

    // Each passenger must be assigned to one of the three flights

    foreach (flights[i]) flights[i] inside {0, 1, 2};


    // Ensure passengers 'a' and 'b' always travel together

    flights[0] == flights[1]; // Both passenger a and b travel on the same flight


    // Count how many passengers are on each flight

    foreach (flight_count[i]) {

      flight_count[i] == (flights.count(i)); // Count passengers in flight i

    }


    // Each flight must have between 1 and 4 passengers

    foreach (flight_count[i]) flight_count[i] inside {[1:4]};

  }


  // Display the flight assignments

  function void display_flight_allocation();

    $display("Flight assignments:");

    foreach (flights[i]) begin

      $display("Passenger %0d -> Flight %0d", i, flights[i]);

    end

    $display("Flights distribution: Flight 0: %0d, Flight 1: %0d, Flight 2: %0d",

             flight_count[0], flight_count[1], flight_count[2]);

  endfunction

endclass


// Testbench

module tb_flight_scheduler;

  initial begin

    FlightScheduler scheduler = new();

    if (scheduler.randomize()) begin

      scheduler.display_flight_allocation();

    end else begin

      $display("Failed to randomize!");

    end

  end

endmodule

Q.  3*3 Array question :


class A ;

  rand int mem[3][3];

  constraint c1{ 

      unique{mem}; 

    foreach(mem[i,j]) 

    {

      mem[i][j] inside {[1:9]}; 

    }

  };

    

  constraint c2{

    foreach(mem[i])

    {

      foreach(mem[k])

      {

        mem[i].sum() == mem[k].sum();

      } 

    }

  };

      

  constraint c3{

    foreach(mem[,j])

    {

      foreach(mem[,k])

      {

        mem.sum() with (mem[item.index][j]) == mem.sum() with (mem[item.index][k]);

      } 

    }

  }; 

  

endclass




module t();

  A a_h ;

  initial begin

   a_h = new ; 

      a_h.randomize();

      $display("value is %p", a_h.mem); 

   end 

endmodule

       

Thursday, November 13, 2025

Fifo depth , randc function using rand

Calculate the depth of FIFO :

Writing frequency = fA = 80MHz. Reading Frequency = fB = 50MHz. Burst Length = No. of data items to be transferred = 120. There are no idle cycles in both reading and writing which means that, all the items in the burst will be written and read in consecutive clock cycles.

====================================================================

Ans:  1 write = 80 MHZ = 12.5 ns   (  1MHz is 1000 ns) 

        120 writes = 120*12.5 ns = 1500 ns 

        reading 1 = 50 MHz = 20 ns  

       in 1500 ns how many reads = 1500/20 = 75 

  deapth = wrire -read = 120-75 = 45  

=============================================

Question 

 Writing Side = 80 words in 100 clocks • Reading Side = 8 words in 10 clocks • BURST wr 160 

What will be the FIFO depth 

=======================================================

Solution : • Worst scenario of overflow of data is when there is 160 clocks of continuous write. Lets assume first 20 cycle is idle and then 80 clock cycle writing. Other set of writing starts at 101 clock cycle. Worst scenario : 160 words are written in 160 clocks Reading possibility : 8*16 = 128 words can be read So depth of FIFO : 160-128 = 32


================

constraint for a rand variable to behave like a randc.

credit https://www.linkedin.com/pulse/constraint-45-mohamed-irsath-i-qs58c/ 

In order to achieve the requested constraint, we first need to understand the difference between rand and randc variables.

Rand: By defining a variable as rand, it becomes an active variable when you randomize the object created for the class where the variable is defined. While randomizing, it will take possible values that obey the constraints written for that variable. If no constraints are specified, it can generate any value in its range and may repeat the same value multiple times without producing all possible values.

Randc: randc behaves similarly to rand, but with an additional feature denoted by the "c" for cyclic. This cyclic behavior allows the variable to generate all possible values, but without repeating any value until it has generated all possible values at least once.

For example, consider a 3-bit variable a. If a is declared as rand, it can take any value from 0 to 7 while randomizing. It may repeat values before generating all values from 0 to 7. On the other hand, if a is declared as randc, it won't repeat any generated value until it has generated all values from 0 to 7.

class sample;
  rand  bit [2:0] rand_a;
  bit [2:0] rand_q[$];
  
  constraint rand_a_c {
    unique{rand_a,rand_q}; 
  }
  
  function void post_randomize();
    if(rand_q.size() == 7) rand_q.delete();
    rand_q.push_back(rand_a);
  endfunction
endclass

module top;
  sample s=new();
  initial begin
    $display("############## OUTPUT ###############");
    $display("the Behvariablef rand variable as randc");
  	repeat(10) begin
    	s.randomize();
      $display(" rand_a = %0d",s.rand_a);
      $display(" rand_q = %p",s.rand_q);
  	end
    $display("see there is no repetition till \n it generate 0 to 7 \n even though it is a rand variable ");
    $display("################ END ################");
  end
endmodule

 Things to prepare : 

byte wise sorting a queue in system Verilog 

reverse a fifo

constraints related 


1. Few questions on writing constraints for certain scenarios. 2. FSM for number divisible by 3 3. UVM subscriber, sequences, TLM ports and FIFO. 4. write code for random number generation for given distribution and ranges. 5. byte addressing in an integer memory system. 6. constrain for non-overlapping segment-addresses generation. 7. Explain any testbench architecture you have worked on. 8. Lots of simple questions to test SystemVerilog and OOP concepts.



1.  have a 7 bit par_groups. Every time I randomize, I need to pick 3 groups that are unique and less than 32. Below is an example on how I did it.

Is there an better way to do it? This does not scale well. If I need to pick 15 unique groups from 32, this becomes a not so good solution.


Ans 

class example1;
 
  rand bit [6:0] par_groups; // why is this size different?
  rand bit[4:0] group[3];
 
  constraint group_c{unique {group};}
 
  constraint par_groups_c{par_groups inside {group};}
 
  function void post_randomize();
    $display("group = %p", group);
  endfunction  
 
endclass