主题包含三个模块uart_top.c,test_uart.c,uart_trans.c
module uart_top(
clk,
rst,
txd
);
input clk, rst;
output txd;
wire clk_i;
clock clock (
.inclk0( clk ),
.c0(clk_i )
);
//该clk是一个ip,作用为分频
//由于uart是异步收发模块,不需要时钟线驱动,因此需要配置波特率,即bit per second,bps
reg rst_r;
reg rst_i;
always @(posedge clk_i or negedge rst)
if (~rst)
rst_r <= 1'b1;
else
rst_r <= #1 1'b0;
always @(posedge clk_i)
rst_i <= #1 rst_r;
wire[7:0] dat;
wire signal;
wire busy;
test_uart test_uart(
.clk ( clk_i ),
.rst ( rst_i ),
.dat ( dat ),
.signal( signal),
.busy ( busy )
);
uart_trans uart_trans(
.clk ( clk_i ),
.TxD_start( signal),
.TxD_data ( dat ),
.TxD ( txd ),
.TxD_busy ( busy )
);
endmodule
module test_uart(
clk,
rst,
dat,
signal,
busy
);
input clk, rst;
output[7:0] dat;
output signal;
input busy;
parameter idle = 0;
parameter load = 1;
parameter start = 2;
parameter sending = 3;
parameter loop = 4;
parameter nop = 5;
parameter next = 6;
reg[3 : 0] state;
reg[7 : 0] rom_dat;
reg[7 : 0] tmp_dat;
reg signal;
reg[4 : 0] cnt;
reg[4 : 0] char_cnt;
always@(posedge clk or posedge rst)
begin
if(rst)
begin
cnt <= 5'd0;
char_cnt <= 5'd0;
tmp_dat <= 8'd0;
signal <= 1'b0;
state <= nop;
end
else
case(state)
nop :
begin
char_cnt <= 5'd0;
cnt <= 5'd0;
state <= idle;
end
idle :
begin
if(busy == 1'b0)
begin
tmp_dat <= rom_dat;
signal <= 1'b0;
state <= load;
end
end
load :
begin
signal <= 1'b1;
state <= start;
end
start :
begin
signal <= 1'b0;
state <= sending;
end
sending :
if( busy == 1'b0 ) state <= next;
else state <= sending;
next :
begin
if(cnt == 5'h10 )
begin
state <= nop;
end
else
begin
state <= idle;
char_cnt <= char_cnt + 1'b1;
cnt <= cnt + 1'b1;
end
end
default :
state <= nop;
endcase
end
assign dat = rom_dat;
always @(char_cnt[4:0])
begin
rom_dat = 8'hxx;
case(char_cnt[4:0])
5'h0 : rom_dat = "1";
5'h1 : rom_dat = "2";
5'h2 : rom_dat = "3";
5'h3 : rom_dat = "5";
5'h4 : rom_dat = "5";
5'h5 : rom_dat = "6";
5'h6 : rom_dat = "7";
5'h7 : rom_dat = "8";
5'h8 : rom_dat = "9";
5'h9 : rom_dat = "a";
5'ha : rom_dat = "b";
5'hb : rom_dat = "c";
5'hc : rom_dat = "d";
5'hd : rom_dat = "e";
5'he : rom_dat = "f";
5'hf : rom_dat = 8'h0a;
5'h10 : rom_dat = 8'h0d;
endcase
end
endmodule
module uart_trans(clk, TxD_start, TxD_data, TxD, TxD_busy);
input clk, TxD_start;
input [7:0] TxD_data;
output TxD, TxD_busy;
parameter ClkFrequency = 25000000;
parameter Baud = 115200;
parameter RegisterInputData = 1;
// Baud generator
parameter BaudGeneratorAccWidth = 16;
reg [BaudGeneratorAccWidth:0] BaudGeneratorAcc;
wire [BaudGeneratorAccWidth:0] BaudGeneratorInc = ((Baud<<(BaudGeneratorAccWidth-4))+(ClkFrequency>>5))/(ClkFrequency>>4);
wire BaudTick = BaudGeneratorAcc[BaudGeneratorAccWidth];
wire TxD_busy;
always @(posedge clk) if(TxD_busy) BaudGeneratorAcc <= BaudGeneratorAcc[BaudGeneratorAccWidth-1:0] + BaudGeneratorInc;
// Transmitter state machine
reg [3:0] state;
wire TxD_ready = (state==0);
assign TxD_busy = ~TxD_ready;
reg [7:0] TxD_dataReg;
always @(posedge clk) if(TxD_ready & TxD_start) TxD_dataReg <= TxD_data;
wire [7:0] TxD_dataD = RegisterInputData ? TxD_dataReg : TxD_data;
always @(posedge clk)
case(state)
4'b0000: if(TxD_start) state <= 4'b0001;
4'b0001: if(BaudTick) state <= 4'b0100;
4'b0100: if(BaudTick) state <= 4'b1000; // start
4'b1000: if(BaudTick) state <= 4'b1001; // bit 0
4'b1001: if(BaudTick) state <= 4'b1010; // bit 1
4'b1010: if(BaudTick) state <= 4'b1011; // bit 2
4'b1011: if(BaudTick) state <= 4'b1100; // bit 3
4'b1100: if(BaudTick) state <= 4'b1101; // bit 4
4'b1101: if(BaudTick) state <= 4'b1110; // bit 5
4'b1110: if(BaudTick) state <= 4'b1111; // bit 6
4'b1111: if(BaudTick) state <= 4'b0010; // bit 7
4'b0010: if(BaudTick) state <= 4'b0011; // stop1
4'b0011: if(BaudTick) state <= 4'b0000; // stop2
default: if(BaudTick) state <= 4'b0000;
endcase
reg muxbit;
always @( * )
case(state[2:0])
3'd0: muxbit <= TxD_dataD[0];
3'd1: muxbit <= TxD_dataD[1];
3'd2: muxbit <= TxD_dataD[2];
3'd3: muxbit <= TxD_dataD[3];
3'd4: muxbit <= TxD_dataD[4];
3'd5: muxbit <= TxD_dataD[5];
3'd6: muxbit <= TxD_dataD[6];
3'd7: muxbit <= TxD_dataD[7];
endcase
reg TxD;
always @(posedge clk) TxD <= (state<4) | (state[3] & muxbit);
endmodule