Verification Guild
A Community of Verification Professionals

 Create an AccountHome | Calendar | Downloads | FAQ | Links | Site Admin | Your Account  

Login
Nickname

Password

Security Code: Security Code
Type Security Code
BACKWARD

Don't have an account yet? You can create one. As a registered user you have some advantages like theme manager, comments configuration and post comments with your name.

Modules
· Home
· Downloads
· FAQ
· Feedback
· Recommend Us
· Web Links
· Your Account

Advertising

Who's Online
There are currently, 71 guest(s) and 1 member(s) that are online.

You are Anonymous user. You can register for free by clicking here

  
Verification Guild: Forums

 Forum FAQForum FAQ   SearchSearch   UsergroupsUsergroups   ProfileProfile  ProfileDigest    Log inLog in 

Processor Verification Methodolgies
Goto page Previous  1, 2, 3, 4  Next
 
Post new topic   Reply to topic    Verification Guild Forum Index -> Main
View previous topic :: View next topic  
Author Message
war_isbest
Senior
Senior


Joined: Dec 05, 2007
Posts: 21

PostPosted: Mon Jan 21, 2013 12:49 am    Post subject: Instruction sequence generator Reply with quote

Dear friends,
I need some help in constrainsts.
I created a base class inst_class with all properties defined by the instruction architecture and a method to form the instruction based on opcode type selected (eg. arith, control etc).
I created a scenario class which has a dynamic array of the inst_class named items[].
the base scenario class is extended by common instruction scenario class which has constraints to create valid sequences.

the common instruction scenario class is extended by dep_scenario which has more constraints to force instruction with dependency.
the common instruction scenario class is extended by arith_scenario which has more constraints to generate only arithmetic instruction.

In the ENV class i have a queue(named scenario_c) of type common instruction scenario.

Now the generation happens like this.
Program block creates few objects of type arith_scenario, dep_scenario and common_scenario and pushes down the queue.

In the ENV class i have run task which goes like this:

foreach scenario_c[i]
for (j=0;j<scenario_c.length<j++)
begin
scenario_c[i].items[j]=new;
scenario_c[i].items[j].randomize();
scenario_c[i].items[j].form_instr();
end


Now he problem is the constriaints of arith_scenario, dep_scenario and common_scenario are not passed to inst_class.

How can i do that.
Plz help
Back to top
View user's profile
war_isbest
Senior
Senior


Joined: Dec 05, 2007
Posts: 21

PostPosted: Wed Jan 23, 2013 11:42 pm    Post subject: plz help Reply with quote

Dear friends kindly reply.
Back to top
View user's profile
miket
Senior
Senior


Joined: Jan 12, 2004
Posts: 31
Location: Ottawa, Ontario, Canada

PostPosted: Mon Jan 28, 2013 8:04 am    Post subject: Reply with quote

Since we're shameless plugging papers here, I will put in a plug for a collegaue's paper on this topic. It was presented at SNUG, so this link will not work unless you are a Synopsys customer:
https://www.synopsys.com/news/pubs/snug/2012/canada/mc1_paper_elms.pdf
Alas, there is little discussion about the Reference Model in this paper. My strong recommendation there would be to create a TLM at the highest level of abstraction you can get away with. (Actually, that's my default position on all Reference Models, but doubly so in this case.)

--mike
Back to top
View user's profile Send e-mail Visit poster's website
Hans
Senior
Senior


Joined: Dec 17, 2003
Posts: 50
Location: Ottawa, Ontario, Canada

PostPosted: Mon Jan 28, 2013 9:02 am    Post subject: Re: Instruction stream generation Reply with quote

Rather interesting to see that this thread continues to be alive.

I don't know the paper miket just shamelessly plugged as I have no access to it, but it's from a trusted source (hey miket, long time no see Wink ) so you should go get it to help with your instruction stream modeling challenges.

Safe from that, it sounds pretty conclusive that your current model does not enable polymorphism to have your inst_class take on the constraints of the derived scenario classes. But you would have to share additional code details (all class implementations you mention) to pinpoint the problem.

- HvdS
Back to top
View user's profile
war_isbest
Senior
Senior


Joined: Dec 05, 2007
Posts: 21

PostPosted: Sun Feb 03, 2013 1:40 pm    Post subject: Kindly put the paper Reply with quote

Dear mike,
Kindly provide a direct link of the paper or email me at
waris.mohammad@gmail.com
Back to top
View user's profile
war_isbest
Senior
Senior


Joined: Dec 05, 2007
Posts: 21

PostPosted: Sun Feb 03, 2013 1:43 pm    Post subject: Reply with quote

Dear hans,
I may nt be able to put the whole code.
Is it ok if i put the structure of each class?
Back to top
View user's profile
Hans
Senior
Senior


Joined: Dec 17, 2003
Posts: 50
Location: Ottawa, Ontario, Canada

PostPosted: Sun Feb 03, 2013 1:50 pm    Post subject: Reply with quote

Just putting the structure will in this particular case probably not suffice. You would have to include the relevant class data members, i.e. those involved or 'should-be' involved in some sort of 'factory pattern/override' applied to enable the polymorphism
Back to top
View user's profile
war_isbest
Senior
Senior


Joined: Dec 05, 2007
Posts: 21

PostPosted: Mon Feb 04, 2013 11:39 pm    Post subject: code snippets Reply with quote

Code:
///inst_class.sv//////
`include "../tb/verilog/typedef_operation.sv"
class inst_class;
 static int count = 0;
  int id;///an id for each instruction 
rand kind_e kind;
rand opcode_type_e opcode_type;

rand logic[1:0] op;
rand logic[3:0] cond;
rand logic[2:0] op2;
rand logic[5:0] op3;
rand logic[8:0]opf;
rand logic[8:0] opc;
//and many more properties

constraint opcode_type_valid{
 

(opcode_type==CALLt)-> kind inside {CALL};
(opcode_type==SETHIt)-> kind inside {SETHI};
(opcode_type==CONTROL)-> kind inside {BA,BEQ,Bicc,FBFCC};
(opcode_type==ALU)-> kind inside {ADD,ADDX,ADDcc,ADDXcc,TADDcc,TADDccTV,SUB,SUBcc,
              SUBX,SUBXcc,AND,ANDcc,OR,ORcc,XOR,XORcc,
              ANDN,ANDNcc,ORN,ORNcc,XNOR,XNORcc,SLL,SRL,SRA,JMPL};
(opcode_type==FPU)-> kind inside {FADDS};
(opcode_type==LD_ST)-> kind inside {LDW,STW};
(opcode_type==MULTIC)-> kind inside {UMUL,SMUL,UMULcc,SMULcc};

     }

 function new ();//(virtual pipe_if ifc);
  //this.ifc=ifc;
  id = count++;
 
  endfunction:new


constraint legal_ALU

{
if (op==2'b10)                       
{                         
(kind == ADD) -> op3== 6'h00;
kind == AND -> op3 == 6'h01;
kind == OR  -> op3 == 6'h02;
kind == XOR ->  op3 == 6'h03;
kind == SUB -> op3 == 6'h04;
kind == ANDN ->  op3 == 6'h05;
kind == ORN ->  op3 == 6'h06;
kind == XNOR ->  op3 == 6'h07;
//etc etc
}     
}

task form_inst;
  if(opcode_type==CALLt)instr={2'b01,disp30};
  else if (opcode_type==CONTROL )instr={2'b00,a_bit,cond,op2,disp22};
  else if(opcode_type==ALU )
    begin
    instr=((i_bit)) ?
    {2'b10,rd,op3,rs1,i_bit,simm13}:
    {2'b10,rd,op3,rs1,i_bit,asi,rs2};
      if(op3==6'b111001 || op3==6'b111000)///JMPL and RETT
      begin
     $info("operand1+operand2=%h",(operand1+ operand2));
       end
      if(kind==JMPL)
        begin
        instr=((i_bit)) ?// or LD_ST add later
             {2'b10,rd,6'h38,rs1,i_bit,simm13}:
             {2'b10,rd,6'h38,rs1,i_bit,asi,rs2};
         `ifdef _DEBUG
          $info("JMPL selected");
        `endif   
        end
    end
  else if (opcode_type==SETHIt)
  begin
    instr={2'b00,rd,3'b100,imm22};//sethi
  end   
  else if(opcode_type==LD_ST)instr={2'b11,rd,op3,rs1,i_bit,asi,rs2};
  else if(opcode_type==FPU)instr={2'b10,rd,6'h34,rs1,opf,rs2};//op3=h35 for fpcmp
  else instr=32'h01000000;//nop
  $info("formed instruction=%h id=%d kind=%s  opcode_type=%s",instr,id,kind,opcode_type);

endtask:form_inst 
endclass


///scenario.sv///////
`include "../tb/verilog/inst_class.sv"
class instruction_scenario extends inst_class;
rand int unsigned scenario_kind;
rand int unsigned length=50;
rand inst_class items[];
rand int unsigned repeated;


function int unsigned define_scenario (string name,
                                       int unsigned max_len);
$info("secenario is %s",name);
this.length=max_len;                                       
endfunction
 
endclass



//////////////////common_instruction_scenario.sv///
`include "../tb/verilog/scenario.sv"
class common_instruction_scenario extends instruction_scenario;

constraint three_CTI_bad

{
foreach(items[i]){
                   if(i>1){
                           if((items[i].opcode_type==CONTROL) &&  (items[i-1].opcode_type==CONTROL))
                           {
                           items[i-2].opcode_type!=CONTROL;
                           }
                         
                      }
             }

}

endclass
//////////////////////////////////////////////////////////


///////dep_scenario.sv//////////
`include "../tb/verilog/common_scenario.sv"
class dep_scenario extends common_instruction_scenario;
 
int SCN_MORE_DEP;
int base_addr, addr_range;
constraint more_dep_scn_valid {
  //check below line 15/10/12
   if (scenario_kind == SCN_MORE_DEP) {
     
      repeated == 0;         length == 10;
      foreach (items[i]) {
         items[i].rd inside {[base_addr : base_addr+addr_range]};
         items[i].rs1 inside {[base_addr : base_addr+addr_range]};
         items[i].rs2 inside {[base_addr : base_addr+addr_range]};
      }
   }
}

//constraint depcheck
//{
// items[23].kind ==BA ;
//}


function new;
  super.new();
    this.base_addr = 0;
   this.addr_range = 4;
 
   this.SCN_MORE_DEP = define_scenario ("SCN_MORE_DEP", 40);
endfunction


function void pre_randomize ();
   super.pre_randomize();
   this.base_addr = 0;
   this.addr_range = 4;
endfunction


endclass

class arith_only_scn extends common_instruction_scenario;
   int SCN_ARITH_ONLY;
   constraint arith_only_scn_valid {
      if (scenario_kind == SCN_ARITH_ONLY) {
         repeated == 0;
         length inside {[5:10]};
         foreach (items[i]) {
            foreach (items[i]) {
               items[i].opcode_type == ALU;
            }
         }
      }
   }
   function new ();
      super.new();
      this.SCN_ARITH_ONLY = define_scenario ("SCN_ARITH_ONLY", 30);
   endfunction
endclass

//////////////////////////////////
/////////////////////////////////
///env.sv/////////
//`include "../tb/verilog/inst_class.sv"
//`include "../tb/verilog/instr_packet.sv"
//`include "../tb/verilog/common_scenario.sv"
`include"../tb/verilog/drv_inst.sv"
//`include"../tb/verilog/drv.sv"
`include"../tb/verilog/interfaces.sv"
`include"../tb/verilog/regfile_mon.sv"
`include"../tb/verilog/checker_sb.sv"
class env;
  instruction_scenario scenario_set[$];
  static int number_comm_scn;
virtual pipe_if ifc;
virtual model_if ifm;
event handshake;
mailbox mb_g2d,regf2sb,mod2sb;
drv_inst drv;
regfile_mon regmon;
checker_sb checkb;


//drv dv;
static int mbcnt,basic_scn_no;
function new(virtual pipe_if ifc,virtual model_if ifm,mailbox mod2sb);
  mb_g2d=new;
  regf2sb=new;
  this.mod2sb=mod2sb;// initialized in pgm block
  this.ifc=ifc;
  this.ifm=ifm;
  drv=new(ifc,ifm,mb_g2d);
  regmon=new(ifc,regf2sb );
  checkb=new(ifc,regf2sb,mod2sb);
  mbcnt=0;
  //drv=new(ifc,ifm);
  basic_scn_no=$urandom_range(5,100);
endfunction



task config_proc;
  inst_class i1,i2,i3,i4,i5;
  number_comm_scn=$urandom_range(1,100);
  i1=new;
  i2=new;
 
 // some code to config the processor for a mode eg. cache disable
//
//
 
 $info("configuration_over");
endtask:config_proc

task generator_good( mailbox mbx);
  inst_class instruction;
   
   
  foreach(scenario_set[i])
   begin
     scenario_set[i].items=new[scenario_set[i].length];
     for(int j=0;j<scenario_set[i].length;j++)
     scenario_set[i].items[j]=new;
   end
   
    foreach(scenario_set[i])   
   assert(scenario_set[i].randomize()) else $fatal(0, "Instruction::randomize failed"); 
   
foreach(scenario_set[i])
  begin
     for(int j=0;j<scenario_set[i].length;j++)
     begin
     scenario_set[i].items[j].form_inst;
     $display("GEN: Sending instruction with id=%d", scenario_set[i].items[j].id);
    `ifdef _ALUTEST///when verifying ALU
     if(scenario_set[i].items[j].opcode_type==ALU )
      begin
       `ifdef _DEBUG
        $info("entering ALU thread");
        $info("drive instruction =%h with op1= %h and op2 =%h and rd=%d  and id=%d",scenario_set[i].items[j].instr,scenario_set[i].items[j].operand1,scenario_set[i].items[j].operand2,scenario_set[i].items[j].rd,scenario_set[i].items[j].id);
        `endif 
       
      mbx.put(scenario_set[i].items[j]);
      `ifdef _DEBUG
        $info("sending ALU instruction");
       `endif   
      end
    else mbx.put(scenario_set[i].items[j]);             // Send transaction to driver
    `endif
     end
end
endtask   
 
 
task run;
 
  generator_good(mb_g2d);
  //gen.run_rcv(handshake);
 
endtask:run
task runrcv;
 
  drv.run_rcv;
  //dv.drv_fetch(handshake);
 
endtask:runrcv



endclass
////////////////////////////////////


//////pgm_pipe.sv////
`timescale 1ns/1ns

//`include"../tb/interfaces.sv"   

//`include"$HOME_32b_hdl/pipe_mod.sv"
`include"../tb/verilog/instr_packet.sv"
`include "../tb/verilog/dep_scenario.sv"
`include "../tb/verilog/proc_model.sv"
`include "../tb/verilog/env.sv"

program automatic pgm_pipe (
                  model_if if_d,pipe_if pr   
                  );

   
 
   bit termination_condition=1'b0;

   //pipe_ir mod;
   
    mailbox mod2sb;
   decode_model mod_proc;
   env env_p;
   arith_only_scn scn_arith;
   common_instruction_scenario  basic_scenario ;
   dep_scenario scn_dep;
   initial begin : execution_of_main_tb   
  scn_arith=new;
    //init_regs_scn                    scn_regs   =  new;
   basic_scenario = new;
   scn_dep=new;
   //mod=new(pr,if_d);
   mod2sb=new;
   mod_proc=new(pr,if_d,mod2sb);
   env_p=new(pr,if_d,mod2sb);
//   repeat (5) begin
   env_p.scenario_set.push_back (scn_dep);
  // to give the scn_arith scenario a little more weight \u263a
//  end
  // foreach(env_p.scenario_set[i])env_p.scenario_set[i]=new
  // repeat (10) begin
        env_p.scenario_set.push_back (scn_arith);
  // end
   basic_scenario.length=100;
   repeat (env_p.basic_scn_no) begin
        env_p.scenario_set_c.push_back (basic_scenario);
       
   end
   
   
   
   wait(pr.reset);
   //fork
   while(1)
  begin
  repeat (1) @ (posedge pr.pl_clk);
 // fork  //uncomment for cheker
  fork
  mod_proc.run;
  env_p.runrcv;
 
  join
 // env_p.checkb.compare; //uncomment for cheker
 // join_any //uncomment for cheker
  if(termination_condition)
  break;
 
//  join_any
end

  $display("all instructions processed");   
   
   $display("-----end of test------");
   $finish;

end : execution_of_main_tb   
initial
begin
  while(1)
  begin
  repeat (1) @ (posedge pr.pl_clk);
   
   @(negedge (pr.d_en_ip))   env_p.regmon.run_mon;
 
   
   
  if(termination_condition)
  break;
  end

end

//////checker

initial
begin
wait(pr.reset);
  while(1)
  begin
  repeat (1) @ (posedge pr.pl_clk);
   env_p.checkb.compare;
  if(termination_condition)
  break;
  end

end





initial begin
termination_condition=1'b0;
#1000000
termination_condition=1'b1;
end

initial
 begin

  pr.reset=1'b0;
  #100
  pr.reset=1'b1;//reset removal
  env_p.config_proc;
   $display("-----start of test------");
 
//  while(1)
//  begin
//  repeat (1) @ (posedge pr.pl_clk); 
  env_p.run;
  $info("instruction generation completed");
//  if(termination_condition)
//  break;
//  end   
   
 
end

endprogram : pgm_pipe






Back to top
View user's profile
Hans
Senior
Senior


Joined: Dec 17, 2003
Posts: 50
Location: Ottawa, Ontario, Canada

PostPosted: Tue Feb 05, 2013 9:16 am    Post subject: Reply with quote

I just had a look at your code. Here are few comments for you to ponder, followed at the end by what I think is the crux of your problem.

First, this instruction and instruction scenario generation code much resembles the (original) VMM scenario generation solution. Whether derived from it or not, it would behoove you to consult the documentation on VMM scenario generation. It includes a description and examples on how to override scenario items and scenarios in the basic scenario descriptor and generator classes. There is also a 2007 SNUG paper on the topic co-authored by myself - quite a good paper in my own humble opinion. You can get it from Synopsys from their SNUG archives, or a quick Google on the title returns the following links:

http://www.docin.com/p-237268624.html
http://bbs.eetop.cn/thread-257345-1-1.html

Secondly, and more concretely with respect to your code, a few observations:

Why does your instruction_scenario class (the base scenario class) extend from inst_class (the 'item' class)? The former models a sequence of items but is not an item itself. It does not seem to be harmful in the end but does add unnecessary overhead to your scenario classes.

You do a `include on common_scenario.sv somewhere. Is this a typo and should it be `include common_instruction_scenario.sv? This brings me to the question as to whether this code provided actually compiles and runs (except for the proper functioning of the constraints).

Lastly, and to your original question, if you reconsider your code from the env class:

Code:

foreach scenario_c[i]
for (j=0;j<scenario_c.length<j++)
begin
scenario_c[i].items[j]=new;
scenario_c[i].items[j].randomize();
scenario_c[i].items[j].form_instr();
end


then you should realize that you are only ever randomizing individual items (scenario_c[i].items[j].randomize()) outside of the scenario context and thus not taking in scnenario level constraints.

To accomplish what you want you need to randomize at the scenario level, i.e. scenario_c[i].randomize(). This does require that you 'prefill' the items array for any given scenario so that it has length > 0 and each item in it is actually not null (i.e. is newed). You do this in fact in your 'generator_good' task, so seeing the name of this task you may have already figured out the remedy to your problem.

So this is the way to do it. Now, their are better (in terms of reuse etc.) ways to organize your instruction scenario generation code. Again for this refer to the scenario or sequence generator solutions in the different verification methodologies like VMM, or much more prevalent these days of course, the UVM. If you are really stuck on creating your home grown solution, then consider a plain SystemVerilog solution with comparable reuse characteristics described in a DVCon paper from a few years back, "Advanced Stimulus Generation Using Scenarios". You can get it from tjhis link - http://www.xtreme-eda.com/downloads-technical-library.html#section1

I apologize (not really, Wink) for the couple of shameless plugs I threw in here (the paper references), though I do honestly think these are very decent paper references on the topic.

If you have any more questions and would like to discuss in more detail, please indicate and we can continue communicating privately.

Regards - Hans
Back to top
View user's profile
war_isbest
Senior
Senior


Joined: Dec 05, 2007
Posts: 21

PostPosted: Wed Feb 06, 2013 12:38 am    Post subject: plz email the pdfs Reply with quote

Can you please email the pdf of the first 2 links.

Yes this code is inspired by a paper from SNUG for which i got the link in this forum.
Thanks for pointing out the randomization mistakes.

Regarding moving to VMM/UVM , it may take some time for me as i have just started learning UVM material from verificationacadamy.com.
No trainings yet.

regards
waris
email: waris.mohammad@gmail.com
Back to top
View user's profile
Hans
Senior
Senior


Joined: Dec 17, 2003
Posts: 50
Location: Ottawa, Ontario, Canada

PostPosted: Wed Feb 06, 2013 7:22 am    Post subject: Reply with quote

I'll send you the PDFs privately.

Hans
Back to top
View user's profile
war_isbest
Senior
Senior


Joined: Dec 05, 2007
Posts: 21

PostPosted: Thu Feb 07, 2013 12:23 am    Post subject: randomization failed Reply with quote

Dear friends,
I changed the code to scenario_set[i].randomize().
now the simulator (questasim 10.0b) gives internal error just before randomization.

Are there any conflicting constraints in my code ??
Back to top
View user's profile
Hans
Senior
Senior


Joined: Dec 17, 2003
Posts: 50
Location: Ottawa, Ontario, Canada

PostPosted: Thu Feb 07, 2013 7:09 am    Post subject: Reply with quote

Your nested foreach constraint for arith scenarios looks off; there is no 2nd iterator.

Other than that it is difficult to see without running oneself where things might actually be going wrong - could be various places - happy debug!
Back to top
View user's profile
war_isbest
Senior
Senior


Joined: Dec 05, 2007
Posts: 21

PostPosted: Wed Feb 13, 2013 2:42 am    Post subject: right method of writing a constraint Reply with quote

Dear friends

Which of the below method is correct for writing a constraint if i want CALL-> ALU sequence?
Code:

foreach(items[i])
{
if(i%2 ){
         items[i].opcode_type=CALL;
         items[i+1].opcode_type=ALU;
         }
 
}


OR
Code:


foreach(items[i])
{
if(i%2 ){
         items[i].opcode_type=CALL;
         foreach(items[j] && j=i+1)         
         {
          items[j].opcode_type=ALU;
         }
        }
 
}

Back to top
View user's profile
Hans
Senior
Senior


Joined: Dec 17, 2003
Posts: 50
Location: Ottawa, Ontario, Canada

PostPosted: Wed Feb 13, 2013 7:12 am    Post subject: Reply with quote

The first one looks fine, but will not work I think for an items array with odd length. You'd have to add the condition that "items.size() % 2 == 0".

The second constraint should work I think.

Your constraint solver will have debug modes that you can use to help resolve solver failures
Back to top
View user's profile
Display posts from previous:   
Post new topic   Reply to topic    Verification Guild Forum Index -> Main All times are GMT - 5 Hours
Goto page Previous  1, 2, 3, 4  Next
Page 3 of 4

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Verification Guild © 2006 Janick Bergeron
Web site engine's code is Copyright © 2003 by PHP-Nuke. All Rights Reserved. PHP-Nuke is Free Software released under the GNU/GPL license.
Page Generation: 0.277 Seconds