`timescale1ns/1psmoduleuart(clk,reset,rxd,txd,send_key,rcv_data);inputclk,reset,rxd,send_key;outputtxd;output[7:0]rcv_data;regtxd;//计数分频器,651分频50M,8倍采样reg[9:0]clk_counter;always@(posedgeclkorposedgereset)beginif(reset)clk_counter=10'd0;//复位置0elseif(clk_counter==10'd651)//651一次循环clk_counter=10'd0;elseclk_counter=clk_counter+1;end//产生采样时钟sample_clkregsample_clk;always@(posedgeclkorposedgereset)beginif(reset)sample_clk=1'd0;elseif(clk_counter==10'd651)//仅当clk_counter为651时s_c高sample_clk=1'd1;elsesample_clk=1'd0;end//接收数据reg[1:0]receiveflag;reg[2:0]sample_counter;reg[3:0]bit_counter;reg[7:0]rcv_data;reg[7:0]rcv_sr;always@(posedgeclkorposedgereset)beginif(reset)beginreceiveflag=2'b00;sample_counter=3'd0;bit_counter=4'd0;rcv_data=8'b1111_1111;rcv_sr=8'd0;endelseif(sample_clk)beginif((receiveflag==2'b00)&&(rxd==1'b0))//检测起始位beginif(sample_counter==3'd3)//确定起始位中点beginsample_counter=3'd0;receiveflag=2'b01;//置1,开始接收bit_counter=4'd0;endelsesample_counter=sample_counter+1;endelseif(receiveflag==2'b01)beginif(sample_counter==3'd7)//到了一帧的中点beginif(bit_counter==4'd8)//接收完毕beginreceiveflag=2'b10;//置2endelsebeginrcv_sr={rxd,rcv_sr[7:1]};//读到的数保存至高位,移位sample_counter=3'd0;bit_counter=bit_counter+1;//位计数器+1endendelsesample_counter=sample_counter+1;endelseif(receiveflag==2'b10)//标志为2时接收完毕beginrcv_data=rcv_sr;//保存在rcv_data中receiveflag=2'b00;endendend//计数分频,5208分50Mreg[12:0]clk_counter_s;always@(posedgeclkorposedgereset)beginif(reset)clk_counter_s=13'd0;elseif(clk_counter_s==13'd5208)clk_counter_s=13'd0;elseclk_counter_s=clk_counter_s+1;end//产生发送时钟信号send_clkregsend_clk;always@(posedgeclkorposedgereset)beginif(reset)send_clk=1'd0;elseif(clk_counter_s==13'd5208)//5208时一次高电平send_clk=1'd1;elsesend_clk=1'd0;end//发送串行数据reg[1:0]send_flag;reg[7:0]send_data;reg[3:0]sb_c;//send_bit_counteralways@(posedgeclkorposedgereset)beginif(reset)begintxd=1'b1;//空闲是高send_flag=2'b00;send_data=8'd0;sb_c=4'd0;endelseif(send_clk)beginif((send_flag==2'b00)&&(send_key==1'b1))//空闲且按键为高时开始发送beginsend_flag=2'b01;//标志置1,开始发送txd=1'b0;send_data=rcv_data;//发送的是rcv_data,后面要改这个endelsebeginif(send_flag==2'b01)beginif(sb_c==4'd8)send_flag=2'b10;//第8位时结束,将标志置2elsetxd=send_data[sb_c];//发送相应位sb_c=sb_c+1;endelsebeginif(send_flag==2'b10)//结束发送begintxd=1'b1;sb_c=4'd0;send_flag=2'b00;endendendendendendmodule