Saturday, 18 June 2016

Task inside Interface

interface simple_bus (input logic clk); // Define the interface
  logic req, gnt;
  logic [7:0] addr, data;
  logic [1:0] mode;
  logic start, rdy;

modport slave(input req, addr, mode, start, clk,
               output gnt, rdy,
               ref data,
               import slaveRead,slaveWrite);
             
//import into module that uses the modport
modport master(input gnt, rdy, clk,
               output req, addr, mode, start,
               ref data,
               import masterRead,masterWrite);
             
//import into module that uses the modport
task masterRead(input logic[7:0] raddr=8'h0); // masterRead method
  $display("Inside Master_Read");
endtask
             
task slaveRead;
  $display("Inside Slave_Read");
endtask
           
task masterWrite(input logic [7:0] waddr=8'h0);
  $display("Inside Master_Write");
endtask
             
task slaveWrite;
  $display("Inside Slave_Write");
endtask
             
endinterface: simple_bus
             
             
module mod (interface i)               ;
  always@(posedge i.clk) begin
     i.slaveRead;
     i.masterRead;
     i.slaveWrite;
     i.masterWrite;
   end              
endmodule
               
module top;
  logic clk = 0;
   simple_bus sb_intf(clk); // Instantiate the interface
   mod m (sb_intf.master) ;

   always #5 clk=!clk;
                 
   initial begin
      #50 $finish;                  
   end                                  

endmodule
Process Control in System Verilog


module test;

  task automatic do_n_way( int N );
  process job[] = new [N];
  foreach(job[j]) begin
    fork
      automatic int k = j;
      begin
        job[k] = process::self();      
        #(5+k);
      end
    join_none
  end

  foreach(job[j]) // wait for all processes to start
    wait( job[j] != null);

  $display("All JOB Started !!",$time);

    job[1].suspend();
 
    job[1].resume();  

    job[1].await();
 
    foreach(job[j]) begin
      if(job[j].status != process::FINISHED )
        job[j].kill();  
    end  
  endtask

  initial begin
    do_n_way(3);
  end

endmodule

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
/////////////////////Fork JoinExample///////////////////////////
//////////////////////////////////////////////////////////////////////////
module test;

  task automatic do_n_way( int N );
  process job[] = new [N];
  foreach(job[j]) begin
    fork
      automatic int k = j;
      begin
        job[k] = process::self();      
        #(5+k);
      end
    join_none
  end

  foreach(job[j]) // wait for all processes to start
    wait( job[j] != null);

  $display("All JOB Done !!",$time);

    job[1].suspend();
    #15
    job[1].resume();  

    job[0].await();
    //job[1].await();
 
    foreach(job[j]) begin
      if(job[j].status != process::FINISHED )begin
        $display("JOb[%0d] killed with status::%0d @%t",j,job[j].status,$time);
        job[j].kill();  
      end
    end  
 
    foreach(job[j]) begin
      $display("JOb[%0d] status ::%0d  @%t",j,job[j].status,$time);
    end
 
  endtask

  initial begin
   fork  //Try using without fork
    do_n_way(3);
    do_n_way(4);
   join
  end

endmodule


//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////AWAIT Example///////////////////////////
//////////////////////////////////////////////////////////////////////////
module test;

  task automatic do_n_way( int N );
  process job[] = new [N];
  foreach(job[j]) begin
    fork
      automatic int k = j;
      begin
        job[k] = process::self();      
        #(5+k);
      end
    join_none
  end

  foreach(job[j]) // wait for all processes to start
    wait( job[j] != null);

  $display("All JOB Done !!",$time);

    job[1].suspend();
    #15
    job[1].resume();  

    job[0].await();
    job[1].await();
 
    foreach(job[j]) begin
      if(job[j].status != process::FINISHED )begin
        $display("JOb[%0d] killed with status :: ",j,job[j].status);
        job[j].kill();  
      end
    end  
 
    foreach(job[j]) begin
      $display("JOb[%0d] status :: ",j,job[j].status);
    end
 
  endtask

  initial begin
    do_n_way(3);
  end


endmodule  

Monday, 11 April 2016

Binding Multiclock Domain Assertion

///////////////////////////////////////////////////////////
/////////////////// DFF module/////////////////////
///////////////////////////////////////////////////////////
module dff(
           input wire din,clk,rstn,
           output reg qout
          );
         
always@(posedge clk,negedge rstn)
  begin
    if(~rstn)
      qout<=0;
    else
      qout<=din;
  end
endmodule

///////////////////////////////////////////////////////////
/////////////////// DUT module////////////////////
///////////////////////////////////////////////////////////
module DUT (
            input rst1,rst2,clk1,clk2,in1,in2,in3,
            output  out
           );  

  wire qout1,qout2,and_out;

  dff dff1(.din(in1),.clk(clk1),.rstn(rst1),.qout(qout1));  
  assign and_out=qout1 & in2;

  dff dff2(.din(and_out),.clk(clk2),.rstn(rst2),.qout(qout2));  
  assign out=qout2 | in3;          

endmodule

///////////////////////////////////////////////////////////
/////////////////// ASSERTION Module////////
///////////////////////////////////////////////////////////
module dut_assertions(
                      input  wire rst1,rst2,clk1,clk2,in1,in2,in3,out
            );
reg val1,val2,val3;
 
 //sequence seq1(val1,val2); 
  //@(posedge clk1)
  //(1'b1,val1=in1) ##0(1'b1,val2=in2);
 //endsequence

  sequence seq1;
   (1,assign12_t);
  endsequence

 //sequence seq2(val3);
  //@(posedge clk2)
  //(1'b1,val3=in3);
 //endsequence

  sequence seq2;
   (1,assign3_t);
  endsequence

//property p(val1,val2,val3);
 //(@(posedge clk1) disable iff (!rst1) (rst1 throughout seq1(val1,val2))) |->  (@(posedge clk2) disable iff (!rst2) (rst2 throughout seq2(val3)));
//endproperty

  property p;
    (@(posedge clk1)  (rst1 throughout seq1)) ##1  (@(posedge clk2) (rst2 throughout seq2));
  endproperty

//assert property (p(val1,val2,val3))  begin
  assert property (p)  begin
///////////////////////////////////////////////////////////
//// Assertion Action Block Verifying DUT functionality////
///////////////////////////////////////////////////////////
  case({val1,val2,val3})
    3'b000,3'b010,3'b100 :
       begin
         if(!out)
           $display("DUT check passed for %b Out1=%b",{val1,val2,val3},out);
         else
           $error("DUT check failed for %b Out1=%b",{val1,val2,val3},out);    
       end
    3'b001,3'b011,3'b101,3'b110,3'b111 :
       begin
         if(out)
           $display("DUT check passed for %b Out2=%b",{val1,val2,val3},out);
         else
           $error("DUT check failed for %b Out2=%b",{val1,val2,val3},out);    
        end
   endcase
end
else  begin
  $error("Assertion failed");    
end
/////////////////////////////////////////////////////////////
////// Task holding values of in1 and in2////
/////////////////////////////////////////////////////////////
 task assign12_t;
   $display($time,"val1:%b ,val2:%b ,val3:%b",in1,in2,in3);
   val1=in1;
   val2=in2;  
 endtask
/////////////////////////////////////////////////////////////////
//////// Task holding values of in3 /////////////////
//////////////////////////////////////////////////////////////////
 task assign3_t;
   $display($time,"val1:%b, val2:%b ,val3:%b",in1,in2,in3);
   val3=in3;  
 endtask
   
endmodule
 
/////////////////////////////////////////////////////////////////////////
/////Binding DUT and ASSERTION Module//////////
//////////////////////////////////////////////////////////////////////////
module bind_assertion ();
  //bind DUT dut_assertions DUT_ASSERT(.rst1(rst1),.rst2(rst2),.clk1(clk1),.clk2(clk2),.in1(in1),.in2(in2),.in3(in3),.out(out));
  bind DUT dut_assertions DUT_ASSERT(.*);

endmodule


///////////////////////////////////////////////////////////////////////////
////////////////// DUT TEST MODULE ////////////////////////
///////////////////////////////////////////////////////////////////////////
module test;
  reg rst1,rst2,clk1,clk2,in1,in2,in3;
  wire out;              

  DUT dut_inst(.rst1(rst1),.rst2(rst2),.clk1(clk1),.clk2(clk2),.in1(in1),.in2(in2),.in3(in3),.out(out));
  //DUT dut_inst(.*);

always #5 clk1=~clk1;
always #10 clk2=~clk2;

initial begin
  clk1=0;clk2=0;
  rst1=1;rst2=1;
  in1=0;in2=1;in3=1;
  #10 rst2=0;

  #15 rst2=1;
  #10 rst1=0;
  #15 rst1=1;
  in1=0;in2=0;in3=0;
  #50 $finish;
end    
endmodule






Wednesday, 6 April 2016

 Generating Unique Random Values for Array.
 [Supported in IEEE 1800-2012] 


1). Randomizing all 32 members of array ,each member with 16 bit width

   class  random_unique_array_c;
       rand bit [15:0] uniq_arr [31:0];
       constraint  unique_cnstnt {unique {uniq_arr };}
   endcalss : random_unique_array_c


2). Randomizing all 32 members of array ,each member with 16 bit width, with exclusion of  some values.

   class  random_unique_array_c;
       rand bit [15:0] uniq_arr [31:0];
               bit [15:0] exclude_val [ ] = {3,6,9};
       constraint  unique_cnstnt {unique {uniq_arr,exclude_val,12 };}   //uniq_arr will not have values
   endcalss : random_unique_array_c                                                     //3,6,9,12



For more info see IEEE 1800-2012 LRM  section  18.5.5 "Uniqueness constraints"