这次我们介绍 transaction class svidTrans extends vmm_data; // 定义公用的静态消息接口 static vmm_log log = new("svidTrans", "class"); // 定义枚举类型 typedef enum bit[4:0] {SETVID_FAST=1, SETVID_SLOW, SETVID_DECAY, SETPS, SETREGADR, SETREGDAT, GETREG} cmd_e; typedef enum bit[1:0] {ERROR=2'b00, NAK=2'b01, ACK=2'b10, REJECT=2'b11} ack_e; //******************************************************** // Properity //******************************************************** // 定义随机的函数成员 //packet filed rand bit[2:0] sop; rand bit[3:0] address; rand bit[4:0] command; rand bit[7:0] payload; rand bit parity; rand bit[2:0] eop; // 由于约束中要用到 CFG 值,而transaction的 new函数必须干净,因此引入CFG的OBJ handler // 当然我们也可以在transaction的扩展类中引入此handler,然后附加相关的constraint //static SysCfg and RegCfg object handler static svidREGCfg reg_cfg; //dut response bit [1:0] resp_ack='b1; bit [7:0] resp_data='b1; bit resp_parity='b1; // delayed virtual clock cycle rand int unsigned delay_cycles; // preambel before sop rand int unsigned preamble_bits; // vclk stop after n bit is tranferred rand int unsigned vclk_stop_after_n_bits; // 控制各个error的子开关 // switches rand bit subsw_adr_error; rand bit subsw_cmd_error; rand bit subsw_pld_error; rand bit subsw_eop_error; rand bit subsw_clk_stop; rand bit subsw_add_delay; //******************************************************** // task and function //******************************************************** extern function new(); //拷贝transaction内容到指定的handler指向的内存区域,或者生成一个新的区域和handler extern virtual function vmm_data copy(vmm_data to=null); //显示transaction的内容,以便调试和用fsdbLog extern virtual function string psdisplay(string prefix=""); //虽然不是虚函数但是可以在扩展类中覆盖post_randomize()的定义 extern function void post_randomize(); //******************************************************** // Basic Constraints //******************************************************** constraint valid_delay; constraint valid_preamble; constraint valid_clkstop; constraint valid_sop; constraint valid_adr; constraint valid_cmd; constraint valid_eop; constraint valid_payload; endclass 在testcase中我们继续定义了transaction的扩展类,并以此作为蓝本。 class myTrans extends svidTrans; /* 控制error injection 几率 constraint valid_switches { subsw_adr_error dist {0:=9, 1:=1}; subsw_cmd_error dist {0:=9, 1:=1}; subsw_pld_error dist {0:=9, 1:=1}; subsw_eop_error dist {0:=9, 1:=1}; subsw_clk_stop dist {0:=5, 1:=1}; subsw_add_delay dist {0:=2, 1:=1}; } */ /* 根据data_id控制并生成特定的senario constraint data_id_cmd_valid { if(data_id==0) command==GETREG; else if(data_id==1) command==SETREGADR; else if(data_id==2) command==SETREGDAT; else if(data_id==3) command==SETVID_FAST; else if(data_id==4) command==SETVID_SLOW; else if(data_id==5) command inside {SETPS,SETVID_DECAY}; } */ /* 用post_randomize全定制senario function void post_randomize(); if(data_id==0) begin address=0; command=GETREG; payload=8'h10; vclk_stop_after_n_bits=36; end if(data_id==1) begin address=1; command=GETREG; payload=8'h10; vclk_stop_after_n_bits=36; end if(data_id==2) begin address=1; command=GETREG; payload=8'h1c; vclk_stop_after_n_bits=36; end if(data_id==3) begin address=1; command=GETREG; payload=8'h11; vclk_stop_after_n_bits=36; end super.post_randomize(); endfunction */ endclass