OpenCores
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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.