pink_star 2021-06-10 21:02 采纳率: 0%
浏览 74

modelsim仿真

我有一段代码,原本是用quartus将代码下载到fpga板上,然后运行友善串口调试助手输入1234,收到1234。

现在,这个代码就是modelsim仿真来模拟一下这个过程,也不知道弄好没,网上的教程都是弄出波形,我要的是能够输入1234,然后输出一个结果

module rcv(clk,
          rst,
          RxD,
          RxD_data,
          RxD_data_ready,
          );
input      clk,
           rst,
           RxD;
output[7:0] RxD_data;       // 接收数据寄存器        
output     RxD_data_ready;  // 接收完8位数据,RxD_data 值有效时,RxD_data_ready 输出读信号


parameter  ClkFrequency = 25000000;  // 时钟频率-25MHz
parameter  Baud = 115200;           // 波特率-115200

reg[2:0]  bit_spacing;
reg      RxD_delay;
reg     RxD_start;
reg[3:0]  state;
reg[7:0]  RxD_data;
reg      RxD_data_ready;

// 波特率产生,使用8倍过采样
parameter Baud8 = Baud*8;
parameter Baud8GeneratorAccWidth = 16;
wire   [Baud8GeneratorAccWidth:0] Baud8GeneratorInc = ((Baud8<<(Baud8GeneratorAccWidth-7))+(ClkFrequency>>8))/(ClkFrequency>>7);
reg    [Baud8GeneratorAccWidth:0] Baud8GeneratorAcc;

always @(posedge clk or negedge rst)
   if(~rst)
     Baud8GeneratorAcc <= 0;
  else  
   Baud8GeneratorAcc <= Baud8GeneratorAcc[Baud8GeneratorAccWidth-1:0] + Baud8GeneratorInc;

// Baud8Tick 为波特率的8倍 - 115200*8 = 921600
wire  Baud8Tick = Baud8GeneratorAcc[Baud8GeneratorAccWidth]; 

// next_bit 为波特率 - 115200
always @(posedge clk )
 if(~rst||(state==0))
     bit_spacing <= 0;
 else if(Baud8Tick)
    bit_spacing <= bit_spacing + 1;
wire next_bit = (bit_spacing==7);

// 检测到 TxD 有下跳沿时,RxD_start 置1,准备接收数据
always@(posedge clk)
 if(Baud8Tick)
 begin
  RxD_delay <= RxD;
    RxD_start <= (Baud8Tick & RxD_delay & (~RxD));
 end 

// 状态机接收数据
always@(posedge clk or negedge rst)
 if(~rst)
    state <= 4'b0000;
 else if(Baud8Tick)
   case(state)
4'b0000: if(RxD_start) state <= 4'b1000;  // 检测到下跳沿
    4'b1000: if(next_bit)  state <= 4'b1001;  // bit 0
    4'b1001: if(next_bit)  state <= 4'b1010;  // bit 1
    4'b1010: if(next_bit)  state <= 4'b1011;  // bit 2
    4'b1011: if(next_bit)  state <= 4'b1100;  // bit 3
    4'b1100: if(next_bit)  state <= 4'b1101;  // bit 4
    4'b1101: if(next_bit)  state <= 4'b1110;  // bit 5
    4'b1110: if(next_bit)  state <= 4'b1111;  // bit 6
    4'b1111: if(next_bit)  state <= 4'b0001;  // bit 7
    4'b0001: if(next_bit)  state <= 4'b0000;  // 停止位
    default: state <= 4'b0000;
    endcase

// 保存接收数据到 RxD_data 中
always @(posedge clk or negedge rst)
   if(~rst)
     RxD_data <= 8'b00000000;
 else if(Baud8Tick && next_bit && state[3])

   RxD_data <= {RxD, RxD_data[7:1]};
   

// RxD_data_ready 置位信号
always @(posedge clk or negedge rst)
   if(~rst)
     RxD_data_ready <= 0;
 else
   RxD_data_ready <= (Baud8Tick && next_bit && state==4'b0001);

endmodule

  • 写回答

1条回答 默认 最新

  • 她嫌我菜呜呜呜 2024-04-17 11:48
    关注
    您的代码看起来是一个接收串口数据的模块,其中使用了状态机来检测和接收串口数据。要在 ModelSim 中模拟这个过程,并验证输入和输出,您需要创建一个测试台(testbench)来模拟串口输入和输出,并将其连接到您的模块。
    
    以下是一个简单的示例测试台,用于模拟输入 1234 并验证输出结果:
    
    `timescale 1ns/1ps
    
    module tb_rcv;
    
    // Parameters
    parameter ClkFrequency = 25000000;  // 时钟频率-25MHz
    parameter Baud = 115200;           // 波特率-115200
    
    // Inputs
    reg clk;
    reg rst;
    reg RxD;
    
    // Outputs
    wire [7:0] RxD_data;
    wire RxD_data_ready;
    
    // Instantiate the rcv module
    rcv dut (
        .clk(clk),
        .rst(rst),
        .RxD(RxD),
        .RxD_data(RxD_data),
        .RxD_data_ready(RxD_data_ready)
    );
    
    // Clock generation
    initial begin
        clk = 0;
        forever #((1000000000/ClkFrequency)/2) clk = ~clk; // Assuming a 50% duty cycle
    end
    
    // Reset generation
    initial begin
        rst = 1;
        #10;
        rst = 0;
        #10;
    end
    
    // Stimulus generation
    initial begin
        // Send '1234' serially
        RxD = 1;
        #100;
        RxD = 0;
        #100;
        RxD = 1;
        #100;
        RxD = 1;
        #100;
        RxD = 0;
        #100;
        RxD = 0;
        #100;
        RxD = 1;
        #100;
        RxD = 1;
        #100;
        RxD = 1;
        #100;
        RxD = 0;
        #100;
        RxD = 1;
        #100;
        RxD = 0;
        #100;
        RxD = 1;
        #100;
        RxD = 0;
        #100;
        RxD = 1;
        #100;
        RxD = 0;
        #100;
        RxD = 1;
        #100;
        RxD = 1;
        #100;
        RxD = 1;
        #100;
        RxD = 1;
        #100;
        RxD = 1;
        #100;
        RxD = 0;
        #100;
    end
    
    // Monitor for RxD_data_ready
    always @(posedge clk) begin
        if (RxD_data_ready) begin
            $display("Received: %d", RxD_data);
            $stop;
        end
    end
    
    endmodule
    在这个测试台中,我们模拟了串口输入序列,并在 RxD_data_ready 信号置位时打印接收到的数据。您可以将这个测试台与您的模块一起编译并运行仿真,以验证您的模块是否按预期工作。
    
    请注意,这只是一个简单的示例测试台,您可能需要根据您的具体需求进行修改和调整。
    
    
    评论

报告相同问题?

悬赏问题

  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
  • ¥50 如何openEuler 22.03上安装配置drbd
  • ¥20 ING91680C BLE5.3 芯片怎么实现串口收发数据
  • ¥15 无线连接树莓派,无法执行update,如何解决?(相关搜索:软件下载)
  • ¥15 Windows11, backspace, enter, space键失灵