信号发射器
module UART_RX(
send_en,
din,
Baud_set,
clk,
rst_n,
dout,
Tx_done,
uart_state
);//信号发射器
input send_en;
input [7:0] din;
input [2:0] Baud_set;
input clk;
input rst_n;
output dout;
output Tx_done;
output uart_state;
reg dout;
reg Tx_done;
reg uart_state;
reg [13:0] bps_DR;
reg sclk;
reg [13:0] cnt;
reg [7:0] data0;
reg [7:0] data1;
reg [3:0] data_cnt;
always@(*)begin//速度选择器
if(!rst_n)begin
bps_DR=14'd10417;
end
else begin
case(Baud_set)
0:bps_DR=14'd10417;
1:bps_DR=14'd5208;
2:bps_DR=14'd2603;
3:bps_DR=14'd1735;
4:bps_DR=14'd876;
default:bps_DR=14'd10417;
endcase
end
end
always@(posedge clk or negedge rst_n)begin//根据速度进行计数
if(!rst_n)begin
cnt<=14'd0;
end
else if(cnt==bps_DR)begin
cnt<=14'd0;
end
else begin
cnt<=cnt+1;
end
end
always@(posedge clk or negedge rst_n)begin//由速度决定的计数器决定的时钟
if(!rst_n)begin
sclk<=1'b0;
end
else if(cnt==bps_DR)begin
sclk<=~sclk;
end
else begin
sclk<=sclk;
end
end
always@(posedge sclk or negedge rst_n)begin//触发器消除不定态以达到数据稳定
if(!rst_n)begin
data0<=8'd0;
data1<=8'd0;
end
else begin
data0<=din;
data1<=data0;
end
end
always@(posedge sclk or negedge rst_n)begin//决定输出状态的计数器
if(!rst_n)begin
data_cnt<=4'd0;
end
else if(data_cnt==4'd11)begin
data_cnt<=4'd0;
end
else begin
data_cnt<=data_cnt+1'd1;
end
end
always@(posedge sclk or negedge rst_n)begin//由计数器决定输出状态
if(!rst_n)begin
dout<=1'd1;
end
else begin
case(data_cnt)
0:dout<=1'd1;
1:dout<=1'd0;
2:dout<=data1[0];
3:dout<=data1[1];
4:dout<=data1[2];
5:dout<=data1[3];
6:dout<=data1[4];
7:dout<=data1[5];
8:dout<=data1[6];
9:dout<=data1[7];
10:dout<=1'd1;
default:dout<=1'd1;
endcase
end
end
always@(posedge sclk or negedge rst_n)begin//输出完毕为1
if(!rst_n)begin
Tx_done<=1'd0;
end
else if(data_cnt==4'd11)begin
Tx_done<=1'd1;
end
else begin
Tx_done<=1'd0;
end
end
always@(posedge sclk or negedge rst_n)begin//为0时,接收器开始接收信号
if(!rst_n)begin
uart_state<=1'd0;
end
else if(send_en &&(Tx_done==1'd0))begin
uart_state<=1'd1;
end
else begin
uart_state<=1'd0;
end
end
endmodule
信号接收器
(1)方法一
module UART_TX(
clk,
rst_n,
data_rx,
Baud_set,
data_byte,
rx_done
);//信号接收器plan1
input clk;//200M
input rst_n;//复位
input data_rx;//输入
input [2:0] Baud_set;//速度选择
output [7:0] data_byte;//输出
output rx_done;//输出完毕信号
reg [7:0] data_byte;
reg rx_done;
reg sclk;
reg data_0;//第一级触发器
reg data_1;//第一级触发器
reg [13:0] bps_DR;//波特率
reg [13:0] cnt;//速度计数器
reg [3:0] data_cnt;//输出状态计数器
reg state;//用于帮助计数的高电平
reg dout;
wire data_negedge;//下降沿
assign data_negedge=data_1&!data_0;
always@(*)begin//速度选择器
if(!rst_n)begin
bps_DR=14'd10417;
end
else begin
case(Baud_set)
0:bps_DR=14'd10417;//9600
1:bps_DR=14'd5208;//19200
2:bps_DR=14'd2603;//38400
3:bps_DR=14'd1735;//57600
4:bps_DR=14'd876;//115200
default:bps_DR=14'd10417;
endcase
end
end
always@(posedge clk or negedge rst_n)begin//根据速度进行计数
if(!rst_n)begin
cnt<=14'd0;
end
else if(cnt==bps_DR)begin
cnt<=14'd0;
end
else begin
cnt<=cnt+1'd1;
end
end
always@(posedge clk or negedge rst_n)begin//由速度决定的计数器决定的时钟
if(!rst_n)begin
sclk<=1'b0;
end
else if(cnt==bps_DR)begin
sclk<=~sclk;
end
else begin
sclk<=sclk;
end
end
always@(posedge sclk or negedge rst_n)begin//两级触发器消除不定态以达到数据稳定
if(!rst_n)begin
data_0<=1'd0;
data_1<=1'd0;
end
else begin
data_0<=data_rx;
data_1<=data_0;
end
end
always@(negedge sclk or negedge rst_n)begin//用于帮助计数器计数的高电平
if(!rst_n)begin
state<=1'd0;
end
else if(data_negedge)begin
state<=1'd1;
end
else if(data_cnt==4'd9)begin
state<=1'd0;
end
else begin
state<=state;
end
end
always@(negedge sclk or negedge rst_n)begin//决定输出状态的计数器
if(!rst_n)begin
data_cnt<=4'd0;
end
else if(state)begin
if(data_cnt==4'd9)begin
data_cnt<=4'd0;
end
else begin
data_cnt<=data_cnt+1'd1;
end
end
else begin
data_cnt<=4'd0;
end
end
always@(negedge sclk or negedge rst_n)begin//由计数器决定输出状态
if(!rst_n)begin
data_byte<=1'd0;
dout<=1'd1;
end
else begin
case(data_cnt)
0:dout<=1'd0;
1:data_byte[0]<=data_1;
2:data_byte[1]<=data_1;
3:data_byte[2]<=data_1;
4:data_byte[3]<=data_1;
5:data_byte[4]<=data_1;
6:data_byte[5]<=data_1;
7:data_byte[6]<=data_1;
8:data_byte[7]<=data_1;
9:dout<=1'd1;
default:begin
data_byte<=data_byte;
dout<=dout;
end
endcase
end
end
always@(negedge sclk or negedge rst_n)begin//接收完成为1
if(!rst_n)begin
rx_done<=1'd0;
end
else if(data_cnt==4'd9)begin
rx_done<=1'd1;
end
else begin
rx_done<=rx_done;
end
end
endmodule
(2)方法二
module uart_rx(
clk,
rst_n,
data_rx,
Baud_set,
data_byte,
rx_done
);//信号接收器plan2
input clk;//200M
input rst_n;//复位
input data_rx;//输入
input [2:0] Baud_set;//速度选择
output [7:0] data_byte;//输出
output rx_done;//输出完毕信号
reg [7:0] data_byte;
reg rx_done;
reg sclk;//速度选择器决定的时钟
reg dclk;
reg data_0;//第一级触发器
reg data_1;//第一级触发器
reg [13:0] bps_DR;//波特率
reg [13:0] cnt;//速度计数器
reg [13:0] dcnt;
reg [7:0] data_cnt;//输出状态计数器
reg state;//用于帮助计数的高电平
reg [2:0] start;//开始中间态
reg start_1;//开始当前态
reg start_out;//开始输出态
reg [2:0] stop;//停止中间态
reg stop_1;//停止当前态
reg stop_out;//停止输出态
wire data_negedge;//下降沿
reg [2:0] bit0;//中间态
reg bit_0;//当前态
reg [2:0] bit1;//中间态
reg bit_1;//当前态
reg [2:0] bit2;//中间态
reg bit_2;//当前态
reg [2:0] bit3;//中间态
reg bit_3;//当前态
reg [2:0] bit4;//中间态
reg bit_4;//当前态
reg [2:0] bit5;//中间态
reg bit_5;//当前态
reg [2:0] bit6;//中间态
reg bit_6;//当前态
reg [2:0] bit7;//中间态
reg bit_7;//当前态
assign data_negedge=data_1&!data_0;//定义下降沿
always@(*)begin//速度选择器
if(!rst_n)begin
bps_DR=14'd10417;
end
else begin
case(Baud_set)
0:bps_DR=14'd10417;//9600
1:bps_DR=14'd5208;//19200
2:bps_DR=14'd2603;//38400
3:bps_DR=14'd1735;//57600
4:bps_DR=14'd876;//115200
default:bps_DR=14'd10417;
endcase
end
end
always@(posedge clk or negedge rst_n)begin//根据速度进行计数
if(!rst_n)begin
cnt<=14'd0;
end
else if(cnt==bps_DR)begin
cnt<=14'd0;
end
else begin
cnt<=cnt+1'd1;
end
end
always@(posedge clk or negedge rst_n)begin//由速度决定的计数器决定的时钟
if(!rst_n)begin
sclk<=1'b0;
end
else if(cnt==bps_DR)begin
sclk<=~sclk;
end
else begin
sclk<=sclk;
end
end
always@(posedge clk or negedge rst_n)begin//根据速度进行计数
if(!rst_n)begin
dcnt<=14'd0;
end
else if(dcnt==(bps_DR/16))begin
dcnt<=14'd0;
end
else begin
dcnt<=dcnt+1'd1;
end
end
always@(posedge clk or negedge rst_n)begin//由速度决定的计数器决定的时钟
if(!rst_n)begin
dclk<=1'b0;
end
else if(dcnt==(bps_DR/16))begin
dclk<=~dclk;
end
else begin
dclk<=dclk;
end
end
always@(posedge sclk or negedge rst_n)begin//两级触发器消除不定态以达到数据稳定
if(!rst_n)begin
data_0<=1'd0;
data_1<=1'd0;
end
else begin
data_0<=data_rx;
data_1<=data_0;
end
end
always@(posedge sclk or negedge rst_n)begin//用于帮助计数器计数的高电平
if(!rst_n)begin
state<=1'd0;
end
else if(data_negedge)begin
state<=1'd1;
end
else if(data_cnt==8'd159)begin
state<=1'd0;
end
else begin
state<=state;
end
end
always@(posedge dclk or negedge rst_n)begin//输出状态计数器
if(!rst_n)begin
data_cnt=8'd0;
end
else if(state)begin
if(data_cnt==8'd159)begin
data_cnt<=8'd0;
end
else begin
data_cnt<=data_cnt+1'd1;
end
end
else begin
data_cnt<=1'd0;
end
end
always@(posedge dclk or negedge rst_n)begin//由计数器决定中间态变化
if(!rst_n)begin
start<=3'd0;
stop<=3'd0;
bit0=3'd0;
bit1=3'd0;
bit2=3'd0;
bit3=3'd0;
bit4=3'd0;
bit5=3'd0;
bit6=3'd0;
bit7=3'd0;
end
else begin
case(data_cnt)
8'd6,8'd7,8'd8,8'd9,8'd10:start<=start+data_1;
8'd22,8'd23,8'd24,8'd25,8'd26:bit0<=bit0+data_1;
8'd38,8'd39,8'd40,8'd41,8'd42:bit1<=bit1+data_1;
8'd54,8'd55,8'd56,8'd57,8'd58:bit2<=bit2+data_1;
8'd70,8'd71,8'd72, 8'd73,8'd74:bit3<=bit3+data_1;
8'd86,8'd87,8'd88,8'd89,8'd90:bit4<=bit4+data_1;
8'd102,8'd103,8'd104,8'd105,8'd106:bit5<=bit5+data_1;
8'd118,8'd119,8'd120,8'd121,8'd122:bit6<=bit6+data_1;
8'd134,8'd135,8'd136,8'd137,8'd138:bit7<=bit7+data_1;
8'd150,8'd151,8'd152,8'd153,8'd154:stop<=stop+data_1;
8'd15:start<=3'd0;
8'd31:bit0<=3'd0;
8'd47:bit1<=3'd0;
8'd63:bit2<=3'd0;
8'd79:bit3<=3'd0;
8'd95:bit4<=3'd0;
8'd111:bit5<=3'd0;
8'd127:bit6<=3'd0;
8'd143:bit7<=3'd0;
8'd159:stop<=3'd0;
default:begin
start<=start;
bit0<=bit0;
bit1<=bit1;
bit2<=bit2;
bit3<=bit3;
bit4<=bit4;
bit5<=bit5;
bit6<=bit6;
bit7<=bit7;
stop<=stop;
end
endcase
end
end
always@(posedge dclk or negedge rst_n)begin//判断中间态,并给当前态赋值
if(!rst_n)begin
start_1<=1'b0;
stop_1<=1'b0;
bit_0<=1'b0;
bit_1<=1'b0;
bit_2<=1'b0;
bit_3<=1'b0;
bit_4<=1'b0;
bit_5<=1'b0;
bit_6<=1'b0;
bit_7<=1'b0;
end
else begin
case(data_cnt)
8'd15:if(start>=3'd3)
start_1<=1'b1;
else
start_1<=1'b0;
8'd31:if(bit0>=3'd3)
bit_0<=1'b1;
else
bit_0<=1'b0;
8'd47:if(bit1>=3'd3)
bit_1<=3'd1;
else
bit_1<=1'b0;
8'd63:if(bit2>=3'd3)
bit_2<=3'd1;
else
bit_2<=1'b0;
8'd79:if(bit3>=3'd3)
bit_3<=3'd1;
else
bit_3<=1'b0;
8'd95:if(bit4>=3'd3)
bit_4<=3'd1;
else
bit_4<=1'b0;
8'd111:if(bit5>=3'd3)
bit_5<=3'd1;
else
bit_5<=1'b0;
8'd127:if(bit6>=3'd3)
bit_6<=3'd1;
else
bit_6<=1'b0;
8'd143:if(bit7>=3'd3)
bit_7<=3'd1;
else
bit_7<=1'b0;
8'd159:if(stop>=3'd3)
stop_1<=3'd1;
else
stop_1<=3'd0;
default:begin
start_1<=start_1;
stop_1<=stop_1;
bit_0<=bit_0;
bit_1<=bit_1;
bit_2<=bit_2;
bit_3<=bit_3;
bit_4<=bit_4;
bit_5<=bit_5;
bit_6<=bit_6;
bit_7<=bit_7;
end
endcase
end
end
always@(negedge dclk or negedge rst_n)begin//给输出赋值
if(!rst_n)begin
data_byte<=8'd0;
start_out<=1'b0;
stop_out<=1'b0;
end
else begin
case(data_cnt)
8'd16:start_out=start_1;
8'd32:data_byte[0]<=bit_0;
8'd48:data_byte[1]<=bit_1;
8'd64:data_byte[2]<=bit_2;
8'd80:data_byte[3]<=bit_3;
8'd96:data_byte[4]<=bit_4;
8'd112:data_byte[5]<=bit_5;
8'd128:data_byte[6]<=bit_6;
8'd144:data_byte[7]<=bit_7;
8'd0:stop_out<=stop_1;
default:begin
data_byte<=data_byte;
start_out<=start_out;
stop_out<=stop_out;
end
endcase
end
end
always@(negedge dclk or negedge rst_n)begin//接收完成为1
if(!rst_n)begin
rx_done<=1'd0;
end
else if(data_cnt==8'd159)begin
rx_done<=1'd1;
end
else begin
rx_done<=rx_done;
end
end
endmodule