UVM Update: Register Package

8,361 views

Published on

Published in: Technology, Design

UVM Update: Register Package

  1. 1. UVM UpdateRegister Package Verification Engineer Agnisys Technology Pvt. Ltd.
  2. 2. Agenda• Introduction to UVM• UVM Register Model• Our experience with using Register Model• Register Model Generator 2
  3. 3. Verification Methodologies• History – February 2011 Accellera releases UVM 1.0 – Recently, June 2011 UVM 1.1 is released 3
  4. 4. Introduction to UVM• Universal Verification Methodology – A methodology and a class library for building Advanced Reusable Verification Components• Relies on strong, proven industry foundations – Engineers worldwide can write thorough and reusable test environments 4
  5. 5. UVM Environment • Module top () as top level element. • Test Class • Contains Testbench • Reusable components with different configSource: Accellera DAC Presentation 5
  6. 6. What’s in UVM ?• Base Classes• Factory Classes• Phasing• Configuration• TLM• Sequences & Sequencers• Message Reporting• Register Model 6
  7. 7. Base Classes• Facilitate the design of modular, scalable, reusable verification environments• The basic building blocks for all environments are components and the transactions they use to communicate establish structal hierarchy transactions phase-- build, connect, run, etc. 7
  8. 8. Factory Classes • Manufacture (create) UVM objects and components. – Only one instance of the factory is present in a given simulationclass uvm_component_registry #( type T = uvm_component, string Tname = "<unknown>") extends uvm_object_wrapper 8
  9. 9. Phasing Several new runtime phases in parallel with run_phase() By default, all components must allow all other components to complete a phase before all components move to next phaseSource: Accellera DAC Presentation 9
  10. 10. Configuration & TLM• Configuration – The configuration & resource classes, access to store or receive from database. • uvm_resource_db • uvm_config_db – Configuration mechanism advantages: • Wild cards and regular expressions allow configuration of multiple attributes with a single command Initiator target • Run-time configuration support• TLM put – Unidirectional put/get interfaces Initiator target – TLM 2.0 • Well-defined completion semantics get 10
  11. 11. Sequencers & Sequences• Sequences – User-defined procedures that generate multiple uvm_sequence_item-based transactions – Reused, extended, randomized, and combined sequentially and hierarchically• Sequencers – Arbiter for controlling transaction flow – pull or push semantic between Driver 11
  12. 12. Message Reporting• Messages print trace information with advantages over $display: – Aware of its hierarchy/scope in testbench – Allows filtering based on hierarchy, verbosity, and time `uvm_info("PKT", "Packet Sent“, UVM_LOW); 12
  13. 13. Agenda• Introduction to UVM• UVM Register Model• Our experience with using Register Model• Register Model Generator 13
  14. 14. Register Model• Object oriented Shadow Model for Registers and Memories in DUT• Components – Field – Register – Register File – Memory – Block 14
  15. 15. Register Model BLK_1 R0 R0 Registers R1 R0 F1 F2 F3 F4 F1 F2 F3 F4 uvm_reg F10 F11 F10 F11 ARR[0] F10 F11 . . . F10 F11 ARR[1] F10 F11 F5 F6 F7 Register Arrays . F8 F9 . F5 F6 F7 F8 F9 F5 . . F6 F7 . F8 F9 F10 F11 ARR[n]uvm_reg_block MEM_0 . F5 F6 F7 RF0 [0] BLOCK . F8 F9 RF1 [0] . BLK_n F5 F6 F7 RF0 [1] R0 uvm_reg_file F8 F9 RF1 [1] Register File Array F1 F2 F3 F4 . F10 F11 F10 F11 . . . . RF0 [m] F10 F11 F5 F6 F7 F5 F6 F7 F8 F5 F6 F9 F7 F8 F9 RF1 [m] F8 F9 F5 . . F6 F7 uvm_mem Memory MEM_0 MEM0 F8 F9 MEM_0 15
  16. 16. Register Package Usage Read-WriteGenerator Adapter Backdoor Bus Specific R/W Bus Agent 16
  17. 17. Mirroring• Register model mirrors content of registers in DUT – Updated on read() and write() – “Scoreboard” for checking – Memories : Scoreboard • uvm_mem::peek() Monitor • uvm_mem::poke() R0 R1 Monitor DUT R0.read (. . .); R0 Sequence ... Sequencer Driver R1.write (. . .); APB R1 17
  18. 18. Front-door vs. Back-door• Front Door: Normal bus access• Back Door – Access RTL directly in zero-time • Load memory – Hardware writable Scoreboard • Counter, status flags Monitor – Must define “hdl_path” • Generator-specific R0 R1 Monitor DUT R0.read (. . .); R0 Sequence ... Sequencer Driver R1.write (. . .); APB R1 18
  19. 19. Agenda• Introduction to UVM• UVM Register Model• Our experience with using Register Model• Register Model Generator 19
  20. 20. HDL Path HDL path components are specified using the following methods: a) uvm_reg_block::configure() and uvm_reg_block::add_hdl_path() b) uvm_reg_file::configure() and uvm_reg_file::add_hdl_path() c) uvm_reg::configure() and uvm_reg::add_hdl_path_slice() d) uvm_mem::configure() and uvm_mem::add_hdl_path_slice() CODE: Clear HDL paths if R0.clear_hdl_path(); mentioned above in R0.add_hdl_path_slice("dut.R0", 0, 32); configure() R1.clear_hdl_path(); R1.add_hdl_path_slice("dut.R1", 0, 64); R0 Monitor R1 array name DUTAnd For Register Arrays: R0 Sequence Sequencer Driver foreach (reg_array[i]) begin APB R1 reg[i].clear_hdl_path(); reg[i].add_hdl_path_slice($sformatf(“DUT_ARRAY[%0x]", i), 0, 32); end 20
  21. 21. Mapping in Block byte-width of the bus Base AddressAPB_map = create_map("APB", ‘h0, 4, UVM_LITTLE_ENDIAN, 1); Byte addressing:APB_map_map.add_reg (R0, ‘h0);APB_map.add_reg (R1, ‘h4); consecutive endianess addresses refer are 1 byte apartAPB_map = create_map("APB", ‘h0, 8, UVM_LITTLE_ENDIAN, 0);APB_map_map.add_reg (R0, ‘h0); R0 - 32 bitAPB_map.add_reg (R1, ‘h4); R1 - 64 bit R0 Monitor If (Byte addressing == 0) then R1 Bus width = Max size of Register in Register Model DUT R0 Sequence Sequencer Driver APB R1 21
  22. 22. Coverage Coverage models for• For all elements except in Register File addresses read or written in an address map.• Pre-defined Functional Coverage Type Identifiers – UVM_NO_COVERAGE No coverage models. Block – UVM_CVR_FIELD_VALS Coverage models for R0 0x000 F1 F2 F3 F4 – UVM_CVR_REG_BITS values of fields. . – UVM_CVR_ADDR_MAP Coverage models for . – UVM_CVR_ALL bits read or written R1 0x008 in registers. 7 6 5 4 3 2 1 0 All coverage models. . R2 F5 F6 F7 0x014• Not instantiated by default R3 F8 F9 0x015 – Can be large. Instantiate only when needed. – To enable: MEM_0 0x020 - 0x030 uvm_reg::include_coverage (”*”, (UVM_CVR_REG_BITS + . . )); 22
  23. 23. Coverageclass my_reg_R1 extends uvm_reg; block_MEM0 extends uvm_mem; block_block extends uvm_reg_block; R0 R0 localuvm_reg_field F1; randblock_MEM0 MEM0; m_offset; uvm_reg_addr_t Register randblock_R1 R1; uvm_reg_field F2; F1 F2 F3 R1 covergroup cg_addr; rand uvm_reg_field F3; local uvm_reg_addr_t m_offset; { QUADRANTS : coverpoint m_offset bins FIRST = {[0:2]}; covergroup cg_vals; F10 F11 ARR[0] covergroup cg_addr; SECOND = {[3:5]}; bins F1: coverpoint F1.value[6:0]; F2: coverpoint F2.value[13:0];m_offset { block_MEM0 : coverpoint{[6:8]}; bins THIRD = F10 F11 ARR[1] F3: coverpointhit = FOURTH = : h47] }; endgroup} bins F3.value[19:0]; } bins { [h18 {[9:11]}; Register . . endgroupblock_reg1 : coverpoint m_offset { function new(string = { ‘h4 }; bins hit name = "my_reg_R1"); Arrays . function}new(string name = "block_mem_reg"); super.new(name, 32, build_coverage( F10 F11 ARR[n] endgroup super.new(name, h30, 32, "RW",UVM_CVR_FIELD_VALS));build_coverage(UVM_CVR_ADDR_MAP)); . . . function new(string name = "block_block"); endfunction F5 F6 F7 RF0 [0] RF1 [0] super.new(name, if (has_coverage(UVM_CVR_ADDR_MAP)) F8 F9build_coverage(UVM_CVR_ADDR_MAP)); virtual functionnew();sample(uvm_reg_data_t data, cg_addr = void if (has_coverage(UVM_CVR_ADDR_MAP)) uvm_reg_data_t byte_en, F5 F6 F7 RF0 [1] endfunction = new(); cg_addr bit is_read, F8 F9 RF1 [1] endfunction uvm_reg_map map); `uvm_object_utils(block_MEM0) if (has_coverage(UVM_CVR_FIELD_VALS)) Register . virtual function void sample(uvm_reg_addr_t cg_vals.sample();offset, bit is_read, uvm_reg_map map); virtual function void sample(uvm_reg_addr_t endfunction File .offset,(get_coverage(UVM_CVR_ADDR_MAP)) begin if bit is_read, uvm_reg_map map); virtual functionoffset; ifm_offset = void sample_values();begin (get_coverage(UVM_CVR_ADDR_MAP)) F5 F6 F7 RF0 [m] cg_addr.sample(); m_offset = offset; super.sample_values(); F8 F9 RF1 [m] end(get_coverage(UVM_CVR_FIELD_VALS)) ifcg_addr.sample(); end cg_vals.sample(); endfunction. . . Memory MEM_0 MEM0endclass : block_block endclass 23
  24. 24. Pre-Defined Sequences Sequence• Factory given Sequences ignores this Register • hdl_path Access needed uvm_resource_db#(bit)::set({"REG::",regmodel.blk.r0.get_full_name()}, "NO_REG_TESTS", 1, this); SEQUENCES ATTRIBUTES uvm_reg_hw_reset_seq NO_REG_TESTS uvm_reg_bit_bash_seq NO_MEM_TESTS uvm_reg_access_seq NO_REG_HW_RESET_TEST uvm_mem_walk_seq NO_REG_BIT_BASH_TEST uvm_mem_access_seq NO_REG_ACCESS_TEST uvm_reg_mem_built_in_seq NO_MEM_WALK_TEST uvm_reg_mem_hdl_paths_seq NO_MEM_ACCESS_TEST 24
  25. 25. Special Registers• Pre-Defined Registers Indirect Register Array (External) – Indirect Indexed Registersclass my_blk extends uvm_reg_block; INDIRECT_REG[0] INDIRECT_REG[1] ind_idx_reg IND_IDX; ind_data_reg IND_DATA; ind_reg INDIRECT_REG[256]; virtual function build(); INDIRECT_REG[2] . . IND_IDX . data`ifdef INCA [0:7] 0x00 Not in the Register Map begin . uvm_reg r[256]; my_blk foreach(INDIRECT_REG[i]) IND_DATA 0x04 . r[i]=INDIRECT_REG [i]; . IND_DATA.configure(IND_IDX, r, this, null); INDIRECT_REG[255] end`else INDIRECT_REG[256] IND_DATA.configure(IND_IDX, INDIRECT_REG , this,null);`endif . . default_map = create_map(““, 0, 4, UVM_BIG_ENDIAN); default_map.add_reg(IND_IDX, 0); default_map.add_reg(IND_DATA, 4); 25endclass
  26. 26. Special Registers cont. .• Aliased Registers – Accessible from multiple addresses in the same address map. – Fields in aliased registers will have different behavior depending on the address used to access them. class my_blk extends uvm_reg_block; rand my_reg_Ra Ra; rand class my_reg_Ra extends uvm_reg; my_reg_Rb Rb; R0 virtual rand uvm_reg_field F1; function build(); . . . .. . . . F1 F2 F3 F4 Ra ‘h100 default_map.add_reg(Ra, ‘h0100); "RW", . . .); F1.configure(this, 8, 0, F10 F11 Aliased endfunction default_map.add_reg(Rb, ‘h0200); F10 F11 Registers endclass Rb ‘h200 begin F10 F11 class my_reg_Rb extends uvm_reg; alias_RaRb RaRb; RaRb = uvm_reg_field F1; . . . . alias_RaRb::type_id::create("RaRb",,get_full_name()); RaRb.configure(Ra, Rb); 8, 0, "RO", . . .); F1.configure(this, end endfunction endclass endfunction endclass 26
  27. 27. Special Registers• FIFO class fifo_reg extends uvm_reg_fifo; function new(string name = "fifo_reg"); super.new(name,8,32,UVM_NO_COVERAGE); endfunction: new `uvm_object_utils(fifo_reg) endclass• RO and WO Sharing the Same Address default_map.add_reg(R1, h100, "RO"); default_map.add_reg(W1, h100, "WO"); endfunction : build 27
  28. 28. Agenda• Introduction to UVM• UVM Register Model• Our experience with using Register Model• Register Model Generator 28
  29. 29. Generation of Register Model EDA GENERATOR Vendors 29
  30. 30. Why use a Generated Register Model• Create correct-by-construction models – Coverage types – Constraints – Backdoor access – Special register• Sync with specification• Ease of use 30
  31. 31. Free UVM Register tools• Cadence : RGM – IP-XACT to UVM• Synopsys : Ralgen – RALF to UVM• Agnisys : IDSExcel – Excel to UVM 31
  32. 32. Summary• UVM register package must be used for any serious SoC verification• Not using a register model is painful• Not using a generated register model is very painful• Any questions? 32
  33. 33. 33
  34. 34. 34
  35. 35. UVM: Factory Classes cont. .• Three basic operations for creating components: 1. Registering objects and components types with the factory 2. Designing components to use the factory to create objects or components 3. Configuring the factory with type and instance overrides, both within and outside components 35
  36. 36. Register Model Usage• Physical Interface• Read- Write• Checking Scoreboard Monitor Register Model Monitor DUT R0.read (. . .); R0 Sequence ... Sequencer Driver R1.write (. . .); APB R1 36
  37. 37. Introspection 37
  38. 38. Special Registers cont. . class write_also_to_F extends uvm_reg_cbs; local uvm_reg_field m_toF; • Aliased Registers function new(uvm_reg_field toF); m_toF = toF; endfunctionclass my_blk extends uvm_reg_block; virtual function void post_predict(uvm_reg_field fld, uvm_reg_data_t value, rand my_reg_Ra Ra; uvm_predict_e kind, rand my_reg_Rb Rb; uvm_path_e path, virtual function build(); uvm_reg_map map); default_map = create_map("", 0, 4, UVM_BIG_ENDIAN); if (kind != UVM_PREDICT_WRITE) return; Ra = reg_Ra::type_id::create("Ra",,get_full_name()); void(m_toF.predict(value, -1, UVM_PREDICT_WRITE, path, map)); . . . endfunction Rb = reg_Rb::type_id::create("Rb",,get_full_name()); R0 endclass class alias_RaRb extends uvm_object; . . . F1 F2 F3 F4 protected reg_Ra m_Ra; Ra default_map.add_reg(Ra, ‘h0100); ‘h100 protected reg_Rb m_Rb; F10 Aliased default_map.add_reg(Rb, ‘h0200); F11 `uvm_object_utils(alias_RaRb) F10 Registers F11 function new(string name = "alias_RaRb"); beginRb ‘h200 super.new(name); alias_RaRb RaRb; F10 F11 endfunction: new RaRb = alias_RaRb::type_id::create("RaRb",,get_full_name()); function void configure(reg_Ra Ra, reg_Rb Rb); RaRb.configure(Ra, Rb); write_also_to_F F2F; end m_Ra = Ra;endfunction m_Rb = Rb;endclass F2F = new(Rb.F1); uvm_reg_field_cb::add(Ra.F1, F2F); endfunction : configure endclass : alias_RaRb 38

×