Mirage? 2021-04-17 04:35 采纳率: 0%
浏览 14

如何设计UART和测试设计好的UART

`timescale 1ns / 1ps

module model_uart
# ( parameter SYSTEM_CLOCK_MHZ = 100,
    parameter BAUD_RATE = 115200 )
(
    input sysClk, nRst,
    output baudClk,
    // Transmitter interface
    input [7:0] dataout,
    input txWrite,
    output txEmpty, txUnderrun,
    output txD,
    // Receiver interface
    input  rxD,
    output [7:0] datain,
    input rxRead,
    output rxEmpty, rxOverrun, rxFramingError, rxBreakDetect    
    );

reg [9:0] txShiftReg, rxShiftReg;
reg bclk = 0;
reg framingError,rxInProgress,overrun,underrun,received;
integer txCount,rxCount;

localparam CLK_DIV = $rtoi(SYSTEM_CLOCK_MHZ*1e6/BAUD_RATE);
localparam BAUD_PERIOD_ns = 1000*CLK_DIV/SYSTEM_CLOCK_MHZ;
localparam HALF_PERIOD = BAUD_PERIOD_ns/2;
localparam START = 3'b001;
localparam STOP  = 3'b011;
 
always #(HALF_PERIOD) bclk=!bclk;

always @(posedge nRst) begin // reset deasserted
    txShiftReg = 10'bX; rxShiftReg = 10'bX;
    txCount = 0; rxCount=0; rxInProgress = 0; framingError=0; overrun=0; underrun=0; received=0;  
end

always @(posedge bclk) begin // transmit serial         
    if (txCount>0) begin
        txShiftReg = {1'bX, txShiftReg[9:1]};
        txCount=txCount-1;
    end
end

always @(negedge bclk) begin // receive serial
    case (rxCount)
        0: begin
            rxShiftReg=10'b0_XXXX_XXXX_X;
            if (rxInProgress==1) overrun=1;
            if (rxD==START) begin
                rxInProgress=1;
                rxCount=rxCount+1;
            end
          end                    
        10: begin
            rxInProgress=0;
            if (rxShiftReg[9]!=STOP) framingError=1;
            received=1;
            end    
        default: begin
            rxShiftReg={rxD,rxShiftReg[9:1]};
            rxCount=rxCount+1;
            end                
    endcase
end

always @(posedge sysClk) begin // bus interface
    if (txWrite) begin
        underrun = (txCount!=0);         
        txShiftReg = { STOP, dataout, START };
        @(posedge bclk) txCount=10;
    end
    if (rxRead) begin
        overrun=0; framingError=0; received=0;
        rxCount=0; // rxShiftReg = 10'bX;
    end
end

// continuous assignments
assign baudClk = bclk & nRst;
assign txEmpty = (txCount==0);
assign txUnderrun = underrun;
assign txD = txShiftReg[***TODO***];
assign datain = rxShiftReg[***TODO***];

如何写上述URAT的 关于 接收器和发射器的 单元测试? 上述txD和 detain变量该如何赋值?

  • 写回答

2条回答 默认 最新

  • 码农阿豪@新空间 新星创作者: 前端开发技术领域 2024-07-16 09:42
    关注
    让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如果还有疑问可以评论或留言
    为了编写上述UART模块的单元测试,首先需要使用测试框架来创建测试。在Verilog中,常用的测试框架包括Verilator、VUnit等。在这里我们以Verilator为例来编写一个简单的单元测试。 首先需要编写一个测试文件test_model_uart.cpp,内容如下:
    #include <verilated.h>
    #include "Vmodel_uart.h"
    int main() {
        // 初始化Verilator
        Verilated::commandArgs(0, nullptr);
        // 创建一个UART模块实例
        Vmodel_uart* dut = new Vmodel_uart;
        // 将sysClk、nRst信号置为0
        dut->sysClk = 0;
        dut->nRst = 0;
        // 将输入数据dataout设为0xAA
        dut->dataout = 8'hAA;
        // 初始化其它信号为0
        dut->txWrite = 0;
        dut->rxRead = 0;
        // 模拟时钟信号
        for (int i = 0; i < 1000; i++) {
            dut->sysClk = 0;
            // 模拟上升沿
            dut->eval();
            dut->sysClk = 1;
            // 模拟下降沿
            dut->eval();
        }
        // 打印测试结果
        if (dut->rxEmpty == 1) {
            printf("Receive data: %X\n", dut->datain);
        } else {
            printf("No data received\n");
        }
        // 销毁UART模块实例
        delete dut;
        return 0;
    }
    

    接下来编译test_model_uart.cpp并链接Verilator生成的模拟器,具体命令如下:

    verilator -Wall --cc model_uart.v
    cd obj_dir
    make -B -j -f Vmodel_uart.mk Vmodel_uart
    g++ -I/usr/share/verilator/include -I obj_dir -o test_model_uart test_model_uart.cpp obj_dir/Vmodel_uart__ALL.a -lm -lstdc++
    

    最后运行生成的测试可执行文件test_model_uart,如果UART接收到数据,将会打印接收到的数据,否则打印"No data received"。 通过编写类似上面的单元测试文件,可以对UART模块的接收器和发射器进行测试,并验证其功能是否符合设计要求。在测试过程中,需要考虑各种接收和发送情况,包括正常数据传输、溢出、帧错误等情况。在单元测试中赋值txD和datain变量时,可以根据测试要求设置不同的值,如发送数据、接收数据等。

    评论

报告相同问题?