Verilog语法学习EP10:串口接收模块
设计一个串口接收模块,设计要求如下:
代码如下:
//2025.9.16
//串口接收数据
`timescale 1ns/10ps
module UART_RXer(clk,rst,RX,data_out,en_data_out
);
input clk;
input rst;
input RX;
output[7:0] data_out;//接受字节输出
output en_data_out;//输出使能reg[7:0] data_out;
reg[7:0] state;//主状态机
reg[12:0] con;//用于计算比特宽度24000000/4800
reg[3:0] con_bits;//用于计算比特数reg RX_delay;//RX的延时;
reg en_data_out;always@(posedge clk or negedge rst) beginif(~rst) beginstate<=0;con<=0;con_bits<=0;RX_delay<=0;data_out<=0;en_data_out<=0;//一旦定义了寄存器要及时给他复位endelse beginRX_delay<=RX;case(state)0://等空闲begin//1bit的宽度if(con==5000-1) begincon<=0;endelse begincon<=con+1;end//记录比特数每为0加一if(con==0) beginif(RX) begincon_bits<=con_bits+1;endelse begincon_bits<=0;endendif(con_bits==12)beginstate<=1;endend1://等起始位beginen_data_out<=0;if(~RX&RX_delay)beginstate<=2;endend2://收最低位b0beginif(con==7500-1)begincon<=0;data_out[0]<=RX;state<=3;endelse begincon<=con+1;endend3://b1beginif(con==5000-1)begincon<=0;data_out[1]<=RX;state<=4;endelse begincon<=con+1;endend4://b2beginif(con==5000-1)begincon<=0;data_out[2]<=RX;state<=5;endelse begincon<=con+1;endend5://b3beginif(con==5000-1)begincon<=0;data_out[3]<=RX;state<=6;endelse begincon<=con+1;endend6://b4beginif(con==5000-1)begincon<=0;data_out[4]<=RX;state<=7;endelse begincon<=con+1;endend7://b5beginif(con==5000-1)begincon<=0;data_out[5]<=RX;state<=8;endelse begincon<=con+1;endend8://b6beginif(con==5000-1)begincon<=0;data_out[6]<=RX;state<=9;endelse begincon<=con+1;endend9://b7beginif(con==5000-1)begincon<=0;data_out[7]<=RX;state<=10;endelse begincon<=con+1;endend10://产生使能脉冲beginen_data_out<=1;state<=1;enddefault:beginstate<=0;con<=0;con_bits<=0;en_data_out<=0; end endcaseend
endendmodule//-----testbench of UART_RXer----
module UART_RXer_tb();
reg clk,rst;
wire RX;
wire[7:0] data_out;
wire en_data_out;reg[25:0] RX_send;//里面装有串口字节发送数据
assign RX=RX_send[0];//链接RXreg con;UART_RXer UART_RXer(.clk(clk),.rst(rst),.RX(RX),.data_out(data_out),.en_data_out(en_data_out)
);
initial beginclk<=0;rst<=0;RX_send<={1'b1,8'haa,1'b0,16'hffff};con<=0;#17 rst<=1;#4000000 $stop;
endalways #5 clk=~clk;always@(posedge clk) beginif(con==5000-1) begincon<=0;endelse begincon<=con+1;endif(con==0) beginRX_send[24:0] = RX_send[25:1];RX_send[25] = RX_send[0];end
endendmodule
测试结果如下图所示: