diff --git a/hw/dv/sv/usb20_agent/usb20_agent_pkg.sv b/hw/dv/sv/usb20_agent/usb20_agent_pkg.sv index 2022bd1ccb73b..641436ee3a210 100644 --- a/hw/dv/sv/usb20_agent/usb20_agent_pkg.sv +++ b/hw/dv/sv/usb20_agent/usb20_agent_pkg.sv @@ -12,8 +12,23 @@ package usb20_agent_pkg; `include "uvm_macros.svh" `include "dv_macros.svh" - // parameters - + // usb20_item enums + typedef enum bit [2:0] {PktTypeSoF, PktTypeToken, PktTypeData, PktTypeHandshake} pkt_type_e; + typedef enum bit [7:0] {PidTypeOutToken = 8'b0001_1110, PidTypeInToken = 8'b1001_0110, + PidTypeSofToken = 8'b0101_1010, PidTypeSetupToken = 8'b1101_0010, + PidTypeData0 = 8'b0011_1100, PidTypeData1 = 8'b1011_0100, PidTypeData2 = 8'b0111_1000, + PidTypeMData = 8'b1111_0000, PidTypeAck = 8'b0010_1101, PidTypeNak = 8'b1010_0101, + PidTypeStall = 8'b1110_0001, PidTypeNyet = 8'b0110_1001} pid_type_e; + + typedef enum byte {bmRequestType0 = 8'b0_00_00000, bmRequestType1 = 8'b0_00_00001, + bmRequestType2 = 8'b0_00_00010, bmRequestType3 = 8'b1_00_00000, + bmRequestType4 = 8'b1_00_00001, bmRequestType5 = 8'b1_00_00010} bmrequesttype_e; + + typedef enum byte {bRequestGET_STATUS = 8'h00, bRequestCLEAR_FEATURE = 8'h01, + bRequestSET_FEATURE = 8'h03, bRequestSET_ADDRESS = 8'h05, bRequestGET_DESCRIPTOR = 8'h06, + bRequestSET_DESCRIPTOR = 8'h07, bRequestGET_CONFIGURATION = 8'h08, + bRequestSET_CONFIGURATION = 8'h09, bRequestGET_INTERFACE = 8'h0A, + bRequestSET_INTERFACE = 8'h0B, bRequestSYNCH_FRAME = 8'h0C} brequest_e; // local types // forward declare classes to allow typedefs below typedef class usb20_item; @@ -21,7 +36,7 @@ package usb20_agent_pkg; // reuse dv_base_seqeuencer as is with the right parameter set typedef dv_base_sequencer #(.ITEM_T (usb20_item), - .CFG_T (usb20_agent_cfg)) usb20_sequencer; + .CFG_T (usb20_agent_cfg)) usb20_sequencer; // functions diff --git a/hw/dv/sv/usb20_agent/usb20_driver.sv b/hw/dv/sv/usb20_agent/usb20_driver.sv index 004d7d5f7e9be..ef24b73c826f1 100644 --- a/hw/dv/sv/usb20_agent/usb20_driver.sv +++ b/hw/dv/sv/usb20_agent/usb20_driver.sv @@ -2,12 +2,12 @@ // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 - class usb20_driver extends dv_base_driver #(usb20_item, usb20_agent_cfg); `uvm_component_utils(usb20_driver) `uvm_component_new - int usb_rst_time =100_000; // upto 10ms + + int usb_rst_time = 100_000; // upto 10ms int usb_idle_clk_cycles = 5; bit [7:0] SYNC_PATTERN = 8'b1000_0000; bit [1:0] EOP = 2'b00; @@ -17,8 +17,8 @@ class usb20_driver extends dv_base_driver #(usb20_item, usb20_agent_cfg); function void build_phase(uvm_phase phase); super.build_phase(phase); - if (!uvm_config_db#(virtual usb20_block_if)::get(this, "*.env.m_usb20_agent*", "bif", cfg.bif)) - begin + 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 endfunction @@ -36,25 +36,24 @@ class usb20_driver extends dv_base_driver #(usb20_item, usb20_agent_cfg); usb20_item seq_item; usb20_item rsp_item; forever begin - if( cfg.if_mode == Host) begin + if (cfg.if_mode == Host) begin seq_item_port.get_next_item(seq_item); - $cast(rsp_item,seq_item.clone()); + $cast(rsp_item, seq_item.clone()); rsp_item.set_id_info(seq_item); - if (seq_item.m_pkt_type==PktTypeToken) begin + if (seq_item.m_pkt_type == PktTypeToken) begin prepare_token_packet(seq_item, rsp_item); - end else if (seq_item.m_pkt_type== PktTypeData) begin + end else if (seq_item.m_pkt_type == PktTypeData) begin prepare_data_packet(seq_item, rsp_item); end else if (seq_item.m_pkt_type == PktTypeHandshake) begin prepare_handshake_packet(seq_item, rsp_item); - end else if (seq_item.m_pkt_type== PktTypeSoF) begin - prepare_sof_packet( seq_item, rsp_item); + end else if (seq_item.m_pkt_type == PktTypeSoF) begin + prepare_sof_packet(seq_item, rsp_item); end end end endtask - - task prepare_token_packet( usb20_item seq_item, usb20_item rsp_item); + task prepare_token_packet(usb20_item seq_item, usb20_item rsp_item); bit driver_token_pkt[]; bit comp_token_pkt[]; $cast(m_token_pkt, seq_item); @@ -67,16 +66,22 @@ class usb20_driver extends dv_base_driver #(usb20_item, usb20_agent_cfg); m_token_pkt.crc5 = {<<{m_token_pkt.crc5}}; m_token_pkt.pack(driver_token_pkt); // to make complete packet need to attach SYNC at start of packet - comp_token_pkt = new[driver_token_pkt.size() +8]; - for (int i = 0; i < 8; i = i + 1) begin + comp_token_pkt = new[driver_token_pkt.size() + 8]; + for (int i = 0; i < 8; i++) begin comp_token_pkt[i] = SYNC_PATTERN[i]; end - for (int i = 0; i < driver_token_pkt.size(); i = i + 1) begin + for (int i = 0; i < driver_token_pkt.size(); i++) begin comp_token_pkt[i + 8] = driver_token_pkt[i]; end - `uvm_info(`gfn, $sformatf(" Complete Token_Packet=%p", comp_token_pkt), UVM_LOW) + `uvm_info(`gfn, $sformatf("Complete Token_Packet = %p", comp_token_pkt), UVM_DEBUG) drive_pkt(comp_token_pkt); - seq_item_port.item_done(); + if (seq_item.m_pid_type == PidTypeInToken) begin + get_dut_response(rsp_item); + seq_item_port.item_done(rsp_item); + `uvm_info (`gfn, $sformatf("In drive afer In packet : \n %0s", rsp_item.sprint()), UVM_DEBUG) + end else begin + seq_item_port.item_done(); + end endtask task prepare_data_packet (usb20_item seq_item, usb20_item rsp_item); @@ -87,20 +92,23 @@ class usb20_driver extends dv_base_driver #(usb20_item, usb20_agent_cfg); // Modified each field of the packet to start with the Least Significant Bit (LSB) m_data_pkt.m_pid_type = {<<4{m_data_pkt.m_pid_type}}; m_data_pkt.m_pid_type = {<<{m_data_pkt.m_pid_type}}; + m_data_pkt.data = {<<8{m_data_pkt.data}}; m_data_pkt.data = {<<{m_data_pkt.data}}; + m_data_pkt.crc16 = {<<{m_data_pkt.crc16}}; m_data_pkt.pack(driver_data_pkt); - `uvm_info(`gfn, $sformatf(" Driver Data_Packet=%p", driver_data_pkt), UVM_LOW) - // to make complete packet need to attach SYNC at start of packet - comp_data_pkt = new[driver_data_pkt.size() +8]; - for (int i = 0; i < 8; i = i + 1) begin + `uvm_info(`gfn, $sformatf("Driver Data_Packet = %p", driver_data_pkt), UVM_DEBUG) + // To make complete packet need to attach SYNC at start of packet + comp_data_pkt = new[driver_data_pkt.size() + 8]; + for (int i = 0; i < 8; i++) begin comp_data_pkt[i] = SYNC_PATTERN[i]; end - for (int i = 0; i < driver_data_pkt.size(); i = i + 1) begin + for (int i = 0; i < driver_data_pkt.size(); i++) begin comp_data_pkt[i + 8] = driver_data_pkt[i]; end - `uvm_info(`gfn, $sformatf(" Complete Data_Packet=%p", comp_data_pkt), UVM_LOW) + `uvm_info(`gfn, $sformatf("Complete Data_Packet = %p", comp_data_pkt), UVM_DEBUG) drive_pkt(comp_data_pkt); - seq_item_port.item_done(); + get_dut_response(rsp_item); + seq_item_port.item_done(rsp_item); endtask task prepare_handshake_packet(usb20_item seq_item, usb20_item rsp_item); @@ -110,54 +118,53 @@ class usb20_driver extends dv_base_driver #(usb20_item, usb20_agent_cfg); m_handshake_pkt.m_pid_type = {<<4{m_handshake_pkt.m_pid_type}}; m_handshake_pkt.m_pid_type = {<<{m_handshake_pkt.m_pid_type}}; m_handshake_pkt.pack(driver_handshake_pkt); - `uvm_info(`gfn, $sformatf("Driver Handshake_Packet=%p", driver_handshake_pkt), UVM_LOW) - // to make complete packet need to attach SYNC at start of packet - comp_handshake_pkt = new[driver_handshake_pkt.size() +8]; - for (int i = 0; i < 8; i = i + 1) begin + `uvm_info(`gfn, $sformatf("Driver Handshake_Packet = %p", driver_handshake_pkt), UVM_DEBUG) + // To make complete packet need to attach SYNC at start of packet + comp_handshake_pkt = new[driver_handshake_pkt.size() + 8]; + for (int i = 0; i < 8; i++) begin comp_handshake_pkt[i] = SYNC_PATTERN[i]; end - for (int i = 0; i < driver_handshake_pkt.size(); i = i + 1) begin + for (int i = 0; i < driver_handshake_pkt.size(); i++) begin comp_handshake_pkt[i + 8] = driver_handshake_pkt[i]; end - `uvm_info(`gfn, $sformatf(" Complete Handshake_Packet=%p", comp_handshake_pkt), UVM_LOW) + `uvm_info(`gfn, $sformatf("Complete Handshake_Packet = %p", comp_handshake_pkt), UVM_DEBUG) drive_pkt(comp_handshake_pkt); seq_item_port.item_done(); endtask task prepare_sof_packet( usb20_item seq_item, usb20_item rsp_item); - //TODO: Drive method to drive SOF packet + // TODO: Drive method to drive SOF packet endtask task drive_pkt(bit comp_pkt[]); bit nrzi_out[]; - + bit bit_stuff_out[]; // Bit Stuffing performed on packet - bit_stuffing(comp_pkt); - + bit_stuffing(comp_pkt, bit_stuff_out); + `uvm_info(`gfn, $sformatf("Complete Packet after BIT STUFFING = %p", bit_stuff_out), UVM_DEBUG) // NRZI Implementation - nrzi_encoder(comp_pkt,nrzi_out); - `uvm_info(`gfn, $sformatf(" Complete Packet after NRZI=%p", nrzi_out), UVM_LOW) + nrzi_encoder(bit_stuff_out, nrzi_out); + `uvm_info(`gfn, $sformatf("Complete Packet after NRZI = %p", nrzi_out), UVM_DEBUG) // Loop to drive packet bit by bit - for (int i=0; i < nrzi_out.size(); i= i + 1) begin + for (int i = 0; i < nrzi_out.size(); i++) begin @(posedge cfg.bif.usb_clk) begin cfg.bif.drive_p = nrzi_out[i]; cfg.bif.drive_n = ~nrzi_out[i]; end end end_of_packet(); - // seq_item_port.item_done(); endtask - // EOP Task + // EOP Task // ------------------------------- task end_of_packet(); - for (int j =0; j <2; j=j+1) begin + for (int j = 0; j < 2; j++) begin @(posedge cfg.bif.usb_clk) cfg.bif.drive_p = EOP[j]; cfg.bif.drive_n = EOP[j]; end @(posedge cfg.bif.usb_clk) begin - `uvm_info(`gfn, "\n After EOP Idle state", UVM_LOW) + `uvm_info(`gfn, "\n After EOP Idle state", UVM_DEBUG) cfg.bif.drive_p = 1'b1; cfg.bif.drive_n = 1'b0; end @@ -165,28 +172,28 @@ class usb20_driver extends dv_base_driver #(usb20_item, usb20_agent_cfg); // Bit Stuffing Task // ------------------------------- - task bit_stuffing(input bit packet[]); + task bit_stuffing(input bit packet[], output bit bit_stuff_out[]); int consecutive_ones_count = 0; for (int i = 0; i < packet.size(); i++) begin if (packet[i] == 1'b1) begin - consecutive_ones_count = consecutive_ones_count +1; + consecutive_ones_count = consecutive_ones_count + 1; if (consecutive_ones_count == 6) begin - packet = new [packet.size() +1] (packet); + packet = new[packet.size() + 1](packet); for (int j = packet.size() ; j > i; j = j - 1) begin packet[j] = packet[j - 1]; end - i=i+1; + i = i + 1; packet[i] = 1'b0; consecutive_ones_count = 0; - end - end else if (packet[i] ==1'b0) begin - consecutive_ones_count =0; + end + end else if (packet[i] == 1'b0) begin + consecutive_ones_count = 0; end end - `uvm_info(`gfn, $sformatf("Bit_stuffing result: %p", packet), UVM_LOW) + bit_stuff_out = packet; endtask - // NRZI Encoding Task + // NRZI Encoding/Decoding Task // ------------------------------- task nrzi_encoder(input bit packet[], output bit nrzi_out[]); @@ -202,15 +209,30 @@ class usb20_driver extends dv_base_driver #(usb20_item, usb20_agent_cfg); end endtask + task nrzi_decoder(input bit nrzi_in[], output bit decoded_packet[]); + bit prev_bit = 1'b1; + decoded_packet = new[nrzi_in.size()]; + for (int i = 0; i < nrzi_in.size(); i++) begin + if (nrzi_in[i] == prev_bit) begin + // If the current NRZI bit matches the previous bit, it's a 0. + decoded_packet[i] = 1'b1; + end else begin + // If the current NRZI bit is different from the previous bit, it's a 1. + decoded_packet[i] = 1'b0; + end + prev_bit = nrzi_in[i]; + end + endtask + // RESET signals Task // ------------------------------- - virtual task reset_signals(); + virtual task reset_signals(); cfg.bif.usb_rx_d_i = 1'b1; cfg.bif.usb_vbus = 1'b1; - cfg.bif.drive_p =1'b1; - cfg.bif.drive_n =1'b1; + cfg.bif.drive_p = 1'b1; + cfg.bif.drive_n = 1'b1; @(posedge cfg.bif.rst_ni); - `uvm_info(`gfn, "\n Hardware Reset in Progress", UVM_LOW) + `uvm_info(`gfn, "Hardware Reset in Progress", UVM_DEBUG) cfg.bif.usb_vbus = 1'b0; cfg.bif.drive_p = 1'bz; cfg.bif.drive_n = 1'bz; @@ -218,30 +240,53 @@ class usb20_driver extends dv_base_driver #(usb20_item, usb20_agent_cfg); cfg.bif.usb_vbus = 1'b1; cfg.bif.drive_p = 1'b1; cfg.bif.drive_n = 1'b0; - `uvm_info(`gfn, "\n Out of Hardware Reset", UVM_LOW) + `uvm_info(`gfn, "Out of Hardware Reset", UVM_DEBUG) bus_reset(); endtask // USB Bus Reset Task // ------------------------------- task bus_reset(); - `uvm_info(`gfn, "\n USB Bus Reset Started", UVM_LOW) @(posedge cfg.bif.usb_clk) - cfg.bif.drive_p =1'b1; - cfg.bif.drive_n =1'b0; + cfg.bif.drive_p = 1'b1; + cfg.bif.drive_n = 1'b0; // Waitfor device active state - `DV_SPINWAIT(wait(cfg.bif.usb_dp_pullup_o == 1'b1);,"timeout waiting for usb_pullup", 500_000) - `uvm_info(`gfn, "\n BUS is in reset phase", UVM_LOW) + `DV_SPINWAIT(wait(cfg.bif.usb_dp_pullup_o);, "timeout waiting for usb_pullup", 500_000) @(posedge cfg.bif.usb_clk) - cfg.bif.drive_p =1'b0; - cfg.bif.drive_n =1'b0; + cfg.bif.drive_p = 1'b0; + cfg.bif.drive_n = 1'b0; // Reset bus or drive 0 on both DP and DN for 10ms repeat(usb_rst_time) @(posedge cfg.bif.usb_clk); - `uvm_info(`gfn, "\n Reset for 10ms completed", UVM_LOW) + `uvm_info(`gfn, "Reset for 10ms completed", UVM_DEBUG) // After reset change state to IDLE @(posedge cfg.bif.usb_clk) - cfg.bif.drive_p =1'b1; - cfg.bif.drive_n =1'b0; + cfg.bif.drive_p = 1'b1; + cfg.bif.drive_n = 1'b0; repeat(usb_idle_clk_cycles) @(posedge cfg.bif.usb_clk); endtask + + // Get_DUT_Response + // ------------------------------- + task get_dut_response(usb20_item rsp_item); + bit received_pkt[]; + bit decoded_received_pkt[]; + int receive_index = 0; + bit [7:0] received_pid = 0; + `uvm_info(`gfn, "After drive Packet in wait to check usb_dp_en_o signal", UVM_DEBUG) + wait(cfg.bif.usb_dp_en_o); + while (cfg.bif.usb_dp_en_o) begin + received_pkt = new[received_pkt.size() + 1](received_pkt); + @(posedge cfg.bif.usb_clk) + received_pkt[receive_index] = cfg.bif.usb_p; + receive_index = receive_index + 1; + end + `uvm_info(`gfn, $sformatf("Received Packet = %p", received_pkt), UVM_LOW) + nrzi_decoder (received_pkt, decoded_received_pkt); + `uvm_info(`gfn, $sformatf("Decoded Received Packet = %p", decoded_received_pkt), UVM_LOW) + for (int i = 0 ; i < 8; i++) begin + received_pid[i] = decoded_received_pkt[i + 8]; + end + received_pid = {<<4{received_pid}}; + rsp_item.m_pid_type = received_pid; + endtask endclass diff --git a/hw/dv/sv/usb20_agent/usb20_item.sv b/hw/dv/sv/usb20_agent/usb20_item.sv index f28588f34651a..a17a335ac3f6a 100644 --- a/hw/dv/sv/usb20_agent/usb20_item.sv +++ b/hw/dv/sv/usb20_agent/usb20_item.sv @@ -2,86 +2,152 @@ // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 -typedef enum bit [2:0] {PktTypeSoF, PktTypeToken, PktTypeData, PktTypeHandshake} pkt_type_e; -typedef enum bit [7:0] {PidTypeOutToken=8'b0001_1110, PidTypeInToken=8'b1001_0110, - PidTypeSofToken=8'b0101_1010, PidTypeSetupToken=8'b1101_0010, PidTypeData0=8'b0011_1100, - PidTypeData1=8'b1011_0100, PidTypeData2=8'b0111_1000, PidTypeMData=8'b1111_0000, - PidTypeAck=8'b0010_1101, PidTypeNak=8'b1010_0101, PidTypeStall=8'b1110_0001, - PidTypeNyet=8'b0110_1001} pid_type_e; - class usb20_item extends uvm_sequence_item; pid_type_e m_pid_type; pkt_type_e m_pkt_type; + bmrequesttype_e m_bmRT; + brequest_e m_bR; `uvm_object_new + endclass class token_pkt extends usb20_item; - rand bit [6:0] address; rand bit [3:0] endpoint; bit [4:0] crc5; - constraint endpoint_c{ + constraint endpoint_c { endpoint inside {[0:11]}; } - `uvm_object_utils_begin (token_pkt) - `uvm_field_enum(pid_type_e, m_pid_type, UVM_DEFAULT) - `uvm_field_int(address, UVM_DEFAULT) - `uvm_field_int(endpoint, UVM_DEFAULT) - `uvm_field_int(crc5, UVM_DEFAULT) + `uvm_object_utils_begin(token_pkt) + `uvm_field_enum(pid_type_e, m_pid_type, UVM_DEFAULT) + `uvm_field_int(address, UVM_DEFAULT) + `uvm_field_int(endpoint, UVM_DEFAULT) + `uvm_field_int(crc5, UVM_DEFAULT) `uvm_object_utils_end `uvm_object_new function void post_randomize(); - crc5 = generate_crc5(address,endpoint); + crc5 = generate_crc5(address, endpoint); endfunction - function bit [4:0] generate_crc5(bit [6:0] address,bit [3:0] endpoint); + function bit [4:0] generate_crc5(bit [6:0] address, bit [3:0] endpoint); bit [4:0] crc; bit [4:0] crc_reg; bit [10:0] data; bit [4:0] polynomial = 5'b0_0101; bit as1; bit [4:0] as2; - data = {endpoint,address}; + data = {endpoint, address}; crc_reg = 5'b1_1111; for (int i = 0; i <= 10; i++) begin as1 = data[i] ^ crc_reg[4]; - as2 = ({crc_reg[3:2], (as1^crc_reg[1]),crc_reg[0],as1}); + as2 = ({crc_reg[3:2], (as1 ^ crc_reg[1]), crc_reg[0], as1}); crc_reg = as2; end - crc = ~{crc_reg[0],crc_reg[1],crc_reg[2],crc_reg[3],crc_reg[4]}; + crc = ~{crc_reg[0], crc_reg[1], crc_reg[2], crc_reg[3], crc_reg[4]}; return crc; endfunction endclass class data_pkt extends usb20_item; - rand bit data []; - bit [15:0] crc16; - // TODO: Sequence item for data packet - `uvm_object_utils_begin (data_pkt) + bit [15:0] crc16; + rand byte unsigned data[]; // Dynamic array + + `uvm_object_utils_begin(data_pkt) + `uvm_field_enum(pid_type_e, m_pid_type, UVM_DEFAULT) + `uvm_field_array_int(data, UVM_DEFAULT) + `uvm_field_int(crc16, UVM_DEFAULT) `uvm_object_utils_end `uvm_object_new + constraint data_c { + data.size() <= 64; + } + + function void set_payload(byte bmRequestType, byte bRequest, byte wVH, byte wVL, byte wIH, + byte wIL, byte wLH, byte wLL); + + data = '{bmRequestType, bRequest, wVH, wVL, wIH, wIL, wLH, wLL}; + crc16 = generate_crc16(data); + endfunction + + function void post_randomize(); + crc16 = generate_crc16(data); + endfunction + + function bit [15:0] generate_crc16(input byte unsigned data[]); + bit [15:0] crc; + bit [15:0] crc_reg; + bit as1; + bit [15:0] as2; + bit [15:0] polynomial = 16'h8005; + bit data1[]; + typedef bit data_result[] ; + data_result data_array; + data_array = data_result'(data); + crc = 16'b1111_1111_1111_1111; + data_array = {<<8{data_array}}; + data_array = {<<{data_array}}; + for (int i = 0; i < data_array.size(); i++) begin + if ((crc[15] ^ data_array[i]) == 1) begin + crc = {crc[14:0], 1'b0} ^ polynomial; + end + else begin + crc = {crc[14:0], 1'b0}; + end + end + crc = ~crc; + crc = {<<{crc}}; + return crc; + endfunction endclass class sof_pkt extends usb20_item; - // TODO: Sequence item for sof packet + rand bit [10:0] framecnt ; + bit [4:0] crc5; + `uvm_object_utils_begin (sof_pkt) + `uvm_field_enum(pid_type_e, m_pid_type, UVM_DEFAULT) + `uvm_field_int(framecnt, UVM_DEFAULT) + `uvm_field_int(crc5 , UVM_DEFAULT) `uvm_object_utils_end `uvm_object_new + function void post_randomize(); + crc5 = generate_crc5(); + endfunction + + function bit [4:0] generate_crc5(); + bit [4:0] crc; + bit [4:0] crc_reg; + bit [10:0] data; + bit [4:0] polynomial = 5'b0_0101; + bit as1; + bit [4:0] as2; + data = framecnt; + crc_reg = 5'b1_1111; + for (int i = 0; i <= 10; i++) begin + as1 = data[i] ^ crc_reg[4]; + as2 = ({crc_reg[3:2], (as1 ^ crc_reg[1]), crc_reg[0], as1}); + crc_reg = as2; + end + crc = ~{crc_reg[0], crc_reg[1], crc_reg[2], crc_reg[3], crc_reg[4]}; + return crc; + endfunction + endclass class handshake_pkt extends usb20_item; - // TODO: Sequence item for handshake packet `uvm_object_utils_begin (handshake_pkt) + `uvm_field_enum(pid_type_e, m_pid_type, UVM_DEFAULT) `uvm_object_utils_end `uvm_object_new + endclass