基于FPGA 做一个数据采集模块 用Modelsim仿真

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于FPGA 做一个数据采集模块 用Modelsim仿真相关的知识,希望对你有一定的参考价值。

在仿真的时候写的testbench需要有激励 时钟 复位激励都已写好 但是8位连续的数据源怎样写?

参考技术A 这是很基本的一个tb,就是把cnt值直接赋给模块的输入信号,即8'd0,8'd1...8'd255。。。

module tb;

reg clk;
reg rst;
reg [7:0] cnt;

initial begin
clk = 1'b1;
rst = 1'b0;
#10000 rst = 1'b1;
#1000 rst = 1'b0;
end

always begin
#250 clk = ~clk;
end

always @(posedge clk)begin
if(rst)
cnt <= 8'd0;
else if(Crqst)
cnt <= cnt + 1'b1;
end

dut dut(
.clk (clk ),
.rst (rst ),
.data_in (cnt ),
.Crqst (Crqst )
);

endmodule

基于FPGA的串口通信,按键控制发送0~255数据


前言

本实验是基于FPGA的串口通信实验。

想要完整电路图的同学可直接可加我微信:wxid_c82ezb72s7cf22或QQ:1871478767。

一、实验结果

①:串口发送0~255数据,通过按键来控制,按键每按下一次,就实现发送一次数据,并且数据加一。如下图所示:
②:和①大致一样,每次按键按下,数据就减一。如下图:

③:对于波特率,本次实验也是将其单独独立出来,用户可以随意更改,本次我采用的是9600.

二、实验步骤

本实验总共只有两个模块,一个是按键消抖模块,另一个是串口通信中的发送模块。

顶层模块

module top_uart(
      input        sys_clk,       //时钟信号50Mhz
      input        sys_rst_n,     //复位信号
      
      input        key,           //按键信号       
      output     uart_txd,                 //UART发送端口
      output   wire  key_value,
      output    wire key_flag
      );
      

assign uart_en = key_flag & (~key_value);

//*****************************************************
//**                    main code
//*****************************************************
//串口发送模块
s_c u_s_c(
    .sys_clk        (sys_clk),
    .sys_rst_n      (sys_rst_n),
    .key_value      (key_value),
    .uart_en        (uart_en),
    .uart_txd        (uart_txd )
   );

//按键消抖模块
key_debounce u_key_debounce(
    .sys_clk        (sys_clk),
    .sys_rst_n      (sys_rst_n),
    
    .key            (key),
    .key_flag       (key_flag),
    .key_value      (key_value)
    );
    
endmodule 

串口发送模块中的累加模块

always @(posedge sys_clk or negedge sys_rst_n) begin         
    if (!sys_rst_n)
       uart_din <= 8'b0;   
    else if(uart_en)
    uart_din <= uart_din + 1'd1;
    else
          uart_din <= uart_din;   
 end

之前要定义一下uart_din的位宽,我此处定义的是8位,即是最大值为255,用户可以根据自己的需要进行改动,此处不做过多的赘述。

波特率

用户可以自行更改波特率

parameter  CLK_FREQ = 50000000;          
parameter  UART_BPS = 9600;     //波特率此处更改         
localparam BPS_CNT  = CLK_FREQ/UART_BPS; 

边沿检测

//捕获uart_en上升沿,得到一个时钟周期的脉冲信号
assign en_flag = (~uart_en_d0) & uart_en;
//assign en_flag = (~uart_en_d1) & uart_en_d0;                                                 
always @(posedge sys_clk or negedge sys_rst_n) begin         
    if (!sys_rst_n) begin
        uart_en_d0 <= 1'b0;                                  
        //uart_en_d1 <= 1'b0;
    end                                                      
    else begin                                               
        uart_en_d0 <= uart_en;                               
        //uart_en_d1 <= uart_en_d0;                            
    end
end

实验中遇到的问题及解决办法

我在本次实验中遇到了许多问题,但是最值得被记录的一个是这个边沿检测的时序问题。
在上述边沿检测代码中,可以看到我注释了一些,那是因为如果将uart_en打两拍之后,取//assign en_flag = (~uart_en_d1) & uart_en_d0,这个则是取第二拍,如下图所示:

图中的箭头是第一拍。
这个的结果是,发出的数据从01开始累加,而不是从00开始。
我改进的办法在上述代码中也可以看出,上时序图:

这样改进之后,就会取第一拍,就是从00开始计数了。

写在最后的话

想要完整代码的小伙伴可直接可加我微信:wxid_c82ezb72s7cf22
或者
QQ:1871478767

我现在还是一个FPGA小白,在文章中的一些地方的措辞会有一些口语化,而并不是用专业的术语,希望大家理解,相反,我个人还是有点高兴,因为如果一个知识能够用你自己的话说出来,那样对于知识的理解是非常深刻的,相信在之后的学习中,我自己会逐渐向专业靠拢,为之努力!

加油吧!打工人!!!

以上是关于基于FPGA 做一个数据采集模块 用Modelsim仿真的主要内容,如果未能解决你的问题,请参考以下文章

求一个fpga高速信号采集设计方案

基于模拟退火的FPGA布局方法

基于FPGA的高速数据采集系统实现

基于FPGA的串口通信,按键控制发送0~255数据

FPGA软件使用

FPGA软件使用