sequence
apb_sequence
- config_apbuart
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52class 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模式
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21class 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模式
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20class 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
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16class 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
错误的停止位.
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17class 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
错误的奇偶校验位.
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17class 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
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18class 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的上升边缘来确定。
复制代码
1
2
3
4
5
6
7
8
9property 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拉高的下一个周期拉高。
复制代码
1
2
3
4
5
6
7
8
9property 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不应该是未知的。
复制代码
1
2
3
4
5
6
7
8
9property 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的值不应该是未知的。
复制代码
1
2
3
4
5
6
7
8
9property 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的值不应更改。
复制代码
1
2
3
4
5
6
7
8
9property 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在整个写周期中应该保持不变.
复制代码
1
2
3
4
5
6
7
8
9property 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时不应该是未知的.
复制代码
1
2
3
4
5
6
7
8
9property 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之前断言.
复制代码
1
2
3
4
5
6
7
8
9property 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内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复