Search the Community
Showing results for tags 'ral'.
-
I am trying to verify 8 bit RW registers and in some of the registers 4 bits are RESERVED lets say [3:0] . My bit bash sequence tries to write in these constant bit and flags me a mismatch error in the DUT and Mirrored Value. How do i stop my bit bash sequence from checking these RESERVED bits of a register. Thanks for your help
-
Hi, I wanted to use the field.mirror() task provided in the uvm_reg_field class to check only a particular field. However, I see that the field.mirror() task is just calling the parent register mirror task. Hence the entire register is read and compared which I didn't intend to do. I tried this in my sequence and I see the above mentioned behavior. This looks like a serious bug. Can you please confirm this. Regards, Shreyas
-
Hello, I was wondering if are there any resources (papers, blogs, posts, best practices) about methodologies to implement UVM RAL for "large" designs (>100K registers and 50K rams)? I tried to do some research online but most of the results never cover "large" designs. I have experience using RAL and doing some customisation to make it work in a particular environment (callbacks, maps, defining specialised registers, sequences) but most of them were "little" (1K regs and 100 rams) I'm interested on any information about aspects such as: Reg model re-usability and portability at sub-system and system level environments Performance: How heavy is the register model, since having this much registers may have a huge performance penalty over simulations Dynamic reconfiguration (I know in 1.2 once your model is locked not much can be done) RAM modelling in RAL (since it the uvm_mem is different from uvm_reg) Register Model Partitioning at block level Register Model limitations on real projects usage Implementation of different sized registers and non uniform mapping General RAL limitations Any material or hints on these topics is really appreciated Apologies for the broad question Thanks -R
-
Hi, I have an issue where teh DUT returns an X for register read but the reg2bus still sees it as a 0. When I was going over the uvm_reg_bus_op struct the type for data is uvm_reg_data_t which is only 2-state. Is there a way to override this argument to support 3/4-state? Maybe uvm_reg_data_logic_t? Please let me know. Thanks in advance! Vignesh
-
I recently came upon an issue where attempting to write a memory via a backdoor yields a warning similar to the following: "reporter [RegModel] Memory 'tst_reg_blk.test_mem' is not contained within map 'Backdoor' (called from get_access())" In addition to the warning, it appears that due rw.map being overwritten (as explained in the second link), Read-Only memories can be written to via the backdoor, since get_access end up returning the default value of "RW". This appears to be in conflict with the Spec: Researching this warning turned up a couple prior forum posts from 2014: http://forums.accellera.org/topic/2104-question-about-backdoor-map/ http://forums.accellera.org/topic/2107-problem-with-backdoor-access-to-uvm_mem/ Neither of which had an associated answer. I came up with a test case to reproduce the warning: //####################################################################### // Backdoor accesses to a UVM_MEM that is a member of more than 1 map // causes a UVM_WARNING that that the memory is not contained within // the 'Backdoor' register map. // // This appears to happen due to the uvm_mem::Xcheck_accessX call in // uvm_mem::do_write, which replaces rw.map with the pseudo-map 'Backdoor'. // This replacement precedes the get_access(rw.map) call later in do_write. // The warning is generated when map membership is checked in get_local_map // which is called from get_access in the case that there is > 1 maps to // which the memory belongs. // // Below is a test case that reproduces the warning, as well as a workaround // that replaces the overwritten map (if WORKAROUND is defined). //####################################################################### package test_pkg; import uvm_pkg::*; `include "uvm_macros.svh" typedef class basic_test; typedef class test_env; typedef class test_reg_block; typedef class test_mem_class; //######################################### // Test //######################################### class basic_test extends uvm_test; test_env env; `uvm_component_utils(basic_test) //---- New Function ---- function new(string name = "basic_test", uvm_component parent); super.new(name, parent); endfunction : new //---- Build Phase ---- function void build_phase(uvm_phase phase); super.build_phase(phase); env = test_env::type_id::create("env", this); endfunction //---- Run Phase ---- virtual task run_phase(uvm_phase phase); uvm_reg_data_t data = 'hA5; uvm_reg_addr_t offset = 'h0000; uvm_status_e status; phase.raise_objection(this, "Starting Test"); `uvm_info(get_type_name(), "Got into Test Run_Phase.", UVM_LOW) `uvm_info(get_type_name(), $sformatf("Writing 0x%h.", data), UVM_LOW) //This causes a warning if WORKAROUND is not defined env.tst_reg_blk.test_mem.write(.status(status), .offset(offset), .value(data), .path(UVM_BACKDOOR), .map(env.tst_reg_blk.test_reg_map), .parent(null), .prior(-1), .extension(null), .fname(""), .lineno(0)); data = 'h0; //Warning does not occur on read env.tst_reg_blk.test_mem.read( .status(status), .offset(offset), .value(data), .path(UVM_BACKDOOR), .map(env.tst_reg_blk.test_reg_map), .parent(null), .prior(-1), .extension(null), .fname(""), .lineno(0)); `uvm_info(get_type_name(), $sformatf("Read 0x%h.", data), UVM_LOW) phase.drop_objection(this, "Test Is Done"); endtask : run_phase endclass //######################################### // Basic Environment //######################################### class test_env extends uvm_env; test_reg_block tst_reg_blk; `uvm_component_utils(test_env) //---- New Function ---- function new(input string name, input uvm_component parent=null); super.new(name,parent); endfunction //---- Build Phase ---- function void build_phase(uvm_phase phase); super.build_phase(phase); tst_reg_blk = test_reg_block::type_id::create("tst_reg_blk"); tst_reg_blk.configure(); tst_reg_blk.setup(); tst_reg_blk.set_hdl_path_root("test_tb"); endfunction : build_phase endclass //######################################### // Register Block Class //######################################### class test_reg_block extends uvm_reg_block; uvm_reg_map test_reg_map; uvm_reg_map test_reg_map_2; test_mem_class test_mem; `uvm_object_utils(test_reg_block) //---- New Function ---- function new(input string name="test_reg_block"); super.new(name); endfunction // new //Create Map, Add/Configure Memory, Lock Model function void setup(); test_reg_map = create_map("test_reg_map", 'h00000000, 4, UVM_LITTLE_ENDIAN, .byte_addressing(0)); test_reg_map_2 = create_map("test_reg_map", 'h00000000, 4, UVM_LITTLE_ENDIAN, .byte_addressing(0)); test_mem = test_mem_class::type_id::create("test_mem", , get_full_name()); test_mem.configure(this, "rtl_mem"); test_reg_map.add_mem( .mem(test_mem), .offset (32'h00000000), .rights ("RO"), .unmapped (0)); test_reg_map_2.add_mem( .mem(test_mem), .offset (32'h00000000), .rights ("RO"), .unmapped (0)); this.lock_model(); endfunction // setup endclass //######################################### // Register Block Class //######################################### class test_mem_class extends uvm_mem; `uvm_object_utils(test_mem_class) //---- New Function ---- function new(input string name="test_mem_class"); super.new(.name(name), .size(16), .n_bits(8), .access("RW"), .has_coverage(UVM_NO_COVERAGE)); endfunction // new //---- Bug Workaround ---- // Override the do_write task grab a local copy of the map. // Then override pre_write (which occurs after Xcheck_accessX) // to reassign the map with the local copy in the case of a // backdoor access. // // An actual fix would involve changing the behaviour of // Xcheck_accessX, which is non-virtual. `ifdef WORKAROUND protected uvm_reg_map backup_map; virtual task do_write (uvm_reg_item rw); backup_map = rw.map; super.do_write(rw); endtask virtual task pre_write (uvm_reg_item rw); super.pre_write(rw); if(rw.path == UVM_BACKDOOR) begin if(backup_map == null) rw.map = rw.local_map; else rw.map = backup_map; end endtask `endif endclass endpackage : test_pkg //######################################### // Basic TB //######################################### module test_tb(); import uvm_pkg::*; import test_pkg::*; `include "uvm_macros.svh" reg [7:0] rtl_mem [16]; initial run_test("basic_test"); endmodule I was able to come up with a work-around, but I feel that I am missing something. What is the actual purpose of uvm_reg_map::backdoor()? What is it's intended use case? Given that it has no parent block (thus not allowing memories or registers to be added), I do not know how it could be used. Thank you in advance for considering my question. //----------------- Edit ------------------------ I realized after the fact that this is a pre-IEEE issue. I Don't know if the topic can be moved to the correct forum. However, the question still stands; what is the intended purpose of the Backdoor pseudo-map?
-
Hi All, I am working in verification. Where i have to generate reg_block for all the IP's using IPXACT. also top level reg_block which instantiates all the IP level register block using IPXACT. But i am not interested in Ports/Businterface/component. Please advise me what is the best method to do it. Thanks Saravanan
-
The VCS implementation of uvm_reg_bit_bash_seq UVM register bit bash sequence performs a model.reset() in the sequence body, before starting the core do_block() task. Due to this reset, any configurations made to the DUT before starting the bit bash sequence is lost in the mirror model, while the DUT still has the configuration intact. This is causing failures during the bit-bash process, resulting in a test fail. There is no knob to override the reset functionality, nor can I extend the sequence and bypass the reset. Any thoughts on this? Any work around for this? ~Chethan
-
Hello, We have a test bench environment where we have 2 objects of the same SPI env class. The SPI env sets the sequencer for the RAL model as follows: reg_model.default_map.set_sequencer(spi_master_agt.mem_sqr, reg2spi_adapter); The transaction type handled by the spi_master_agt.mem_sqr is spi_mem_tr. Now I need to extend the spi_mem_tr to spi_mem_tr_1 and spi_mem_tr_2, and then override spi_mem_tr with those separately for the 2 objects of the SPI env class. // Below does not work set_inst_override_by_type ( .relative_inst_path("env.spi_m[0].*"), // Here spi_m[0] is the first instance of the SPI env .original_type(spi_mem_tr::get_type()), .override_type(spi_mem_tr_1::get_type())); set_inst_override_by_type ( .relative_inst_path("env.spi_m[1].*"), // Here spi_m[1] is the second instance of the SPI env .original_type(spi_mem_tr::get_type()), .override_type(spi_mem_tr_2::get_type())); // This does not work too! set_inst_override_by_type ( .relative_inst_path("env.*"), .original_type(spi_mem_tr::get_type()), .override_type(spi_mem_tr_1::get_type())); // Even this does not work! // So looks like "inst" override by type does not work for tr objects in RAL // connecting agents? set_inst_override_by_type ( .relative_inst_path("*"), .original_type(spi_mem_tr::get_type()), .override_type(spi_mem_tr_1::get_type())); // Other the other hand, below works, BUT that overrides the tr in both SPI env objects // That is not what I want; I need to override using different types for the // two SPI env objects spi_mem_tr::type_id::set_type_override(spi_mem_tr_1::get_type()); Questions: Is it possible to do instance specific overrides over transaction class inside the SPI agent connecting to my RAL model? If so, what is the correct way to set the relative_inst_path? If not, are there any hacks to achieve the same? The fact that the global type override does work gives me some hope.
-
Looking for suggestions on the best approach to modeling something akin the following. value1 and value0 are implemented as value_reg[31:0] in RTL. The value actually stored in this register is always whatever you wrote to it. However, what you read back, and what HW sees when it looks at this register depends on the value of value_mode. When value_mode == DIRECT, you'll read back the whatever value is physically stored in value_reg[15:0] as value0 and value_reg[31:16] as value1. When value_mode == MULT, you'll read back a computed value instead. Let quotient == value_reg[15:0] * value_reg[31:16]. Then you'll read back quotient[15:0] as value0 and quotient[31:16] as value1. Right now I've just added tasks write_value( bit [15:0] a, bit [15:0 b ), read_value( output bit [31:0] quotient ) to the register model, which look at value_mode before accessing value_reg. In both cases, write_value() just writes parameters a and b to value0 and value1 using the register model. When value_mode == DIRECT, read_value() reads value0 and value1 multiplies them and returns the result. When value_mode == MULT, read_value() reads value0 and value1, concats them and returns the result. I'm contemplating adding some kind of virtual register to the register model instead of the tasks. Then, implement the logic using either callbacks or a custom front door. It also needs to preserve support for multiple address maps. The goal is to prevent multiple scoreboards and coverage classes which are referencing these registers from having to implement the same computation. The idea of a virtual register is to provide the same uvm_reg API to the user as other registers. A side benefit is the user only makes a single call to read the 32 bit value, rather than making two calls. Cheers.
-
Hi, We are using snps ralgen to generate the regmodel. It appears that the ralgen creates only the default map. We would like to have 2 maps for 2 separated if masters. Is there an online example for such case? A post gen script can do one of the following 2 options: 1. add another instance of uvm_reg_map and copy/clone the ready map after finished build 2. add another instance of uvm_reg_map, and duplicate any map1.add_reg and map1.add_submap to map2 Which is preferable? Thanks! Elihai
-
Hi, I have a question refer to strange messages created by RAL read command. When the register is read, I receive a message like: uvm_pkg::uvm_parent_child_link l103=config_dmaw_seq r107=transfer Do you know how to prevent these messages? Regards, Moshe
-
Hello all, Sorry for stupid question. I have my registers defined as, reg1, reg2, reg3.....................reg64. Now i want to drive a single value (ZERO) to all register using for loop. so i implemented, for (integer i = 0; i<65; i = i+1); des_data[0:7] = 8'h00; block_obj.$sformatf("reg%0d",i).write(status, des_data, UVM_FRONTDOOR,.parent(this)); But i am unable to achieve so. Any one else can suggest alternate solution or logic for the above problem ??
-
Hello All, I have some queries regarding RAL model : (1.) How to declare any particular Register's filed as "signed" in RAL model? (2.) By default all the register fields in RAL model are "unsigned" or "signed"? If possible please guide me for the same. Thanks, Bonny G. Vora
-
Not sure do you have similar problem? I have a problem in handling the reset value in RAL. f the reset value of a field in the register is don't care, what can I do for it? Now my plan is extend a new access type. For this kind of registers, the read value in reset test is not checked. Do you guys think it is a feasible way? Thanks.