263 lines
6.2 KiB
Verilog
263 lines
6.2 KiB
Verilog
module uart_tx(
|
|
|
|
clk,
|
|
rst_n,
|
|
en,
|
|
rx,
|
|
baud_set,
|
|
tx_data,
|
|
|
|
tx,
|
|
tx_done,
|
|
rx_done,
|
|
rx_data
|
|
|
|
);
|
|
|
|
input clk;
|
|
input rst_n;
|
|
input en;
|
|
input rx;
|
|
input [1:0] baud_set;
|
|
input [7:0] tx_data;
|
|
|
|
output reg tx;
|
|
output reg tx_done;
|
|
output reg rx_done;
|
|
output reg [7:0] rx_data;
|
|
|
|
reg [1:0] baud_set_r;
|
|
reg [12:0] tx_bps_cnt,tx_bps_cnt_max;
|
|
reg [7:0] tx_data_r;
|
|
reg tx_clk,rx_clk;
|
|
reg tx_en,rx_en;
|
|
reg [3:0] tx_cnt;
|
|
reg [9:0] rx_bps_cnt,rx_bps_cnt_max;
|
|
reg [2:0] rx_data_r[9:0];
|
|
reg [6:0] rx_cnt;
|
|
|
|
always @ (posedge clk or negedge rst_n)//tx使能
|
|
if(!rst_n)
|
|
tx_en <= 1'b0;
|
|
else if(en)
|
|
tx_en <= 1'b1;
|
|
else if(tx_done)
|
|
tx_en <= 1'b0;
|
|
|
|
always @ (posedge clk or negedge rst_n)//rx使能
|
|
if(!rst_n)
|
|
rx_en <= 1'b0;
|
|
else if(en)
|
|
rx_en <= 1'b1;
|
|
|
|
always @ (posedge clk or negedge rst_n) //同步波特率
|
|
if(!rst_n)
|
|
baud_set_r <= 2'd0;
|
|
else if(en)
|
|
baud_set_r <= baud_set;
|
|
else
|
|
baud_set_r <= baud_set_r;
|
|
|
|
always @ (posedge clk)//发送波特率
|
|
if(tx_en)
|
|
case(baud_set_r)
|
|
2'b00: tx_bps_cnt_max = 13'd5207; //9600
|
|
2'b01: tx_bps_cnt_max = 13'd1301; //38400
|
|
2'b10: tx_bps_cnt_max = 13'd867; //57600
|
|
2'b11: tx_bps_cnt_max = 13'd433; //115200
|
|
endcase
|
|
|
|
always @ (posedge clk)//接收波特率,12倍采样
|
|
if(rx_en)
|
|
case(baud_set_r)
|
|
2'b00: rx_bps_cnt_max = 10'd433; //9600
|
|
2'b01: rx_bps_cnt_max = 10'd108; //38400
|
|
2'b10: rx_bps_cnt_max = 10'd71; //57600
|
|
2'b11: rx_bps_cnt_max = 10'd35; //115200
|
|
endcase
|
|
|
|
|
|
always @ (posedge clk or negedge rst_n)//发送bps计数器
|
|
if(!rst_n)
|
|
tx_bps_cnt <= 13'd0;
|
|
else if(tx_en)
|
|
begin
|
|
if(tx_bps_cnt == tx_bps_cnt_max)
|
|
tx_bps_cnt <= 13'd0;
|
|
else
|
|
tx_bps_cnt <= tx_bps_cnt + 13'd1;
|
|
end
|
|
|
|
always @ (posedge clk or negedge rst_n)//接收bps计数器
|
|
if(!rst_n)
|
|
rx_bps_cnt <= 10'd0;
|
|
else if(rx_en)
|
|
begin
|
|
if(rx_bps_cnt == rx_bps_cnt_max)
|
|
rx_bps_cnt <= 10'd0;
|
|
else
|
|
rx_bps_cnt <= rx_bps_cnt + 10'd1;
|
|
end
|
|
|
|
always @ (posedge clk)//发送时钟生成
|
|
if(tx_en)
|
|
begin
|
|
if(tx_bps_cnt == tx_bps_cnt_max)
|
|
tx_clk <= 1'b1;
|
|
else
|
|
tx_clk <= 1'b0;
|
|
end
|
|
|
|
always @ (posedge clk)//接收时钟生成
|
|
if(rx_en)
|
|
begin
|
|
if(rx_bps_cnt == 1'b1)
|
|
rx_clk <= 1'b1;
|
|
else
|
|
rx_clk <= 1'b0;
|
|
end
|
|
|
|
always @ (posedge clk or negedge rst_n)//发送次数计数器
|
|
if(!rst_n)
|
|
tx_cnt <= 4'd0;
|
|
else if(tx_en)
|
|
begin
|
|
if(tx_cnt == 4'd11)
|
|
tx_cnt <= 4'd0;
|
|
else if(tx_bps_cnt == tx_bps_cnt_max)
|
|
tx_cnt <= tx_cnt +4'd1;
|
|
end
|
|
|
|
always @ (posedge clk or negedge rst_n)//接收次数计数器
|
|
if(!rst_n)
|
|
rx_cnt <= 7'd0;
|
|
else if(rx_en)
|
|
begin
|
|
if((rx_cnt == 7'd118) | (rx_cnt == 8'd8 && (rx_data_r[0] > 3'd2)))
|
|
rx_cnt <= 7'd0;
|
|
else if(rx_bps_cnt == rx_bps_cnt_max)
|
|
rx_cnt <= rx_cnt +7'd1;
|
|
end
|
|
|
|
always @ (posedge clk) //发送数据寄存
|
|
if(tx_en)
|
|
tx_data_r <= tx_data;
|
|
|
|
always @ (posedge clk or negedge rst_n)//发送数据
|
|
if(!rst_n)
|
|
tx <= 1'b1;
|
|
else if(tx_clk)
|
|
begin
|
|
case(tx_cnt)
|
|
4'd0 : tx <= 1'b1;
|
|
4'd1 : tx <= 1'b0;
|
|
4'd2 : tx <= tx_data_r[0];
|
|
4'd3 : tx <= tx_data_r[1];
|
|
4'd4 : tx <= tx_data_r[2];
|
|
4'd5 : tx <= tx_data_r[3];
|
|
4'd6 : tx <= tx_data_r[4];
|
|
4'd7 : tx <= tx_data_r[5];
|
|
4'd8 : tx <= tx_data_r[6];
|
|
4'd9 : tx <= tx_data_r[7];
|
|
4'd10: tx <= 1'b1;
|
|
default : tx <= 1'b1;
|
|
endcase
|
|
end
|
|
else
|
|
tx <= tx;
|
|
|
|
always @ (posedge clk or negedge rst_n)//发送完成标志
|
|
if(!rst_n)
|
|
tx_done <= 1'b0;
|
|
else if(tx_en)
|
|
begin
|
|
if(tx_cnt == 4'd11)
|
|
tx_done <= 1'd1;
|
|
else
|
|
tx_done <= 1'd0;
|
|
end
|
|
|
|
always @ (posedge clk or negedge rst_n)//接收数据
|
|
if(!rst_n)
|
|
begin
|
|
rx_data_r[0] <= 3'd0;
|
|
rx_data_r[1] <= 3'd0;
|
|
rx_data_r[2] <= 3'd0;
|
|
rx_data_r[3] <= 3'd0;
|
|
rx_data_r[4] <= 3'd0;
|
|
rx_data_r[5] <= 3'd0;
|
|
rx_data_r[6] <= 3'd0;
|
|
rx_data_r[7] <= 3'd0;
|
|
rx_data_r[8] <= 3'd0;
|
|
rx_data_r[9] <= 3'd0;
|
|
end
|
|
else if(rx_clk)
|
|
begin
|
|
case(rx_cnt)
|
|
0 :
|
|
begin
|
|
rx_data_r[0] <= 3'd0;
|
|
rx_data_r[1] <= 3'd0;
|
|
rx_data_r[2] <= 3'd0;
|
|
rx_data_r[3] <= 3'd0;
|
|
rx_data_r[4] <= 3'd0;
|
|
rx_data_r[5] <= 3'd0;
|
|
rx_data_r[6] <= 3'd0;
|
|
rx_data_r[7] <= 3'd0;
|
|
rx_data_r[8] <= 3'd0;
|
|
rx_data_r[9] <= 3'd0;
|
|
end
|
|
3, 4, 5, 6, 7, 8 : rx_data_r[0] <= rx_data_r[0] + rx;
|
|
15,16,17,18,19,20: rx_data_r[1] <= rx_data_r[1] + rx;
|
|
27,28,29,30,31,32: rx_data_r[2] <= rx_data_r[2] + rx;
|
|
39,40,41,42,43,44: rx_data_r[3] <= rx_data_r[3] + rx;
|
|
51,52,53,54,55,56: rx_data_r[4] <= rx_data_r[4] + rx;
|
|
63,64,65,66,67,68: rx_data_r[5] <= rx_data_r[5] + rx;
|
|
75,76,77,78,79,80: rx_data_r[6] <= rx_data_r[6] + rx;
|
|
87,88,89,90,91,92: rx_data_r[7] <= rx_data_r[7] + rx;
|
|
99,100,101,102,103: rx_data_r[8] <= rx_data_r[8] + rx;
|
|
111,112,113,114,115: rx_data_r[9] <= rx_data_r[9] + rx;
|
|
default :
|
|
begin
|
|
rx_data_r[0] <= rx_data_r[0];
|
|
rx_data_r[1] <= rx_data_r[1];
|
|
rx_data_r[2] <= rx_data_r[2];
|
|
rx_data_r[3] <= rx_data_r[3];
|
|
rx_data_r[4] <= rx_data_r[4];
|
|
rx_data_r[5] <= rx_data_r[5];
|
|
rx_data_r[6] <= rx_data_r[6];
|
|
rx_data_r[7] <= rx_data_r[7];
|
|
rx_data_r[8] <= rx_data_r[8];
|
|
rx_data_r[9] <= rx_data_r[9];
|
|
end
|
|
endcase
|
|
end
|
|
|
|
always @ (posedge clk or negedge rst_n)
|
|
if(!rst_n)
|
|
rx_data <= 8'd0;
|
|
else if((rx_cnt == 7'd118) & (rx_data_r[9][2]))
|
|
begin
|
|
rx_data[0] <= rx_data_r[1][2];
|
|
rx_data[1] <= rx_data_r[2][2];
|
|
rx_data[2] <= rx_data_r[3][2];
|
|
rx_data[3] <= rx_data_r[4][2];
|
|
rx_data[4] <= rx_data_r[5][2];
|
|
rx_data[5] <= rx_data_r[6][2];
|
|
rx_data[6] <= rx_data_r[7][2];
|
|
rx_data[7] <= rx_data_r[8][2];
|
|
end
|
|
|
|
always @ (posedge clk or negedge rst_n)//发送完成标志
|
|
if(!rst_n)
|
|
rx_done <= 1'b0;
|
|
else if(rx_en)
|
|
begin
|
|
if(rx_cnt == 7'd118)
|
|
rx_done <= 1'd1;
|
|
else
|
|
rx_done <= 1'd0;
|
|
end
|
|
|
|
|
|
endmodule |