-
Notifications
You must be signed in to change notification settings - Fork 762
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[test] Add spi_passthrough support to the power virus test #17747
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,6 +73,64 @@ class chip_sw_power_virus_vseq extends chip_sw_base_vseq; | |
join | ||
endtask | ||
|
||
// Utility task to send a SpiFlashReadQuad command to read 2048 bytes from | ||
// the spi_device_agent0. The expected read response is initialized to | ||
// an alternating pattern of 0xAA an Ox55 to maximize the toggling. | ||
virtual task execute_spi_flash_sequence(); | ||
const int test_payload_size = 2048; | ||
bit [7:0] test_opcode = SpiFlashReadQuad; | ||
bit [7:0] rsp_fill_data; | ||
spi_device_flash_seq m_spi_device_seq; | ||
spi_host_flash_seq m_spi_host_seq; | ||
spi_item host_rsp, device_rsp; | ||
spi_item device_rsp_q[$]; | ||
spi_agent_cfg agent_cfg = cfg.m_spi_host_agent_cfg; | ||
|
||
fork begin : isolation_fork | ||
// The device agent handles the incoming command. | ||
fork | ||
forever begin : send_spi_device_seq_forever | ||
`uvm_create_on(m_spi_device_seq, p_sequencer.spi_device_sequencer_hs[0]); | ||
// To maximize the toggling, fill the device agent's response queue | ||
// with an alternating pattern of 0xaa and 0x55. | ||
for (int ii = 0; ii < test_payload_size; ii = ii + 1) begin | ||
rsp_fill_data = (ii % 2 == 1) ? 8'haa : 8'h55; | ||
m_spi_device_seq.byte_data_q.push_back(rsp_fill_data); | ||
end | ||
`uvm_send(m_spi_device_seq); | ||
device_rsp_q.push_back(m_spi_device_seq.rsp); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I assume the response packets are comprised of random bits? was there a way to make them all There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will check this one 👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think one way to do it is to assign the rsp value before sending the sequence, for example something like this: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or like you did in line 130, that could work too I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the guidance! I updated the code based on your suggestion. Now, the response packages are an alternating pattern of |
||
end | ||
|
||
// The host agent sends the command, receives the response, and | ||
// checks the result. | ||
begin : spi_host_thread | ||
`uvm_create_on(m_spi_host_seq, p_sequencer.spi_host_sequencer_h); | ||
// set the host sequence's parameters. | ||
m_spi_host_seq.opcode = test_opcode; | ||
m_spi_host_seq.read_size = test_payload_size; | ||
`uvm_info(`gfn, $sformatf("spi passthrough payload size = %0x", | ||
m_spi_host_seq.read_size), UVM_LOW); | ||
`uvm_send(m_spi_host_seq); | ||
// Wait for a small delay to allow the device agent to push the response | ||
// into the queue. | ||
#1ps; | ||
`uvm_info(`gfn, $sformatf("spi passthrough opcode = %0x", | ||
test_opcode), UVM_LOW); | ||
|
||
// Check that the command, address, and data sent matches on both sides. | ||
`DV_CHECK_EQ(device_rsp_q.size(), 1); | ||
host_rsp = m_spi_host_seq.rsp; | ||
device_rsp = device_rsp_q.pop_front(); | ||
if (!host_rsp.compare(device_rsp)) begin | ||
`uvm_error(`gfn, $sformatf("Compare mismatch\nhost_rsp:\n%sdevice_rsp:\n%s", | ||
host_rsp.sprint(), device_rsp.sprint())) | ||
end | ||
end | ||
join_any | ||
disable fork; | ||
end join | ||
endtask | ||
|
||
task pre_start(); | ||
// i2c_agent configs | ||
configure_i2c_agents(); | ||
|
@@ -83,11 +141,27 @@ class chip_sw_power_virus_vseq extends chip_sw_base_vseq; | |
cfg.m_spi_device_agent_cfgs[1].spi_mode = Quad; | ||
cfg.m_spi_device_agent_cfgs[1].if_mode = dv_utils_pkg::Device; | ||
cfg.m_spi_device_agent_cfgs[1].is_active = 0; | ||
|
||
// Configs for SPI passthrough part of the test | ||
cfg.m_spi_device_agent_cfgs[0].byte_order = '0; | ||
// Set CSB inactive times to reasonable values. sys_clk is at 24 MHz, and | ||
// it needs to capture CSB pulses. | ||
cfg.m_spi_host_agent_cfg.min_idle_ns_after_csb_drop = 50; | ||
cfg.m_spi_host_agent_cfg.max_idle_ns_after_csb_drop = 200; | ||
spi_agent_configure_flash_cmds(cfg.m_spi_host_agent_cfg); | ||
spi_agent_configure_flash_cmds(cfg.m_spi_device_agent_cfgs[0]); | ||
// 'kClockFreqHiSpeedPeripheralHz / 2' in SW | ||
cfg.m_spi_host_agent_cfg.sck_period_ps = 48_000; | ||
super.pre_start(); | ||
endtask | ||
|
||
virtual task body(); | ||
// Turn off the FIFO data output assertion, as spi_device issues a read | ||
// before it knows whether it needs the data. | ||
$assertoff(0, "tb.dut.top_earlgrey.u_spi_device.u_readcmd.u_readsram.u_sram_fifo.DataKnown_A"); | ||
$assertoff(0, "tb.dut.top_earlgrey.u_spi_device.u_readcmd.u_readsram.u_fifo.DataKnown_A"); | ||
super.body(); | ||
|
||
// Wait for test_main() to start and configurations to be computed. | ||
`DV_WAIT(cfg.sw_logger_vif.printed_log == "All IPs configured."); | ||
|
||
|
@@ -105,6 +179,14 @@ class chip_sw_power_virus_vseq extends chip_sw_base_vseq; | |
begin: spi_host_1_thread | ||
read_spi_host1_bytes(); | ||
end | ||
|
||
begin : spi_passthrough_thread | ||
// Enable the spi agents. | ||
cfg.chip_vif.enable_spi_host = 1; | ||
cfg.chip_vif.enable_spi_device(.inst_num(0), .enable(1)); | ||
// Send the command and check the response. | ||
execute_spi_flash_sequence(); | ||
end | ||
join | ||
endtask | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Under this isolation fork, do you think this structure is more clear?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Cindy :) I applied this change in the new version.