URL
https://opencores.org/ocsvn/uart2bus_testbench/uart2bus_testbench/trunk
Subversion Repositories uart2bus_testbench
Compare Revisions
- This comparison shows the changes necessary to convert path
/uart2bus_testbench/trunk
- from Rev 2 to Rev 3
- ↔ Reverse comparison
Rev 2 → Rev 3
/doc/uart2bus_verification_plan.odt
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/doc/uart2bus_verification_plan.pdf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tb/test/uart_test.svh
1,26 → 1,61
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// UART2BUS VERIFICATION |
// |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// CREATOR : HANY SALAH |
// PROJECT : UART2BUS UVM TEST BENCH |
// UNIT : TEST |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// TITLE : UART TEST |
// DESCRIPTION: This |
//----------------------------------------------------------------------------- |
// DESCRIPTION: THIS COMPONENT INCLUDES THE MAIN TESTS THAT WILL BE FORCED TO THE DUT. IT INCLUDES |
// VIRTUAL BASE TEST FUNCTION THAT SHARES THE MOST COMMON ATTRIBUTES OF ALL TESTS. |
// THE TESTS IMPLEMENTED THROUGH BELOW ARE RELATED TO THE TESTBENCH SPECIFICATIONS |
// DOCUMENT. YOU CAN DOWNLOAD IT DIRECTLY THROUGH OPENCORES.COM OR FIND IT IN THE DOC |
// DIRECTORY. |
//------------------------------------------------------------------------------------------------- |
// LOG DETAILS |
//------------- |
// VERSION NAME DATE DESCRIPTION |
// 1 HANY SALAH 10012016 FILE CREATION |
//----------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR |
// OPENCORES MEMBERS ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE |
// CREATOR'S PERMISSION |
//----------------------------------------------------------------------------- |
class uart_base_test extends uvm_test; |
|
// 2 HANY SALAH 20012016 ADD BINARY MODE TESTS AND INVALID TESTS |
// 3 HANY SALAH 12022016 IMPROVE BLOCK DESCRIPTION & ADD COMMENTS |
//------------------------------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR OPENCORES MEMBERS |
// ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE CREATOR'S PERMISSION |
//------------------------------------------------------------------------------------------------- |
|
// The base test class that includes the uvm printer and establish the whole environment. |
// It also responsible for setting the environment configurations described in details through the |
// testbench specifications document. |
// The environment configurations are set during the end of elaboration phase. It includes: |
// ---------------------------------------------------------------------------------------- |
// - The active edge : The active clock edge at which, the data is changed on the UART buses. |
// It could be positive edge or negative edge. |
// ---------------------------------------------------------------------------------------- |
// - The start bit : Represent the sequence through which the byte is serialized; either to |
// start with the most significant bit or the least significant bit. |
// ---------------------------------------------------------------------------------------- |
// - The data format : The data representation through the text commands either to be ASCII |
// format or ordinary binary format. |
// ---------------------------------------------------------------------------------------- |
// - The number of stop: The number of stop bits sent after the latest bit of each byte. It |
// bit(s) would be either one or two bits |
// ---------------------------------------------------------------------------------------- |
// - The number of bits: The number of bits within each transferred field. It would be either |
// in the field 7 or 8 bits per field. |
// ---------------------------------------------------------------------------------------- |
// - The parity mode : The used parity type of each field. It would be either no parity bit, |
// odd parity or even parity. |
// ---------------------------------------------------------------------------------------- |
// - The response time : Represent the maximum allowable time within which DUT should respond |
// to the driven request. |
// ---------------------------------------------------------------------------------------- |
// - The false data : Enable force false data on the output port within the read command |
// enable through the both modes; text or binary. |
// ---------------------------------------------------------------------------------------- |
virtual class uart_base_test extends uvm_test; |
|
uart_env env; |
|
uvm_table_printer printer; |
58,7 → 93,8
_config.num_stop_bits = 1; |
_config.num_of_bits = 8; |
_config._paritymode = parity_off; |
_config.response_time = 10000; |
_config.response_time = 8680; |
_config.use_false_data= no; |
endfunction:end_of_elaboration_phase |
|
task run_phase (uvm_phase phase); |
66,252 → 102,488
endtask:run_phase |
endclass:uart_base_test |
|
//------------------------------------------------------------------------------------------------- |
// |
// PURE TEXT MODE TESTS |
// |
//------------------------------------------------------------------------------------------------- |
|
class write_text_mode extends uart_base_test; |
|
seq_1p1 seq1; |
seq_1p2 seq2; |
seq_1p3 seq3; |
seq_1p4 seq4; |
seq_1p5 seq5; |
seq_1p6 seq6; |
seq_1p7 seq7; |
seq_1p8 seq8; |
seq_1p9 seq9; |
seq_1p10 seq10; |
seq_1p11 seq11; |
// This test apply thirteen successive tests of UART write request using text communication mode. |
// Refer to test plan section in the testbench specifications document for more details. |
class write_text_mode extends uart_base_test; |
|
seq_1p1 seq1; |
seq_1p2 seq2; |
seq_1p3 seq3; |
seq_1p4 seq4; |
seq_1p5 seq5; |
seq_1p6 seq6; |
seq_1p7 seq7; |
seq_1p8 seq8; |
seq_1p9 seq9; |
seq_1p10 seq10; |
seq_1p11 seq11; |
seq_1p12 seq12; |
seq_1p13 seq13; |
|
`uvm_component_utils(write_text_mode) |
`uvm_component_utils(write_text_mode) |
|
function new (string name,uvm_component parent); |
super.new(name,parent); |
endfunction:new |
function new (string name,uvm_component parent); |
super.new(name,parent); |
endfunction:new |
|
function void build_phase (uvm_phase phase); |
super.build_phase (phase); |
seq1 = seq_1p1::type_id::create("seq1"); |
seq2 = seq_1p2::type_id::create("seq2"); |
seq3 = seq_1p3::type_id::create("seq3"); |
seq4 = seq_1p4::type_id::create("seq4"); |
seq5 = seq_1p5::type_id::create("seq5"); |
seq6 = seq_1p6::type_id::create("seq6"); |
seq7 = seq_1p7::type_id::create("seq7"); |
seq8 = seq_1p8::type_id::create("seq8"); |
seq9 = seq_1p9::type_id::create("seq9"); |
seq10 = seq_1p10::type_id::create("seq10"); |
seq11 = seq_1p11::type_id::create("seq11"); |
endfunction:build_phase |
function void build_phase (uvm_phase phase); |
super.build_phase (phase); |
seq1 = seq_1p1::type_id::create("seq1"); |
seq2 = seq_1p2::type_id::create("seq2"); |
seq3 = seq_1p3::type_id::create("seq3"); |
seq4 = seq_1p4::type_id::create("seq4"); |
seq5 = seq_1p5::type_id::create("seq5"); |
seq6 = seq_1p6::type_id::create("seq6"); |
seq7 = seq_1p7::type_id::create("seq7"); |
seq8 = seq_1p8::type_id::create("seq8"); |
seq9 = seq_1p9::type_id::create("seq9"); |
seq10 = seq_1p10::type_id::create("seq10"); |
seq11 = seq_1p11::type_id::create("seq11"); |
seq12 = seq_1p12::type_id::create("seq12"); |
seq13 = seq_1p13::type_id::create("seq13"); |
endfunction:build_phase |
|
|
task run_phase (uvm_phase phase); |
super.run_phase(phase); |
phase.raise_objection(this); |
seq1.start(env.agent._seq,null); |
seq2.start(env.agent._seq,null); |
seq3.start(env.agent._seq,null); |
seq4.start(env.agent._seq,null); |
seq5.start(env.agent._seq,null); |
seq6.start(env.agent._seq,null); |
seq7.start(env.agent._seq,null); |
seq8.start(env.agent._seq,null); |
seq9.start(env.agent._seq,null); |
seq10.start(env.agent._seq,null); |
seq11.start(env.agent._seq,null); |
phase.drop_objection(this); |
endtask:run_phase |
endclass:write_text_mode |
task run_phase (uvm_phase phase); |
super.run_phase(phase); |
phase.raise_objection(this); |
seq1.start(env.agent._seq,null); |
seq2.start(env.agent._seq,null); |
seq3.start(env.agent._seq,null); |
seq4.start(env.agent._seq,null); |
seq5.start(env.agent._seq,null); |
seq6.start(env.agent._seq,null); |
seq7.start(env.agent._seq,null); |
seq8.start(env.agent._seq,null); |
seq9.start(env.agent._seq,null); |
seq10.start(env.agent._seq,null); |
seq11.start(env.agent._seq,null); |
seq12.start(env.agent._seq,null); |
seq13.start(env.agent._seq,null); |
phase.drop_objection(this); |
endtask:run_phase |
endclass:write_text_mode |
|
// This test apply thirteen successive tests of UART read request using text communication mode. |
// Refer to test plan section in the testbench specifications document for more details. |
class read_text_mode extends uart_base_test; |
|
seq_2p1 seq1; |
seq_2p2 seq2; |
seq_2p3 seq3; |
seq_2p4 seq4; |
seq_2p5 seq5; |
seq_2p6 seq6; |
seq_2p7 seq7; |
seq_2p8 seq8; |
seq_2p9 seq9; |
seq_2p10 seq10; |
seq_2p11 seq11; |
seq_2p12 seq12; |
seq_2p13 seq13; |
|
class read_text_mode extends uart_base_test; |
|
seq_2p1 seq1; |
seq_2p2 seq2; |
seq_2p3 seq3; |
seq_2p4 seq4; |
seq_2p5 seq5; |
seq_2p6 seq6; |
seq_2p7 seq7; |
seq_2p8 seq8; |
seq_2p9 seq9; |
seq_2p10 seq10; |
seq_2p11 seq11; |
|
`uvm_component_utils(read_text_mode) |
|
`uvm_component_utils(read_text_mode) |
function new (string name,uvm_component parent); |
super.new(name,parent); |
endfunction:new |
|
function new (string name,uvm_component parent); |
super.new(name,parent); |
endfunction:new |
function void build_phase (uvm_phase phase); |
super.build_phase(phase); |
seq1 = seq_2p1::type_id::create("seq1"); |
seq2 = seq_2p2::type_id::create("seq2"); |
seq3 = seq_2p3::type_id::create("seq3"); |
seq4 = seq_2p4::type_id::create("seq4"); |
seq5 = seq_2p5::type_id::create("seq5"); |
seq6 = seq_2p6::type_id::create("seq6"); |
seq7 = seq_2p7::type_id::create("seq7"); |
seq8 = seq_2p8::type_id::create("seq8"); |
seq9 = seq_2p9::type_id::create("seq9"); |
seq10 = seq_2p10::type_id::create("seq10"); |
seq11 = seq_2p11::type_id::create("seq11"); |
seq12 = seq_2p12::type_id::create("seq12"); |
seq13 = seq_2p13::type_id::create("seq13"); |
endfunction:build_phase |
|
function void build_phase (uvm_phase phase); |
super.build_phase(phase); |
seq1 = seq_2p1::type_id::create("seq1"); |
seq2 = seq_2p2::type_id::create("seq2"); |
seq3 = seq_2p3::type_id::create("seq3"); |
seq4 = seq_2p4::type_id::create("seq4"); |
seq5 = seq_2p5::type_id::create("seq5"); |
seq6 = seq_2p6::type_id::create("seq6"); |
seq7 = seq_2p7::type_id::create("seq7"); |
seq8 = seq_2p8::type_id::create("seq8"); |
seq9 = seq_2p9::type_id::create("seq9"); |
seq10 = seq_2p10::type_id::create("seq10"); |
seq11 = seq_2p11::type_id::create("seq11"); |
endfunction:build_phase |
task run_phase (uvm_phase phase); |
super.run_phase(phase); |
phase.raise_objection(this); |
seq1.start(env.agent._seq,null); |
seq2.start(env.agent._seq,null); |
seq3.start(env.agent._seq,null); |
seq4.start(env.agent._seq,null); |
seq5.start(env.agent._seq,null); |
seq6.start(env.agent._seq,null); |
seq7.start(env.agent._seq,null); |
seq8.start(env.agent._seq,null); |
seq9.start(env.agent._seq,null); |
seq10.start(env.agent._seq,null); |
seq11.start(env.agent._seq,null); |
seq12.start(env.agent._seq,null); |
seq13.start(env.agent._seq,null); |
phase.drop_objection(this); |
endtask:run_phase |
endclass:read_text_mode |
|
task run_phase (uvm_phase phase); |
super.run_phase(phase); |
phase.raise_objection(this); |
seq1.start(env.agent._seq,null); |
seq2.start(env.agent._seq,null); |
seq3.start(env.agent._seq,null); |
seq4.start(env.agent._seq,null); |
seq5.start(env.agent._seq,null); |
seq6.start(env.agent._seq,null); |
seq7.start(env.agent._seq,null); |
seq8.start(env.agent._seq,null); |
seq9.start(env.agent._seq,null); |
seq10.start(env.agent._seq,null); |
seq11.start(env.agent._seq,null); |
phase.drop_objection(this); |
endtask:run_phase |
endclass:read_text_mode |
//------------------------------------------------------------------------------------------------- |
// |
// PURE BINARY MODE TESTS |
// |
//------------------------------------------------------------------------------------------------- |
|
class nop_command_mode extends uart_base_test; |
|
seq_3p1 seq1; |
//seq_3p2 seq2; |
seq_3p3 seq3; |
seq_4p1 seq4; |
//seq_4p2 seq5; |
seq_4p3 seq6; |
// This test apply six successive tests of UART nop request using binary communication mode. |
// Refer to test plan section in the testbench specifications document for more details. |
class nop_command_mode extends uart_base_test; |
|
seq_3p1 seq1; |
seq_3p2 seq2; |
seq_3p3 seq3; |
seq_4p1 seq4; |
seq_4p2 seq5; |
seq_4p3 seq6; |
|
`uvm_component_utils(nop_command_mode) |
`uvm_component_utils(nop_command_mode) |
|
function new (string name,uvm_component parent); |
super.new(name,parent); |
endfunction:new |
function new (string name,uvm_component parent); |
super.new(name,parent); |
endfunction:new |
|
function void build_phase (uvm_phase phase); |
super.build_phase(phase); |
seq1 = seq_3p1::type_id::create("seq1"); |
//seq2 = seq_3p2::type_id::create("seq2"); |
seq3 = seq_3p3::type_id::create("seq3"); |
seq4 = seq_4p1::type_id::create("seq4"); |
//seq5 = seq_4p2::type_id::create("seq5"); |
seq6 = seq_4p3::type_id::create("seq6"); |
endfunction:build_phase |
function void build_phase (uvm_phase phase); |
super.build_phase(phase); |
seq1 = seq_3p1::type_id::create("seq1"); |
seq2 = seq_3p2::type_id::create("seq2"); |
seq3 = seq_3p3::type_id::create("seq3"); |
seq4 = seq_4p1::type_id::create("seq4"); |
seq5 = seq_4p2::type_id::create("seq5"); |
seq6 = seq_4p3::type_id::create("seq6"); |
endfunction:build_phase |
|
task run_phase(uvm_phase phase); |
super.run_phase(phase); |
phase.raise_objection(this); |
seq1.start(env.agent._seq,null); |
//seq2.start(env.agent._seq,null); |
seq3.start(env.agent._seq,null); |
seq4.start(env.agent._seq,null); |
//seq5.start(env.agent._seq,null); |
seq6.start(env.agent._seq,null); |
phase.drop_objection(this); |
endtask:run_phase |
endclass:nop_command_mode |
task run_phase(uvm_phase phase); |
super.run_phase(phase); |
phase.raise_objection(this); |
seq1.start(env.agent._seq,null); |
seq2.start(env.agent._seq,null); |
seq3.start(env.agent._seq,null); |
seq4.start(env.agent._seq,null); |
seq5.start(env.agent._seq,null); |
seq6.start(env.agent._seq,null); |
phase.drop_objection(this); |
endtask:run_phase |
endclass:nop_command_mode |
|
class write_command_mode extends uart_base_test; |
|
seq_5p1 seq1; |
seq_5p2 seq2; |
seq_5p3 seq3; |
seq_5p4 seq4; |
seq_5p5 seq5; |
seq_5p6 seq6; |
seq_5p7 seq7; |
seq_5p8 seq8; |
seq_5p9 seq9; |
seq_5p10 seq10; |
|
`uvm_component_utils(write_command_mode) |
// This test apply ten successive tests of UART write request using binary communication mode. |
// Refer to test plan section in the testbench specifications document for more details. |
class write_command_mode extends uart_base_test; |
|
seq_5p1 seq1; |
seq_5p2 seq2; |
seq_5p3 seq3; |
seq_5p4 seq4; |
seq_5p5 seq5; |
seq_5p6 seq6; |
seq_5p7 seq7; |
seq_5p8 seq8; |
seq_5p9 seq9; |
seq_5p10 seq10; |
|
function new (string name,uvm_component parent); |
super.new(name,parent); |
endfunction:new |
`uvm_component_utils(write_command_mode) |
|
function void build_phase (uvm_phase phase); |
super.build_phase(phase); |
seq1 = seq_5p1::type_id::create("seq1"); |
seq2 = seq_5p2::type_id::create("seq2"); |
seq3 = seq_5p3::type_id::create("seq3"); |
seq4 = seq_5p4::type_id::create("seq4"); |
seq5 = seq_5p5::type_id::create("seq5"); |
seq6 = seq_5p6::type_id::create("seq6"); |
seq7 = seq_5p7::type_id::create("seq7"); |
seq8 = seq_5p8::type_id::create("seq8"); |
seq9 = seq_5p9::type_id::create("seq9"); |
seq10 = seq_5p10::type_id::create("seq10"); |
endfunction:build_phase |
function new (string name,uvm_component parent); |
super.new(name,parent); |
endfunction:new |
|
task run_phase (uvm_phase phase); |
super.run_phase(phase); |
phase.raise_objection(this); |
uvm_test_done.set_drain_time(this,5000); |
seq1.start(env.agent._seq,null); |
seq2.start(env.agent._seq,null); |
seq3.start(env.agent._seq,null); |
seq4.start(env.agent._seq,null); |
seq5.start(env.agent._seq,null); |
seq6.start(env.agent._seq,null); |
seq7.start(env.agent._seq,null); |
seq8.start(env.agent._seq,null); |
seq9.start(env.agent._seq,null); |
seq10.start(env.agent._seq,null); |
phase.drop_objection(this); |
endtask:run_phase |
endclass: write_command_mode |
function void build_phase (uvm_phase phase); |
super.build_phase(phase); |
seq1 = seq_5p1::type_id::create("seq1"); |
seq2 = seq_5p2::type_id::create("seq2"); |
seq3 = seq_5p3::type_id::create("seq3"); |
seq4 = seq_5p4::type_id::create("seq4"); |
seq5 = seq_5p5::type_id::create("seq5"); |
seq6 = seq_5p6::type_id::create("seq6"); |
seq7 = seq_5p7::type_id::create("seq7"); |
seq8 = seq_5p8::type_id::create("seq8"); |
seq9 = seq_5p9::type_id::create("seq9"); |
seq10 = seq_5p10::type_id::create("seq10"); |
endfunction:build_phase |
|
class read_command_mode extends uart_base_test; |
|
seq_6p1 seq1; |
seq_6p2 seq2; |
seq_6p3 seq3; |
seq_6p4 seq4; |
seq_6p5 seq5; |
seq_6p6 seq6; |
seq_6p7 seq7; |
seq_6p8 seq8; |
seq_6p9 seq9; |
seq_6p10 seq10; |
task run_phase (uvm_phase phase); |
super.run_phase(phase); |
phase.raise_objection(this); |
uvm_test_done.set_drain_time(this,5000); |
//seq1.start(env.agent._seq,null); |
seq2.start(env.agent._seq,null); |
seq3.start(env.agent._seq,null); |
seq4.start(env.agent._seq,null); |
seq5.start(env.agent._seq,null); |
seq6.start(env.agent._seq,null); |
seq7.start(env.agent._seq,null); |
seq8.start(env.agent._seq,null); |
seq9.start(env.agent._seq,null); |
seq10.start(env.agent._seq,null); |
phase.drop_objection(this); |
endtask:run_phase |
endclass: write_command_mode |
|
`uvm_component_utils(read_command_mode) |
|
function new (string name,uvm_component parent); |
super.new(name,parent); |
seq1 = seq_6p1::type_id::create("seq1"); |
seq2 = seq_6p2::type_id::create("seq2"); |
seq3 = seq_6p3::type_id::create("seq3"); |
seq4 = seq_6p4::type_id::create("seq4"); |
seq5 = seq_6p5::type_id::create("seq5"); |
seq6 = seq_6p6::type_id::create("seq6"); |
seq7 = seq_6p7::type_id::create("seq7"); |
seq8 = seq_6p8::type_id::create("seq8"); |
seq9 = seq_6p9::type_id::create("seq9"); |
seq10 = seq_6p10::type_id::create("seq10"); |
endfunction:new |
// This test apply ten successive tests of UART read request using binary communication mode. |
// Refer to test plan section in the testbench specifications document for more details. |
class read_command_mode extends uart_base_test; |
|
seq_6p1 seq1; |
seq_6p2 seq2; |
seq_6p3 seq3; |
seq_6p4 seq4; |
seq_6p5 seq5; |
seq_6p6 seq6; |
seq_6p7 seq7; |
seq_6p8 seq8; |
seq_6p9 seq9; |
seq_6p10 seq10; |
|
function void build_phase (uvm_phase phase); |
super.build_phase(phase); |
`uvm_component_utils(read_command_mode) |
|
endfunction:build_phase |
function new (string name,uvm_component parent); |
super.new(name,parent); |
seq1 = seq_6p1::type_id::create("seq1"); |
seq2 = seq_6p2::type_id::create("seq2"); |
seq3 = seq_6p3::type_id::create("seq3"); |
seq4 = seq_6p4::type_id::create("seq4"); |
seq5 = seq_6p5::type_id::create("seq5"); |
seq6 = seq_6p6::type_id::create("seq6"); |
seq7 = seq_6p7::type_id::create("seq7"); |
seq8 = seq_6p8::type_id::create("seq8"); |
seq9 = seq_6p9::type_id::create("seq9"); |
seq10 = seq_6p10::type_id::create("seq10"); |
endfunction:new |
|
task run_phase (uvm_phase phase); |
super.run_phase(phase); |
phase.raise_objection(this); |
seq1.start(env.agent._seq,null); |
seq2.start(env.agent._seq,null); |
seq3.start(env.agent._seq,null); |
seq4.start(env.agent._seq,null); |
seq5.start(env.agent._seq,null); |
seq6.start(env.agent._seq,null); |
seq7.start(env.agent._seq,null); |
seq8.start(env.agent._seq,null); |
seq9.start(env.agent._seq,null); |
seq10.start(env.agent._seq,null); |
phase.drop_objection(this); |
endtask:run_phase |
endclass:read_command_mode |
function void build_phase (uvm_phase phase); |
super.build_phase(phase); |
|
endfunction:build_phase |
|
task run_phase (uvm_phase phase); |
super.run_phase(phase); |
phase.raise_objection(this); |
//seq1.start(env.agent._seq,null); |
seq2.start(env.agent._seq,null); |
seq3.start(env.agent._seq,null); |
seq4.start(env.agent._seq,null); |
seq5.start(env.agent._seq,null); |
seq6.start(env.agent._seq,null); |
seq7.start(env.agent._seq,null); |
seq8.start(env.agent._seq,null); |
seq9.start(env.agent._seq,null); |
seq10.start(env.agent._seq,null); |
phase.drop_objection(this); |
endtask:run_phase |
endclass:read_command_mode |
|
//------------------------------------------------------------------------------------------------- |
// |
// COMBINED COMMAND TESTS |
// |
//------------------------------------------------------------------------------------------------- |
|
// this test randomly apply series of 100 text mode commands. They would be either read or write |
// sequences described in text mode tests in the testbench specifications document. |
class text_mode_test extends uart_base_test; |
|
rand int unsigned command_number; |
|
seq_1p1 seq1; |
seq_1p2 seq2; |
seq_1p3 seq3; |
seq_1p4 seq4; |
seq_1p5 seq5; |
seq_1p6 seq6; |
seq_1p7 seq7; |
seq_1p8 seq8; |
seq_1p9 seq9; |
seq_1p10 seq10; |
seq_1p11 seq11; |
seq_1p12 seq12; |
seq_1p13 seq13; |
|
|
seq_2p1 seq14; |
seq_2p2 seq15; |
seq_2p3 seq16; |
seq_2p4 seq17; |
seq_2p5 seq18; |
seq_2p6 seq19; |
seq_2p7 seq20; |
seq_2p8 seq21; |
seq_2p9 seq22; |
seq_2p10 seq23; |
seq_2p11 seq24; |
seq_2p12 seq25; |
seq_2p13 seq26; |
|
`uvm_component_utils(text_mode_test) |
|
constraint limit { |
command_number inside {[1:26]}; |
} |
|
function new (string name , uvm_component parent); |
super.new(name,parent); |
endfunction:new |
|
function void build_phase (uvm_phase phase); |
super.build_phase(phase); |
seq1 = seq_1p1::type_id::create("seq1"); |
seq2 = seq_1p2::type_id::create("seq2"); |
seq3 = seq_1p3::type_id::create("seq3"); |
seq4 = seq_1p4::type_id::create("seq4"); |
seq5 = seq_1p5::type_id::create("seq5"); |
seq6 = seq_1p6::type_id::create("seq6"); |
seq7 = seq_1p7::type_id::create("seq7"); |
seq8 = seq_1p8::type_id::create("seq8"); |
seq9 = seq_1p9::type_id::create("seq9"); |
seq10 = seq_1p10::type_id::create("seq10"); |
seq11 = seq_1p11::type_id::create("seq11"); |
seq12 = seq_1p12::type_id::create("seq12"); |
seq13 = seq_1p13::type_id::create("seq13"); |
seq14 = seq_2p1::type_id::create("seq14"); |
seq15 = seq_2p2::type_id::create("seq15"); |
seq16 = seq_2p3::type_id::create("seq16"); |
seq17 = seq_2p4::type_id::create("seq17"); |
seq18 = seq_2p5::type_id::create("seq18"); |
seq19 = seq_2p6::type_id::create("seq19"); |
seq20 = seq_2p7::type_id::create("seq20"); |
seq21 = seq_2p8::type_id::create("seq21"); |
seq22 = seq_2p9::type_id::create("seq22"); |
seq23 = seq_2p10::type_id::create("seq23"); |
seq24 = seq_2p11::type_id::create("seq24"); |
seq25 = seq_2p12::type_id::create("seq25"); |
seq26 = seq_2p13::type_id::create("seq26"); |
endfunction:build_phase |
|
task run_phase (uvm_phase phase); |
super.run_phase(phase); |
phase.raise_objection(this); |
repeat (100) |
begin |
randomize(); |
case (command_number) |
1: |
begin |
seq1.start(env.agent._seq,null); |
end |
2: |
begin |
seq2.start(env.agent._seq,null); |
end |
3: |
begin |
seq3.start(env.agent._seq,null); |
end |
4: |
begin |
seq4.start(env.agent._seq,null); |
end |
5: |
begin |
seq5.start(env.agent._seq,null); |
end |
6: |
begin |
seq6.start(env.agent._seq,null); |
end |
7: |
begin |
seq7.start(env.agent._seq,null); |
end |
8: |
begin |
seq8.start(env.agent._seq,null); |
end |
9: |
begin |
seq9.start(env.agent._seq,null); |
end |
10: |
begin |
seq10.start(env.agent._seq,null); |
end |
11: |
begin |
seq11.start(env.agent._seq,null); |
end |
12: |
begin |
seq12.start(env.agent._seq,null); |
end |
13: |
begin |
seq13.start(env.agent._seq,null); |
end |
14: |
begin |
seq14.start(env.agent._seq,null); |
end |
15: |
begin |
seq15.start(env.agent._seq,null); |
end |
16: |
begin |
seq16.start(env.agent._seq,null); |
end |
17: |
begin |
seq17.start(env.agent._seq,null); |
end |
18: |
begin |
seq18.start(env.agent._seq,null); |
end |
19: |
begin |
seq19.start(env.agent._seq,null); |
end |
20: |
begin |
seq20.start(env.agent._seq,null); |
end |
21: |
begin |
seq21.start(env.agent._seq,null); |
end |
22: |
begin |
seq22.start(env.agent._seq,null); |
end |
23: |
begin |
seq23.start(env.agent._seq,null); |
end |
24: |
begin |
seq24.start(env.agent._seq,null); |
end |
25: |
begin |
seq25.start(env.agent._seq,null); |
end |
26: |
begin |
seq26.start(env.agent._seq,null); |
end |
default: |
begin |
`uvm_fatal("OUT OF RANGE","Command Number is Out of Range") |
end |
endcase |
end |
phase.drop_objection(this); |
endtask:run_phase |
endclass:text_mode_test |
/tb/analysis/uart_scoreboard.svh
1,32 → 1,39
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// UART2BUS VERIFICATION |
// UART2BUS VERIFICATION |
// |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// CREATOR : HANY SALAH |
// PROJECT : UART2BUS UVM TEST BENCH |
// UNIT : ANALYSIS |
//----------------------------------------------------------------------------- |
// TITLE : UART ANALYSIS |
// DESCRIPTION: This |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// TITLE : UART SCOREBOARD |
// DESCRIPTION: SCOREBOARD IS RESPONSIBLE FOR DOING COMPARISONS BETWEEN THE TRANSACTION CREATED IN |
// THE SEQUENCE AND THE TRANSACTION CAPTURED BY THE MONITOR. |
//------------------------------------------------------------------------------------------------- |
// LOG DETAILS |
//------------- |
// VERSION NAME DATE DESCRIPTION |
// 1 HANY SALAH 22012016 FILE CREATION |
//----------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR |
// OPENCORES MEMBERS ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE |
// CREATOR'S PERMISSION |
//----------------------------------------------------------------------------- |
// 2 HANY SALAH 28012016 ADD BINARY COMMAND CHECKING |
// 3 HANY SALAH 18022016 IMPROVE BLOCK DESCRIPTION & ADD COMMENTS |
//------------------------------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR OPENCORES MEMBERS |
// ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE CREATOR'S PERMISSION |
//------------------------------------------------------------------------------------------------- |
|
class uart_scoreboard extends uvm_scoreboard; |
|
// TLM fifo which buffers the trasaction captured by the monitor. |
uvm_tlm_analysis_fifo #(uart_transaction) mon_fifo; |
|
// TLM port connected to the monitor. |
uvm_analysis_export #(uart_transaction) scbd_mon; |
|
// TLM fifo which buffers the trasaction drived from the driver. |
uvm_tlm_analysis_fifo #(uart_transaction) drv_fifo; |
|
// TLM port connected to the driver. |
uvm_analysis_export #(uart_transaction) scbd_drv; |
|
uart_transaction frm_drv,frm_drv_tmp; |
44,6 → 51,8
extern function void connect_phase (uvm_phase phase); |
|
extern task run_phase (uvm_phase phase); |
|
extern function void ack_checker (); |
endclass:uart_scoreboard |
|
|
69,21 → 78,44
scbd_drv.connect(drv_fifo.analysis_export); |
endfunction:connect_phase |
|
// Run Phase |
task uart_scoreboard::run_phase (uvm_phase phase); |
int iteration; |
iteration = 0; |
|
forever |
begin |
iteration++; |
drv_fifo.get(frm_drv_tmp); |
$cast(frm_drv,frm_drv_tmp.clone()); |
mon_fifo.get(frm_mon_tmp); |
$cast(frm_mon,frm_mon_tmp.clone()); |
|
if (frm_drv._mode != frm_mon._mode) |
begin |
`uvm_fatal("Testbench Bug",$sformatf("Modes aren't similiar .. @time=%0t, It was requested to use %p mode and the applied mode is %p ",$time,frm_drv._mode,frm_mon._mode)) |
`uvm_fatal("Testbench Bug",$sformatf("Modes aren't similiar .. It was requested to use %p mode and the applied mode is %p \n ",frm_drv._mode,frm_mon._mode)) |
end |
|
else if (frm_drv._mode inside {wrong_mode_text,wrong_mode_bin}) |
begin |
if (frm_drv._data == frm_mon._data) |
begin |
`uvm_error("Failed UART Undefined Command","DUT responds to undefined Prefix \n") |
end |
else |
begin |
`uvm_info("Passed UART Undefined Command","DUT doesn't respond to undefined Prefix \n",UVM_NONE) |
end |
end |
|
else if (frm_drv._command inside {invalid_read,invalid_write}) |
begin |
if (frm_drv._data == frm_mon._data) |
begin |
`uvm_error("Failed UART Invalid Command","DUT responds to invalid binary command \n") |
end |
else |
begin |
`uvm_info("Passed UART Invalid Command","DUT doesn't respond to invalid binary command \n",UVM_NONE) |
end |
end |
|
else |
begin |
case (frm_drv._mode) |
91,7 → 123,7
begin |
if(frm_drv._command != frm_mon._command) |
begin |
`uvm_fatal("Testbench Bug",$sformatf("Commands aren't identical .. @time=%0t, It was requested to drive %p command and the applied command is %p ",$time,frm_drv._command,frm_mon._command)) |
`uvm_fatal("Testbench Bug",$sformatf("Commands aren't identical .. It was requested to drive %p command and the applied command is %p \n",frm_drv._command,frm_mon._command)) |
end |
else |
begin |
98,10 → 130,21
case(frm_drv._command) |
read: |
begin |
if (frm_drv._data != frm_mon._data) |
if (frm_drv._spacetype1 == wrong_space || frm_drv._eoltype == wrong_eol) |
begin |
`uvm_error("Failed Read Text Mode",$sformatf("Data fields aren't identical ,, @time=%0t It was requested to drive %p and dut reply with the data %p",$time,frm_drv._data,frm_mon._data)) |
if (frm_drv._data == frm_mon._data) |
begin |
`uvm_error("Failed Wrong Read Command","DUT responds to stimulus with wrong white space or eol charachters \n") |
end |
else |
begin |
`uvm_info("Passed Wrong Read Command",$sformatf("Dut was requested to read the data of the address %h with wrong white spaces or eol character \n",frm_mon.address),UVM_NONE) |
end |
end |
else if (frm_drv._data != frm_mon._data) |
begin |
`uvm_error("Failed Read Text Mode",$sformatf("Data fields aren't identical ,, It was requested to drive %b and dut reply with the data %b \n",frm_drv._data,frm_mon._data)) |
end |
else if((frm_drv._data == frm_mon._data) && |
(frm_drv.address == frm_mon.address) && |
(frm_drv._spacetype1 == frm_mon._spacetype1) && |
108,40 → 151,51
(frm_drv._eoltype == frm_mon._eoltype) && |
(frm_drv._chartype == frm_mon._chartype)) |
begin |
`uvm_info("Passed Read Text Mode",$sformatf("Data fields are identical ,, @time=%0t It was requested to read from the address %h and dut reply with the data %p using white space = %p and %p prefix character and %p as end of line character",$time,frm_drv.address,frm_mon._data,frm_drv._spacetype1,frm_drv._chartype, |
`uvm_info("Passed Read Text Mode",$sformatf("Data fields are identical ,, It was requested to read from the address %h and dut reply with the data %p using white space = %p and %p prefix character and %p as end of line character \n",frm_drv.address,frm_mon._data,frm_drv._spacetype1,frm_drv._chartype, |
frm_drv._eoltype),UVM_NONE) |
end |
else |
begin |
`uvm_error("Failed Read Text Mode",$sformatf("@time=%0t .. It is Requested to request to read data = %p address of %h with character prefix : %p using white space = %p and end of line character %p .. and found data = %p and address=%h with character prefix : %p using white space = %p and end of line character %p",$time, frm_drv._data,frm_drv.address,frm_drv._chartype,frm_drv._spacetype1,frm_drv._eoltype, |
`uvm_error("Failed Read Text Mode",$sformatf("It is Requested to request to read data = %p address of %h with character prefix : %p using white space = %p and end of line character %p .. and found data = %p and address=%h with character prefix : %p using white space = %p and end of line character %p \n",frm_drv._data,frm_drv.address,frm_drv._chartype,frm_drv._spacetype1,frm_drv._eoltype, |
frm_mon._data,frm_mon.address,frm_mon._chartype,frm_mon._spacetype1,frm_mon._eoltype)) |
end |
end |
write: |
begin |
if (frm_drv._data != frm_mon._data) |
if (frm_drv._spacetype1 == wrong_space || frm_drv._spacetype2 == wrong_space || frm_drv._eoltype == wrong_eol) |
begin |
`uvm_error("Failed Write Text Mode",$sformatf("Data fields aren't identical ,, @time=%0t It was requested to drive %p and dut register the data %p",$time,frm_drv._data,frm_mon._data)) |
if (frm_drv._data == frm_mon._data) |
begin |
`uvm_error("Failed Wrong Write Command","DUT responds to stimulus with wrong white space or eol charachters \n") |
end |
else |
begin |
`uvm_info("Passed Wrong Write Command",$sformatf("Dut was requested to read the data of the address %h with wrong white spaces or eol character \n",frm_mon.address),UVM_NONE) |
end |
end |
else if (frm_drv._data != frm_mon._data) |
begin |
`uvm_error("Failed Write Text Mode",$sformatf("Data fields aren't identical ,, It was requested to drive %p and dut register the data %p \n",frm_drv._data,frm_mon._data)) |
end |
else if((frm_drv._data == frm_mon._data) && |
(frm_drv.address == frm_mon.address) && |
(frm_drv._spacetype1 == frm_mon._spacetype1) && |
(frm_drv._spacetype2 == frm_mon._spacetype2) && |
(frm_drv._eoltype == frm_mon._eoltype) && |
(frm_drv._chartype == frm_mon._chartype)) |
begin |
`uvm_info("Passed write Text Mode",$sformatf("Data fields are identical ,, @time=%0t It was requested to write to the address %h and dut register the data %p using white space = %p and %p prefix character and %p as end of line character",$time,frm_drv.address,frm_mon._data,frm_drv._spacetype1,frm_drv._chartype, |
`uvm_info("Passed write Text Mode",$sformatf("Data fields are identical ,, It was requested to write to the address %h and dut register the data %p using white space = %p and %p prefix character and %p as end of line character \n",frm_drv.address,frm_mon._data,frm_drv._spacetype1,frm_drv._chartype, |
frm_drv._eoltype),UVM_NONE) |
end |
else |
begin |
`uvm_error("Failed write Text Mode",$sformatf("@time=%0t .. It is Requested to request to write data = %p address of %h with character prefix : %p using white space = %p and end of line character %p .. and found data = %p and address=%h with character prefix : %p using white space = %p and end of line character %p",$time, frm_drv._data,frm_drv.address,frm_drv._chartype,frm_drv._spacetype1,frm_drv._eoltype, |
`uvm_error("Failed write Text Mode",$sformatf("It is Requested to request to write data = %p address of %h with character prefix : %p using white space = %p and end of line character %p .. and found data = %p and address=%h with character prefix : %p using white space = %p and end of line character %p \n",frm_drv._data,frm_drv.address,frm_drv._chartype,frm_drv._spacetype1,frm_drv._eoltype, |
frm_mon._data,frm_mon.address,frm_mon._chartype,frm_mon._spacetype1,frm_mon._eoltype)) |
end |
|
end |
default: |
begin |
`uvm_fatal("Testbench Bug",$sformatf("@time = %0t .. It isn't allowablt to drive %p command through text mode",$time,frm_drv._command)) |
`uvm_fatal("Testbench Bug",$sformatf("It isn't allowablt to drive %p command through text mode \n",frm_drv._command)) |
end |
endcase |
end |
148,17 → 202,56
end |
binary: |
begin |
|
if (frm_drv._command != frm_mon._command) |
begin |
`uvm_fatal("Testbench Bug",$sformatf("Commands aren't identical .. It was requested to drive %p command and the applied command is %p \n",frm_drv._command,frm_mon._command)) |
end |
else if (frm_drv._command inside {read,write}) |
begin |
if (frm_drv._reqack == frm_mon._reqack && |
frm_drv._reqinc == frm_mon._reqinc && |
frm_drv.address == frm_mon.address && |
frm_drv.length_data == frm_mon.length_data && |
frm_drv._data == frm_mon._data) |
begin |
`uvm_info($sformatf("Passed Binary %p Command",frm_drv._command),$sformatf("Dut is requested to %p command to start address=%h with data = %p and data length = %0d \n",frm_drv._command,frm_drv.address,frm_drv._data,frm_drv.length_data),UVM_NONE) |
ack_checker(); |
end |
else |
begin |
`uvm_error("Failed Binary Command",$sformatf("Dut is requested to %p command to start address=%h with data = %p, data length = %0d and dut reply with start address = %h and data = %p, length_data=%0d \n", |
frm_drv._command,frm_drv.address,frm_drv._data,frm_drv.length_data, |
frm_mon.address,frm_mon._data,frm_mon.length_data)) |
end |
end |
else if (frm_drv._command == nop) |
begin |
`uvm_info("NOP Command",$sformatf("Dut is requested to %p command \n",frm_drv._command),UVM_NONE) |
ack_checker(); |
end |
end |
wrong_mode: |
begin |
|
end |
default: |
begin |
`uvm_fatal("Testbench Bug",$sformatf("Mode is undefined = %p",frm_drv._mode)) |
`uvm_fatal("Testbench Bug",$sformatf("Mode is undefined = %p \n",frm_drv._mode)) |
end |
endcase |
end |
end |
endtask:run_phase |
endtask:run_phase |
|
function void uart_scoreboard::ack_checker(); |
|
if(frm_drv._reqack == yes && frm_mon.acknowledge != 8'h5A) |
begin |
`uvm_error("Undefined Acknowledge",$sformatf("DUT reply with %h as acknowledge character \n",frm_mon.acknowledge)) |
end |
else if (frm_drv._reqack == no && frm_mon.acknowledge != 8'h00) |
begin |
`uvm_error("Wrong Response","Command doesn't request Acknowledge and DUT forward acknowledge character \n") |
end |
else |
begin |
`uvm_info("Accepted Acknowledge","Acknowledge is the defined as standard \n",UVM_NONE) |
end |
|
endfunction:ack_checker |
/tb/interfaces/uart_interface.sv
1,15 → 1,17
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// UART2BUS VERIFICATION |
// |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// CREATOR : HANY SALAH |
// PROJECT : UART2BUS UVM TEST BENCH |
// UNIT : BUS FUNCTIONAL MODEL |
//----------------------------------------------------------------------------- |
// TITLE : UART Interface |
// DESCRIPTION: This |
//----------------------------------------------------------------------------- |
// UNIT : INTERFACE |
//------------------------------------------------------------------------------------------------- |
// TITLE : UART BFM |
// DESCRIPTION: THIS FILE ACT AS UART MASTER DEVICE APPLY REQUESTS TO THE DUT ACROSS THE STANDARD |
// INTERFACES. IT ALSO INCLUDES ALL THE USER AND STANDARD ROUTINES THAT ARE NEED TO |
// APPLY, RECEIVE AND MONITOR UART DIFFERENT ACTIVITIES. |
//------------------------------------------------------------------------------------------------- |
// LOG DETAILS |
//------------- |
// VERSION NAME DATE DESCRIPTION |
16,61 → 18,97
// 1 HANY SALAH 25122015 FILE CREATION |
// 2 HANY SALAH 07012016 ADD USER ROUTINE, TEXT MODE ROUTINES. |
// 3 HANY SALAH 21012016 REPLACE PUSH BYTE WITH PUSH FIELD |
//----------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR |
// OPENCORES MEMBERS ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE |
// CREATOR'S PERMISSION |
//----------------------------------------------------------------------------- |
// 4 HANY SALAH 31012016 ADD FAULT AND INVALID COMMAND INDICATORS |
// 5 HANY SALAH 13022016 IMPROVE BLOCK DESCRIPTION & ADD COMMENTS. |
// 6 HANY SALAH 15022016 ENHANCE BLOCK COMMENTS |
// 7 HANY SALAH 16022016 ENHANCE BLOCK COMMENTS |
// 8 HANY SALAH 17022016 FINALIZE BLOCK COMMENTS |
//------------------------------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR OPENCORES MEMBERS |
// ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE CREATOR'S PERMISSION |
//------------------------------------------------------------------------------------------------- |
`include "defin_lib.svh" |
interface uart_interface (input bit clock, // Global Clock Signal |
interface uart_interface (input bit clock, // UART Clock Signal |
input bit reset); // Global Asynchronous Reset Signal |
|
//----------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// BFM Parameter |
// BFM PARAMETERS |
// |
//----------------------------------------------- |
|
//------------------------------------------------------------------------------------------------- |
// BFM Paramenters are the ones which are set in the test file and are propagated in the whole |
// test-bench. They are defined indetails through test file and specifications document. |
// The range of possible values for all the BFM paramters is stated beside each one |
// |
// Define the active clock edge |
int act_edge; // 2: negative edge 1: positive edge |
|
// Define the first transferred bit from the byte. |
int start_bit; // 2: LSB first 1: MSB first |
|
// Define the number of stop bits of each UART field |
int num_stop_bits;// 2: two stop bits 1: one stop bits |
|
// Define the number of actual bits inbetween the start and stop bits. |
int num_bits; // 7: seven bits data 8: eight bits data |
|
// Define the representation of data through the text mode. |
int data_rep; // 2: binarry 1: ASCII |
int parity; // 3: parity odd 2: parity even 1: parity off |
|
// Define the parity mode used. |
int parity; // 3: parity odd 2: parity even 1: parity off |
|
// Define the maximum allowable time between the UART request and the DUT response. |
time response_time; |
|
// Define the authorization of false data usage. |
int falsedata_gen_en; |
|
//----------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// UART Signals |
// UART SIGNLAS |
// |
//----------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
|
logic ser_in; // Serial Data Input |
logic ser_out; // Serial Data Ouptut |
wire serial_out; |
|
//----------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// USER Variables Declarations |
// USER VARIABLES DECLARATIONS |
// |
//----------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
|
// The user variables are those ones which facilitate the usage of BFM and they aren't mentioned |
// in the standard. |
// |
// Start_trans event is triggered by the driver at the start of each transaction. it would let |
// the other components wake up and poll the UART bus. |
// By triggereing this event, other connected components would know that some UART transaction |
// would be forced on the UART busses. |
event start_trans; |
|
assign serial_out = 1'bz; |
assign serial_out = ser_out; |
// The following two bits are used only in case of apply wrong modes or wrong commands as the |
// following: |
// wrong_data_ctrl is drived by the driver to state that whether the wrong applied command |
// is read or write. |
// Actuall BFM shouldn't discriminate between both of types. Its response should be nothing!!. |
// But this indication facilitates the scoreboard work. |
bit wrong_data_ctrl; //0:read 1: write |
|
//----------------------------------------------- |
// wrong_mode_ctrl is also drived by the driver to state whether the wrong applied mode is |
// text or binary. |
// Actuall BFM also shouldn't discriminate between both of types. Its response should be |
// nothing. But this indication facilitates the scoreboard work. |
bit wrong_mode_ctrl; //0:text 1: binary |
|
//------------------------------------------------------------------------------------------------- |
// |
// USER Routines |
// USER ROUTINES |
// |
//----------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
|
// Through This routine, the uart bfm is initialize its configuration parameters |
// BFM should know through which edge it will either capture or force the data. |
// Also should know whether the sent or received data will start with most sign- |
// ificant bit or least significant bit. |
// Through This routine, the uart bfm initializes its configuration parameters described above. |
function void set_configuration ( int _edge, |
int first_bit, |
int _numstopbits, |
77,7 → 115,8
int _numbits, |
int _datarep, |
int _paritymode, |
time _resp); |
time _resp, |
int _flse_en); |
act_edge = _edge; |
start_bit = first_bit; |
num_stop_bits = _numstopbits; |
85,34 → 124,36
data_rep = _datarep; |
parity = _paritymode; |
response_time = _resp; |
falsedata_gen_en= _flse_en; |
endfunction: set_configuration |
|
|
// Through the following routine, the uart bfm make an event that some transact- |
// -ion would be forced on UART signals |
// Through the following routine, the UART BFM makes an event that some transaction would be |
// forced on UART signals |
function void set_event (); |
-> start_trans ; |
endfunction:set_event |
|
|
// This routine is used to force data directly on serial out bus. This routine transform one |
// bit only to the form of uart. This form is defined in the definition library. |
// High value is defined by the macro `one. |
// Low value is defined by the macro `zero. |
function void force_sout(bit x); |
case (x) |
1'b1: |
begin |
//ser_out = `one; |
ser_out = 1'b1; |
ser_out = `one; |
end |
1'b0: |
begin |
//ser_out = `zero; |
ser_out = 1'b0; |
ser_out = `zero; |
end |
endcase |
endfunction:force_sout |
|
// Through this routine, the uart bfm push bit on the serial ouptut port ser_out |
// based on the configured active edge field, UART will push bit on data. BFM |
// will assign testbench error in case of un-configured active edge. |
// Through this routine, the uart bfm push bit on the serial ouptut port ser_out based on the |
// configured active edge field, UART will push bit on data. BFM will assign testbench error in |
// case of un-configured active edge. |
task push_bit_serout (input bit data); |
case (act_edge) |
`_negedge: |
131,40 → 172,16
end |
default: |
begin |
$error("undefined active edge"); |
$error("Non-configured active edge"); |
end |
endcase |
endtask:push_bit_serout |
|
// Through this routine, the uart bfm push bit on the serial input port ser_in |
// based on the configured active edge field, UART will push bit on data. BFM |
// will assign testbench error in case of un-configured active edge. |
/*task push_bit_serin (input bit data); |
case (act_edge) |
`_negedge: |
begin |
@(negedge clock) |
begin |
ser_in = data; |
end |
end |
`_posedge: |
begin |
@(posedge clock) |
begin |
ser_in = data; |
end |
end |
default: |
begin |
$error("undefined active edge"); |
end |
endcase |
endtask:push_bit_serin*/ |
|
// The following task will catch single bit from serial output port ser_out based |
// on the configured active edge field, UART will capture data bit. BFM will |
// assign testbench error in case of un-configured active edge. |
// The following task will catch single bit from serial output port ser_out based on the config- |
// ured active edge field, UART will capture data bit. Based on the configured active edge, this |
// method block the execution till the correct clock edge and then make delay of a quarter of |
// clock period to guarnttee the stability of data on the serial output port. |
// BFM will assign testbench error in case of un-configured active edge. |
task catch_bit_serout (output bit data); |
case (act_edge) |
`_negedge: |
183,14 → 200,16
end |
default: |
begin |
$error("undefined active edge"); |
$error("Non-configured active edge"); |
end |
endcase |
endtask:catch_bit_serout |
|
// The following task will catch single bit from serial input port ser_in based |
// on the configured active edge field, UART will capture data bit. BFM will |
// assign testbench error in case of un-configured active edge. |
// The following task will catch single bit from serial input port ser_in based on the config- |
// ured active edge field, UART will capture data bit. Based on the configured active edge, this |
// method block the execution till the correct clock edge and then make delay of a quarter of |
// clock period to guarnttee the stability of data on the serial input port. |
// BFM will assign testbench error in case of un-configured active edge. |
task catch_bit_serin (output bit data); |
case (act_edge) |
`_negedge: |
209,15 → 228,23
end |
default: |
begin |
$error("undefined active edge"); |
$error("Non-configured active edge"); |
end |
endcase |
endtask:catch_bit_serin |
|
// Through the following task, UART BFM will force data byte on serial output |
// port based on the configured start_bit field. BFM will assign testbench err- |
// or in case of un-configured start_bit field. |
// Through the following task, UART BFM will force data byte on serial output port based on the |
// configured start_bit field. This mode encapsulate the data byte inbetween start,stop and even |
// parity bits. The sequence would be the following: |
// 1- Force zero bit on the serial output port as start bit. |
// 2- Send the data byte serially bit by bit. |
// 3- Accoriding to configured parity, force parity bit (optional). |
// 4- Insert one or two stop bits according to BFM configuration. |
// BFM will assign testbench error in case of un-configured parameters. |
task push_field_serout (input byte data); |
|
bit temp; |
|
// start bit |
push_bit_serout(1'b0); |
|
242,7 → 269,28
$error("Undefined serial mode"); |
end |
endcase |
|
// parity bits |
if(parity == `_parityeven) |
begin |
temp=1'b1; |
for (int index=0;index <8;index++) |
begin |
temp = temp ^ data [index]; |
end |
end |
else if(parity == `_parityodd) |
begin |
temp=1'b0; |
for (int index=0;index <8;index++) |
begin |
temp = temp ^ data [index]; |
end |
end |
end |
else if (parity != `_parityoff) |
begin |
$error("un-configured parity"); |
end |
// Stop bit(s) |
repeat (num_stop_bits) |
begin |
251,36 → 299,13
|
endtask:push_field_serout |
|
// Through the following task, UART BFM will force data byte on serial output |
// port based on the configured start_bit field. BFM will assign testbench err- |
// or in case of un-configured start_bit field. |
/*task push_byte_serin (input byte data); |
case (start_bit) |
`lsb_first: |
begin |
for (int index=0;index<8;index++) |
begin |
push_bit_serin(data[index]); |
end |
end |
`msb_first: |
begin |
for (int index=7;index>=0;index--) |
begin |
push_bit_serin(data[index]); |
end |
end |
default: |
begin |
$error("Undefined serial mode"); |
end |
endcase |
endtask:push_byte_serin*/ |
|
|
// Through the following task, UART BFM will catpure data byte from serial out- |
// put port based on the configured start_bit field. BFM will assign testbench |
// error in case of un-configured start_bit field. |
// Through the following task, UART BFM will catpure UART field from serial output port based on |
// the configured start_bit field. The following sequence is carried out : |
// 1- Wait start bit. |
// 2- Catpure the following eight bits in packed byte depending on the configured start bit. |
// 3- Depending on the configured number of stop bits, the stop bit(s) are captured. |
// - In case that stop bit(s) is zero, the testbench will assign testbench error. |
// BFM will assign testbench error in case of un-configured start_bit field. |
task catch_field_serout (output byte data); |
bit end_bit; |
|
310,7 → 335,6
if(end_bit != 1'b1) |
begin |
$error("at time =%0t ,, the first end bit = %0b",$time,end_bit); |
$stop; |
end |
if (num_stop_bits == 2) |
begin |
318,61 → 342,87
if(end_bit != 1'b1) |
begin |
$error("at time =%0t ,, the first end bit = %0b",$time,end_bit); |
$stop; |
end |
end |
endtask:catch_field_serout |
|
// Through the following task, UART BFM will catpure data byte from serial out- |
// put port based on the configured start_bit field. BFM will assign testbench |
// error in case of un-configured start_bit field. |
// Through the following task, UART BFM will catpure UART field from serial input port based on |
// the configured start_bit field. The applied sequence here differs from the one applied on |
// capture field from serial output port since wrong and unknown commands are forced to the DUT |
// on the UART interface. The DUT is supposed to make no response to such commands. |
// This routine pays concern to this issue by initiating two parallel threads at the beginning; |
// 1- The first one run in the background to wait response time and triggered some internal |
// event (terminate event). It also set internal bit (path_select) to zero to make an |
// indication that no response has been made. |
// 2- The second one includes two parallel sub-threads: |
// a- The first one wait start bit. |
// b- The other one wait terminate event triggering. |
// Whenever one of those sub-threads is terminated, The main thread is joined. |
// The following sequence is carried out in case that start bit is captured: |
// 1- Wait start bit. |
// 2- Catpure the following eight bits in packed byte depending on the configured start bit. |
// 3- Depending on the configured number of stop bits, the stop bit(s) are captured. |
// - In case that stop bit(s) is zero, the testbench will assign testbench error. |
// BFM will assign testbench error in case of un-configured start_bit field. |
task catch_field_serin (output byte data); |
bit end_bit; |
|
// wait start bit |
bit path_select; |
event terminate; |
path_select = 1'b1; |
fork |
begin |
#response_time; |
-> terminate; |
path_select = 1'b0; |
end |
join_none |
|
wait (ser_in == 1'b0); |
#(`buad_clk_period/2); |
case(start_bit) |
`lsb_first: |
begin |
for (int index=0;index<8;index++) |
fork |
wait (ser_in == 1'b0); |
wait (terminate); |
join_any |
|
if (path_select) |
begin |
#(`buad_clk_period/2); |
case(start_bit) |
`lsb_first: |
begin |
catch_bit_serin(data[index]); |
for (int index=0;index<8;index++) |
begin |
catch_bit_serin(data[index]); |
end |
end |
end |
`msb_first: |
begin |
for (int index=7;index>=0;index--) |
`msb_first: |
begin |
catch_bit_serin(data[index]); |
for (int index=7;index>=0;index--) |
begin |
catch_bit_serin(data[index]); |
end |
end |
end |
default: |
begin |
$error("Undefined serial mode"); |
end |
endcase |
catch_bit_serin(end_bit); |
if(end_bit != 1'b1) |
begin |
$error("at time =%0t ,, the first end bit = %0b",$time,end_bit); |
$stop; |
end |
if (num_stop_bits == 2) |
begin |
default: |
begin |
$error("Undefined serial mode"); |
end |
endcase |
catch_bit_serin(end_bit); |
if(end_bit != 1'b1) |
begin |
$error("at time =%0t ,, the first end bit = %0b",$time,end_bit); |
$stop; |
end |
if (num_stop_bits == 2) |
begin |
catch_bit_serin(end_bit); |
if(end_bit != 1'b1) |
begin |
$error("at time =%0t ,, the first end bit = %0b",$time,end_bit); |
end |
end |
end |
|
endtask:catch_field_serin |
|
|
// Through the following function, the byte is reversed in the manner that the |
// byte is merrored |
// Through the following function, the byte is reversed in the manner where the byte is merrored |
function byte reverse_byte (byte data); |
byte tmp; |
for (int index=0;index<8;index++) |
382,17 → 432,49
return tmp; |
endfunction:reverse_byte |
|
//----------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// UART Routines |
// UART ROUTINES |
// |
//----------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
|
// Through the following method, UART BFM will initialize write request in UART |
// text mode. This task is accomplished with known of either the request chara- |
// cter is capital or small, and also the used white space type is either single |
// space or tab, and finally the end of line mechanism. |
task write_text_mode(input int alph, |
// This method is provided to initiate write request in UART text mode. This task is accomplis- |
// hed through the following sequence: |
// 1- The first field :(Prefix Character) |
// Depending on whether the mode type is text or wrong text and whether the prefix is small |
// or capital character, the BFM force the prefix field. In case of wrong text type, the init- |
// ial field is the provided wrong_prefix input. also internal wrong_mode_ctrl bit is cleared. |
// - In case of undefined type, testbench assign testbench error. |
// ----------------------- |
// 2- The second field:(White Space Character) |
// Depending on whether the used white space type is a single space, a tab space or provided |
// wrong space character is forced on the serial output port. |
// ----------------------- |
// 3- The third field:(Data Character) |
// - In case of the data representation is binary, the data input character is encapsulated |
// in UART field and forced in single field. |
// - In case of the data representation is ASCII, the data input character is divided into |
// two nipples. Each one is converted to ASCII character and sent separately in UART field. |
// The most significant nipple is sent first. |
// ----------------------- |
// 4- The forth field:(White Space Character) |
// Depending on whether the used white space type is a single space, a tab space or provided |
// wrong space character is forced on the serial output port. |
// ----------------------- |
// 5- The fifth field:(Address Two-Character) |
// - In case of the data representation is binary, the address input two-character is divided |
// into two characters. They are encapsulated into two successive UART fields. |
// - In case of the data representation is ASCII, the address input two-character is divided |
// into four nipples. Each one is converted to ASCII character and sent separately in UART |
// field. The ASCII characters are sent where the most significant nipple is sent first. |
// ----------------------- |
// 6- The sixth field:(End-Of-Line Character): |
// Depending on whether the used EOL type is CR, LF or provided wrong space character is |
// forced on the serial output port. |
// ----------------------- |
task write_text_mode(input int _type, |
input byte wrong_prefix, |
input int alph, |
input int scp_type1, |
input byte space_wrong1, |
input int scp_type2, |
402,225 → 484,324
input bit [`size-1:0] address, |
input byte data); |
// Write procedures |
// First Field |
if (alph == `small_let) |
// First Field |
case (_type) |
`text_mode: |
begin |
push_field_serout(`w); |
if (alph == `small_let) |
begin |
push_field_serout(`w); |
end |
else if (alph == `capital_let) |
begin |
push_field_serout(`W); |
end |
else |
$error("Testbench error .. No capitar or small letter is choosed"); |
end |
else if (alph == `capital_let) |
`wrong_mode_txt: |
begin |
push_field_serout(`W); |
push_field_serout(wrong_prefix); |
wrong_mode_ctrl = 1'b0; |
end |
else |
$error("Testbench error .. No capitar or small letter is choosed"); |
|
// Second Field |
if (scp_type1 == `single_space) |
default: |
begin |
push_field_serout(`space); |
$error("Undefined communication mode .."); |
end |
else if (scp_type1 == `tab_space) |
begin |
push_field_serout(`tab); |
end |
else if (scp_type1 == `space_wrong) |
begin |
push_field_serout(space_wrong1); |
end |
else |
$error("Testbench error .. No single space or multiple space is choosed"); |
endcase |
|
// third field |
case (data_rep) |
`binary_rep: |
begin |
push_field_serout(data); |
end |
`ascii_rep: |
begin |
push_field_serout(bin_asci_conv(data[7:4])); |
push_field_serout(bin_asci_conv(data[3:0])); |
end |
default:$error("undefined data representation"); |
endcase |
// Second Field |
if (scp_type1 == `single_space) |
begin |
push_field_serout(`space); |
end |
else if (scp_type1 == `tab_space) |
begin |
push_field_serout(`tab); |
end |
else if (scp_type1 == `space_wrong) |
begin |
push_field_serout(space_wrong1); |
end |
else |
$error("Testbench error .. No single space or multiple space is choosed"); |
|
// forth field |
if (scp_type2 == `single_space) |
// third field |
case (data_rep) |
`binary_rep: |
begin |
push_field_serout(`space); |
push_field_serout(data); |
end |
else if (scp_type2 == `tab_space) |
`ascii_rep: |
begin |
push_field_serout(`tab); |
push_field_serout(bin_asci_conv(data[7:4])); |
push_field_serout(bin_asci_conv(data[3:0])); |
end |
else if (scp_type2 == `space_wrong) |
begin |
push_field_serout(space_wrong2); |
end |
else |
$error("Testbench error .. No single or multiple space is choosed"); |
// fivth field |
case (data_rep) |
`binary_rep: |
begin |
push_field_serout(address[15:08]); |
push_field_serout(address[07:00]); |
end |
`ascii_rep: |
begin |
push_field_serout(bin_asci_conv(address[15:12])); |
push_field_serout(bin_asci_conv(address[11:08])); |
push_field_serout(bin_asci_conv(address[07:04])); |
push_field_serout(bin_asci_conv(address[03:00])); |
end |
default:$error("undefined data representation"); |
endcase |
default:$error("undefined data representation"); |
endcase |
|
// sixth Field |
if (eol == `cr_eol) |
// forth field |
if (scp_type2 == `single_space) |
begin |
push_field_serout(`space); |
end |
else if (scp_type2 == `tab_space) |
begin |
push_field_serout(`tab); |
end |
else if (scp_type2 == `space_wrong) |
begin |
push_field_serout(space_wrong2); |
end |
else |
$error("Testbench error .. No single or multiple space is choosed"); |
// fivth field |
case (data_rep) |
`binary_rep: |
begin |
push_field_serout(`CR); |
push_field_serout(address[15:08]); |
push_field_serout(address[07:00]); |
end |
else if (eol == `lf_eol) |
`ascii_rep: |
begin |
push_field_serout(`LF); |
push_field_serout(bin_asci_conv(address[15:12])); |
push_field_serout(bin_asci_conv(address[11:08])); |
push_field_serout(bin_asci_conv(address[07:04])); |
push_field_serout(bin_asci_conv(address[03:00])); |
end |
else if (eol == `eol_wrong) |
begin |
push_field_serout(eol_wrong); |
end |
else |
$error("Testbench error .. either CR or LF isn't choosed as eol"); |
default:$error("undefined data representation"); |
endcase |
|
// sixth Field |
if (eol == `cr_eol) |
begin |
push_field_serout(`CR); |
end |
else if (eol == `lf_eol) |
begin |
push_field_serout(`LF); |
end |
else if (eol == `eol_wrong) |
begin |
push_field_serout(eol_wrong); |
end |
else |
$error("Testbench error .. either CR or LF isn't choosed as eol"); |
endtask:write_text_mode |
|
// Through the following method, UART BFM will initialize read request in UART |
// text mode and receive the response as defined in UART specification standard |
// This task is accomplished with known of either the request character is cap- |
// ital or small, and also the used white space type is either single space or |
// tab, and finally the end of line mechanism. This methed includes two main se- |
// ctions; the first one includes the four successive fields of defined read re- |
// quest. And the another one includes the response. |
task read_text_mode (input int alph, |
// This method is provided to initiate read request in UART text mode. This task is accomplis- |
// hed through the following sequence: |
// 1- The first field :(Prefix Character) |
// Depending on whether the mode type is text or wrong text and whether the prefix is small |
// or capital character, the BFM force the prefix field. In case of wrong text type, the init- |
// ial field is the provided wrong_prefix input. also internal wrong_mode_ctrl bit is cleared. |
// - In case of undefined type, testbench assign testbench error. |
// ----------------------- |
// 2- The second field:(White Space Character) |
// Depending on whether the used white space type is a single space, a tab space or provided |
// wrong space character is forced on the serial output port. |
// ----------------------- |
// 3- The third field:(Address Two-Character) |
// - In case of the data representation is binary, the address input two-character is divided |
// into two characters. They are encapsulated into two successive UART fields. |
// - In case of the data representation is ASCII, the address input two-character is divided |
// into four nipples. Each one is converted to ASCII character and sent separately in UART |
// field. The ASCII characters are sent where the most significant nipple is sent first. |
// ----------------------- |
// 4- The forth field:(End-Of-Line Character): |
// Depending on whether the used EOL type is CR, LF or provided wrong space character is |
// forced on the serial output port. |
// ----------------------- |
// GETTING RESPONSE : |
// Since we may have no response due to either DUT internal bug or the forced request is |
// wrong (wrong mode, wrong white space, wrong eol), two parallel threads are initiated; The |
// first one is to wait for response time and the other one waits start bit on the serial |
// input port. Both the two threads are terminated by meeting only one of the two events. |
// In case of the start bit is captured and according to the configured the data representa- |
// tion. |
// - If it is binary, the following UART field is captured and its data is considered to be |
// the requested data. |
// - If it is ASCII, the two successive UART fields is captured and each byte is converted to |
// binary nipple. |
// The following character is captured and it must be CR. |
// The following character is captured and it must be LF. |
// - If the last two characters aren't as indicated above, the testbench will assign testbench |
// error. |
// ----------------------- |
task read_text_mode (input int _type, |
input byte wrong_prefix, |
input int alph, |
input int scp_type, |
input byte space_wrong, |
input int eol, |
input byte eol_wrong, |
input bit [`size-1:0] address); |
input bit [`size-1:0] address, |
input byte false_data, |
input int false_data_en); |
byte data; |
byte temp; |
byte char1,char2; |
bit miss; |
time prope1; |
// Read Request |
// First Field |
if (alph == `small_let) |
// First Field |
case (_type) |
`text_mode: |
begin |
push_field_serout(`r); |
if (alph == `small_let) |
begin |
push_field_serout(`r); |
end |
else if (alph == `capital_let) |
begin |
push_field_serout(`R); |
end |
else |
$error("Testbench error .. No capitar or small letter is choosed"); |
end |
else if (alph == `capital_let) |
`wrong_mode_txt: |
begin |
push_field_serout(`R); |
push_field_serout(wrong_prefix); |
wrong_mode_ctrl = 1'b0; |
end |
else |
$error("Testbench error .. No capitar or small letter is choosed"); |
// Second Field |
if (scp_type == `single_space) |
default: |
begin |
push_field_serout(`space); |
$error("Undefined communication mode .."); |
end |
else if (scp_type == `tab_space) |
endcase |
|
// Second Field |
if (scp_type == `single_space) |
begin |
push_field_serout(`space); |
end |
else if (scp_type == `tab_space) |
begin |
push_field_serout(`tab); |
end |
else if (scp_type == `space_wrong) |
begin |
push_field_serout(space_wrong); |
end |
else |
$error("Testbench error .. No single or multiple white space is choosed"); |
|
// Third Field |
case (data_rep) |
`binary_rep: |
begin |
push_field_serout(`tab); |
push_field_serout(address[15:08]); |
push_field_serout(address[07:00]); |
end |
else if (scp_type == `space_wrong) |
`ascii_rep: |
begin |
push_field_serout(space_wrong); |
push_field_serout(bin_asci_conv(address[15:12])); |
push_field_serout(bin_asci_conv(address[11:08])); |
push_field_serout(bin_asci_conv(address[07:04])); |
push_field_serout(bin_asci_conv(address[03:00])); |
end |
else |
$error("Testbench error .. No single or multiple white space is choosed"); |
default:$error("undefined data representation"); |
endcase |
|
// Third Field |
// Forth Field |
if (eol == `cr_eol) |
begin |
push_field_serout(`CR); |
end |
else if (eol == `lf_eol) |
begin |
push_field_serout(`LF); |
end |
else if (eol == `eol_wrong) |
begin |
push_field_serout(eol_wrong); |
end |
else |
$error("Testbench error .. No CR or LF is choosed"); |
|
miss = 1'b0; |
fork |
begin: miss_response_thread |
# response_time; |
disable capture_response_thread; |
miss = 1'b1; |
end |
|
begin: capture_response_thread |
wait(ser_in == 1'b0); |
disable miss_response_thread; |
end |
join |
// Capture Response |
if (miss == 1'b0) |
begin |
if (false_data_en ==`_yes && falsedata_gen_en == `_yes) |
begin |
fork |
push_field_serout(false_data); |
join_none |
end |
case (data_rep) |
`binary_rep: |
begin |
push_field_serout(address[15:08]); |
push_field_serout(address[07:00]); |
catch_field_serin(data); |
end |
`ascii_rep: |
begin |
push_field_serout(bin_asci_conv(address[15:12])); |
push_field_serout(bin_asci_conv(address[11:08])); |
push_field_serout(bin_asci_conv(address[07:04])); |
push_field_serout(bin_asci_conv(address[03:00])); |
catch_field_serin(temp); |
data[7:4] = asci_bin_conv(temp); |
catch_field_serin(temp); |
data[3:0] = asci_bin_conv(temp); |
end |
default:$error("undefined data representation"); |
endcase |
|
// Forth Field |
if (eol == `cr_eol) |
begin |
push_field_serout(`CR); |
end |
else if (eol == `lf_eol) |
begin |
push_field_serout(`LF); |
end |
else if (eol == `eol_wrong) |
begin |
push_field_serout(eol_wrong); |
end |
else |
$error("Testbench error .. No CR or LF is choosed"); |
|
miss = 1'b0; |
prope1 = $time; |
fork |
begin: miss_response_thread |
while (($time-prope1)<response_time) |
default: |
begin |
#1; |
$error("Undefined data representation"); |
$stop; |
end |
disable capture_response_thread; |
miss = 1'b1; |
end |
|
begin: capture_response_thread |
wait(ser_in == 1'b0); |
disable miss_response_thread; |
end |
join |
// Capture Response |
if (miss == 1'b0) |
endcase |
catch_field_serin(char1); |
catch_field_serin(char2); |
if (char1 != `CR || char2 != `LF) |
begin |
case (data_rep) |
`binary_rep: |
begin |
catch_field_serin(data); |
end |
`ascii_rep: |
begin |
catch_field_serin(temp); |
data[7:4] = asci_bin_conv(temp); |
catch_field_serin(temp); |
data[3:0] = asci_bin_conv(temp); |
end |
default: |
begin |
$error("Undefined data representation"); |
$stop; |
end |
endcase |
catch_field_serin(char1); |
catch_field_serin(char2); |
if (char1 != `CR || char2 != `LF) |
begin |
$error("EOL is refuesed"); |
end |
$error("EOL is refuesed"); |
end |
end |
endtask:read_text_mode |
|
// Write bytes of data in command mode |
task automatic write_binary_mode (input int reqack, |
// This method is provided to initiate write request in UART binary mode. This task is accompli- |
// shed through the following sequence: |
// ----------------------- |
// NOTE :: ALL THE FOLLOWING BYTES ARE ENCAPSULATED INTO DEFINED UART FIELD FORM |
// ----------------------- |
// 1- The first byte :(Prefix byte) |
// Depending on whether the mode type is binary or wrong binary the BFM force the prefix field |
// In case of wrong binary type, the initial field is the provided wrong_prefix input. also |
// internal wrong_mode_ctrl bit is set. |
// - In case of undefined type, testbench assign testbench error. |
// ----------------------- |
// 2- The second byte:(Command byte) |
// Depending on whether the command is valid or invalid command, the two bits of the command |
// are assigned. Also the auto increment bit and acknowledge request bit are assigned |
// ----------------------- |
// 3- The third byte:(Address highest byte) |
// - The address bits [15:08] . |
// ----------------------- |
// 4- The forth field:(Address lowest byte) |
// - The address bits [07:00] . |
// ----------------------- |
// 5- The fifth field:(Length Of Data byte) |
// - The number of data bytes inclosed into this stimulus. |
// ----------------------- |
// 6- The rest fields:(Data): |
// Data Bytes are sent one by one. |
// ----------------------- |
// GETTING RESPONSE: |
// In case that the command includes acknowledge request, UART BFM will wait for the ackno- |
// wledge unified character. |
// ----------------------- |
task automatic write_binary_mode (input int _type, |
input byte wrong_prefix, |
input int command, |
input int reqack, |
input int reqinc, |
input int unsigned data_length, |
input bit [`size-1:0] address, |
629,9 → 810,38
int unsigned index; |
|
// first byte : binary prefix |
push_field_serout(`bin_prfx); |
case(_type) |
`binary_mode: |
begin |
push_field_serout(`bin_prfx); |
end |
`wrong_mode_binry: |
begin |
push_field_serout(wrong_prefix); |
wrong_mode_ctrl = 1'b1; |
end |
default: |
begin |
$error("Undefined Communication Mode"); |
end |
endcase |
|
// second byte : command |
case(command) |
`write_comm: |
begin |
tmp[5:4] = `write_ctrl; |
end |
`wrong_comm_write: |
begin |
tmp[5:4] = `invalid_ctrl; |
wrong_data_ctrl = 1'b1; |
end |
default: |
begin |
$error("Undefined Command"); |
end |
endcase |
tmp[5:4] = 2'b10; |
if(reqinc==`_yes) |
begin |
687,20 → 897,89
|
endtask:write_binary_mode |
|
// Read bytes of data in command mode |
task automatic read_binary_mode (input int reqack, |
// This method is provided to initiate read request in UART binary mode. This task is accompli- |
// shed through the following sequence: |
// ----------------------- |
// NOTE :: ALL THE FOLLOWING BYTES ARE ENCAPSULATED INTO UART DEFINED FIELD FORM |
// ----------------------- |
// 1- The first byte :(Prefix byte) |
// Depending on whether the mode type is binary or wrong binary the BFM force the prefix field |
// In case of wrong binary type, the initial field is the provided wrong_prefix input. also |
// internal wrong_mode_ctrl bit is set. |
// - In case of undefined type, testbench assign testbench error. |
// ----------------------- |
// 2- The second byte:(Command byte) |
// Depending on whether the command is valid or invalid command, the two bits of the command |
// are assigned. Also the auto increment bit and acknowledge request bit are assigned |
// ----------------------- |
// 3- The third byte:(Address highest byte) |
// - The address bits [15:08] . |
// ----------------------- |
// 4- The forth field:(Address lowest byte) |
// - The address bits [07:00] . |
// ----------------------- |
// 5- The fifth field:(Length Of Data byte) |
// - The number of data bytes inclosed into this stimulus. |
// ----------------------- |
// GETTING RESPONSE: |
// Through this field, three independent parallel processes are carried out : |
// i- The first one is mendatory and is responsible for capturing the UART fields drived by |
// The DUT on the serial input port. Also it is responsible for capturing the acknowledge |
// byte in case that the command include acknowledge request. |
// ii- The second one is responsible for terminating this routine in case that no response has |
// been driven by the DUT within the response time. |
// iii- The last one is to drive dummy UART fields. It is used only when both the internal |
// false data enable and the global false data enable are set. Refer to UART testbench |
// specifications document for more details. |
// ----------------------- |
task automatic read_binary_mode (input int _type, |
input byte wrong_prefix, |
input int _command, |
input int reqack, |
input int reqinc, |
input int unsigned data_length, |
input bit [`size-1:0] address, |
ref byte data []); |
ref byte data [], |
ref byte false_data [], |
input bit false_data_en); |
byte tmp; |
int unsigned index; |
int unsigned index_false; |
|
// first byte : binary prefix |
push_field_serout(`bin_prfx); |
case (_type) |
`binary_mode: |
begin |
push_field_serout(`bin_prfx); |
end |
`wrong_mode_binry: |
begin |
push_field_serout(wrong_prefix); |
wrong_mode_ctrl = 1'b1; |
end |
default: |
begin |
$error("Undefined Communication Mode"); |
end |
endcase |
|
// second byte : command |
tmp[5:4] = 2'b01; |
case (_command) |
`read_comm: |
begin |
tmp[5:4] = `read_ctrl; |
end |
`wrong_comm_read: |
begin |
tmp[5:4] = `invalid_ctrl; |
wrong_data_ctrl = 1'b0; |
end |
default: |
begin |
$error("Undefined Command type"); |
end |
endcase |
|
if(reqinc==`_yes) |
begin |
tmp[1] = 1'b0; |
710,6 → 989,8
tmp[1] = 1'b1; |
end |
else |
$error("undefined acknowledge request"); |
end |
begin |
$error("undefined increment request"); |
end |
724,8 → 1005,6
end |
else |
begin |
$error("undefined acknowledge request"); |
end |
push_field_serout(tmp); |
|
// Third byte : higher byte of address |
735,19 → 1014,37
push_field_serout(address[07:00]); |
|
// Fifth byte : data length |
push_field_serout(data_length); |
|
index = 0; |
while(index<data_length) |
if (data_length == 256) |
begin |
catch_field_serin(data[index]); |
index++; |
tmp = 8'b00; |
end |
else |
begin |
tmp = data_length; |
end |
push_field_serout(tmp); |
|
index = 0; |
|
fork |
if(false_data_en == `_yes && falsedata_gen_en == `_yes) |
begin |
while(index_false<data_length) |
begin |
push_field_serout(false_data[index_false]); |
index_false++; |
end |
end |
while(index<data_length) |
begin |
catch_field_serin(data[index]); |
index++; |
end |
join |
if (reqack == `_yes) |
begin |
catch_field_serin(tmp); |
if (tmp != `ACK) |
if (tmp != `ACK && _type == `binary_mode && _command == `read_comm) |
begin |
$error("The captured acknowledge isn't as unified character"); |
end |
754,13 → 1051,49
end |
endtask:read_binary_mode |
|
// No Operation Command |
task nop_command (input int reqack, |
// This method is provided to initiate NOP command in UART binary mode. This task is accompli- |
// shed through the following sequence: |
// ----------------------- |
// NOTE :: ALL THE FOLLOWING BYTES ARE ENCAPSULATED INTO UART DEFINED FIELD FORM |
// ----------------------- |
// 1- The first byte :(Prefix byte) |
// Depending on whether the mode type is binary or wrong binary the BFM force the prefix field |
// In case of wrong binary type, the initial field is the provided wrong_prefix input. also |
// internal wrong_mode_ctrl bit is set. |
// - In case of undefined type, testbench assign testbench error. |
// ----------------------- |
// 2- The second byte:(Command byte) |
// The two bits of commads are assigned. Also the auto increment bit and acknowledge request |
// bit are assigned |
// ----------------------- |
// GETTING RESPONSE: |
// In case that the command includes acknowledge request, UART BFM will wait for the ackno- |
// wledge unified character. |
// ----------------------- |
task nop_command (input int _type, |
input byte wrong_prefix, |
input int reqack, |
input int reqinc); |
byte tmp; |
int unsigned index; |
// first byte : prefix |
push_field_serout(`bin_prfx); |
wrong_mode_ctrl = 1'b0; |
// first byte : binary prefix |
case (_type) |
`binary_mode: |
begin |
push_field_serout(`bin_prfx); |
end |
`wrong_mode_binry: |
begin |
push_field_serout(wrong_prefix); |
wrong_mode_ctrl = 1'b1; |
end |
default: |
begin |
$error("Undefined Communication Mode"); |
end |
endcase |
|
// second byte : command |
tmp[5:4] = 2'b00; |
801,104 → 1134,162
end |
endtask:nop_command |
|
task automatic wrong_command (input int reqack, |
input int reqinc, |
input byte wrong_prefix, |
input int unsigned data_length, |
input bit [`size-1:0] address, |
ref byte data []); |
byte tmp; |
int index; |
time prope1; |
|
push_field_serout(wrong_prefix); |
tmp[5:4] = 2'b01; |
if(reqinc==`_yes) |
begin |
tmp[1] = 1'b0; |
end |
else if (reqinc == `_no) |
begin |
tmp[1] = 1'b1; |
end |
else |
begin |
$error("undefined increment request"); |
end |
|
if(reqack==`_yes) |
begin |
tmp[0] = 1'b1; |
end |
else if (reqack == `_no) |
begin |
tmp[0] = 1'b0; |
end |
else |
begin |
$error("undefined acknowledge request"); |
end |
push_field_serout(tmp); |
|
// Third byte : higher byte of address |
push_field_serout(address[15:08]); |
|
// Forth byte : Lower byte of address |
push_field_serout(address[07:00]); |
|
// Fifth byte : data length |
push_field_serout(data_length); |
|
fork : response_thread |
begin |
index = 0; |
|
while(index<data_length) |
begin |
catch_field_serin(data[index]); |
index++; |
end |
|
if (reqack == `_yes) |
begin |
catch_field_serin(tmp); |
if (tmp != `ACK) |
begin |
$error("The captured acknowledge isn't as unified character"); |
end |
end |
end |
|
begin |
prope1=$time; |
while (($time-prope1)< response_time) |
begin |
#1; |
end |
disable response_thread; |
end |
join |
|
endtask:wrong_command |
|
|
// Wait idle time |
// This task is used to make the bus idle for time (idle). |
task wait_idle_time (time idle); |
force_sout(1'b1); |
#idle; |
endtask: wait_idle_time |
|
//----------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// MONITOR ROUTINES |
// MONITOR ROUTINES |
// |
//----------------------------------------------- |
|
// This routine is used to wait for transaction start |
//------------------------------------------------------------------------------------------------- |
// This section of routines is used to monitor the UART signals and capture all the informations |
// about the stimulus, DUT state and DUT response as well. Each one is described in details below |
// |
// This routine is used to wait for transaction start. It waits for start_trans triggering. |
task wait_event(); |
wait (start_trans); |
endtask:wait_event |
|
// This method is the main method of the monitoring routines used to capture the UART |
// transactions on the UART interfaces. Whenever it is called, it carries out the following |
// procedures: |
// 1- Capture the first field loaded on the serial output port and detect the command type to be |
// either text read, text write, binary, wrong command. And according to the command, another |
// proper task will be called. |
// NOTE: In case of wrong command, with the aid of internal bit wrong_mode_ctrl, UART BFM could |
// detect the actual type of wrong command. |
// ----------------------- |
// 2- (I) In case that the command type is text, the dynamic array of data is initialized with |
// the standard size one byte. Also command and character type fields are assigned. Refer |
// to transaction fields for more informations about these fields. |
// (II) In case that the command type is binary, capture_binary_command task is called. |
// (III) In case that the command type is wrong, nothing is done. |
task automatic capture_command (output int command_type, |
output int _command, |
output int _chartype, |
output int _spacetype1, |
output int space_wrong1, |
output int _spacetype2, |
output int space_wrong2, |
output int _eoltype, |
output int eol_wrong, |
output bit [`size-1:0] address, |
ref byte data [], |
output byte acknowledge, |
output int unsigned data_length, |
output int _reqack, |
output int _reqinc); |
|
byte temp; |
byte read_byte; |
catch_field_serout(read_byte); |
case (read_byte) |
`w: |
begin |
command_type = `text_mode; |
_command = `write_comm; |
_chartype = `small_let; |
data = new [1]; |
capture_text_write_command(_spacetype1, |
space_wrong1, |
_spacetype2, |
space_wrong2, |
_eoltype, |
eol_wrong, |
address, |
data[0]); |
end |
`W: |
begin |
command_type = `text_mode; |
_command = `write_comm; |
_chartype = `capital_let; |
data = new [1]; |
capture_text_write_command(_spacetype1, |
space_wrong1, |
_spacetype2, |
space_wrong2, |
_eoltype, |
eol_wrong, |
address, |
data[0]); |
end |
`r: |
begin |
command_type = `text_mode; |
_command = `read_comm; |
_chartype = `small_let; |
data = new [1]; |
capture_text_read_command(_spacetype1, |
space_wrong1, |
_eoltype, |
eol_wrong, |
address, |
data [0]); |
end |
`R: |
begin |
command_type = `text_mode; |
_command = `read_comm; |
_chartype = `capital_let; |
data = new [1]; |
capture_text_read_command(_spacetype1, |
space_wrong1, |
_eoltype, |
eol_wrong, |
address, |
data [0]); |
end |
`bin_prfx: |
begin |
command_type = `binary_mode; |
capture_binary_command(_command, |
_reqack, |
_reqinc, |
address, |
data_length, |
data, |
acknowledge); |
end |
default: |
begin |
if (wrong_mode_ctrl) |
begin |
command_type = `wrong_mode_binry; |
end |
else |
begin |
command_type = `wrong_mode_txt; |
end |
end |
endcase |
endtask:capture_command |
|
// This method is used to capture read command in text mode. Whenever it is called, the following |
// procedures are carried out : |
// ----------------------- |
// 1- Capture the second command field which includes the white space character. |
// ----------------------- |
// 2- According to the configured data representation: |
// i- Binary representation: Catch the following two UART fields on the serial output port |
// which include the current stimulus address. |
// ii- ASCII representation: Catch the following four UART fields on the serial output port |
// which include the current stimulus address in ASCII format.their |
// data bytes are converted to binary format. |
// ----------------------- |
// 3- Capture the following field which includes the end of line character. |
// ----------------------- |
// GETTING RESPONSE: |
// - Run two concurrent threads: |
// i- The first one is to wait response time. |
// ii- The second one is to capture the data UART fields on the serial input port. |
// - In case that no response is found, this task is terminated. |
// - After catch the data fields, the next two fields are also captured to check the two end |
// of line characters. |
// ----------------------- |
task capture_text_read_command (output int _spacetype, |
output int space_wrong, |
output int _eoltype, |
906,6 → 1297,8
output bit [`size-1:0] address, |
output byte data); |
byte read_byte; |
bit miss; |
|
catch_field_serout(read_byte); |
case (read_byte) |
`space: |
966,45 → 1359,86
end |
endcase |
|
case(data_rep) |
`binary_rep: |
miss = 1'b0; |
fork |
begin: miss_response_thread |
#response_time; |
disable capture_response_thread; |
miss = 1'b1; |
end |
|
begin: capture_response_thread |
wait(ser_in == 1'b0); |
disable miss_response_thread; |
end |
join |
|
if (miss==1'b0) |
begin |
case(data_rep) |
`binary_rep: |
begin |
catch_field_serin(read_byte); |
data = read_byte; |
end |
`ascii_rep: |
begin |
catch_field_serin(read_byte); |
data[7:4] = asci_bin_conv(read_byte); |
catch_field_serin(read_byte); |
data[3:0] = asci_bin_conv(read_byte); |
end |
default: |
begin |
$error("undefined data representation"); |
$stop; |
end |
endcase |
|
catch_field_serin(read_byte); |
if (read_byte == `CR) |
begin |
catch_field_serin(read_byte); |
data = read_byte; |
if (read_byte != `LF) |
begin |
$error("the catpured byte isn't LF"); |
end |
end |
`ascii_rep: |
else if (read_byte == `LF) |
begin |
catch_field_serin(read_byte); |
data[7:4] = bin_asci_conv(read_byte); |
catch_field_serin(read_byte); |
data[3:0] = bin_asci_conv(read_byte); |
$error("The captured byte is LF instead of CR"); |
end |
default: |
else |
begin |
$error("undefined data representation"); |
$stop; |
$error("Fatal Error : final character in read request isn't CR and LF"); |
end |
endcase |
end |
|
catch_field_serin(read_byte); |
if (read_byte == `CR) |
begin |
catch_field_serin(read_byte); |
if (read_byte != `LF) |
begin |
$error("the catpured byte isn't LF"); |
end |
end |
else if (read_byte == `LF) |
begin |
$error("The captured byte is LF instead of CR"); |
end |
else |
begin |
$error("Fatal Error : final character in read request isn't CR and LF"); |
end |
endtask:capture_text_read_command |
|
// This method is used to capture write command in text mode. Whenever it is called, the follo- |
// wing procedures are carried out : |
// ----------------------- |
// 1- Capture the second command field which includes the white space character. |
// ----------------------- |
// 2- According to the configured data representation: |
// i- Binary representation: Catch the following UART field on the serial output port |
// which includes the current stimulus data. |
// ii- ASCII representation: Catch the following two UART fields on the serial output port |
// which include the current stimulus data in ASCII format.their |
// data bytes are converted to binary format. |
// ----------------------- |
// 3- Capture the next field which includes the white space character. |
// ----------------------- |
// 4- According to the configured data representation: |
// i- Binary representation: Catch the following two UART fields on the serial output port |
// which include the current stimulus address. |
// ii- ASCII representation: Catch the following four UART fields on the serial output port |
// which include the current stimulus address in ASCII format.their |
// data bytes are converted to binary format. |
// ----------------------- |
// 3- Capture the following field which includes the end of line character. |
// ----------------------- |
|
task capture_text_write_command ( output int _spacetype1, |
output int space_wrong1, |
1114,16 → 1548,55
endcase |
endtask: capture_text_write_command |
|
// This method is used to capture binary mode command. Whenever it is called, the following |
// procedures are carried out : |
// ----------------------- |
// 1- Capture and decode the second command field which includes the command, the acknowledge |
// request and also the address auto-increment enable. |
// - In case that the command bits indicate invalid command, BFM uses wrond_data_ctrl internal |
// bit to know wether this stimulus is wrong read or wrong write. No response should be driven |
// by the DUT in the both cases. But we need to discriminte between the two cases to facili- |
// tates the scoreboard job. |
// ----------------------- |
// 2- Capture the following field which includes the higher byte of the command address. |
// ----------------------- |
// 3- Capture the following field which includes the lower byte of the command address. |
// ----------------------- |
// 4- Capture the next field which includes the number of data bytes. |
// ----------------------- |
// 5- According to the decoded command: |
// i- Read Command : Poll the serial input port and capture number of successive UART fields |
// equal to the number of data bytes. In case of acknowledge request, ano- |
// ther field is captured and compared to the standard acknowledge |
// character |
// |
// ii- Write Command : Poll the serial output port and capture number of successive UART fie- |
// lds equal to the number of data bytes. In case of acknowledge request, |
// another field is captured on the serial input port and compare to the |
// standard acknowledge character |
// |
// iii- NOP Command : In case of acknowledge request, another field is captured on the serial |
// input port and compared to the standard acknowledge character |
// |
// iv- Invalid Command : In case that it is wrong read command, the same sequence obligied at |
// the valid read command is carried out. |
// In case that it is wrond write command, the same sequence obligied at |
// the valid write command is carried out. |
// ----------------------- |
// NOTE: Since the number of data bytes is defined at the run-time, we use queue of bytes to |
// packetaize the data temporarily and re-assign it to the dynamic array of data. |
// ----------------------- |
task automatic capture_binary_command (output int _command, |
output int _reqack, |
output int _reqinc, |
output bit [15:0] address, |
output int data_length, |
ref byte data [ ], |
ref byte data [], |
output byte acknowledge); |
byte read_byte; |
int index; |
byte que [$]; |
|
// first byte |
catch_field_serout(read_byte); |
case(read_byte[5:4]) |
1139,11 → 1612,23
begin |
_command = `write_comm; |
end |
`invalid_ctrl: |
begin |
if(wrong_data_ctrl) |
begin |
_command = `wrong_comm_write; |
end |
else |
begin |
_command = `wrong_comm_read; |
end |
end |
default: |
begin |
$error("undefined 2-bits command"); |
$error("invalid Command"); |
end |
endcase |
|
if (read_byte[1]) |
begin |
_reqinc = `_no; |
1160,148 → 1645,52
begin |
_reqack = `_no; |
end |
if (_command != `nop_comm) |
begin |
catch_field_serout(read_byte); |
address[15:08] = read_byte; |
|
catch_field_serout(read_byte); |
address[15:08] = read_byte; |
catch_field_serout(read_byte); |
address[07:00] = read_byte; |
|
catch_field_serout(read_byte); |
address[07:00] = read_byte; |
catch_field_serout(read_byte); |
if (read_byte == 8'h00) |
begin |
data_length = 256; |
end |
else |
begin |
data_length = read_byte; |
end |
|
catch_field_serout(read_byte); |
if (read_byte == 8'h00) |
begin |
data_length = 256; |
end |
else |
begin |
data_length = read_byte; |
end |
|
que.delete(); |
case (_command) |
`read_comm: |
begin |
index=0; |
while(index < data_length) |
que.delete(); |
if (_command == `read_comm || _command == `wrong_comm_read) |
begin |
catch_field_serin(read_byte); |
que.push_back(read_byte); |
index++; |
index=0; |
while(index < data_length) |
begin |
catch_field_serin(read_byte); |
que.push_back(read_byte); |
index++; |
end |
end |
end |
`write_comm: |
begin |
index=0; |
while(index < data_length) |
else if (_command == `write_comm || _command == `wrong_comm_write) |
begin |
catch_field_serout(read_byte); |
que.push_back(read_byte); |
index++; |
index=0; |
while(index < data_length) |
begin |
catch_field_serout(read_byte); |
que.push_back(read_byte); |
index++; |
end |
end |
data = new [que.size]; |
data = que; |
end |
default: |
begin |
$error("Undefined Command"); |
end |
endcase |
|
data = new [que.size]; |
data = que; |
catch_field_serin(acknowledge); |
if(_reqack == `_yes) |
begin |
catch_field_serin(acknowledge); |
end |
endtask:capture_binary_command |
|
// General Capture Command Routine |
task automatic capture_command (output int command_type, |
output int _command, |
output int _chartype, |
output int _spacetype1, |
output int space_wrong1, |
output int _spacetype2, |
output int space_wrong2, |
output int _eoltype, |
output int eol_wrong, |
output bit [`size-1:0] address, |
ref byte data [], |
output byte acknowledge, |
output int unsigned data_length, |
output int _reqack, |
output int _reqinc); |
|
byte read_byte; |
catch_field_serout(read_byte); |
case (read_byte) |
`w: |
begin |
command_type = `text_mode; |
_command = `write_comm; |
_chartype = `small_let; |
data = new [1]; |
capture_text_write_command(_spacetype1, |
space_wrong1, |
_spacetype2, |
space_wrong2, |
_eoltype, |
eol_wrong, |
address, |
data[0]); |
end |
`W: |
begin |
command_type = `text_mode; |
_command = `write_comm; |
_chartype = `capital_let; |
data = new[1]; |
capture_text_write_command(_spacetype1, |
space_wrong1, |
_spacetype2, |
space_wrong2, |
_eoltype, |
eol_wrong, |
address, |
data[0]); |
end |
`r: |
begin |
command_type = `text_mode; |
_command = `read_comm; |
_chartype = `small_let; |
data = new[1]; |
capture_text_read_command(_spacetype1, |
space_wrong1, |
_eoltype, |
eol_wrong, |
address, |
data[0]); |
end |
`R: |
begin |
command_type = `text_mode; |
_command = `read_comm; |
_chartype = `capital_let; |
data = new [1]; |
capture_text_read_command(_spacetype1, |
space_wrong1, |
_eoltype, |
eol_wrong, |
address, |
data[0]); |
end |
`bin_prfx: |
begin |
command_type = `binary_mode; |
capture_binary_command(_command, |
_reqack, |
_reqinc, |
address, |
data_length, |
data, |
acknowledge); |
end |
default: |
begin |
command_type = `wrong_mode; |
_command = `wrong_comm; |
end |
endcase |
endtask:capture_command |
endinterface:uart_interface |
endinterface:uart_interface |
/tb/interfaces/uart_arbiter.sv
1,47 → 1,52
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// UART2BUS VERIFICATION |
// |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// CREATOR : HANY SALAH |
// PROJECT : UART2BUS UVM TEST BENCH |
// UNIT : INTERFACE |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// TITLE : UART Arbiter |
// DESCRIPTION: This |
//----------------------------------------------------------------------------- |
// DESCRIPTION: THIS BFM ACT AS ARBITER CONNECTED TO THE DUT. ITS DUTY IS ONLY TO GIVE THE DUT THE |
// BUS GRANT OR NOT. |
//------------------------------------------------------------------------------------------------- |
// LOG DETAILS |
//------------- |
// VERSION NAME DATE DESCRIPTION |
// 1 HANY SALAH 29122015 FILE CREATION |
//----------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR |
// OPENCORES MEMBERS ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE |
// CREATOR'S PERMISSION |
//----------------------------------------------------------------------------- |
// 2 HANY SALAH 12022016 ENHANCE BLOCK DESCRIPTION & ADD COMMENTS |
//------------------------------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR OPENCORES MEMBERS |
// ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE CREATOR'S PERMISSION |
//------------------------------------------------------------------------------------------------- |
interface uart_arbiter (input bit clock, |
input bit reset); |
|
//-------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// Bus Control Signals |
// Bus Control Signals |
// |
//-------------------------------- |
//------------------------------------------------------------------------------------------------- |
|
logic int_req; // Request Internal Bus Access |
logic int_gnt; // Grant Internal Bus Access |
|
//-------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// Arbiter Control Signals |
// Arbiter Control Signals |
// |
//-------------------------------- |
//------------------------------------------------------------------------------------------------- |
|
// When this routine is called, it wait the request signal activation to give the bus grant to |
// the DUT. |
task accept_req (); |
wait (int_req); |
int_gnt = 1'b1; |
endtask:accept_req |
|
// When this routine is called, it wait the request signal activation and then declain the |
// the request buy set int_gnt to zero. |
task declain_req (); |
wait (int_req); |
int_gnt = 1'b0; |
/tb/interfaces/rf_interface.sv
1,24 → 1,29
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// |
// UART2BUS VERIFICATION |
// |
//----------------------------------------------------------------------------- |
// |
//------------------------------------------------------------------------------------------------- |
// CREATOR : HANY SALAH |
// PROJECT : UART2BUS UVM TEST BENCH |
// UNIT : INTERFACE |
//----------------------------------------------------------------------------- |
// TITLE : UART Interface |
// DESCRIPTION: This |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// TITLE : REGISTER FILE BFM |
// DESCRIPTION: THIS BUS FUNCTIONAL MODEL (BFM) ACTS AS ACTUAL REGISTER FILE CONNECTED TO THE DUT |
// ACROSS THE NON-STANDARD INTERFACE. IT IS IMPLEMENTED IN THE MANNER THAT APPLY THE |
// COMMUNICATION PROTOCOL DESCRIPED IN THE DUT MICROARCHITECTURE SPECIFICATIONS |
//------------------------------------------------------------------------------------------------- |
// LOG DETAILS |
//------------- |
// VERSION NAME DATE DESCRIPTION |
// 1 HANY SALAH 25122015 FILE CREATION |
//----------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR |
// OPENCORES MEMBERS ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE |
// CREATOR'S PERMISSION |
//----------------------------------------------------------------------------- |
// 2 HANY SALAH 20012016 ADD READ BLOCK ROUTINE |
// 3 HANY SALAH 11022016 IMPROVE BLOCK DESCRIPTION & ADD BLOCK COMMENTS |
//------------------------------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR OPENCORES MEMBERS |
// ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE CREATOR'S PERMISSION |
//------------------------------------------------------------------------------------------------- |
`include "defin_lib.svh" |
interface rf_interface (input bit clock, // Global Clock Signal |
input bit reset); // Global Asynchronous Reset Signal |
25,13 → 30,13
|
|
|
//-------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// Register File Side Signals |
// Register File Side Signals |
// |
//-------------------------------- |
//------------------------------------------------------------------------------------------------- |
|
logic [15:0] int_address; // Address Bus To Register File |
logic [15:0] int_address; // Address Bus To Register File |
|
logic [7:0] int_wr_data; // Write Data To Register File |
logic int_write; // Write Contorl To Register File |
39,29 → 44,39
logic [7:0] int_rd_data; // Read Data From Register File |
logic int_read; // Read Control To Register File |
|
//-------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// CONTROL SIGNALS |
// CONTROL SIGNALS |
// |
//-------------------------------- |
//------------------------------------------------------------------------------------------------- |
|
// This output is set when the testbench gives the bus access to the UART DUT |
logic int_gnt; |
|
// This input is activated whenever the UART DUT request to grant the bus access |
logic int_req; |
//-------------------------------- |
|
//------------------------------------------------------------------------------------------------- |
// |
// Internal Variables |
// Internal Variables |
// |
//-------------------------------- |
//------------------------------------------------------------------------------------------------- |
|
// Memory of 64K bytes as Register File |
byte register_file [`mem_size-1:0]; |
|
//-------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// Operation Blocks |
// Operation Blocks |
// |
//-------------------------------- |
|
//------------------------------------------------------------------------------------------------- |
|
// This is the main operation always block that responds to the asynchronous reset. Every clock |
// positive edge, it check for both int_read & int_write inputs. if the int_write is activated, |
// it store the data forced on the int_wr_data into the memory location defined by the address |
// applied on the int_address port. if the int_read is activated, it load the data stored in the |
// memory location defined by the address applied on the int_address port. |
// It's forbidden to assert both the int_write & int_read signal in the same time. |
always |
begin |
@(posedge clock or posedge reset); |
81,46 → 96,61
end |
end |
|
//-------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// Non Standard Routines |
// Non Standard Routines |
// |
//-------------------------------- |
//------------------------------------------------------------------------------------------------- |
|
// fill_byte routine is a function that fill only single byte in the register |
// file |
function void fill_byte (bit [`size-1:0] address, |
byte data); |
|
register_file[address] = data; |
endfunction:fill_byte |
// fill_byte routine is a function that fill only a single byte in the register file defined by |
// the input address with the single byte identified by data. |
function void fill_byte (bit [`size-1:0] address, |
byte data); |
register_file[address] = data; |
endfunction:fill_byte |
|
// fill_block routine is a function that fill continuous block of locations |
// in the register file |
function automatic void fill_block(bit [`size-1:0] address, |
ref byte data [], |
int unsigned block_length); |
// fill_block routine is a function that fill continuous block of locations in the register file. |
// The starting address identified by the address input and the data is defined by the dynamic |
// array data with length equal to block_length input. |
// In case that the block of memory locations includes the top memory location which meant that |
// the memory pointer(address) will reach its highest possible value and roll to zero. The imp- |
// lemented function has put this point in the concern |
function automatic void fill_block(bit [`size-1:0] address, |
ref byte data [], |
int unsigned block_length); |
|
for (int unsigned index = 0; index < block_length; index++) |
for (int unsigned index = 0; index < block_length; index++) |
begin |
// in case that the memory pointer has rolled over. the new address will be calculated from |
// the following relationship |
// The new address = the actual address - the whole memory size. |
if(address+index > `mem_size-1) |
begin |
register_file[address+index-`mem_size] = data [index]; |
end |
else |
begin |
register_file[address+index] = data [index]; |
end |
end |
endfunction:fill_block |
|
// reset_mem routine is a function that fill reset the register file contents to zero |
function void reset_mem(); |
for (int unsigned index = 0; index < `mem_size; index++) |
begin |
register_file[address+index] = data [index]; |
register_file[index] = 8'b0; |
end |
endfunction:fill_block |
endfunction:reset_mem |
|
// reset_mem routine is a function that fill reset the register file to contents |
// zero |
function void reset_mem(); |
for (int unsigned index = 0; index < `mem_size; index++) |
begin |
register_file[index] = 8'b0; |
end |
endfunction:reset_mem |
|
// read_mem_data routine is a function that load bus with the data content |
function byte read_mem_data(bit [`size-1:0] address); |
return register_file[address]; |
endfunction: read_mem_data |
|
// This routine read adjacent block of memory location into dynamic array of data and the |
// starting address defined by the address input. |
// The point of memory pointer rolling over has been put in the consideration <described above> |
task automatic read_block(input int unsigned data_length, |
input bit [15:0] address, |
ref byte data []); |
127,19 → 157,38
data = new [data_length]; |
for (int unsigned index=0;index<data_length;index++) |
begin |
data[index] = read_mem_data(address+index); |
if (address+index > `mem_size-1) |
begin |
data[index] = read_mem_data(address+index-`mem_size); |
end |
else |
begin |
data[index] = read_mem_data(address+index); |
end |
end |
endtask:read_block |
|
//----------------------------------------- |
// |
// MONITOR ROUTINES |
// |
//----------------------------------------- |
|
task automatic capture_transaction (output bit[`size-1:0] address, |
ref byte data []); |
int index; |
//------------------------------------------------------------------------------------------------- |
// |
// MONITOR ROUTINES |
// |
//------------------------------------------------------------------------------------------------- |
|
// This routine capture both the data and the address of the current transaction across the non- |
// standard interface side. |
// When it is called, it is blocked till the raising edge of int_gnt input. And during the high |
// level of int_gnt input. This routine samples both int_read and int_write inputs every positive |
// edge of the clock signal. If int_read is active, it realizes that the current transaction is |
// read and sample the int_rd_data bus at the current clock tick. |
// If the int_write is active, it realizes that the current transaction is write and sample the |
// int_wr_data bus at the current clock tick. |
// Note : - The transaction address is the address of the first affected memory location. |
// - It's obvious that one of the signals int_read or int_write at least should be active |
// when the int_gnt is active. which is implemented through the error alarm below. |
task automatic capture_transaction (output bit [`size-1:0] address, |
ref byte data [], |
output int unsigned data_length); |
int unsigned index; |
index = 0; |
@(posedge int_gnt); |
while (int_gnt) |
159,9 → 208,10
end |
else |
begin |
$error("both int_write and int_read is inactive"); |
$error("Both int_read and int_write is inactive while int_gnt is active"); |
end |
index++; |
data_length = index; |
end |
endtask:capture_transaction |
endinterface:rf_interface |
/tb/uart_pkg.sv
1,24 → 1,24
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// UART2BUS VERIFICATION |
// |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// CREATOR : HANY SALAH |
// PROJECT : UART2BUS UVM TEST BENCH |
// UNIT : TOP MODULE |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// TITLE : UART Package |
// DESCRIPTION: This file |
//----------------------------------------------------------------------------- |
// DESCRIPTION: THIS PACKAGE IMPORTS THE ALL SUBPACKAGES AND WHOLE TESTS |
//------------------------------------------------------------------------------------------------- |
// LOG DETAILS |
//------------- |
// VERSION NAME DATE DESCRIPTION |
// 1 HANY SALAH 11012016 FILE CREATION |
//----------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR |
// OPENCORES MEMBERS ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE |
// CREATOR'S PERMISSION |
//----------------------------------------------------------------------------- |
// 2 HANY SALAH 13022016 MODIFY BLOCK DESCRIPTION & ADD COMMENTS |
//------------------------------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR OPENCORES MEMBERS |
// ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE CREATOR'S PERMISSION |
//------------------------------------------------------------------------------------------------- |
package uart_pkg; |
|
import uvm_pkg::*; |
25,6 → 25,7
import agent_pkg::*; |
import env_pkg::*; |
|
|
`include "uvm_macros.svh" |
|
`include "uart_test.svh" |
/tb/uart_top.sv
1,24 → 1,25
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// UART2BUS VERIFICATION |
// UART2BUS VERIFICATION |
// |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// CREATOR : HANY SALAH |
// PROJECT : UART2BUS UVM TEST BENCH |
// UNIT : TOP MODULE |
//----------------------------------------------------------------------------- |
// TITLE : UART Top |
// DESCRIPTION: This |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// TITLE : UART TOP |
// DESCRIPTION: THIS TOP MODULE THAT INHERITS THE ALL TESTBENCH COMPONENT AND CONNECT THEM TO DUT. |
// ALSO INCLUDES THE CLOCK GENERATION MECHANISM. |
//------------------------------------------------------------------------------------------------- |
// LOG DETAILS |
//------------- |
// VERSION NAME DATE DESCRIPTION |
// 1 HANY SALAH 11012016 FILE CREATION |
//----------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR |
// OPENCORES MEMBERS ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE |
// CREATOR'S PERMISSION |
//----------------------------------------------------------------------------- |
// 2 HANY SALAH 18022016 IMPROVE BLOCK DESCRIPTION & ADD COMMENTS |
//------------------------------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR OPENCORES MEMBERS |
// ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE CREATOR'S PERMISSION |
//------------------------------------------------------------------------------------------------- |
`include "defin_lib.svh" |
`include "uart2bus_top.v" |
|
29,27 → 30,33
|
`include "uvm_macros.svh" |
|
// Global System clock |
logic clk_glob; |
|
// UART clock (1/Baud Rate) |
logic clk_uart; |
|
// Glocal Asynchronous reset |
logic reset; |
|
assign rf_inf.int_req = arb_inf.int_req; |
assign rf_inf.int_gnt = arb_inf.int_gnt; |
|
// Initiate UART BFM |
uart_interface uart_inf (.reset(reset), |
.clock(clk_uart)); |
|
// Initiate Register File BFM |
rf_interface rf_inf (.reset(reset), |
.clock(clk_glob)); |
|
// Initiate Arbiter BFM |
uart_arbiter arb_inf (.reset (reset), |
.clock(clk_glob)); |
|
// Initiate Design Under Test DUT |
uart2bus_top dut( .clock(clk_glob), |
.reset(reset), |
//.ser_in(serial_out), |
.ser_in(uart_inf.ser_out), |
.ser_out(uart_inf.ser_in), |
.int_address(rf_inf.int_address), |
72,6 → 79,7
reset = 1'b0; |
end |
|
// Clock Signals Generator |
initial |
begin |
fork |
85,11 → 93,6
#(`buad_clk_period/2) clk_uart = ~clk_uart; |
#((`buad_clk_period/2)+1) clk_uart = ~clk_uart; |
end |
begin |
#(500000000); |
$error("Exceed the maximum limited time for simulation .."); |
$finish; |
end |
join |
end |
|
102,12 → 105,12
|
uvm_config_db#(virtual uart_arbiter)::set(uvm_root::get(),"*","arb_inf",arb_inf); |
|
run_test("write_text_mode"); |
//run_test("write_text_mode"); |
//run_test("read_text_mode"); |
//run_test("nop_command_mode"); |
//run_test("read_command_mode"); |
//run_test("write_command_mode"); |
run_test("text_mode_test"); |
end |
|
|
|
endmodule:uart_top_tb |
/tb/run.do
8,9 → 8,9
|
#vlog -novopt agent/agent_pkg.sv +incdir+agent +incdir+agent/driver +incdir+./ +incdir+agent/configuration +incdir+agent/sequence +incdir+agent/transaction +incdir+../../../uvm-1.2/src/ |
|
vlog -novopt agent/agent_pkg.sv +incdir+agent +incdir+agent/driver +incdir+./ +incdir+agent/configuration +incdir+agent/sequence +incdir+agent/transaction +incdir+agent/monitor |
vlog -novopt agent/agent_pkg.sv +incdir+agent +incdir+agent/driver +incdir+./ +incdir+agent/configuration +incdir+agent/sequence +incdir+agent/transaction +incdir+agent/monitor +incdir+agent/coverage |
|
vlog -novopt env/env_pkg.sv +incdir+env +incdir+analysis |
vlog -novopt env/env_pkg.sv +incdir+env +incdir+analysis |
#vlog -novopt env/env_pkg.sv +incdir+env +incdir+../../../uvm-1.2/src/ |
|
vlog -novopt uart_pkg.sv +incdir+test/ +incdir+agent/ +incdir+env/ +incdir+./ +incdir+../ |
28,14 → 28,14
vlog -novopt uart_top.sv +incdir+../../rtl/i2c/ +incdir+./ +incdir+../rtl |
#vlog -novopt uart_top.sv +incdir+../../rtl/i2c/ +incdir+../../../uvm-1.2/src/ |
|
vsim -novopt uart_top_tb |
vsim -novopt +coverage uart_top_tb |
#vsim -novopt uart_top_tb +UVM_TIMEOUT=50,'NO' |
#vsim -novopt uart_top_tb +uvm_set_severity=uart_scoreboard,uart_s,UVM_LOW,UVM_LOW |
view wave |
|
add wave \ |
sim:/uart_top_tb/uart_inf/ser_in \ |
sim:/uart_top_tb/uart_inf/ser_out \ |
sim:/uart_top_tb/uart_inf/serial_out \ |
sim:/uart_top_tb/serial_out \ |
sim:/uart_top_tb/uart_inf/clock \ |
sim:/uart_top_tb/uart_inf/start_trans \ |
sim:/uart_top_tb/rf_inf/int_address \ |
/tb/env/env_pkg.sv
1,24 → 1,25
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// UART2BUS VERIFICATION |
// |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// CREATOR : HANY SALAH |
// PROJECT : UART2BUS UVM TEST BENCH |
// UNIT : ENVIRONEMNT |
//----------------------------------------------------------------------------- |
// TITLE : UART ENVIRONMENT PKG |
// DESCRIPTION: This |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// TITLE : UART ENVIRONMENT PACKAGE |
// DESCRIPTION: THIS PACKAGE INCLUDE |
//------------------------------------------------------------------------------------------------- |
// LOG DETAILS |
//------------- |
// VERSION NAME DATE DESCRIPTION |
// 1 HANY SALAH 10012016 FILE CREATION |
//----------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR |
// OPENCORES MEMBERS ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE |
// CREATOR'S PERMISSION |
//----------------------------------------------------------------------------- |
// 2 HANY SALAH 24012016 ADD UART SCOREBOARD |
// 3 HANY SALAH 11022016 IMPROVE BLOCK DESCRIPTION & ADD COMMENTS |
//------------------------------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR OPENCORES MEMBERS |
// ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE CREATOR'S PERMISSION |
//------------------------------------------------------------------------------------------------- |
|
package env_pkg; |
|
/tb/env/uart_env.svh
1,24 → 1,24
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// UART2BUS VERIFICATION |
// |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// CREATOR : HANY SALAH |
// PROJECT : UART2BUS UVM TEST BENCH |
// UNIT : AGENT |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// TITLE : UART ENVIRONMENT |
// DESCRIPTION: This |
//----------------------------------------------------------------------------- |
// DESCRIPTION: THIS BLOCK INCLUDES THE TESTBENCH AGENTS AND SCOREBOARD |
//------------------------------------------------------------------------------------------------- |
// LOG DETAILS |
//------------- |
// VERSION NAME DATE DESCRIPTION |
// 1 HANY SALAH 10012016 FILE CREATION |
//----------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR |
// OPENCORES MEMBERS ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE |
// CREATOR'S PERMISSION |
//----------------------------------------------------------------------------- |
// 2 HANY SALAH 11022016 IMPROVE BLOCK DESCRIPTION & ADD COMMENTS |
//------------------------------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR OPENCORES MEMBERS |
// ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE CREATOR'S PERMISSION |
//------------------------------------------------------------------------------------------------- |
class uart_env extends uvm_env; |
|
uart_agent agent; |
/tb/defin_lib.svh
1,15 → 1,16
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// UART2BUS VERIFICATION |
// |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// CREATOR : HANY SALAH |
// PROJECT : UART2BUS UVM TEST BENCH |
// UNIT : DEFINITION LIBRARY |
//----------------------------------------------------------------------------- |
// TITLE : UART Definition Library |
// DESCRIPTION: This |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// TITLE : UART DEFINITION LIBRARY |
// DESCRIPTION: THIS LIBRARY INCLUDES ALL THE USER MACROSES, TIMESCALE, TRANSACTION DATA TYPES, |
// GLOBAL FUNCTIONS AND CONFIGURATION DATA TYPES |
//------------------------------------------------------------------------------------------------- |
// LOG DETAILS |
//------------- |
// VERSION NAME DATE DESCRIPTION |
16,18 → 17,26
// 1 HANY SALAH 25122015 FILE CREATION |
// 2 HANY SALAH 31122015 ADD DATA TYPE DEFINITIONS |
// 3 HANY SALAH 11012016 ADD TIMING PARAMETERS DEFINITION |
//----------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR |
// OPENCORES MEMBERS ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE |
// CREATOR'S PERMISSION |
//----------------------------------------------------------------------------- |
// 4 HANY SALAH 18022016 IMPROVE BLOCK DESCRIPTION |
//------------------------------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR OPENCORES MEMBERS |
// ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE CREATOR'S PERMISSION |
//------------------------------------------------------------------------------------------------- |
|
`timescale 1ns/1ns |
//------------------------------------------ |
|
//------------------------------------------------------------------------------------------------- |
// |
// Definition Identifiers |
// Definition Identifiers |
// |
//------------------------------------------ |
//------------------------------------------------------------------------------------------------- |
|
// Define high value |
`define one 1'b1 |
|
// Define low value |
`define zero 1'b0 |
|
// Define size of address line |
`define size 16 |
|
82,9 → 91,12
// Binary Mode Command |
`define binary_mode 2 |
|
// Wrong Mode Command |
`define wrong_mode 3 |
// Wrong Mode text Command |
`define wrong_mode_txt 3 |
|
// Wrong Mode bin Command |
`define wrong_mode_binry 4 |
|
// Read Command |
`define read_comm 1 |
|
94,9 → 106,12
// nop Command |
`define nop_comm 3 |
|
// wrong Command |
`define wrong_comm 4 |
// wrong Read Command |
`define wrong_comm_read 4 |
|
// wrong Write Command |
`define wrong_comm_write 5 |
|
// Use single white space |
`define single_space 1 |
|
147,11 → 162,20
|
// Write Control |
`define write_ctrl 2'b10 |
//------------------------------------------ |
|
// Invalid Control |
`define invalid_ctrl 2'b11 |
|
`define _parityoff 1 |
|
`define _parityeven 2 |
|
`define _parityodd 3 |
//------------------------------------------------------------------------------------------------- |
// |
// Timing Defines |
// Timing Defines |
// |
//------------------------------------------ |
//------------------------------------------------------------------------------------------------- |
// Define stability time |
`define stab 10 |
|
160,34 → 184,36
|
// Define the period of baud clock in terms of ns |
`define buad_clk_period 8680 |
//------------------------------------------ |
|
//------------------------------------------------------------------------------------------------- |
// |
// Configuration Data Type |
// Configuration Data Type |
// |
//------------------------------------------ |
//------------------------------------------------------------------------------------------------- |
|
// Represents the active edge |
typedef enum {pos_edge=1, // Based on positive edge |
neg_edge=2} act_edge; // Based on negative edge |
// Represents the active edge |
typedef enum {pos_edge=1, // Based on positive edge |
neg_edge=2} act_edge; // Based on negative edge |
|
// Represent the starting bit |
typedef enum {msb=1, // Most Significant bit first |
lsb=2} start_bit; // Least Significant bit first |
// Represent the starting bit |
typedef enum {msb=1, // Most Significant bit first |
lsb=2} start_bit; // Least Significant bit first |
|
//------------------------------------------ |
//------------------------------------------------------------------------------------------------- |
// |
// New Data Type Definitions |
// New Data Type Definitions |
// |
//------------------------------------------ |
//------------------------------------------------------------------------------------------------- |
|
// Represents the mode of command to be one of the following options {text, command, wrong}. Wrong |
// command mode is used to send a tricky fault command to test our DUT. |
typedef enum {text=1, // Communicate using text mode |
binary=2, // Communicate using command mode |
wrong_mode=3} mode; // Communicate using wrong prefix |
// Represents the mode of command to be one of the following options {text, command, wrong}. |
// Wrong command mode is used to send a tricky fault command to test our DUT. |
typedef enum {text=1, // Communicate using text mode |
binary=2, // Communicate using command mode |
wrong_mode_text=3, // Communicate using wrong prefix(text mode) |
wrong_mode_bin=4} mode; // Communicate using wrong prefix(binary mode) |
|
// Represents the type of the used white space to be one of the following options {single, tab, wrong}. |
// Wrong type also is used to push tricky byte in the text mode. |
// Represents the type of the used white space to be one of the following options {single, tab, |
// wrong}. Wrong type also is used to push tricky byte in the text mode. |
typedef enum {single=1, // Using single space as a white space |
tab=2, // Using tab as a white space |
wrong_space=3} space_type; // Using wrong white space |
199,10 → 225,11
wrong_eol=3} eol_type; // Using wrong EOL |
|
// Represents the command either to be one of the following choices {read, write, NOP} |
typedef enum {read=1, // Read Command |
write=2, // Write Command |
nop=3, // Make No Operation |
invalid=4} command; // Invalid command value |
typedef enum {read=1, // Read Command |
write=2, // Write Command |
nop=3, // Make No Operation |
invalid_read=4, // Invalid Command with read data |
invalid_write=5} command; // Invalid Command with write data |
|
// Represents both acknowledge and incremental address request{yes, no} |
typedef enum {yes=1, // Request Acknowledge |
217,164 → 244,167
declain=2} arbit; // Refuse Bus Grant |
|
// Define mode of data {ascii or binary} |
typedef enum {bin=1, |
ascii=2} data_mode; |
typedef enum {bin=1, // Binary Representation (data remains unchanged) |
ascii=2} data_mode; // ASCII Representation (each niblle is converted into |
// ASCII byte) |
|
// Define mode of the used parity |
typedef enum {parity_off=1, |
parity_even=2, |
parity_odd=3} parity_mode ; |
typedef enum {parity_off=1, // Don't Add Parity Field |
parity_even=2, // Add Even Parity to fields |
parity_odd=3} parity_mode ; // Add Odd Parity to fields |
|
//------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// GLOBAL FUNCTION |
// GLOBAL FUNCTIONS |
// |
//------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
|
// Binary To ASCII Conversion to convert nibble into ASCII byte through the following look-up-table |
function byte bin_asci_conv (bit[3:0] data); |
byte temp; |
case (data) |
4'h0: |
begin |
temp = 8'h30; |
end |
4'h1: |
begin |
temp = 8'h31; |
end |
4'h2: |
begin |
temp = 8'h32; |
end |
4'h3: |
begin |
temp = 8'h33; |
end |
4'h4: |
begin |
temp = 8'h34; |
end |
4'h5: |
begin |
temp = 8'h35; |
end |
4'h6: |
begin |
temp = 8'h36; |
end |
4'h7: |
begin |
temp = 8'h37; |
end |
4'h8: |
begin |
temp = 8'h38; |
end |
4'h9: |
begin |
temp = 8'h39; |
end |
4'hA: |
begin |
temp = 8'h41; |
end |
4'hB: |
begin |
temp = 8'h42; |
end |
4'hC: |
begin |
temp = 8'h43; |
end |
4'hD: |
begin |
temp = 8'h44; |
end |
4'hE: |
begin |
temp = 8'h45; |
end |
4'hF: |
begin |
temp = 8'h46; |
end |
endcase |
return temp; |
endfunction:bin_asci_conv |
// Binary To ASCII Conversion to convert nibble into ASCII byte through the following look-up- |
// table |
function byte bin_asci_conv (bit[3:0] data); |
byte temp; |
case (data) |
4'h0: |
begin |
temp = 8'h30; |
end |
4'h1: |
begin |
temp = 8'h31; |
end |
4'h2: |
begin |
temp = 8'h32; |
end |
4'h3: |
begin |
temp = 8'h33; |
end |
4'h4: |
begin |
temp = 8'h34; |
end |
4'h5: |
begin |
temp = 8'h35; |
end |
4'h6: |
begin |
temp = 8'h36; |
end |
4'h7: |
begin |
temp = 8'h37; |
end |
4'h8: |
begin |
temp = 8'h38; |
end |
4'h9: |
begin |
temp = 8'h39; |
end |
4'hA: |
begin |
temp = 8'h41; |
end |
4'hB: |
begin |
temp = 8'h42; |
end |
4'hC: |
begin |
temp = 8'h43; |
end |
4'hD: |
begin |
temp = 8'h44; |
end |
4'hE: |
begin |
temp = 8'h45; |
end |
4'hF: |
begin |
temp = 8'h46; |
end |
endcase |
return temp; |
endfunction:bin_asci_conv |
|
// ASCII To Binary Conversion is to convert ASCII byte into Binary nibble through the following Look-Up-Table |
function bit [3:0] asci_bin_conv (byte data); |
bit [3:0] temp; |
case (data) |
8'h30: |
begin |
temp = 4'h0; |
end |
8'h31: |
begin |
temp = 4'h1; |
end |
8'h32: |
begin |
temp = 4'h2; |
end |
8'h33: |
begin |
temp = 4'h3; |
end |
8'h34: |
begin |
temp = 4'h4; |
end |
8'h35: |
begin |
temp = 4'h5; |
end |
8'h36: |
begin |
temp = 4'h6; |
end |
8'h37: |
begin |
temp = 4'h7; |
end |
8'h38: |
begin |
temp = 4'h8; |
end |
8'h39: |
begin |
temp = 4'h9; |
end |
8'h41: |
begin |
temp = 4'hA; |
end |
8'h42: |
begin |
temp = 4'hB; |
end |
8'h43: |
begin |
temp = 4'hC; |
end |
8'h44: |
begin |
temp = 4'hD; |
end |
8'h45: |
begin |
temp = 4'hE; |
end |
8'h46: |
begin |
temp = 4'hF; |
end |
default: |
begin |
$error("undefined ascii symbol"); |
end |
endcase |
return temp; |
endfunction:asci_bin_conv |
// ASCII To Binary Conversion is to convert ASCII byte into Binary nibble through the following |
// Look-Up-Table |
function bit [3:0] asci_bin_conv (byte data); |
bit [3:0] temp; |
case (data) |
8'h30: |
begin |
temp = 4'h0; |
end |
8'h31: |
begin |
temp = 4'h1; |
end |
8'h32: |
begin |
temp = 4'h2; |
end |
8'h33: |
begin |
temp = 4'h3; |
end |
8'h34: |
begin |
temp = 4'h4; |
end |
8'h35: |
begin |
temp = 4'h5; |
end |
8'h36: |
begin |
temp = 4'h6; |
end |
8'h37: |
begin |
temp = 4'h7; |
end |
8'h38: |
begin |
temp = 4'h8; |
end |
8'h39: |
begin |
temp = 4'h9; |
end |
8'h41: |
begin |
temp = 4'hA; |
end |
8'h42: |
begin |
temp = 4'hB; |
end |
8'h43: |
begin |
temp = 4'hC; |
end |
8'h44: |
begin |
temp = 4'hD; |
end |
8'h45: |
begin |
temp = 4'hE; |
end |
8'h46: |
begin |
temp = 4'hF; |
end |
default: |
begin |
$error("undefined ascii symbol"); |
end |
endcase |
return temp; |
endfunction:asci_bin_conv |
/tb/agent/transaction/uart_transaction.svh
1,42 → 1,53
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// UART2BUS VERIFICATION |
// |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// CREATOR : HANY SALAH |
// PROJECT : UART2BUS UVM TEST BENCH |
// UNIT : TRANSACTION |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// TITLE : UART Transaction |
// DESCRIPTION: This |
//----------------------------------------------------------------------------- |
// DESCRIPTION: THIS FILE INCLUDES MAIN TRANSACTION ATTRIBUTES, CONSTRAINTS AND DO-COPY OVERRIDE |
// FUNCTION |
//------------------------------------------------------------------------------------------------- |
// LOG DETAILS |
//------------- |
// VERSION NAME DATE DESCRIPTION |
// 1 HANY SALAH 31122015 FILE CREATION |
// 2 HANY SALAH 01012016 COMPLETE ATTRIBUTES |
//----------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR |
// OPENCORES MEMBERS ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE |
// CREATOR'S PERMISSION |
//----------------------------------------------------------------------------- |
// 3 HANY SALAH 26012016 ADD VALID TRANSACTION CONSTRAINTS |
// 4 HANY SALAH 11022016 IMPROVE BLOCK DESCRIPTION AND ADD CODING COMMENTS |
//------------------------------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR OPENCORES MEMBERS |
// ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE CREATOR'S PERMISSION |
//------------------------------------------------------------------------------------------------- |
class uart_transaction extends uvm_sequence_item; |
|
// Represent the mode of operation either to be text or command mode |
rand mode _mode; |
|
// Represent the wrong prefix forced in wrong mode |
rand byte wrong_prefix; |
|
// Represent the type of space either to be single space or tab |
rand space_type _spacetype1,_spacetype2; |
|
// Represent the wrong character used as a white space [Refer To Verification Plan For More Information] |
// Represent the wrong character used as a white space [Refer To Verification Plan For More |
// Information] |
rand byte space_wrong1; |
|
// Represent the wrong character used as a white space [Refer To Verification Plan For More Information] |
// Represent the wrong character used as a white space [Refer To Verification Plan For More |
// Information] |
rand byte space_wrong2; |
|
// Represent the used data through the stimulus |
rand byte _data []; |
|
// Represent the false data that is drivin on the serial output bus through the read command |
// response |
rand byte false_data []; |
|
// Represent the length of data used through the stimulus |
rand int unsigned length_data; |
|
43,7 → 54,8
// Represent the type of end of line used |
rand eol_type _eoltype; |
|
// Represent the wrong character used as an end of line [Refer To Verification Plan For More Information] |
// Represent the wrong character used as an end of line [Refer To Verification Plan For More |
// Information] |
rand byte eol_wrong; |
|
// Represent the used address through the stimulus |
64,11 → 76,19
// Represent the internal bus state either free or busy |
rand arbit _arbit; |
|
// Represents random idle time |
// Represent the request to use false data through the read command. |
rand req false_data_en; |
|
// Represents random idle time before and after the UART stimulus |
rand time time_before,time_after; |
|
// Represents the acknowledge byte driven by the DUT |
byte acknowledge; |
|
// Represent the number of the transaction through the whole sequences |
int _id; |
|
// Represent the scale that is used to scale the idle time values described above |
int unsigned scale = 100; |
|
`uvm_object_utils(uart_transaction) |
77,14 → 97,57
super.new(name); |
endfunction: new |
|
// This constraint limit the size of unbounded data and false data arrays to be in the range |
// between one byte and 256 successive bytes. |
// To make Testbench more simple, the length of data is constrained to be less than or equal |
// 10 bytes. |
// Idle time valu |
constraint data_length { |
_data.size == length_data; |
false_data.size ==length_data; |
length_data <= 10; |
length_data inside {[1:256]}; |
time_before inside {200,300,400,500,600,700,800,900,1000}; |
time_after inside {200,300,400,500,600,700,800,900,1000}; |
} |
|
// This constraint is used to constrain the wrong character not to be as the UART standard |
// characters. |
// In case of text command, it is critical to make the white space wrong character |
// not to be simiar to either single space character or Tab space character.Address and Data |
// bytes as well shouldn't be like the standard characters. |
// In case of binary command, it is also critical to make the length byte, address bytes, data |
// bytes similiar to UART standard characters. |
constraint transaction_valid { |
!(space_wrong1 inside {`space,`tab,`w,`W,`bin_prfx,`CR,`LF}); |
!(space_wrong2 inside {`space,`tab,`w,`W,`bin_prfx,`CR,`LF}); |
!(eol_wrong inside {`space,`tab,`w,`W,`bin_prfx,`CR,`LF}); |
if (_mode inside {wrong_mode_text,wrong_mode_bin}) |
{ |
!(space_wrong1 inside {`w,`W,`r,`R,`bin_prfx}); |
!(space_wrong2 inside {`w,`W,`r,`R,`bin_prfx}); |
!(address [15:08] inside {`w,`W,`r,`R,`bin_prfx}); |
!(address [07:00] inside {`w,`W,`r,`R,`bin_prfx}); |
foreach(_data[i]) |
!(_data[i] inside {`w,`W,`r,`R,`bin_prfx}); |
|
!(length_data inside {`w,`W,`r,`R,`bin_prfx}); |
|
|
} |
} |
|
// This constraint is used to re-distribute the random enable bit of the false data usage |
constraint read_data_constraints{ |
|
if(_command == read) |
{ |
false_data_en dist {no:=8, yes:=2}; |
} |
} |
|
extern function void do_copy (uvm_object rhs); |
|
endclass:uart_transaction |
|
|
113,4 → 176,8
time_before =_trans.time_before; |
time_after =_trans.time_after; |
acknowledge = _trans.acknowledge; |
wrong_prefix=_trans.wrong_prefix; |
false_data =_trans.false_data; |
false_data_en =_trans.false_data_en; |
_id =_trans._id; |
endfunction:do_copy |
/tb/agent/agent_pkg.sv
1,24 → 1,25
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// UART2BUS VERIFICATION |
// |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// CREATOR : HANY SALAH |
// PROJECT : UART2BUS UVM TEST BENCH |
// UNIT : AGENT |
//----------------------------------------------------------------------------- |
// TITLE : UART AGENT PKG |
// DESCRIPTION: This |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// TITLE : UART AGENT PACKAGE |
// DESCRIPTION: THIS PACKAGE INCLUDES ALL AGENT BLOCKS AND ALSO DEFINITIONS LI- |
// BRARY. |
//------------------------------------------------------------------------------------------------- |
// LOG DETAILS |
//------------- |
// VERSION NAME DATE DESCRIPTION |
// 1 HANY SALAH 10012016 FILE CREATION |
//----------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR |
// OPENCORES MEMBERS ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE |
// CREATOR'S PERMISSION |
//----------------------------------------------------------------------------- |
// 2 HANY SALAH 11022016 IMPROVE BLOCK DESCRIPTION |
//------------------------------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR OPENCORES MEMBERS |
// ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE CREATOR'S PERMISSION |
//------------------------------------------------------------------------------------------------- |
|
package agent_pkg; |
|
32,6 → 33,7
`include "uart_config.svh" |
`include "uart_driver.svh" |
`include "uart_monitor.svh" |
`include "uart_coverage.svh" |
|
`include "uart_agent.svh" |
|
/tb/agent/configuration/uart_config.svh
1,47 → 1,61
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// UART2BUS VERIFICATION |
// UART2BUS VERIFICATION |
// |
//----------------------------------------------------------------------------- |
// CREATOR : HANY SALAH |
//-------------------------------------------------------------------------------------------------// CREATOR : HANY SALAH |
// PROJECT : UART2BUS UVM TEST BENCH |
// UNIT : CONFIGURATION |
//----------------------------------------------------------------------------- |
// TITLE : UART Configuration |
// DESCRIPTION: This |
//----------------------------------------------------------------------------- |
// LOG DETAILS |
// UNIT : AGENT |
//-------------------------------------------------------------------------------------------------// TITLE : UART Configuration |
// DESCRIPTION: UART Configuration INCLUDES INSTANCE OF THE THREE BFMS. ALSO INCLUDES THE WHOLE EN- |
// VIRONMENT CONFIGURATIONS THAT ARE SET IN THE TEST. |
//-------------------------------------------------------------------------------------------------// LOG DETAILS |
//------------- |
// VERSION NAME DATE DESCRIPTION |
// 1 HANY SALAH 02012016 FILE CREATION |
//----------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR |
// OPENCORES MEMBERS ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE |
// CREATOR'S PERMISSION |
//----------------------------------------------------------------------------- |
// 2 HANY SALAH 09022016 REFINE THE BLOCK DESCRIPTION AND ADD DESCRIPTIVE COMMENTS |
//-------------------------------------------------------------------------------------------------// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR OPENCORES MEMBERS |
// ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE CREATOR'S PERMISSION |
//------------------------------------------------------------------------------------------------- |
|
class uart_config extends uvm_object; |
|
// Uart BFM Instance |
virtual uart_interface uart_inf; |
|
// Register File BFM Instance |
virtual rf_interface rf_inf; |
|
// Arbiter BFM Instance |
virtual uart_arbiter arb_inf; |
|
// Active clock edge that would syncronize the whole system to be either the positive or the neg- |
// tive edge |
act_edge _edge; |
|
// Define the sequence to be used in transmitting one byte serially; either to start with the MSB |
// or the LSB. |
start_bit _start; |
|
// Define the Represenetation of data through the text mode to be either ASCII or Binary |
data_mode _datamode; |
|
// Define the number of stop bits at the final of each UART field to be one of two bits |
int num_stop_bits; |
|
// Define the number of bits inbetween the start and the stop bits to be seven or eight bits |
int num_of_bits; |
|
// Define the parity mode used to be either no parity, odd parity or even parity. |
parity_mode _paritymode; |
|
// Define the maximum time between the generated stimulus and the DUT response. |
time response_time; |
|
// Define the possibility of generating false data through the read command. This attribute is |
// general control one that would be make this feature would be used or not. And another field |
// would be generated through the sequence. |
req use_false_data; |
|
`uvm_object_utils(uart_config) |
|
function new (string name = "uart_config"); |
/tb/agent/monitor/uart_monitor.svh
14,6 → 14,8
//------------- |
// VERSION NAME DATE DESCRIPTION |
// 1 HANY SALAH 12012016 FILE CREATION |
// 2 HANY SALAH 31012016 ADD INVALID WRITE CASE TO TRANSACTION |
// PACKETAIZATION METHOD |
//----------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR |
// OPENCORES MEMBERS ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE |
99,11 → 101,16
int _eoltype; |
int _reqack; |
int _reqinc; |
byte data_temp[$]; |
|
iteration = 0; |
forever |
begin |
iteration++; |
//trans.reset_fields(); |
uart_inf.wait_event(); |
trans.acknowledge=8'b00; |
|
uart_inf.capture_command(command_type, |
_command, |
_chartype, |
119,29 → 126,30
trans.length_data, |
_reqack, |
_reqinc); |
trans._mode = mode'(command_type); |
trans._command = command'(_command); |
trans._chartype = char_type'(_chartype); |
trans._spacetype1 = space_type'(_spacetype1); |
trans._spacetype2 = space_type'(_spacetype2); |
trans._eoltype = eol_type '(_eoltype); |
trans._reqinc = req '(_reqinc); |
trans._reqack = req '(_reqack); |
if (trans._command == write) |
begin |
if (trans._mode == text) |
trans._mode = mode'(command_type); |
trans._command = command'(_command); |
trans._chartype = char_type'(_chartype); |
trans._spacetype1 = space_type'(_spacetype1); |
trans._spacetype2 = space_type'(_spacetype2); |
trans._eoltype = eol_type '(_eoltype); |
trans._reqinc = req '(_reqinc); |
trans._reqack = req '(_reqack); |
if (trans._command == write || trans._command == invalid_write) |
begin |
trans._data[0] = rf_inf.read_mem_data(trans.address[7:0]); |
if (trans._mode == text || trans._mode == wrong_mode_text) |
begin |
trans._data[0] = rf_inf.read_mem_data(trans.address); |
end |
else if (trans._mode == binary || trans._mode == wrong_mode_bin) |
begin |
rf_inf.read_block(trans.length_data, |
trans.address, |
trans._data); |
end |
end |
else if (trans._mode == binary) |
begin |
rf_inf.read_block(trans.data_length, |
trans.address, |
trans._data); |
end |
end |
//display_content(); |
mon_scbd.write(trans); |
//display_content(); |
trans._id = iteration; |
mon_scbd.write(trans); |
end |
|
|
endtask:run_phase |
/tb/agent/sequence/uart_sequence.svh
1,27 → 1,31
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// UART2BUS VERIFICATION |
// |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// CREATOR : HANY SALAH |
// PROJECT : UART2BUS UVM TEST BENCH |
// UNIT : SEQUENCE |
//----------------------------------------------------------------------------- |
// TITLE : UART Sequence |
// DESCRIPTION: This |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// TITLE : UART SEQUENCE |
// DESCRIPTION: THIS FILE INCLUDES THE ALL SEQUENCES THAT WOULD BE FORCED INTO DUT. THE SEQUENCES |
// MENTIONED BELOW IS IDENTIFIED IN THE MANNER RELATED TO THE TEST PLAN SECTION IN |
// THE DOCUMENT; IT IS IDENTIFIED USING TWO TERMS; SUBSECTION AND ITEM INSIDE SUB- |
// SECTION. |
//------------------------------------------------------------------------------------------------- |
// LOG DETAILS |
//------------- |
// VERSION NAME DATE DESCRIPTION |
// 1 HANY SALAH 01012016 FILE CREATION |
// 2 HANY SALAH 02012016 ADD REST OF TESTS |
//----------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR |
// OPENCORES MEMBERS ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE |
// CREATOR'S PERMISSION |
//----------------------------------------------------------------------------- |
// 3 HANY SALAH 29012016 INSERT WRONG MODE IN BOTH BINARY AND TEXT COMMUNICATION |
// MODES |
// 4 HANY SALAH 09022016 REFINE BLOCK DESCRIPTION |
//------------------------------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR OPENCORES MEMBERS |
// ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE CREATOR'S PERMISSION |
//------------------------------------------------------------------------------------------------- |
|
|
// Base Sequence Class that hold the common attributes to all sequences |
class uart_base_sequence extends uvm_sequence #(uart_transaction); |
|
35,11 → 39,11
endfunction:new |
endclass:uart_base_sequence |
|
//------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// WRITE IN TEXT MODE |
// WRITE IN TEXT MODE |
// |
//------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
|
// 1.1 Apply UART write request using capital W |
class seq_1p1 extends uart_base_sequence; |
271,7 → 275,7
length_data == 1; |
_eoltype != wrong_eol; |
_command == write; |
address == 4'hFFFF; |
address == 16'hFFFF; |
_reqinc == no; |
_arbit == accept; |
}; |
325,7 → 329,7
length_data == 1; |
_eoltype != wrong_eol; |
_command == write; |
_data [0] == 2'hff; |
_data [0] == 8'hff; |
_reqinc == no; |
_arbit == accept; |
} ; |
334,11 → 338,62
endclass:seq_1p11 |
|
|
//------------------------------------------------------- |
// 1.12 Apply UART write request using different EOL character. |
class seq_1p12 extends uart_base_sequence; |
|
`uvm_object_utils(seq_1p12) |
|
function new (string name = "seq_1p12"); |
super.new(name); |
endfunction:new |
|
virtual task body (); |
start_item(trans); |
trans.randomize() with { |
_mode == text; |
_spacetype1 != wrong_space; |
_spacetype2 != wrong_space; |
length_data == 1; |
_eoltype == wrong_eol; |
_command == write; |
_reqinc == no; |
_arbit == accept; |
} ; |
finish_item(trans); |
endtask:body |
endclass:seq_1p12 |
|
|
// 1.13 Apply UART Write request using wrong prefix |
class seq_1p13 extends uart_base_sequence; |
|
`uvm_object_utils(seq_1p13) |
|
function new (string name = "seq_1p13"); |
super.new(name); |
endfunction:new |
|
virtual task body (); |
start_item(trans); |
trans.randomize() with { |
_mode == wrong_mode_text; |
_spacetype1 != wrong_space; |
_spacetype2 != wrong_space; |
length_data == 1; |
_eoltype != wrong_eol; |
_command == write; |
_reqinc == no; |
_arbit == accept; |
} ; |
finish_item(trans); |
endtask:body |
endclass:seq_1p13 |
|
//------------------------------------------------------------------------------------------------- |
// |
// READ IN TEXT MODE |
// READ IN TEXT MODE |
// |
//------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
|
// 2.1 Apply UART read request using capital R |
class seq_2p1 extends uart_base_sequence; |
570,7 → 625,7
length_data == 1; |
_eoltype != wrong_eol; |
_command == read; |
address == 4'hFFFF; |
address == 16'hFFFF; |
_reqinc == no; |
_arbit == accept; |
} ; |
624,7 → 679,7
length_data == 1; |
_eoltype != wrong_eol; |
_command == read; |
_data [0] == 2'hff; |
_data [0] == 8'hff; |
_reqinc == no; |
_arbit == accept; |
} ; |
632,11 → 687,63
endtask:body |
endclass:seq_2p11 |
|
//------------------------------------------------------- |
|
// 2.12 Apply UART read request using different EOL character. |
class seq_2p12 extends uart_base_sequence; |
|
`uvm_object_utils(seq_2p12) |
|
function new (string name = "seq_2p12"); |
super.new(name); |
endfunction:new |
|
virtual task body (); |
start_item(trans); |
trans.randomize() with { |
_mode == text; |
_spacetype1 != wrong_space; |
_spacetype2 != wrong_space; |
length_data == 1; |
_eoltype == wrong_eol; |
_command == read; |
_reqinc == no; |
_arbit == accept; |
} ; |
finish_item(trans); |
endtask:body |
endclass:seq_2p12 |
|
|
// 2.13 Apply UART Read request using wrong prefix |
class seq_2p13 extends uart_base_sequence; |
|
`uvm_object_utils(seq_2p13) |
|
function new (string name = "seq_2p13"); |
super.new(name); |
endfunction:new |
|
virtual task body (); |
start_item(trans); |
trans.randomize() with { |
_mode == wrong_mode_text; |
_spacetype1 != wrong_space; |
_spacetype2 != wrong_space; |
length_data == 1; |
_eoltype != wrong_eol; |
_command == read; |
_reqinc == no; |
_arbit == accept; |
} ; |
finish_item(trans); |
endtask:body |
endclass:seq_2p13 |
|
//------------------------------------------------------------------------------------------------- |
// |
// NOP IN COMMAND MODE |
// NOP IN COMMAND MODE |
// |
//------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
|
// 3.1 Apply UART NOP command with acknowledge request and right command |
// mode prefix |
657,6 → 764,7
_arbit == accept; |
_reqack == yes; |
} ; |
$display("reached here sequence @time=%0t ,, _mode = %p",$time,trans._mode); |
finish_item(trans); |
endtask:body |
endclass:seq_3p1 |
674,9 → 782,9
virtual task body (); |
start_item(trans); |
trans.randomize() with { |
_mode == wrong_mode; |
_mode == wrong_mode_bin; |
_command == nop; |
address[15:7] != 2'h00; |
address != 16'h0; |
(length_data > 1) -> (_reqinc == yes); |
_arbit == accept; |
_reqack == yes; |
754,9 → 862,9
virtual task body (); |
start_item(trans); |
trans.randomize() with { |
_mode == wrong_mode; |
_mode == wrong_mode_bin; |
_command == nop; |
address[15:7] != 2'h00; |
address[15:7] != 8'h00; |
(length_data > 1) -> (_reqinc == yes); |
_arbit == accept; |
_reqack == no; |
798,11 → 906,11
endtask:body |
endclass:seq_4p3 |
|
//------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// WRITE IN COMMAND MODE |
// WRITE IN COMMAND MODE |
// |
//------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
|
// 5.1 Apply UART write command with wrong prefix. |
class seq_5p1 extends uart_base_sequence; |
816,9 → 924,9
virtual task body (); |
start_item(trans); |
trans.randomize() with { |
_mode == wrong_mode; |
_mode == wrong_mode_bin; |
_command == write; |
address[15:7] != 2'h00; |
address[15:7] != 8'h00; |
(length_data > 1) -> (_reqinc == yes); |
_arbit == accept; |
} ; |
924,7 → 1032,7
trans.randomize() with { |
_mode == binary; |
_command == write; |
address == 4'hffff; |
address == 16'hFFFF; |
(length_data > 1) -> (_reqinc == yes); |
_arbit == accept; |
} ; |
1042,12 → 1150,11
endtask:body |
endclass:seq_5p10 |
|
|
//------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// READ IN COMMAND MODE |
// READ IN COMMAND MODE |
// |
//------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
|
// 6.1 Apply UART read command with wrong prefix. |
class seq_6p1 extends uart_base_sequence; |
1061,9 → 1168,9
virtual task body (); |
start_item(trans); |
trans.randomize() with { |
_mode == wrong_mode; |
_mode == wrong_mode_bin; |
_command == read; |
address[15:7] != 2'h00; |
address[15:7] != 8'h00; |
(length_data > 1) -> (_reqinc == yes); |
_arbit == accept; |
} ; |
1169,7 → 1276,7
trans.randomize() with { |
_mode == binary; |
_command == read; |
address == 4'hffff; |
address == 16'hFFFF; |
(length_data > 1) -> (_reqinc == yes); |
_arbit == accept; |
} ; |
1287,11 → 1394,11
endtask:body |
endclass:seq_6p10 |
|
//------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// INTERNAL BUS |
// INTERNAL BUS |
// |
//------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
|
// 7.1 Apply UART read or write commands and give the UART the bus grant. |
class seq_7p1 extends uart_base_sequence; |
1335,4 → 1442,54
} ; |
finish_item(trans); |
endtask:body |
endclass:seq_7p2 |
endclass:seq_7p2 |
|
//------------------------------------------------------------------------------------------------- |
// |
// INVALID COMMANDS |
// |
//------------------------------------------------------------------------------------------------- |
|
// 8.1 Apply Invalid UART command in form of write binary command. |
class seq_8p1 extends uart_base_sequence; |
|
`uvm_object_utils(seq_8p1) |
|
function new (string name="seq_8p1"); |
super.new(name); |
endfunction:new |
|
virtual task body (); |
start_item(trans); |
trans.randomize() with { |
_mode == binary; |
_command == invalid_write; |
(length_data > 1) -> (_reqinc == yes); |
_arbit == accept; |
_reqinc == yes; |
} ; |
finish_item(trans); |
endtask:body |
endclass:seq_8p1 |
|
// 8.2 Apply Invalid UART command in form of read binary command. |
class seq_8p2 extends uart_base_sequence; |
|
`uvm_object_utils(seq_8p2) |
|
function new (string name="seq_8p2"); |
super.new(name); |
endfunction:new |
|
virtual task body (); |
start_item(trans); |
trans.randomize() with { |
_mode == binary; |
_command == invalid_read; |
(length_data > 1) -> (_reqinc == yes); |
_arbit == declain; |
_reqinc == yes; |
} ; |
finish_item(trans); |
endtask:body |
endclass:seq_8p2 |
/tb/agent/uart_agent.svh
1,35 → 1,44
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// UART2BUS VERIFICATION |
// |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// CREATOR : HANY SALAH |
// PROJECT : UART2BUS UVM TEST BENCH |
// UNIT : AGENT |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// TITLE : UART AGENT |
// DESCRIPTION: This |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// LOG DETAILS |
//------------- |
// VERSION NAME DATE DESCRIPTION |
// 1 HANY SALAH 10012016 FILE CREATION |
//----------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR |
// OPENCORES MEMBERS ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE |
// CREATOR'S PERMISSION |
//----------------------------------------------------------------------------- |
// 2 HANY SALAH 09022016 ADD COVERAGE BLOCK |
// 3 HANY SALAH 11022016 IMPROVE BLOCK DESCRIPTION & ADD COMMENTS |
//------------------------------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR OPENCORES MEMBERS |
// ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE CREATOR'S PERMISSION |
//------------------------------------------------------------------------------------------------- |
|
class uart_agent extends uvm_agent; |
|
// UART Driver |
uart_driver _drv; |
|
// UART Sequencer |
uvm_sequencer#(uart_transaction) _seq; |
|
// UART Monitor |
uart_monitor _mon; |
|
// UART Coverage block |
uart_coverage _cov; |
|
// TLM analysis port that is linked to driver tlm analysis port. |
uvm_analysis_port #(uart_transaction) drv_port; |
|
// TLM analysis port that is linked to monitor tlm analysis port. |
uvm_analysis_port #(uart_transaction) mon_port; |
|
`uvm_component_utils(uart_agent) |
49,6 → 58,7
_drv = uart_driver::type_id::create("_drv",this); |
_seq = uvm_sequencer#(uart_transaction)::type_id::create("_seq",this); |
_mon = uart_monitor::type_id::create("_mon",this); |
_cov = uart_coverage::type_id::create("_cov",this); |
|
drv_port = new ("drv_port",this); |
mon_port = new ("mon_port",this); |
61,4 → 71,5
_drv.drv_scbd_cov.connect(drv_port); |
|
_mon.mon_scbd.connect(mon_port); |
_mon.mon_scbd.connect(_cov.cov_mon); |
endfunction:connect_phase |
/tb/agent/driver/uart_driver.svh
1,30 → 1,30
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// |
// UART2BUS VERIFICATION |
// UART2BUS VERIFICATION |
// |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// CREATOR : HANY SALAH |
// PROJECT : UART2BUS UVM TEST BENCH |
// UNIT : DRIVER |
//----------------------------------------------------------------------------- |
// TITLE : UART Driver |
// DESCRIPTION: This |
//----------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
// TITLE : UART DRIVER |
// DESCRIPTION: THIS DRIVER IS RESPONSIBLE FOR SETTING BFMS CONFIGURATIONS. ALSO DRIVING STIMULUS |
// TO THE BFMS AND SENDING TRANSACTIONS TO SCOREBOARD. |
//------------------------------------------------------------------------------------------------- |
// LOG DETAILS |
//------------- |
// VERSION NAME DATE DESCRIPTION |
// 1 HANY SALAH 02012016 FILE CREATION |
// 2 HANY SALAH 07012016 ADD INITIALIZE BFM METHOD |
//----------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR |
// OPENCORES MEMBERS ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE |
// CREATOR'S PERMISSION |
//----------------------------------------------------------------------------- |
// 2 HANY SALAH 07012016 ADD INITIALIZE BFM METHOD |
// 3 HANY SALAH 17022016 IMPROVE BLOCK DESCRIPTION AND ADD COMMENTS |
//------------------------------------------------------------------------------------------------- |
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR OPENCORES MEMBERS |
// ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE CREATOR'S PERMISSION |
//------------------------------------------------------------------------------------------------- |
|
class uart_driver extends uvm_driver #(uart_transaction); |
|
// Two Transaction Instances that are used to bring and clone the |
// stimulus |
// Two Transaction Instances that are used to bring and clone the stimulus |
uart_transaction trans,_trans; |
|
// Instance from Global UART Configuration |
39,6 → 39,7
// Arbiter Interface Instance |
virtual uart_arbiter arb_inf; |
|
// Analysis Port to both scoreboard and driver |
uvm_analysis_port #(uart_transaction) drv_scbd_cov; |
|
`uvm_component_utils(uart_driver) |
47,35 → 48,22
super.new(name,parent); |
endfunction: new |
|
function void display_content (); |
$display("here %s\n command_type = %p \n command = %p \n char_type = %p \n space_type1 = %p \n space_wrong1 = %8b \n space_type2 = %p \n space_wrong2 = %8b \n eol_type = %p \n eol_wrong = %8b \n address = %h \n data = %8b", get_full_name(),trans._mode, |
trans._command, |
trans._chartype, |
trans._spacetype1, |
trans.space_wrong1, |
trans._spacetype2, |
trans.space_wrong2, |
trans._eoltype, |
trans.eol_wrong, |
trans.address, |
trans._data[0]); |
endfunction:display_content |
|
// UVM Build Phase Declaration that includes locating instances and get |
// interfaces handler from the configuration database |
// UVM Build Phase Declaration that includes locating instances and get interfaces handler from |
// the configuration database |
extern function void build_phase (uvm_phase phase); |
|
// Both BFMs configurations setting and BFMs assignment are carried out through this UVM phase. |
extern function void end_of_elaboration_phase (uvm_phase phase); |
|
// UVM Run Phase Declaratio |
extern task run_phase (uvm_phase phase); |
|
// Actual drive data routine |
extern task drive_data (int iteration); |
extern task drive_data (); |
|
// initialize bfms |
extern function void initialize_bfms (act_edge _edge, |
start_bit _bit, |
int enable, |
int num_stop_bits, |
int num_of_bits, |
data_mode _datamode, |
112,57 → 100,49
`uvm_fatal("NOVIF",{"virtual interface must be set for:",get_full_name(),".arb_inf"}) |
arb_inf=_config.arb_inf; |
|
initialize_bfms(_config._edge, |
_config._start, |
_config.use_false_data, |
_config.num_stop_bits, |
_config.num_of_bits, |
_config._datamode, |
_config._paritymode, |
_config.response_time); |
|
endfunction:end_of_elaboration_phase |
|
function void uart_driver::initialize_bfms (act_edge _edge, |
start_bit _bit, |
int enable, |
int num_stop_bits, |
int num_of_bits, |
data_mode _datamode, |
parity_mode _paritymode, |
time _resp); |
uart_inf.set_configuration(_edge,_bit,num_stop_bits,num_of_bits,_datamode,_paritymode,_resp); |
uart_inf.set_configuration (_edge,_bit,num_stop_bits,num_of_bits,_datamode,_paritymode,_resp,enable); |
endfunction:initialize_bfms |
|
task uart_driver::run_phase (uvm_phase phase); |
|
int iteration; |
iteration = 0; |
|
initialize_bfms(_config._edge, |
_config._start, |
_config.num_stop_bits, |
_config.num_of_bits, |
_config._datamode, |
_config._paritymode, |
_config.response_time); |
|
forever |
begin |
iteration++; |
if (iteration == 3) |
begin |
//$stop; |
end |
seq_item_port.get_next_item(_trans); |
$cast(trans,_trans.clone()); |
drv_scbd_cov.write(trans); |
//display_content(); |
drive_data(iteration); |
drive_data(); |
seq_item_port.item_done(); |
end |
endtask:run_phase |
|
task uart_driver::drive_data(int iteration); |
task uart_driver::drive_data(); |
uart_inf.wait_idle_time(trans.time_before*trans.scale); |
uart_inf.set_event(); |
case (trans._mode) |
text: |
if (trans._mode == text || trans._mode == wrong_mode_text) |
begin |
case(trans._command) |
case(trans._command) |
read: |
begin |
fork |
/*fork |
begin |
if (trans._arbit == accept) |
begin |
173,19 → 153,24
arb_inf.declain_req(); |
end |
end |
join_none |
join_none*/ |
rf_inf.fill_byte (trans.address, |
trans._data[0]); |
uart_inf.read_text_mode(trans._chartype, |
uart_inf.read_text_mode(trans._mode, |
trans.wrong_prefix, |
trans._chartype, |
trans._spacetype1, |
trans.space_wrong1, |
trans._eoltype, |
trans.eol_wrong, |
trans.address); |
trans.address, |
trans.false_data[0], |
trans.false_data_en); |
|
end |
write: |
begin |
fork |
/*fork |
begin |
if (trans._arbit == accept) |
begin |
196,8 → 181,10
arb_inf.declain_req(); |
end |
end |
join_none |
uart_inf.write_text_mode(trans._chartype, |
join_none*/ |
uart_inf.write_text_mode(trans._mode, |
trans.wrong_prefix, |
trans._chartype, |
trans._spacetype1, |
trans.space_wrong1, |
trans._spacetype2, |
206,6 → 193,7
trans.eol_wrong, |
trans.address, |
trans._data[0]); |
|
end |
nop: |
begin |
215,54 → 203,45
begin |
`uvm_fatal("wrong output", "wrong_mode") |
end |
endcase |
end |
binary: |
begin |
case(trans._command) |
read: |
begin |
rf_inf.fill_block(trans.address, |
trans._data, |
trans.length_data); |
uart_inf.read_binary_mode(trans._reqack, |
trans._reqinc, |
trans.length_data, |
trans.address, |
trans._data); |
end |
write: |
begin |
uart_inf.write_binary_mode(trans._reqack, |
trans._reqinc, |
trans.length_data, |
trans.address, |
trans._data); |
end |
nop: |
begin |
uart_inf.nop_command(trans._reqack, |
trans._reqinc); |
end |
default: |
begin |
`uvm_fatal("UNDEFINED COMMAND","Binary command should be either read or write or no operation") |
end |
endcase |
end |
wrong_mode: |
else if (trans._mode==binary || trans._mode==wrong_mode_bin) |
begin |
uart_inf.wrong_command(trans._reqack, |
trans._reqinc, |
trans.space_wrong1, |
trans.length_data, |
trans.address, |
trans._data); |
if (trans._command == read || trans._command == invalid_read) |
begin |
rf_inf.fill_block(trans.address, |
trans._data, |
trans.length_data); |
uart_inf.read_binary_mode(trans._mode, |
trans.wrong_prefix, |
trans._command, |
trans._reqack, |
trans._reqinc, |
trans.length_data, |
trans.address, |
trans._data, |
trans.false_data, |
trans.false_data_en); |
end |
else if (trans._command == write || trans._command == invalid_write) |
begin |
uart_inf.write_binary_mode(trans._mode, |
trans.wrong_prefix, |
trans._command, |
trans._reqack, |
trans._reqinc, |
trans.length_data, |
trans.address, |
trans._data); |
end |
else |
begin |
uart_inf.nop_command(trans._mode, |
trans.wrong_prefix, |
trans._reqack, |
trans._reqinc); |
end |
|
end |
default: |
begin |
`uvm_fatal("UNEXPECTED VALUE","Command should be text or command or wrong") |
end |
endcase |
uart_inf.wait_idle_time(trans.time_after*trans.scale); |
endtask:drive_data |