作者见注释
`timescale 1ns/1ns
module UART(rst_n,clk50M,txd);
input rst_n,clk50M;
output txd;
reg txd_start;
reg [7:0] txd_data;
wire txd_busy;
async_transmitter async_transmitter(
.rst_n(rst_n),
.clk(clk50M),
.txd_start(txd_start),
.txd_data(txd_data),
.txd_busy(txd_busy),
.txd(txd)
);
always@(negedge rst_n,posedge clk50M)
begin
if(!rst_n)
begin
txd_data<=8'h0;
txd_start<=1'b0;
end
else
if((txd_busy==1'b0) &&(txd_start==1'b0))
begin
txd_start<=1'b1;
txd_data<=txd_data+8'h1;
end
else
txd_start<=1'b0;
end
endmodule /*
作者:小鱼有水
本设计只限于学习,欢迎大家拍砖
*/
`timescale 1ns/1ns
module async_transmitter(rst_n,clk,txd_start,txd_data,txd_busy,txd);
input rst_n,clk;
input txd_start;
input [7:0] txd_data;
output txd_busy;
output txd;
//时钟分频系数,本设计波特率选取的是19200,数据位为8位,停止位为1位
parameter clk_prescaler1 = 162;
parameter clk_prescaler2 = 15;
reg [7:0] cnt1;
reg [3:0] cnt2;
reg flag1,flag2;
reg txd_busy;
reg txd;
parameter idle = 2'b00; //空闲
parameter send_start = 2'b01; //发送起始位
parameter send_byte = 2'b10; //发送数据字节
parameter send_stop = 2'b11; //发送停止位
reg [1:0] cur_state;
reg [7:0] shift_reg; //移位寄存器,存储要发送的数据
reg [2:0] shift_cnt; //发送计数器,表明当前要发送一个字节的哪一位
//产生串口发送时钟
always@(negedge rst_n,posedge clk)
begin
if(!rst_n)
begin
cnt1<=8'd0;
flag1<=1'b0;
end
else
begin
if(cnt1==clk_prescaler1)
begin
cnt1<=8'd0;
flag1<=1'b1;
end
else
begin
cnt1<=cnt1+8'd1;
flag1<=1'b0;
end
end
end
always@(negedge rst_n,posedge clk)
begin
if(!rst_n)
begin
cnt2<=4'd0;
flag2<=1'b0;
end
else
begin
if(flag1==1'b1)
begin
if(cnt2==clk_prescaler2)
begin
cnt2<=4'd0;
flag2<=1'b1;
end
else
begin
cnt2<=cnt2+4'd1;
end
end
else
flag2<=1'b0;
end
end
//发送数据
always@(negedge rst_n,posedge clk)
begin
if(!rst_n)
begin
txd<=1'b1;
cur_state<=idle;
shift_cnt<=3'd0;
txd_busy<=1'b0;
end
else
begin
if(flag2==1'b1)
begin
case(cur_state)
idle:
begin
txd<=1'b1;
txd_busy<=1'b0;
end
send_start:
begin
txd<=1'b0;
cur_state<=send_byte;
end
send_byte:
begin
txd<=shift_reg[shift_cnt];
if(shift_cnt==3'h7)
begin
shift_cnt<=3'h0;
cur_state<=send_stop;
end
else
begin
shift_cnt<=shift_cnt+3'h1;
end
end
send_stop:
begin
txd<=1'd1;
cur_state<=idle;
end
default:
begin
cur_state<=idle;
txd<=1'd1;
txd_busy<=1'b0;
end
endcase
end
if(txd_start==1'b1)
begin
shift_reg<=txd_data;
cur_state<=send_start;
txd_busy<=1'b1;
end
end
end
endmodule
|
本文地址:http://114er.blogspot.com/2010/12/ztuartfpga.html 原创文章如转载,请注明链接: 转自Welcome Funny Guys |

0 评论: