module uart_tx(
clk,
rst,
data_in,
en,
txd,
txd_busy
);
input clk;
input rst;
input[7:0] data_in;
input en;
output txd;
reg txd;
output txd_busy;
reg txd_busy;
reg[7:0] data_buff;
parameter[3:0]IDLE =4'b0000,
START=4'b0001,
S0 =4'b0011,
S1 =4'b0111,
S2 =4'b0110,
S3 =4'b0100,
S4 =4'b1100,
S5 =4'b1010,
S6 =4'b1110,
STOP =4'b1111;
reg[3:0] state;
always@(posedge clk)
if(rst)
state<=IDLE;
else
case(state)
IDLE:
begin
if(en)
begin
data_buff<=data_in;
txd<=1'b0;
txd_busy<=1'b1;
state<=START;
end
else
begin
txd<=1'b1;
txd_busy<=1'b0;
state<=IDLE;
end
end
START:
begin
txd<=data_buff[0];
state<=S0;
end
S0:
begin
txd<=data_buff[1];
state<=S1;
end
S1:
begin
txd<=data_buff[2];
state<=S2;
end
S2:
begin
txd<=data_buff[3];
state<=S3;
end
S3:
begin
txd<=data_buff[4];
state<=S4;
end
S4:
begin
txd<=data_buff[5];
state<=S5;
end
S5:
begin
txd<=data_buff[6];
state<=S6;
end
S6:
begin
txd<=data_buff[7];
state<=STOP;
end
STOP:
begin
txd<=1'b1;
txd_busy<=1'b0;
state<=IDLE;
end
endcase
endmodule
module baud_gen(
clk,
rst,
baud_sel,
tx_clk,
rx_clk
);
parameter TX_BAUD_9600 = 13'd5208,//50MHz/9600;
TX_BAUD_19200 = 13'd2604,//50MHz/19200;
TX_BAUD_115200 = 13'd433; //50MHz/115200;
parameter TX_BAUD_9600_HALF = 13'd2604,//50MHz/9600;
TX_BAUD_19200_HALF = 13'd1302,//50MHz/19200;
TX_BAUD_115200_HALF = 13'd4206; //50MHz/115200;
parameter RX_BAUD_9600 = 13'd325,//50MHz/9600;
RX_BAUD_19200 = 13'd163,//50MHz/19200;
RX_BAUD_115200 = 13'd27; //50MHz/115200;
parameter RX_BAUD_9600_HALF = 13'd163,//50MHz/9600;
RX_BAUD_19200_HALF = 13'd82,//50MHz/19200;
RX_BAUD_115200_HALF = 13'd13; //50MHz/115200;
input clk;
input rst;
input [1:0] baud_sel;
output tx_clk;
output rx_clk;
reg tx_clk;
reg rx_clk;
//------------------------------------------------------TX CLK
reg [12:0] cont1;
reg [12:0] duty1;
always @(posedge clk)
begin
if(rst)
begin
cont1 <= 13'd0;
duty1 <= 13'd0;
end
else
case(baud_sel)
2'd0:begin
cont1 <= TX_BAUD_9600;
duty1 <= TX_BAUD_9600_HALF;
end
2'd1:begin
cont1 <= TX_BAUD_19200;
duty1 <= TX_BAUD_19200_HALF;
end
2'd2:begin
cont1 <= TX_BAUD_115200;
duty1 <= TX_BAUD_115200_HALF;
end
default:begin
cont1 <= TX_BAUD_9600;
duty1 <= TX_BAUD_9600_HALF;
end
endcase
end
reg [12:0] cnt1;
always @(posedge clk)
begin
if(rst)
cnt1 <= 13'd0;
else if(cnt1 == cont1-1)
cnt1 <= 13'd0;
else
cnt1 <= cnt1 + 1'b1;
end
always @(posedge clk)
begin
if(rst)
tx_clk <= 1'b0;
else if (cnt1 <duty1)
tx_clk <= 1'b1;
else
tx_clk <= 1'b0;
end
//------------------------------------------------------RX CLK
reg [8:0] cont2;
reg [8:0] duty2;
always @(posedge clk)
begin
if(rst)
begin
cont2 <= 9'd0;
duty2 <= 9'd0;
end
else
case(baud_sel)
2'd0:begin
cont2 <= RX_BAUD_9600;
duty2 <= RX_BAUD_9600_HALF;
end
2'd1:begin
cont2 <= RX_BAUD_19200;
duty2 <= RX_BAUD_19200_HALF;
end
2'd2:begin
cont2 <= RX_BAUD_115200;
duty2 <= RX_BAUD_115200_HALF;
end
default:begin
cont2 <= RX_BAUD_9600;
duty2 <= RX_BAUD_9600_HALF;
end
endcase
end
reg [8:0] cnt2;
always @(posedge clk)
begin
if(rst)
cnt2 <= 9'd0;
else if(cnt2 == cont2-1)
cnt2 <= 9'd0;
else
cnt2 <= cnt2 + 1'b1;
end
always @(posedge clk)
begin
if(rst)
rx_clk <= 1'b0;
else if (cnt2 <duty2)
rx_clk <= 1'b1;
else
rx_clk <= 1'b0;
end
endmodule
文章评论(0条评论)
登录后参与讨论