FPGA(vrilog)uart串口协议,能连续发送接收,进制转换

//---------------------------------顶层

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'd250)&&(current_state==stop))//cont==10'd250连续发数
        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==(PI+1)/2)
    vs_cont<=1'b1;
else
    vs_cont<=1'b0;
end
//----------------------------------------打三拍,消抖

reg vs_tb1;
always@(posedge clk or negedge rst)
begin 
if(~rst)
    vs_tb1<=1'b0;
else
    vs_tb1<=in_top_z;
end

reg vs_tb2;
always@(posedge clk or negedge rst)
begin 
if(~rst)
    vs_tb2<=1'b0;
else
    vs_tb2<=vs_tb1;
end
reg vs_tb;
always@(posedge clk or negedge rst)
begin 
if(~rst)
    vs_tb<=1'b0;
else
    vs_tb<=vs_tb1;
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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yang_wei_bk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值