FPGA always语句块实现rx串口 时序图timescale 1ns / 1ps //rx端口 always语句块的写法 //1、rx是用来接收数据的涉及数据传输---防止亚稳态--打拍打一拍 //2、需要根据数据帧结构来进行数据接收 //2-1、需要只知道处理一个bit的时间---需要一个bit计时器--cnt_clk(传输一个Bit需要的时钟周期时间/波特率) //2-2、需要一个bit位计数器用来对bit位进行计数方便看具体传输到哪个位置便于取出一帧数据中的有效数据位部分bit计时器推动bit计数器自加 //2-3、抓取有效数据需要一个寄存器---寄存有效数据 //3、规定一个工作时间---en 起始位开始(采集下降沿上班 停止位结束cnt_bit9下班 module rx( input sysclk , input rst_n , input rx ,//一根数据线--传输串行输入数据一个bit一个bit的输入进来数据的 output [7:0] rx_data , //并行输出的有效数据位 output rx_done /Ç信号握手信号---作用是意味着一帧数据传输完成 rx_done1---别的模块可以正常使用rx_data ); reg reg1;//第一拍--缓存输入进来rx数据线上的数据防止亚稳态 reg reg2;//第二拍--将第一拍的数据缓存到第二拍采集下降沿 reg [31:0] cnt_clk;//传输一个bit需要的时钟周期 reg [9:0] cnt_bit;//bit位计数器--能够表示具体传输到哪一个Bit位了 wire flag;//采集下降沿的信号 flag1 有效信号 reg en;//规定数据传输的工作时间 en拉高--数据在进行传输 en拉低---数据不传输 reg [7:0] data_reg;//有效数据位寄存器--在整个帧结构中抓取有效数据位 parameter delay clk/BPS;//传输一个bit需要的周期数 -- 5208传输一个bit需要5208个周期每个周期是20ns parameter BPS 9600;//声明波特率自己选择 parameter clk 50_000_000; // bit计时器模块 always(posedge sysclk) if(!rst_n) cnt_clk0; else if(en1)begin//en拉高表示工作时间传输数据 if(cnt_clkdelay-1)//传输一位bit的时钟周期 cnt_clk0; else cnt_clkcnt_clk1; end else//en没有拉高 不工作 cnt_clk0; //bit计数器模块 always(posedge sysclk) if(!rst_n) cnt_bit0; else if(en1)begin if(cnt_clkdelay-1) //传输一个bit到了 计数器开始自加 cnt_bitcnt_bit1; else cnt_bitcnt_bit; end else cnt_bit0; //reg寄存数据模块 always(posedge sysclk) if(!rst_n)begin reg11;//因为采集下降沿数据又是从空闲到起始位如果是多帧数据上一个数据结束总是停止位高电平下一帧数据开始总是起始位低电平 reg21;//因为采集下降沿数据又是从空闲到起始位如果是多帧数据上一个数据结束总是停止位高电平下一帧数据开始总是起始位低电平 end else begin reg1rx;//开始工作开始传输数据 数据先寄存到reg1 然后到reg2 reg2reg1; end ///下降沿采集成功标志信号 assign flag (~reg1reg2)?1:0; //工作时间模块 always(posedge sysclk) if(!rst_n) en0; else if(flag1)//下降沿采集到了就拉高 en1; else if(cnt_bit9cnt_clkdelay/2-1)//停止位结束 en0; else enen; //data_reg有效数据位传输模块 always(posedge sysclk) if(!rst_n) data_reg0; else if(en1cnt_bit0cnt_bit9cnt_clkdelay/2-1)//数据位中间时刻采样---避免数据交接点的亚稳态现象引起的数据错乱现象 data_reg[cnt_bit-1]reg2; //数据通过二拍一位一位的传入到数据寄存器当中 else if(en1) data_regdata_reg; else data_reg0; assign rx_data (cnt_bit9cnt_clkdelay/2-1)?data_reg:rx_data; assign rx_done (cnt_bit9cnt_clkdelay/2-1)?1:0; endmodule