In the previous sections, we focussed mainly on introductory and syntax aspects of 'e'. However, it is important for a verification engineer to understand how to build a complete verification system with 'e'. This section discusses the complete verification process of a simple USB packet's pid decoder. This section also discusses the specification of USB's packet ID decoder, verification components, verification plan and test plan.
DUT Specification
This section describes the complete DUT specification of a simple USB packet ID decoder. Figure shows the input/output specification of the DUT. The PID Decoder accepts data packet on a single 8-bit input port called 'data_in' and in combination with the transceiver signals - rxvalid, rxlastbyte and rxbserror - it decodes the packet ID.
Data Packet Description
A token packet is a sequence of bytes with first 4 bytes containing sync field, the next set of bytes containing data and the last byte containing CRC. The packet format has the following characteristics.
This section describes the complete DUT specification of a simple USB packet ID decoder. Figure shows the input/output specification of the DUT. The PID Decoder accepts data packet on a single 8-bit input port called 'data_in' and in combination with the transceiver signals - rxvalid, rxlastbyte and rxbserror - it decodes the packet ID.
Data Packet Description
A token packet is a sequence of bytes with first 4 bytes containing sync field, the next set of bytes containing data and the last byte containing CRC. The packet format has the following characteristics.
- The 'SYNC' consists of 32 bits - 32'h8000_0000 ( The LSB is transmitted first)
- PID is 8 bits. The first 4 bits are 'type' field and the next 4 bits are compliment of 'type'
- Address is 7 bits.
- Endpoint is 4 bits.
- CRC5 is 5 bits
All packets begin with a synchronization (SYNC) field. A SYNC from an initial transmitter is defined to be 32 bits for high-speed. SYNC serves only as a synchronization mechanism. The last two bits in the SYNC field are a marker that is used to identify the end of the SYNC field and the start of the PID.
A packet identifier (PID) immediately follows the SYNC field of every USB packet. A PID consists of a four-bit packet type field followed by a four-bit check field. The PID indicates the type of packet. The four-bit check field of the PID ensures reliable decoding of the PID so that the remainder of the packet is interpreted correctly. The PID check field is generated by performing a one' s complement of the packet type field. A PID error exists if the four PID check bits are not complements of their respective packet identifier bits.
DUT Input Protocol
Figure shows the input protocol of the DUT. The characteristics of the DUT input protocol are as follows:
A packet identifier (PID) immediately follows the SYNC field of every USB packet. A PID consists of a four-bit packet type field followed by a four-bit check field. The PID indicates the type of packet. The four-bit check field of the PID ensures reliable decoding of the PID so that the remainder of the packet is interpreted correctly. The PID check field is generated by performing a one' s complement of the packet type field. A PID error exists if the four PID check bits are not complements of their respective packet identifier bits.
DUT Input Protocol
Figure shows the input protocol of the DUT. The characteristics of the DUT input protocol are as follows:
- All input signals are active high and are synchronized to the rising edge of the clock. Therefore, any signal that is an input to the DUT is driven at the rising edge of the clock.
- The rx_valid signal has to be asserted on the same clock after the sync packet is transmitted.
- The rx_last_byte signal has to be asserted if the EOP is on the higher order byte and valid data is on the lower order byte.
DUT Output Protocol
Figure shows the output protocol of DUT. The characteristics of the DUT output protocol are as follows:
- All output signals are active high and are synchronized to the rising edge of the clock. Therefore, any signal that is an output from the DUT is sampled at the rising edge of the clock.
- The Decoder asserts the 'in_token' when it detects '69' in the 'PID' field & the edge of rx_valid signal.
- The Decoder asserts the 'out_token' when it detects 'E1' in the 'PID' field & the edge of rx_valid signal.
- The Decoder asserts the 'setup_token' when it detects '2D' in the 'PID' field & the edge of rx_valid signal.
- The Decoder asserts the 'pid_err_out' when 'type' field and its compliment doesn't match & the edge of rx_valid signal.
DUT HDL Source Code
Example shows the verilog source code used to describe the DUT PID Decoder.
//***************************************************************************************************************
// Block : pid_dec
// Description : This block decodes the pid and asserts the corresponding
// tokens and also asserts the pid error if the last four bits
// are not the compliment of the first four bits
//***************************************************************************************************************
module pid_dec
(
// Inputs
clock_in,
reset_in,
rx_valid,
rx_last_byte,
rx_bs_err,
data_in,
// Outputs
in_token_out,
out_token_out,
setup_token_out,
pid_error_out,
invalid_token_out
);
// Inputs
input clock_in;
input reset_in;
input[15:0] data_in;
input rx_valid;
input rx_last_byte;
input rx_bs_err;
// Outputs
output in_token_out;
output out_token_out;
output setup_token_out;
output invalid_token_out;
output pid_error_out;
reg in_token_out;
reg out_token_out;
reg setup_token_out;
reg invalid_token_out;
reg pid_error_out;
// Signal Declarations
reg next_in;
reg next_out;
reg next_setup;
reg next_invalid;
reg next_pid_err;
reg rx_valid_r;
wire rx_valid_edge;
assign rx_valid_edge = rx_valid & ~rx_valid_r;
// Signal Assignments .
//***************************************************************************************************************
// Process for PID Decode
//***************************************************************************************************************
always @(data_in)
begin : hpdc_main
next_in = 1'b0 ;
next_out = 1'b0 ;
next_setup = 1'b0 ;
next_invalid = 1'b0 ;
next_pid_err = 1'b0 ;
// Here last four bits are taken and compared with its
// compliment inorder to verify whether the pid and
// its complement are proper
case (data_in[11:8])
4'b0001 :
// Decoding OUT PID
begin
if ((data_in[15:12] == ~(data_in[11:8])) && rx_valid_edge)
begin
next_out = 1'b1 ;
next_pid_err = 1'b0 ;
end
else if ((data_in[15:12] != ~(data_in[11:8])) && rx_valid_edge)
begin
next_pid_err = 1'b1 ;
end
else
next_pid_err = 1'b0 ;
end
4'b1001 :
// Decoding IN PID
begin
if ((data_in[15:12] == ~(data_in[11:8])) && rx_valid_edge)
begin
next_in = 1'b1 ;
next_pid_err = 1'b0 ;
end
else if ((data_in[15:12] != ~(data_in[11:8])) && rx_valid_edge)
begin
next_pid_err = 1'b1 ;
end
else
next_pid_err = 1'b0 ;
end
4'b1101 :
// Decoding SETUP PID
begin
if ((data_in[15:12] == ~(data_in[11:8])) && rx_valid_edge)
begin
next_setup = 1'b1 ;
next_pid_err = 1'b0 ;
end
else if ((data_in[15:12] != ~(data_in[11:8])) && rx_valid_edge)
begin
next_pid_err = 1'b1 ;
end
else
next_pid_err = 1'b0 ;
end
// Incase the incoming bit stream contains anything other than
// the expected value then this default state is entered
default :
begin
next_invalid = 1'b1 ;
end
endcase
end
//***************************************************************************************************************
// Process for latching the Decoded PID
//***************************************************************************************************************
always @(negedge reset_in or posedge clock_in)
begin : hpdc_regs
if (reset_in)
begin
in_token_out <= 1'b0 ;
out_token_out <= 1'b0 ;
setup_token_out <= 1'b0 ;
invalid_token_out <= 1'b0 ;
pid_error_out <= 1'b0 ;
rx_valid_r <= 1'b0;
end
else
begin
begin
in_token_out <= next_in ;
out_token_out <= next_out ;
setup_token_out <= next_setup ;
invalid_token_out <= next_invalid ;
pid_error_out <= next_pid_err ;
rx_valid_r <= rx_valid;
end
end
end
endmodule
Test bench
module pid_dec_TB;
reg clock_in;
reg reset_in;
reg [15:0] data_in;
reg rx_valid;
reg rx_last_byte;
reg rx_bs_err;
wire in_token_out;
wire out_token_out;
wire setup_token_out;
wire pid_error_out;
wire invalid_token_out;
pid_dec inst_pid_dec
(
.clock_in(clock_in),
.reset_in(reset_in),
.data_in(data_in),
.rx_valid(rx_valid),
.rx_last_byte(rx_last_byte),
.rx_bs_err(rx_bs_err),
.in_token_out(in_token_out),
.out_token_out(out_token_out),
.setup_token_out(setup_token_out),
.pid_error_out(pid_error_out),
.invalid_token_out(invalid_token_out)
);
specman sn();
// clock_in generation logic
initial
begin
clock_in = 1'b0;
reset_in = 1'b1;
forever
#5 clock_in = ~clock_in;
end
initial
begin
#100 reset_in = 1'b0;
end
endmodule // pid_dec_TB
Verification Plan
A verification plan is required to describe what is to be verified and how it will be verified. It also should address 3 aspects of verification.
- Coverage measuresment
- Stimulus Generation
- Response Checking
The verification will be developed in 'e'.
Test Plan
Tests are derived from test plan. A test plan contains all tests that are to be run to verify the DUT. A test plan contains an exhaustive list of items to be tested. In 'e' tests are simply the extensions of existing structs and unit definitions.
Test1
Create the packets with a certain probability distribution.
No comments:
Post a Comment