UART项目验证(二) 验证策略和验证点提取

1.1 uart 模块验证流程

1、理解dut

2、制定验证策略方法

3、提取验证点(feature list)-》testcase list

4、搭建验证平台(1、验证框架图2、验证环境代码);sanity case

5、执行验证

写testcase跑仿真+regression(1、大批量仿真(rtl_freeze前)收集覆盖率(前提是仿真pass)、分析覆盖率+补充case 2、后仿netlist(rtl_freeze后))

1.2 uart 模块及验证策略和验证方法

验证策略:白盒测试(已知内部代码和结构)

验证方法:随机测试(分析覆盖率)+定向测试

code coverage:line/condition/fsm/assertion/toggle

function converage:covergroup/coverpoint/bins/cross/sample

1.3 提取验证功能点

 小知识点:interrupt 三组寄存器:status mask clear

  • 7
    点赞
  • 110
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个带有FIFO的UART接收器和发送器以及控制模块的Verilog代码及其测试代码: ```verilog module uart( input clk, input reset, // 发送端口 output tx, input [7:0] data_in, input send_data, input send_enable, // 接收端口 input rx, output [7:0] data_out, output reg data_valid, // 控制端口 input [1:0] baud_rate, input [7:0] data_threshold, output reg tx_busy, output reg rx_full, output reg rx_overflow ); // FIFO深度 localparam FIFO_DEPTH = 16; // 定义FIFO状态和数据宽度 typedef struct { reg [7:0] data; reg valid; } fifo_entry_t; // 定义FIFO数组 reg [FIFO_DEPTH-1:0] fifo_ptr; fifo_entry_t fifo[FIFO_DEPTH]; // 初始化FIFO指针 initial begin fifo_ptr = 0; end // 发送状态机 reg [3:0] send_state; localparam SEND_IDLE = 4'd0; localparam SEND_START = 4'd1; localparam SEND_DATA = 4'd2; localparam SEND_PARITY = 4'd3; localparam SEND_STOP = 4'd4; reg send_parity; reg send_stop; // 发送寄存器 reg [7:0] send_data_reg; reg [3:0] send_bits_left; // 初始化发送状态机 always @(posedge clk) begin if (reset) begin send_state <= SEND_IDLE; end else begin case (send_state) SEND_IDLE: begin if (send_enable) begin tx <= 0; send_data_reg <= data_in; send_bits_left <= 8; send_parity <= 1; send_stop <= 1; send_state <= SEND_START; end end SEND_START: begin tx <= 0; send_state <= SEND_DATA; end SEND_DATA: begin tx <= send_data_reg[0]; send_data_reg <= {send_data_reg[6:0], 0}; send_parity <= ~send_parity; send_bits_left <= send_bits_left - 1; if (send_bits_left == 0) begin send_state <= SEND_PARITY; end end SEND_PARITY: begin tx <= send_parity; send_state <= SEND_STOP; end SEND_STOP: begin tx <= send_stop; send_state <= SEND_IDLE; end endcase end end // 接收状态机 reg [3:0] recv_state; localparam RECV_IDLE = 4'd0; localparam RECV_START = 4'd1; localparam RECV_DATA = 4'd2; localparam RECV_PARITY = 4'd3; localparam RECV_STOP = 4'd4; reg recv_parity; reg recv_stop; // 接收寄存器 reg [7:0] recv_data_in; // 初始化接收状态机 always @(posedge clk) begin if (reset) begin recv_state <= RECV_IDLE; data_valid <= 0; end else begin case (recv_state) RECV_IDLE: begin if (!rx) begin recv_state <= RECV_START; recv_data_in <= 0; recv_parity <= 1; recv_stop <= 1; end end RECV_START: begin recv_state <= RECV_DATA; end RECV_DATA: begin recv_data_in <= {recv_data_in[6:0], rx}; recv_parity <= ~recv_parity; recv_state <= RECV_PARITY; end RECV_PARITY: begin if (recv_parity == rx) begin recv_state <= RECV_STOP; end else begin recv_state <= RECV_IDLE; rx_overflow <= 1; end end RECV_STOP: begin recv_stop <= rx; recv_state <= RECV_IDLE; if (fifo_ptr != FIFO_DEPTH-1) begin fifo[fifo_ptr].data <= recv_data_in; fifo[fifo_ptr].valid <= 1; fifo_ptr <= fifo_ptr + 1; end else begin rx_full <= 1; end end endcase if (fifo_ptr <= data_threshold) begin rx_full <= 0; end end end // 从FIFO中提取数据 always @(posedge clk) begin if (reset) begin data_out <= 0; data_valid <= 0; end else begin if (fifo[fifo_ptr].valid) begin data_valid <= 1; data_out <= fifo[fifo_ptr].data; fifo[fifo_ptr].valid <= 0; fifo_ptr <= (fifo_ptr == FIFO_DEPTH-1) ? 0 : fifo_ptr + 1; end else begin data_valid <= 0; end end end // 通过波特率计算发送时钟周期 reg [7:0] baud_cycles; always @* begin case (baud_rate) 2'd0: baud_cycles = 10416; 2'd1: baud_cycles = 5208; 2'd2: baud_cycles = 2604; 2'd3: baud_cycles = 1302; endcase end // 发送时钟计数器 reg [7:0] send_clk_count; // 发送模块 always @(posedge clk) begin if (reset) begin send_clk_count <= 0; tx_busy <= 0; end else begin if (send_enable) begin if (send_clk_count < baud_cycles) begin send_clk_count <= send_clk_count + 1; end else begin send_clk_count <= 0; end tx_busy <= 1; end else begin send_clk_count <= 0; tx_busy <= 0; end end end endmodule // 测试代码 module uart_test; // 时钟模块 reg clk; always #5 clk = ~clk; // 重置模块 reg reset; initial begin reset = 1; #10 reset = 0; end // UART模块 wire tx; wire [7:0] data_out; wire data_valid; wire rx; wire tx_busy; wire rx_full; wire rx_overflow; reg [7:0] data_in; reg send_data; reg send_enable; reg [1:0] baud_rate; reg [7:0] data_threshold; uart dut( .clk(clk), .reset(reset), .tx(tx), .data_in(data_in), .send_data(send_data), .send_enable(send_enable), .rx(rx), .data_out(data_out), .data_valid(data_valid), .baud_rate(baud_rate), .data_threshold(data_threshold), .tx_busy(tx_busy), .rx_full(rx_full), .rx_overflow(rx_overflow) ); // 发送数据 initial begin // 发送一个字节 send_data = 1; send_enable = 1; data_in = 8'h57; #500; send_enable = 0; // 发送另一个字节 send_data = 1; send_enable = 1; data_in = 8'hAB; #500; send_enable = 0; end // 模拟接收数据 initial begin // 第一个字节 #1000; assert(data_valid); assert(data_out == 8'h57); #10; assert(!data_valid); // 第个字节 #1000; assert(data_valid); assert(data_out == 8'hAB); #10; assert(!data_valid); // 结束测试 #1000 $finish; end endmodule ``` 该代码实现了一个带有16字节FIFO的UART发送器和接收器以及一个控制模块。发送器和接收器使用状态机来解码和编码字节,并将它们存储在FIFO中。控制模块负责生成发送时钟,并监视FIFO的状态以检测接收器的溢出和FIFO的满状态。在测试代码中,发送两个字节并验证接收器是否正确接收它们。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值