基于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仿真的主要内容,如果未能解决你的问题,请参考以下文章