概述
sequence
apb_sequence
- config_apbuart
class config_apbuart extends uvm_sequence #(apb_transaction);
`uvm_object_utils (config_apbuart)
apb_transaction apbuart_sq;
uart_config cfg;
function new (string name = "config_apbuart");
super.new (name);
endfunction
task body();
apbuart_sq = apb_transaction::type_id::create("apbuart_sq");
cfg = uart_config::type_id::create("cfg");
// Write data for Configuring the registers
`uvm_do_with(apbuart_sq,{
apbuart_sq.PWRITE == 1'b1;
apbuart_sq.PADDR == cfg.baud_config_addr;
})
`uvm_do_with(apbuart_sq,{
apbuart_sq.PWRITE == 1'b0;
apbuart_sq.PADDR == cfg.baud_config_addr;
})
`uvm_do_with(apbuart_sq,{
apbuart_sq.PWRITE == 1'b1;
apbuart_sq.PADDR == cfg.frame_config_addr;
})
`uvm_do_with(apbuart_sq,{
apbuart_sq.PWRITE == 1'b0;
apbuart_sq.PADDR == cfg.frame_config_addr;
})
`uvm_do_with(apbuart_sq,{
apbuart_sq.PWRITE == 1'b1;
apbuart_sq.PADDR == cfg.parity_config_addr;
})
`uvm_do_with(apbuart_sq,{
apbuart_sq.PWRITE == 1'b0;
apbuart_sq.PADDR == cfg.parity_config_addr;
})
`uvm_do_with(apbuart_sq,{
apbuart_sq.PWRITE == 1'b1;
apbuart_sq.PADDR == cfg.stop_bits_config_addr;
})
`uvm_do_with(apbuart_sq,{
apbuart_sq.PWRITE == 1'b0;
apbuart_sq.PADDR == cfg.stop_bits_config_addr;
})
endtask
endclass
- transmit_single_beat
transmit模式
class transmit_single_beat extends uvm_sequence #(apb_transaction);
`uvm_object_utils (transmit_single_beat)
apb_transaction apbuart_sq;
uart_config cfg;
function new (string name = "transmit_single_beat");
super.new (name);
endfunction
task body();
apbuart_sq = apb_transaction::type_id::create("apbuart_sq");
cfg = uart_config::type_id::create("cfg");
`uvm_do_with(apbuart_sq,{
apbuart_sq.PWRITE == 1'b1;
apbuart_sq.PADDR == cfg.trans_data_addr;
})
endtask
endclass
- rec_reg_test
receive模式
class rec_reg_test extends uvm_sequence#(apb_transaction);
`uvm_object_utils(rec_reg_test)
apb_transaction apbuart_sq;
uart_config cfg;
function new(string name = "rec_reg_test");
super.new(name);
endfunction: new
task rec_reg_test::body();
apbuart_sq = apb_transaction::type_id::create("apbuart_sq");
cfg = uart_config::type_id::create("cfg");
`uvm_do_with(apbuart_sq,{
apbuart_sq.PWRITE == 1'b0;
apbuart_sq.PADDR == cfg.receive_data_addr;
})
endtask
endclass: rec_reg_test
uart_sequence
- recdrv_test_uart
class recdrv_test_uart extends uvm_sequence#(uart_transaction);
`uvm_object_utils(recdrv_test_uart)
uart_transaction uart_sq;
function new(string name = "recdrv_test_uart");
super.new(name);
endfunction: new
task body();
uart_sq = uart_transaction::type_id::create("uart_sq");
`uvm_do_with(uart_sq,{
uart_sq.sb_corr == 1'b0;
})
endtask
endclass: recdrv_test_uart
- fe_test_uart
错误的停止位.
class fe_test_uart extends uvm_sequence#(uart_transaction);
`uvm_object_utils(fe_test_uart)
uart_transaction uart_sq;
function new(string name = "fe_test_uart");
super.new(name);
endfunction: new
task body();
uart_sq = uart_transaction::type_id::create("uart_sq");
`uvm_do_with(uart_sq,{
uart_sq.bad_parity == 1'b0;
uart_sq.sb_corr == 1'b1;
})
endtask
endclass: fe_test_uart
- pe_test_uart
错误的奇偶校验位.
class pe_test_uart extends uvm_sequence#(uart_transaction);
`uvm_object_utils(pe_test_uart)
uart_transaction uart_sq;
function new(string name = "pe_test_uart");
super.new(name);
endfunction: new
task body();
uart_sq = uart_transaction::type_id::create("uart_sq");
`uvm_do_with(uart_sq,{
uart_sq.bad_parity == 1'b1;
uart_sq.sb_corr == 1'b0;
})
endtask
endclass: pe_test_uart
- err_free_test_uart
class err_free_test_uart extends uvm_sequence#(uart_transaction);
`uvm_object_utils(err_free_test_uart)
uart_transaction uart_sq;
function new(string name = "err_free_test_uart");
super.new(name);
endfunction: new
task body();
uart_sq = uart_transaction::type_id::create("uart_sq");
`uvm_do_with(uart_sq,{
uart_sq.bad_parity == 1'b0;
uart_sq.sb_corr == 1'b0;
//uart_sq.payload == 32'h11223344;
})
endtask
endclass: err_free_test_uart
test case
根据对spec的测试点分解以及sequence的开发,指定以下测试计划.
- 通过在配置寄存器中存储特定的值来设置config。配置元素如下:波特率,帧大小,奇偶校验,停止位,可以通过使用APB接口提供的PADDR变量来访问它们的特定配置地址。
- 首先通过运行config sequence将配置设置写入DUT,然后将一些数据写入PWDATA端口,并通过TX-pin串行(逐位)读取数据。输出应该是相同的。加载在PWDATA上的数据应该在TX-pin上串行接收。
- 在RX引脚上逐位加载数据,然后在preready时从PRDATA端口读取数据。同样,我们可以先运行随机配置设置,然后根据相应的配置设置运行此测试。
- 发送一个帧,其中包含损坏的停止位。DUT应响应输出PSLVERR位拉高。设置DUT为random config,然后运行此测试。
- 发送包含损坏的奇偶校验位的帧。DUT应响应PSLVERR为高。设置DUT为random config,然后运行此测试。
- 设置random config,随机奇偶校验错误和帧错误。使DUT处于receive模式,包括在RX引脚上逐位发送数据,然后在PREADY时从PRDATA端口读取数据。
- 测试过程与上述随机序列相同。唯一会发生的变化是使用时钟和复位驱动器序列,时钟会有不同的周期,并会在每次transaction后进行重置。
assertion
以下是对于APB协议的断言。
- SETUP_state
在setup_state中,PSELx应该是HIGH, PENABLE应该是LOW, setup_state可以通过检测PSELx的上升边缘来确定。
property SETUP_state;
@(posedge PCLK) disable iff (!PRESETn)
$rose(PSELx) |-> !(PENABLE);
endproperty
assert property(SETUP_state)
// $display("-------------------Check#1: SETUP_state PASS------------------");
else
`uvm_error("ASSERTION_FAILED",$sformatf("------ :: Check#1: SETUP_state FAILED :: ------"))
- ACCESS_state
ACCESS_state发生在SETUP_state的一个循环之后,所以PENABLE应该在PSELx拉高的下一个周期拉高。
property ACCESS_state;
@(posedge PCLK) disable iff (!PRESETn)
$rose(PSELx) |-> ##1($rose(PENABLE));
endproperty
assert property(ACCESS_state)
// $display("-------------------Check#2: ACCESS_state PASS------------------
else
`uvm_error("ASSERTION_FAILED",$sformatf("------ :: Check#2: ACCESS_state FAILED :: ------"))
- valid_PWRITE_PADDR_in_SETUP
在SETUP_state中,PWRITE和PADDR不应该是未知的。
property valid_PWRITE_PADDR_in_SETUP;
@(posedge PCLK) disable iff (!PRESETn)
(PSELx && !PENABLE) |-> !($isunknown(PWRITE)) && !($isunknown(PADDR));
endproperty
assert property(valid_PWRITE_PADDR_in_SETUP)
// $display("-------------------Check#3: valid_PWRITE_PADDR_in_SETUP PASS------------------");
else
`uvm_error("ASSERTION_FAILED",$sformatf("------ :: Check#3: valid_PWRITE_PADDR_in_SETUP FAILED :: ------"))
- valid_PWDATA_in_write_operation
在SETUP_state中,写操作期间PWDATA的值不应该是未知的。
property valid_PWDATA_in_write_operation;
@(posedge PCLK) disable iff (!PRESETn)
(PSELx && !PENABLE && PWRITE) |-> !($isunknown(PWDATA));
endproperty
assert property(valid_PWDATA_in_write_operation)
// $display("-------------------Check#4: valid_PWDATA_in_write_operation PASS------------------");
else
`uvm_error("ASSERTION_FAILED",$sformatf("------ :: Check#4: valid_PWDATA_in_write_operation FAILED :: ------"))
- stable_PWRITE_PADDR_in_ACCESS
在ACCESS_state中,PWRITE和PADDR的值不应更改。
property stable_PWRITE_PADDR_in_ACCESS;
@(posedge PCLK) disable iff (!PRESETn)
(PSELx && PENABLE) |-> $stable({PWRITE, PADDR});
endproperty
assert property(stable_PWRITE_PADDR_in_ACCESS)
// $display("-------------------Check#5: stable_PWRITE_PADDR_in_ACCESS PASS------------------");
else
`uvm_error("ASSERTION_FAILED",$sformatf("------ :: Check#5: stable_PWRITE_PADDR_in_ACCESS FAILED :: ------"))
- stable_PWDATA_during_write_operation
PWDATA在整个写周期中应该保持不变.
property stable_PWDATA_during_write_operation;
@(posedge PCLK) disable iff (!PRESETn)
(PSELx && PENABLE && PWRITE) |-> $stable(PWDATA);
endproperty
assert property(stable_PWDATA_during_write_operation)
// $display("-------------------Check#6: stable_PWDATA_during_write_operation PASS------------------");
else
`uvm_error("ASSERTION_FAILED",$sformatf("------ :: Check#6: stable_PWDATA_during_write_operation FAILED :: ------"))
- valid_PRDATA_in_read_operation
在读操作中,PRDATA的值在断言PREADY时不应该是未知的.
property valid_PRDATA_in_read_operation;
@(posedge PCLK) disable iff (!PRESETn)
(PREADY and APB_READ_CYCLE) |-> !($isunknown(PRDATA));
endproperty
assert property(valid_PRDATA_in_read_operation)
// $display("-------------------Check#7: valid_PRDATA_in_read_operation PASS------------------");
else
`uvm_error("ASSERTION_FAILED",$sformatf("------ :: Check#7: valid_PRDATA_in_read_operation FAILED :: ------"))
- PSELx_and_PENABLE_multiple_operation
对于多个读/写操作,PSELx不一定要去断言,但在所有事务完成之前,它仍然保持HIGH。所以我们必须检查每次PENABLE拉高时,PSELx应该在一个cycle之前断言.
property PSELx_and_PENABLE_multiple_operation;
@(posedge PCLK) disable iff (!PRESETn)
PENABLE |-> $past(PSELx);
endproperty
assert property(PSELx_and_PENABLE_multiple_operation)
// $display("-------------------Check#8: PSELx_and_PENABLE_multiple_operation PASS------------------");
else
`uvm_error("ASSERTION_FAILED",$sformatf("------ :: Check#8: PSELx_and_PENABLE_multiple_operation FAILED :: ------"))
最后
以上就是粗暴天空为你收集整理的APB-UART(下)sequencetest caseassertion的全部内容,希望文章能够帮你解决APB-UART(下)sequencetest caseassertion所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复