//---------------------------------顶层
module uart_all
(
input refclk,
input rst_n,
input in_top,//接收
output out_tx
);
wire [7:0]out_top;
uart_top//rx接收模块
uart_top_inst
(
.refclk(refclk),
.rst_n(rst_n),
.in_top(in_top),
.out_top(out_top),
.out_stop(out_stop)
);
uart_tx//发送模块
uart_tx_inst
(
.refclk(refclk),
.rst_n(rst_n),
.in_rx(out_top),
.in_stop(out_stop),
.out_tx(out_tx)
);
endmodule
//-----------------------------------rx接收顶层
module uart_top
(
input refclk,
input rst_n,
input in_top,
output [7:0]out_top,
output out_stop
);
wire rst;
pll //----------------------锁存器,将时钟分为5M
pll_inst
(
.areset(~rst_n),
.inclk0(refclk),
.c0(clk),
.c1(),
.locked(rst)
);
pd
pd_inst
(
.clk(clk),
.rst(rst),
.in_top(in_top),
.out_pd_starte(out_pd_starte)
);
ztj
ztj_inst
(
.clk(clk),
.rst(rst),
.in_top_z(in_top),
.in_en(out_pd_starte),
.out_stop(out_stop),
.out_ztj(out_top)
);
endmodule
//----------------------------------判断rx开始接收
module pd
(
input clk,
input rst,
input in_top,
output out_pd_starte
);
reg vs_pd;
wire neg;
always@(posedge clk or negedge rst)
begin
if(~rst)
vs_pd<=1'b0;
else
vs_pd<=in_top;
end
assign neg=(~in_top)&vs_pd;
reg vs_pd1;
reg [18:0]cont;
always@(posedge clk or negedge rst)
begin
if(~rst)
cont<=1'b0;
else if(cont==19'd4680)
cont<=1'b0;
else if(vs_pd1==1'b1)
cont<=cont+1'b1;
end
always@(posedge clk )
begin
if(~rst)
vs_pd1 <=1'b0;
else if(neg==1'b1)
vs_pd1 <=1'b1;
else if(cont==19'd4680)
vs_pd1<=1'b0;
end
reg vs_pd2;
always@(posedge clk )
begin
if(~rst)
vs_pd2 <=1'b0;
else if(vs_pd1 ==1'b1)
vs_pd2 <=1'b0;
else
vs_pd2<=neg;
end
assign out_pd_starte=vs_pd2;
endmodule
//---------------------------------------------状态机,8bit ASCLL码的接收
module ztj
(
input clk,
input rst,
input in_top_z,
input in_en,
output [7:0]out_ztj,
output out_stop
);
parameter IDLE=4'b0000;
parameter start=4'b0001;
parameter bit0=4'b0010;
parameter bit1=4'b0011;
parameter bit2=4'b0100;
parameter bit3=4'b0101;
parameter bit4=4'b0110;
parameter bit5=4'b0111;
parameter bit6=4'b1000;
parameter bit7=4'b1001;
parameter stop=4'b1010;
parameter PI=10'd520-1;
reg [9:0]cont;
always@(posedge clk)
begin
if(~rst)
cont<=10'd0;
else if(in_en==1'b1)
cont<=10'd0;
else if(cont==PI)
cont<=10'd0;
else
cont<=cont+10'd1;
end
reg [3:0]cont_z;
always@(posedge clk or negedge rst)
begin
if(~rst)
cont_z<=4'd0;
else if(in_en==1'b1)
cont_z<=4'd0;
else if((cont_z==4'd10)&&(cont==PI))
cont_z<=4'd0;
else if(cont==PI-1)
cont_z<=cont_z+4'd1;
end
//----------------------------------------------
reg [7:0]out;
reg [3:0]current_state;
reg [3:0]next_state;
always@(posedge clk or negedge rst)
begin
if(~rst)
current_state<=IDLE;
else
current_state<=next_state;
end
always@(*)
begin
next_state=IDLE;
case(current_state)
IDLE:if(in_en==1'b1)
next_state=start;
else
next_state=IDLE;
start:if(cont_z==4'd1)
next_state=bit0;
else
next_state=start;
bit0:if(cont_z==4'd2)
next_state=bit1;
else
next_state=bit0;
bit1:if(cont_z==4'd3)
next_state=bit2;
else
next_state=bit1;
bit2:if(cont_z==4'd4)
next_state=bit3;
else
next_state=bit2;
bit3:if(cont_z==4'd5)
next_state=bit4;
else
next_state=bit3;
bit4:if(cont_z==4'd6)
next_state=bit5;
else
next_state=bit4;
bit5:if(cont_z==4'd7)
next_state=bit6;
else
next_state=bit5;
bit6:if(cont_z==4'd8)
next_state=bit7;
else
next_state=bit6;
bit7:if(cont_z==4'd9)
next_state=stop;
else
next_state=bit7;
stop:if(cont_z==4'd10)
next_state=IDLE;
else
next_state=stop;
default:next_state=IDLE;
endcase
end
//-------------------------------------------
reg vs_stop;
always@(posedge clk)
begin
if(~rst)
vs_stop<=1'b0;
else if((cont==10'd518)&&(current_state==stop))
vs_stop<=1'b1;
else
vs_stop<=1'b0;
end
assign out_stop=vs_stop;
//-------------------------------------------
reg vs_cont;
always@(posedge clk or negedge rst)
begin
if(~rst)
vs_cont<=1'b0;
else if(cont==cont/2)
vs_cont<=1'b1;
else
vs_cont<=1'b0;
end
//----------------------------------------
reg vs_tb;
always@(posedge clk or negedge rst)
begin
if(~rst)
vs_tb<=1'b0;
else
vs_tb<=in_top_z;
end
always@(posedge clk or negedge rst)
begin
if(~rst)
out<=8'b0;
else if(vs_cont<=1'b1)
begin
case(next_state)
bit0:
out[0]<=vs_tb;
bit1:
out[1]<=vs_tb;
bit2:
out[2]<=vs_tb;
bit3:
out[3]<=vs_tb;
bit4:
out[4]<=vs_tb;
bit5:
out[5]<=vs_tb;
bit6:
out[6]<=vs_tb;
bit7:
out[7]<=vs_tb;
endcase
end
else if(in_en==1'b1)
out<=8'd0;
end
assign out_ztj=out;
endmodule
//-----------------------------tx发送顶层
module uart_tx
(
input refclk,
input rst_n,
input [7:0]in_rx,
input in_stop,
output out_tx
);
pll pll_inst
(
.areset(~rst_n), // refclk.clk
.inclk0(refclk), // reset.reset
.c0(clk), // outclk0.clk
.c1(), // outclk1.clk
.locked(rst) // locked.export
);
ztj_tx
ztj_tx_inst
(
.clk(clk),
.rst(rst),
.in(in_rx),
.tx_en(in_stop),
.out_tx(out_tx)
);
endmodule
//-------------------------------rx状态机,与rx差不多
module ztj_tx
(
input clk,
input rst,
input [7:0]in,
input tx_en,
output out_tx
);
parameter IDLE=4'b0000;
parameter start=4'b0001;
parameter bit0=4'b0010;
parameter bit1=4'b0011;
parameter bit2=4'b0100;
parameter bit3=4'b0101;
parameter bit4=4'b0110;
parameter bit5=4'b0111;
parameter bit6=4'b1000;
parameter bit7=4'b1001;
parameter stop=4'b1010;
parameter PI=10'd520-1;
reg [9:0]cont;
always@(posedge clk)
begin
if(~rst)
cont<=10'd0;
else if(tx_en==1'b1)
cont<=10'd0;
else if(cont==PI)
cont<=10'd0;
else
cont<=cont+10'd1;
end
reg [3:0]cont_z;
always@(posedge clk or negedge rst)
begin
if(~rst)
cont_z<=4'd0;
else if(tx_en==1'b1)
cont_z<=4'd0;
else if((cont_z==4'd10)&&(cont==PI))
cont_z<=4'd0;
else if(cont==PI-1)
cont_z<=cont_z+4'd1;
end
reg out_ztj;
reg [3:0]current_state;
reg [3:0]next_state;
always@(posedge clk or negedge rst)
begin
if(~rst)
current_state<=IDLE;
else
current_state<=next_state;
end
always@(*)
begin
next_state=IDLE;
case(current_state)
IDLE:if(tx_en==1'b1)
next_state=start;
start:if(cont_z==4'd1)
next_state=bit0;
else
next_state=start;
bit0:if(cont_z==4'd2)
next_state=bit1;
else
next_state=bit0;
bit1:if(cont_z==4'd3)
next_state=bit2;
else
next_state=bit1;
bit2:if(cont_z==4'd4)
next_state=bit3;
else
next_state=bit2;
bit3:if(cont_z==4'd5)
next_state=bit4;
else
next_state=bit3;
bit4:if(cont_z==4'd6)
next_state=bit5;
else
next_state=bit4;
bit5:if(cont_z==4'd7)
next_state=bit6;
else
next_state=bit5;
bit6:if(cont_z==4'd8)
next_state=bit7;
else
next_state=bit6;
bit7:if(cont_z==4'd9)
next_state=stop;
else
next_state=bit7;
stop:if(cont_z==4'd10)
next_state=IDLE;
else
next_state=stop;
default:next_state=IDLE;
endcase
end
always@(posedge clk or negedge rst)
begin
if(~rst)
out_ztj<=1'b1;
else
case(next_state)
IDLE:
out_ztj<=1'b1;
start:
out_ztj<=1'b0;
bit0:
out_ztj<=in[0];
bit1:
out_ztj<=in[1];
bit2:
out_ztj<=in[2];
bit3:
out_ztj<=in[3];
bit4:
out_ztj<=in[4];
bit5:
out_ztj<=in[5];
bit6:
out_ztj<=in[6];
bit7:
out_ztj<=in[7];
stop:
out_ztj<=1'b1;
default:out_ztj<=1'b1;
endcase
end
assign out_tx=out_ztj;
endmodule
//----------------------------------测试
`timescale 1ns/1ns
module uart_top_tb();
reg clk;
reg rst_n;
initial
begin
rst_n=0;
#800 rst_n=1;
#100000 $stop;
end
initial
begin
clk=0;
end
always #20 clk<=~clk;
///---simulation pc ------------------------------------------
//bard gen
parameter LEN = 5208 ;
reg [12:0] delay_t ;
reg shift_en ;
always @(posedge clk)
begin
if(~rst_n)
delay_t <= 13'd0;
else if(delay_t == (LEN -1'b1) )
delay_t <= 13'd0;
else
delay_t <= delay_t + 1'b1 ;
if(~rst_n)
shift_en <= 1'd0;
else if(delay_t == 13'b1)
shift_en <= 1'd1;
else
shift_en <= 1'd0;
end
///uart gen
reg [7:0] cnt_time ;
reg down_d ;
reg down_2 ;
always @(posedge clk)
begin
if(~rst_n)
cnt_time <= 8'd0;
else if( shift_en == 1'b1 )
cnt_time <= cnt_time + 1'b1 ;
if(~rst_n)
down_d <= 1'd0;
else if(cnt_time== 8'd10 && ( shift_en == 1'b1 ))
down_d <= 1'b1 ;
else
down_d <= 1'b0 ;
if(~rst_n)
down_2 <= 1'd0;
else if(cnt_time== 8'd110 && ( shift_en == 1'b1 ))
down_2 <= 1'b1 ;
else
down_2 <= 1'b0 ;
end
//parall to serial
reg [9:0]in_1;
always@(posedge clk)
begin
if(~rst_n)
in_1<=10'b111_111_111_1;
else if(down_d )
in_1<=10'b0_0001_1000_1; // simulation Windows integer to ASCII // 00_0011_0001 // OK //0001_1000
else if(down_2)
in_1 <= 10'b0_1100_1010_1; // SWITH. 1100_1010
else if( shift_en == 1'b1 )
in_1<={in_1[8:0],1'b1}; // parall to serial transformation
end
wire uart_tx ; // uart TX signal
assign uart_tx = in_1[9] ;
///---------------------------------------
uart_all
uart_all_inst
(
.refclk(clk),
.rst_n(rst_n),
.in_top(uart_tx),
.out_tx()
);
endmodule