From 4a6958a627eeec2c61eb769a45e00e0f3f22394a Mon Sep 17 00:00:00 2001 From: Nadia Hanif Date: Thu, 21 Dec 2023 16:50:56 +0500 Subject: [PATCH] [usbdev]usb20_monitor This is updated monitor. Signed-off-by: Nadia Hanif --- hw/dv/sv/usb20_agent/usb20_monitor.sv | 340 ++++++++++++++++---------- 1 file changed, 213 insertions(+), 127 deletions(-) diff --git a/hw/dv/sv/usb20_agent/usb20_monitor.sv b/hw/dv/sv/usb20_agent/usb20_monitor.sv index 58aa7b147c9be4..a65e768541eaa4 100644 --- a/hw/dv/sv/usb20_agent/usb20_monitor.sv +++ b/hw/dv/sv/usb20_agent/usb20_monitor.sv @@ -8,144 +8,223 @@ class usb20_monitor extends dv_base_monitor #( .COV_T (usb20_agent_cov) ); `uvm_component_utils(usb20_monitor) + uvm_analysis_port #(usb20_item) usb20_monitor_analysis_port; - bit token_packet[]; - bit data_packet[]; - bit handshake_packet[]; + sof_pkt m_sof_pkt; + token_pkt m_token_pkt; + data_pkt m_data_pkt; + handshake_pkt m_handshake_pkt; + typedef bit destuffed[]; + bit token_packet[$]; + bit data_packet[$]; + bit handshake_packet[$]; + bit sof_packet[$]; bit sync_pattern[]; bit decoded_packet[]; bit monitored_decoded_packet[]; - bit seo; + bit bit_destuffed[]; bit [2:0] eop_cnt = 3'b000; `uvm_component_new function void build_phase(uvm_phase phase); super.build_phase(phase); - usb20_monitor_analysis_port = new("usb20_monitor_analysis_port", this); - if (!uvm_config_db#(virtual usb20_block_if)::get(this, "*.env.m_usb20_agent*", "bif",cfg.bif)) - begin - `uvm_fatal(`gfn, "failed to get usb20_block_if handle from uvm_config_db") - end + m_sof_pkt = sof_pkt::type_id::create("m_sof_pkt", this); + m_token_pkt = token_pkt::type_id::create("m_token_pkt", this); + m_data_pkt = data_pkt::type_id::create("m_data_pkt", this); + m_handshake_pkt = handshake_pkt::type_id::create("m_handshake_pkt", this); + usb20_monitor_analysis_port = new("usb20_monitor_analysis_port", this); + if (!uvm_config_db#(virtual usb20_block_if)::get(this, "*.env.m_usb20_agent*", "bif", + cfg.bif)) begin + `uvm_fatal(`gfn, "failed to get usb20_block_if handle from uvm_config_db") + end + if (!uvm_config_db#(virtual clk_rst_if)::get(this, "*.env", "clk_rst_vif", + cfg.clk_rst_if_i)) begin + `uvm_fatal(`gfn, "failed to get clk_rst_if handle from uvm_config_db") + end endfunction task run_phase(uvm_phase phase); forever begin collect_trans(phase); - //collect_data_packet(phase); - //collect_handshake_packet(phase); + collect_data_packet(phase); + collect_handshake_packet(phase); end endtask - //MONITOR TOKEN_PACKET + // For future use (task written but not used yet) + // Monitor start of frame packet + virtual protected task collect_sof_packet(uvm_phase phase); + typedef bit [34:0] sof_p; + sof_p sof_result; + + // While driving the packet before vbus gets active the reset toggle 2,3 times so below wait + // Conditions waits for the those reset and than it detected the vbus + detect_reset(); + cfg.clk_rst_if_i.wait_for_reset(1, 1); + + // Idle state detected here + while(!(cfg.bif.usb_p & ~cfg.bif.usb_n)) @(posedge cfg.bif.usb_clk); + `uvm_info(`gfn, $sformatf("Idle State_usb_p Monitored = %b Idle State_usb_n Monitored = %b", + cfg.bif.usb_p, cfg.bif.usb_n), UVM_DEBUG) + @(posedge cfg.bif.usb_clk); + wait(~cfg.bif.usb_p); + + // Collecting usb_p from interface + @(posedge cfg.bif.usb_clk); + while (cfg.bif.usb_p || cfg.bif.usb_n) begin + sof_packet.push_back(cfg.vif.usb_p); + @(posedge cfg.bif.usb_clk); + end + repeat (3) sof_packet.push_back(cfg.vif.usb_p); + + `uvm_info(`gfn, $sformatf("Complete Monitored Sof_Packet = %p", sof_packet), UVM_DEBUG) + nrzi_decoder(sof_packet, monitored_decoded_packet); + bit_destuffed = bit_destuffing(monitored_decoded_packet); + + // Bits to binary conversion + sof_result = sof_p'(bit_destuffed); + + `uvm_info(`gfn, $sformatf("Final Sof Packet = %b", sof_result), UVM_DEBUG) + m_sof_pkt.m_pid_type = sof_result[9:2]; + `uvm_info(`gfn, $sformatf("Sof Pid = %b", m_sof_pkt.m_pid_type), UVM_DEBUG) + m_sof_pkt.framecnt = sof_result[20:10]; + `uvm_info(`gfn, $sformatf("Sof framecnt = %b", m_sof_pkt.framecnt), UVM_DEBUG) + m_sof_pkt.crc5 = sof_result[25:21]; + `uvm_info(`gfn, $sformatf("Sof crc5 = %b", m_sof_pkt.crc5), UVM_DEBUG) + analysis_port.write(m_sof_pkt); + endtask + + // Monitor token packet virtual protected task collect_trans(uvm_phase phase); - //while driving the packet before vbus gets active the reset toggle 2,3 times so below wait - //conditions waits for the those reset and than it detected the vbus - wait(cfg.bif.rst_ni); - wait(~cfg.bif.rst_ni); - wait(cfg.bif.rst_ni); - wait(~cfg.bif.rst_ni); - wait(cfg.bif.rst_ni); - `uvm_info(`gfn, $sformatf("\n Vbus detected = %b reset = %b", cfg.bif.usb_vbus, cfg.bif.rst_ni), - UVM_LOW) - //idle state detetcted here - wait(cfg.bif.usb_p & ~cfg.bif.usb_n); - `uvm_info(`gfn, $sformatf("\n Idle State_usb_p Monitored = %b Idle State_usb_n Monitored = %b" , - cfg.bif.usb_p, cfg.bif.usb_n), UVM_LOW) + typedef bit [34:0] token_p; + token_p token_result; + + detect_reset(); + cfg.clk_rst_if_i.wait_for_reset(1, 1); + while(!(cfg.bif.usb_p & ~cfg.bif.usb_n)) @(posedge cfg.bif.usb_clk); + `uvm_info(`gfn, $sformatf("After EOP Idle State Monitored"), UVM_DEBUG) + @(posedge cfg.bif.usb_clk); wait(~cfg.bif.usb_p); - while (1)begin - @(posedge cfg.bif.usb_clk) begin - if(cfg.bif.usb_p == 1'b0 & cfg.bif.usb_n == 1'b0) - begin - seo = 1'b1; - for(int i = 0; i <2; i = i + 1) - begin - token_packet = new[token_packet.size()+1](token_packet); - token_packet[token_packet.size()-1] = cfg.vif.usb_p; - end - break; - end - else - begin - token_packet = new[token_packet.size()+1](token_packet); - token_packet[token_packet.size()-1] = cfg.vif.usb_p; - end - end + + // Collecting usb_p from interface + @(posedge cfg.bif.usb_clk); + while (cfg.bif.usb_p || cfg.bif.usb_n) begin + token_packet.push_back(cfg.vif.usb_p); + @(posedge cfg.bif.usb_clk); end - `uvm_info(`gfn, $sformatf("complete monitored token_packet = %p ", token_packet), UVM_LOW) - bit_destuffing(token_packet); - `uvm_info(`gfn, $sformatf("Monitored destuffed token_packet: %p", token_packet), UVM_LOW) + repeat (3) token_packet.push_back(cfg.vif.usb_p); + + `uvm_info(`gfn, $sformatf("Complete monitored token_packet = %p ", token_packet), UVM_DEBUG) nrzi_decoder(token_packet, monitored_decoded_packet); - `uvm_info(`gfn, $sformatf("Monitored NRZI decoder token_packet =%p", - monitored_decoded_packet), UVM_LOW) + bit_destuffed = bit_destuffing(monitored_decoded_packet); + + // Bits to binary conversion + token_result = token_p'(bit_destuffed); + + `uvm_info(`gfn, $sformatf("Final Token Packet = %b", token_result), UVM_DEBUG) + m_token_pkt.m_pid_type = token_result[26:19]; + `uvm_info(`gfn, $sformatf("Token Pid = %b", m_token_pkt.m_pid_type), UVM_DEBUG) + m_token_pkt.address = token_result[18:12]; + `uvm_info(`gfn, $sformatf("Token Address = %b", m_token_pkt.address), UVM_DEBUG) + m_token_pkt.endpoint = token_result[11:8]; + `uvm_info(`gfn, $sformatf("Token Endpoint = %b", m_token_pkt.endpoint), UVM_DEBUG) + m_token_pkt.crc5 = token_result[7:3]; + `uvm_info(`gfn, $sformatf("Token Crc5 = %b", m_token_pkt.crc5), UVM_DEBUG) + analysis_port.write(m_token_pkt); endtask - //MONITOR DATA_PACKET + // Monitor data packet virtual protected task collect_data_packet(uvm_phase phase); - wait(cfg.bif.usb_p & ~cfg.bif.usb_n); - `uvm_info(`gfn, $sformatf("\n After EOP Idle State Monitored"), UVM_LOW) + bit [7:0] data_pid; + bit [7:0] data_temp[]; + bit data[]; + bit [63:0] data_result; + bit [15:0] data_crc16; + byte unsigned byte_data[]; + + while(!(cfg.bif.usb_p & ~cfg.bif.usb_n)) @(posedge cfg.bif.usb_clk); + `uvm_info(`gfn, $sformatf("After EOP Idle State Monitored"), UVM_DEBUG) + @(posedge cfg.bif.usb_clk); wait(~cfg.bif.usb_p); - while(1)begin - @(posedge cfg.bif.usb_clk) begin - if(cfg.bif.usb_p == 1'b0 & cfg.bif.usb_n == 1'b0) begin - seo = 1; - for(int i = 0; i <2; i = i + 1) - begin - data_packet = new[data_packet.size()+1](data_packet); - data_packet[data_packet.size()-1] = cfg.vif.usb_p; - end - break; - end - else - begin - data_packet = new[data_packet.size()+1](data_packet); - data_packet[data_packet.size()-1] = cfg.vif.usb_p; - end - end + + // Collecting usb_p from interface + @(posedge cfg.bif.usb_clk); + while (cfg.bif.usb_p || cfg.bif.usb_n) begin + data_packet.push_back(cfg.vif.usb_p); + @(posedge cfg.bif.usb_clk); end - `uvm_info(`gfn, $sformatf("Complete Monitored Data_Packet = %p ", data_packet), UVM_LOW) - bit_destuffing(data_packet); - `uvm_info(`gfn, $sformatf("Monitored Destuffed Data_Packet: %p", data_packet), UVM_LOW) + repeat (3) data_packet.push_back(cfg.vif.usb_p); + `uvm_info(`gfn, $sformatf("Complete Monitored Data_Packet = %p", data_packet), UVM_DEBUG) nrzi_decoder(data_packet, monitored_decoded_packet); - `uvm_info(`gfn, $sformatf("Monitored NRZI Decoder Data_Packet =%p", monitored_decoded_packet), - UVM_LOW) + bit_destuffed = bit_destuffing(monitored_decoded_packet); + + // Converting complete packet into transaction level (field wise) + // Data_PID + for (int i = 0; i < 8; i++) begin + data_pid[i] = bit_destuffed[i + 8]; + end + m_data_pkt.m_pid_type = data_pid; + `uvm_info(`gfn, $sformatf("Data Pid = %b", m_data_pkt.m_pid_type), UVM_DEBUG) + // Data_in_bits + for (int i = 0 ; i < bit_destuffed.size() - 35; i++) begin + data = new[data.size() + 1](data); + data[i] = bit_destuffed[i + 16]; + end + data = {<<8{data}}; + data = {<<{data}}; + // Bits_to_byte conversion of data + byte_data = {<