Basic Setup to Use Vera module load synopsysvera
Basic Setup to Use Vera • module load synopsys/vera • Documentation is in: /opt/synopsys/vera/X-2005. 06 -1/vera_v. X-2005. 061_sparc. OS 5/doc • user_guide. pdf is a good starting place
The Standard Vera Testbench Structure • There will be files for each block
Running Vera module adder(in 0, in 1, out 0, clk); input[7: 0] in 0, in 1; input clk; output[8: 0] out 0; reg[8: 0] out 0; always@(posedge clk) begin out 0 <= in 0 + in 1; endmodule • Making a testbench for an adder module • First, invoke the template generator > vera -tem -t adder -c clk adder. v
Template Generator Results • The Interface File (adder. if. vrh) • Defines the interface beween the DUT and the Vera program // adder. if. vrh #ifndef INC_ADDER_IF_VRH #define INC_ADDER_IF_VRH interface adder{ output [7: 0] in 0 OUTPUT_EDGE OUTPUT_SKEW; output [7: 0] in 1 OUTPUT_EDGE OUTPUT_SKEW; input [8: 0] out 0 INPUT_EDGE #-1; input clk CLOCK; } //end of interface adder #endif • Modify if additional signals need to be controlled/observed
More Template Generator Results • The test_top File (adder. test_top. v) • Instantiates top-level testbench (Vera shell + DUT) vera_shell vshell( //Vera shell file. . System. Clock(System. Clock), . adder_in 0 (in 0), . adder_in 1 (in 1), . adder_out 0 (out 0), . adder_clk (clk), ); ‘ifdef emu /*DUT is in emulator, so not instantiated here*/ ‘else adder dut(. in 0 (in 0), . in 1 (in 1), . out 0 (out 0), . clk (clk), ); ‘endif
More Template Generator Results • The Vera File (adder. vr. tmp -> adder. vr) • Contains the Vera code which describes the testbench #define OUTPUT_EDGE PHOLD #define OUTPUT_SKEW #1 #define INPUT_EDGE PSAMPLE #include <vera_defines. vrh> // define any interfaces, and verilog_node here #include "adder. if. vrh” program adder_test { // Here is the main Vera code }
More Template Generator Results • The Vera Shell File (adder_shell. v) • Verilog code which communicates with the Vera testbench Module vera_shell( System. Clock, adder_in 0, adder_in 1, adder_out 0, adder_clk ); input System. Clock; output [7: 0] adder_in 0; output [7: 0] adder_in 1; input [8: 0] adder_out 0; inout adder_clk; wire System. Clock; // Other components of this file are not listed here
Running Vera, Remaining Steps • Compile the adder. vr file vera -cmp -vlog adder. vr • Create the executable vcs -vera adder. v adder_shell. v adder. test_top. v • Run the simulation simv +vera_load=adder. vro
Running Vera, The Big Picture
Randomization in Vera • random() returns a random integer (urandom, random_range, rand_poisson, etc. ) • randomize() method built into all classes will randomly fill all rand properties of an object class Foo { rand integer x; } class Bar { rand integer y; } program main { Foo foo = new(); Bar bar = new(); integer z; void = foo. randomize(); void = bar. randomize(); } • randomize() calls itself recursively on attribute classes
Random Instruction Execution • randcase specifies a block of statements, one of which is executed randomly randcase { weight 1 : statement 1 weight 2 : statement 2. . . weight. N : statement. N } randcase{ 10: i=1; 20: i=2; 50: i=3; }
Constraint Based Randomization • constraints are parts of a class, just like functions, tasks, and properties (attributes) • Constraints define a relationship between variables, at least one of which should be random class Bus{ rand reg[15: 0] addr; rand reg[31: 0] data; constraint word_align {addr[1: 0] == ‘ 2 b 0; } }
Randomize with Constraints • Each call to randomize fills new random data into each rand property according to the constraints of the class program test{ Bus bus = new; repeat (50){ integer result = bus. randomize(); if (result == OK) printf("addr = %16 h data = %32 hn” , bus. addr, bus. data); else printf("Randomization failed. n"); } }
Random Sequence Generation • A (context free) language is defined as a set of production rules • Production rules are selected randomly when there is choice randseq (production_name){ production_definition 1; production_definition 2; . . . production_definition. N; }
Random Sequence Generation • Non-terminals are replaced using production rule • Generation is complete when only terminals remain Production rule example: All possible sentences: main : top middle bottom; top : add | dec; middle : popf | pushf; bottom : mov; • Great for generating instruction sequnces • Weights can be added top : &(2) add | $(1) dec; add popf mov add pushf mov dec popf mov dec pushf mov
Functional Coverage • You may want to keep track of how many times a particular event occurs during simulation • ex. How often is x=1? Does y ever become 0? etc… • A coverage_group defines the interesting events that you want to keep track of coverage_group Cov. Group{ sample_event = @ (posedge CLOCK); sample var 1, ifc. sig 1; sample s_exp(var 1 + var 2); } program cov. Test{ integer var 1, var 2; Cov. Group cg = new(); }
Coverage Bins • To fully define a coverage group, you must know what signal state and transitions you want to count coverage_group Cov. Group{ sample_event = @ (posedge CLOCK); sample var 1, ifc. sig 1; sample s_exp(var 1 + var 2); } • Var 1 is sampled, but what values am I interested in? • State bins and transition bins define the values you want to count
User-Defined Coverage Bins coverage_group My. Cov () { sample_event = @ (posedge clock); sample port_number { state s 0(0: 7); state s 1(8: 15); trans t 1("s 0"->"s 1"); } } • s 0 is values 0 -7 • s 1 is values 8 -15 • t 1 is a transition from s 0 to s 1
- Slides: 18