module uart_tx
#( parameter BPS='d9600,
parameter CLK_FRE='d50_000_000
)
(
input sys_clk,
input sys_rst_n,
//??¡쿿?
input [7:0] uart_tx_data,
input uart_tx_en,
//?¡À????
output reg uart_tx_done,
output reg uart_txd
);
parameter one_bit_num=CLK_FRE/BPS;
parameter bit__num='d10;
reg uart_en_d0;
reg uart_en_d1;
reg [7:0] uart_tx_data_reg;//??§º?¡¤?????〿?\
//reg uart_tx_done; //????????
//??¡¤????????§¡??½wire posedge_uart_en;
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
uart_en_d0<=1'b0;
uart_en_d1<=1'b0;
end
else begin
uart_en_d0<=uart_tx_en;
uart_en_d1<=uart_en_d0;
end
end
assign posedge_uart_en=uart_en_d0&&(~uart_en_d1);
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
uart_tx_data_reg<=8'b0;
end
else if(posedge_uart_en)begin
uart_tx_data_reg<=uart_tx_data;
end
else if(bit_cnt=='d9&&clk_cnt==one_bit_num/2)begin
uart_tx_data_reg<=8'd0;
end
else begin
uart_tx_data_reg<=uart_tx_data_reg;
end
end
reg tx_state;
reg [3:0] bit_cnt;
reg [23:0] clk_cnt;
//reg uart_tx_en;
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
tx_state<=1'b0;
end
else if(posedge_uart_en)begin
tx_state<=1'b1;
end
else if((bit_cnt==bit__num-1)&&(clk_cnt==one_bit_num-1)) begin
tx_state<=1'b0;
end
else begin
tx_state<=tx_state;
end
end
//?txstate????????????¡¤????
//always @(posedge sys_clk or negedge sys_rst_n)begin
// if(!sys_rst_n)begin
// uart_txd<=1'b0;
// end
// else if(tx_state)begin
// if((bit_cnt<='d8)&&(bit_cnt>=1)&&(clk_cnt=='d0))begin
// uart_txd<=uart_tx_data_reg[bit_cnt-1];
// end
// else if(bit_cnt==0) begin
// uart_txd<=1'b0;
// end
// end
// else begin
// uart_txd<=1'b0;
// end
//end
always@(*)begin
if(tx_state)begin
if(clk_cnt==0)begin
case(bit_cnt)
'd0:uart_txd<=1'b0;
'd1:uart_txd<=uart_tx_data_reg[0];
'd2:uart_txd<=uart_tx_data_reg[1];
'd3:uart_txd<=uart_tx_data_reg[2];
'd4:uart_txd<=uart_tx_data_reg[3];
'd5:uart_txd<=uart_tx_data_reg[4];
'd6:uart_txd<=uart_tx_data_reg[5];
'd7:uart_txd<=uart_tx_data_reg[6];
'd8:uart_txd<=uart_tx_data_reg[7];
'd9:uart_txd<=1'b1;
default:;
endcase
end
end
end
// always @(posedge sys_clk or negedge sys_rst_n)begin
// if(tx_state)begin
// if(bit_cnt<'d8&&bit_cnt>='d1&&(clk_cnt==one_bit_num-1))begin
// uart_txd<=uart_tx_data_reg[bit_cnt];
// end
// else begin
// uart_txd<=uart_txd;
// end
// end
// else begin
// uart_txd<=1'b0;
// end
// end
//uart_tx_done,¡¤??????¡¤
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
uart_tx_done<=1'b0;
end
else if(bit_cnt==bit__num-1&&clk_cnt==one_bit_num-1)begin
uart_tx_done<=1'b1;
end
else begin
uart_tx_done<=1'b0;
end
end
//¡¤?????bit?????
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
clk_cnt<=24'd0;
end
else if(tx_state)begin
if(clk_cnt<one_bit_num-1)begin
clk_cnt<=clk_cnt+1'd1;
end
else begin
clk_cnt<=24'd0;
end
end
else begin
clk_cnt<=24'd0;
end
end
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
bit_cnt<=4'd0;
end
else if(tx_state)begin
if(bit_cnt<=bit__num-1'd1)begin
if(clk_cnt==one_bit_num-1)begin
bit_cnt<=bit_cnt+1'd1;
end
else begin
bit_cnt<=bit_cnt;
end
end
else begin
bit_cnt<=4'd0;
end
end
else begin
bit_cnt<='d0;
end
end
endmodule
上板测试代码包括上面的uart_tx模块和下面的uart_tx_test两部分,关键注意case语句的使用,在发送状态下,当计数完一个bit之后根据发送数据的计数器,将寄存的数据向外传输。注意case。一下使uart_tx_test代码
module uart_tx_test
(
input sys_clk ,
input sys_rst_n ,
output uart_txd
);
parameter integer BPS = 'd230400 ;
parameter integer CLK_FRE = 'd50_000_000 ;
reg [31:0] cnt_time;
reg uart_tx_en;
reg [7:0] uart_tx_data;
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
cnt_time <= 'd0;
uart_tx_en <= 1'd0;
uart_tx_data <= 8'd0;
end
else if(cnt_time == (50_000_000 - 1'b1))begin
cnt_time <= 'd0;
uart_tx_en <= 1'd1;
uart_tx_data <= uart_tx_data+1;
end
else begin
cnt_time <= cnt_time + 1'd1;
uart_tx_en <= 1'd0;
uart_tx_data <=uart_tx_data ;
end
end
uart_tx
#(
.BPS (BPS ),
.CLK_FRE (CLK_FRE )
)
uart_tx_inst
(
.sys_clk (sys_clk ),
.sys_rst_n (sys_rst_n ),
.uart_tx_en (uart_tx_en ),
.uart_tx_data (uart_tx_data ),
.uart_tx_done ( ),
.uart_txd (uart_txd )
);
endmodule
本文参考串口(UART)的FPGA实现(含源码工程)孤独的单刀的博文进行的练习。
最后的结果