There can be multiple reasons that can block the test cases to be executed, it might be due to the test environment is not ready or there is a failure somewhere else that stops us getting to execute the test case. What is the blocking item here is C based flow – For processor hex code is required and we generate it using C file whereas IP level verification is generally based on SV-UVM. But is it too easy to reuse IP level test cases at the SoC level design? Yes, it is, and that is what we are going to discuss.
Generally, we put a lot of effort into creating constraint random test cases at IP level verification but it is not being reused at SoC level. How can we utilise the IP level test cases at the SoC level with minor extra efforts during test case creation at IP level verification itself.
RELATED BLOG
Let us first discuss the general CPU based SoC level test case flow.
You will have two files in your SoC level test case. i.e. C and System Verilog (.SV referred henceforth in this paper). In the C file, we write conditional/unconditional register write/read on any IP in the SoC development.
On the SV side, we might have a lot of UVM based code to verify the functionality of the IP like creating packet from/for VIP, starting sequences etc. In IP level test cases we generally have one file.ie “.SV”. In this “.SV” file we will have both registers write/read and UVM based code like starting sequences.
The idea is to come up with a flow where we can separate register write/read and other UVM based code in two different “.SV” files/classes in IP level test cases itself. Separate files can be created for Register write/read code (Same as “.C” code in CPU based verification) and rest of the UVM code (Same as “.SV” code in CPU based verification).
If we already have these two separate files at the IP level test case itself, we can convert the file which contains register write/read code to C file by just using simple Perl script. These two “.SV” classed can be run as parallel threads during test case execution.
Let us consider the below example test.
class i2c_mem_write_read_test extends base_test;
task run_phase(uvm_phase phase);
i2c_vip_mem_write_seq vip_write_seq;
vip_write_seq = i2c_vip_mem_write_seq::type_id ::create(“vip_write_seq”);
//Randomize the data for configuring random value of register
data = $urandom_range(1,5);
//Configure I2C slave controller register
write_task(addr,data);
//Start sequence from VIP for write
vip_write_seq.start(env.virtual_sequencer);
// Read I2C controller register for status check
read_task(addr,read_data)
endtask
endclass
RELATED CASE-STUDY
Above mentioned example test case is what we generally do in IP level test cases.
//This class contains VIP sequence related code which is same as “.SV” test in SoC
class i2c_mem_write_read_test extends base_test;
task run_phase(uvm_phase phase);
i2c_vip_mem_write_seq vip_write_seq;
vip_write_seq = i2c_vip_mem_write_seq::type_id ::create(“vip_write_seq”);
//Randomize the data and pass it to C side using sync_method for
//configuring random value of register
data = $urandom_range(1,5);
sync_method(data);
//Wait for completion of configuration of controller register
sync_method();
//Start sequence from VIP for write
vip_write_seq.start(env.virtual_sequencer);
//Wait for completion of status check of controller register
sync_method();
endtask
endclass
Now we want to re-architect this IP level test case such that it can be used in SoC level as well without any significant modifications/efforts. We will achieve this by creating two separate “.SV” file as discussed initially with one file contain register write/read information and other related to VIP sequence from the above example.
//This class contains register write/read related code which is same as C test in SoC
class i2c_mem_write_read_test_ctest extends i2c_mem_write_read_test;
task run_phase(uvm_phase phase);
//sync_method to get random value from SV side
data = sync_method(sys_addr+offset);
//Configure I2C slave controller register
write_task(addr,data);
//Pass control to SV side for starting VIP sequence
sync_method();
//Wait for sequence from VIP to be complete
sync_method();
// Read I2C controller register for status check
read_task(addr,read_data)
endtask
endclass
Below flow chart describes the communication between c and “.sv” side using sync_method.
sync_method is required at SoC level design because you need to have some mechanism that provides runtime timing control to perform certain register write/read from the processor (which is in C file) i.e.
In the above example, first we configure I2C controller IP registers from C file and then we pass the control to “.SV” side to start VIP sequence (i.e. We cannot begin the VIP sequence at 0 time since Controller configuration is not yet done) using sync_method.
Similarly, we pass control from “.SV” side to C file using sync_method once the VIP sequence is completed. In the C file than we can check the status register value of controller IP (Checking status).
The logic of sync_method () used in the above example test is out of the scope of this article.
We can use this test flow in IP level test cases and then when we migrate it to SoC level verification, and the same test cases can be reused by just converting SV file(which contains register write/read code) to C file using simple Perl script.
Conclusion
This is how we can create the IP level test cases which can be reused at SOC level design that can effectively save approximately 30% to 70 % of the time we spent in creating SOC test cases based on the complexity of protocol and test case. At eInfochips, we provide end to end SoC design services across the entire connected product design flow, from test consulting and implementation to the end of life testing support, ensuring high product quality, operational excellence and agility. Connect us today to know more on our silicon engineering services.