基于VerilogHDL语言的串口设计说明.docx
《基于VerilogHDL语言的串口设计说明.docx》由会员分享,可在线阅读,更多相关《基于VerilogHDL语言的串口设计说明.docx(28页珍藏版)》请在冰豆网上搜索。
基于VerilogHDL语言的串口设计说明
基于VerilogHDL语言的串口设计
串口VerilogHDL代码:
//串口
moduletrans(clk,rst,en,TxD_data,Wsec,RxD,TxD,TxD_busy,rcven,RxD_data);//时钟50MHz
inputclk,rst,en;//en时发送数据使能
input[7:
0]TxD_data;//发送数据输入
input[2:
0]Wsec;//波特率调节0-2400;1-4800;2-9600;3-14400;4-19200;5-38400;6-115200;7-128000
inputRxD;//接收数据输入端
outputTxD,TxD_busy,rcven;//发送,发送忙,接收结束标志输出
output[7:
0]RxD_data;//接收数据输出
wireBaud1,Baud8;
reg[7:
0]addwire;//RAM地址连线
reg[7:
0]data;
wire[7:
0]AD_t;//读取RAM数据的地址用于发送
wire[7:
0]AD_r;//接收的数据存储在RAM中的地址
wire[7:
0]datawire;//数据连线
//发送例化
trans_ttt1(.clk_t(clk),.rst_t(rst),.en_t(en),.BTI_t(Baud1),.recen(recen),
.TxD_data_t(datawire),.TxD_t(TxD),.addro_t(AD_t),.TxD_busy_t(TxD_busy));
//波特生成例化
BaudGtt2(.clk_b(clk),.rst_b(rst),.BTO_b(Baud1),.BTO_R(Baud8),.Wsec_b(Wsec));
//接收例化
trans_rtt3(.clk_r(clk),.rst_r(rst),.BTI_r(Baud8),.RxD_r(RxD),
.RxD_data_r(RxD_data),.wren_r(wren_r),.addro_r(AD_r),.RxD_end(RxD_end));
//LPM_RAM例化
RAM0tt4(.address(addwire),.clock(~clk),.data(data),.wren(wren_r),.q(datawire));
always(posedgeclkornegedgerst)
if(~rst)
addwire<=8'b00000000;
elseif(RxD_end)
begin
addwire<=AD_r;data<=RxD_data;
end
elseaddwire<=AD_t;
endmodule
//发送模块
moduletrans_t(clk_t,rst_t,en_t,BTI_t,TxD_data_t,TxD_t,recen,TxD_busy_t,addro_t,recen);
inputclk_t,rst_t,en_t,BTI_t;
input[7:
0]TxD_data_t;
outputTxD_t;
outputTxD_busy_t;
outputrecen;
output[7:
0]addro_t;
regTxD_t;
reg[7:
0]TxD_dataReg;//寄存器
reg[7:
0]addro_t;//
reg[3:
0]state;
regrecen;
wireTxD_busy_t;
assignBaudTick=BTI_t;//波特输出
//发送启动
wireTxD_ready=(state==0);//TxD_ready=1
assignTxD_busy_t=~TxD_ready;
//加载发送数据
always(posedgeclk_tornegedgerst_t)
if(~rst_t)
TxD_dataReg<=8'b00000000;
elseif(TxD_ready&&en_t)
TxD_dataReg<=TxD_data_t;
//状态机发送
always(posedgeclk_tornegedgerst_t)
if(~rst_t)
begin
state<=4'b0000;//复位时发送1
TxD_t<=1'b1;
end
else
case(state)
4'b0000:
if(en_t)begin
state<=4'b0100;//检测发送开始
end
4'b0100:
if(BaudTick&&en_t)begin
state<=4'b1000;//发送起始位0
TxD_t<=1'b0;
end
4'b1000:
if(BaudTick&&en_t)begin
state<=4'b1001;//bit0
if(en_t)TxD_t<=TxD_dataReg[0];
elseTxD_t<=1'b0;
end
4'b1001:
if(BaudTick&&en_t)begin
state<=4'b1010;//bit1
if(en_t)TxD_t<=TxD_dataReg[1];
elseTxD_t<=1'b0;
end
4'b1010:
if(BaudTick&&en_t)begin
state<=4'b1011;//bit2
if(en_t)TxD_t<=TxD_dataReg[2];
elseTxD_t<=1'b0;
end
4'b1011:
if(BaudTick&&en_t)begin
state<=4'b1100;//bit3
if(en_t)TxD_t<=TxD_dataReg[3];
elseTxD_t<=1'b0;
end
4'b1100:
if(BaudTick&&en_t)begin
state<=4'b1101;//bit4
if(en_t)TxD_t<=TxD_dataReg[4];
elseTxD_t<=1'b0;
end
4'b1101:
if(BaudTick&&en_t)begin
state<=4'b1110;//bit5
if(en_t)TxD_t<=TxD_dataReg[5];
elseTxD_t<=1'b0;
end
4'b1110:
if(BaudTick&&en_t)begin
state<=4'b1111;//bit6
if(en_t)TxD_t<=TxD_dataReg[6];
elseTxD_t<=1'b0;
end
4'b1111:
if(BaudTick&&en_t)begin
state<=4'b0010;//bit7
if(en_t)TxD_t<=TxD_dataReg[7];
elseTxD_t<=1'b0;
end
4'b0010:
if(BaudTick&&en_t)begin
state<=4'b0011;//stop1
TxD_t<=1'b1;
end
4'b0011:
if(BaudTick)begin
state<=4'b0000;//stop2
TxD_t<=1'b1;
end
default:
if(BaudTick)begin
state<=4'b0000;
TxD_t<=1'b1;
end
endcase
always(posedgeclk_tornegedgerst_t)
if(~rst_t)
beginrecen<=0;end
elseif(~TxD_ready)recen<=1;
elserecen<=0;
//地址计数器ddress
always(posedgeclk_tornegedgerst_t)
if(~rst_t)
addro_t<=8'b00000000;
elseif(TxD_ready&&en_t)
addro_t<=addro_t+1;
endmodule
//波特生成模块
moduleBaudG(clk_b,rst_b,BTO_b,BTO_R,Wsec_b);
inputclk_b,rst_b;
input[2:
0]Wsec_b;
outputBTO_b,BTO_R;
regFT,FT8;
reg[16:
0]BGA;
reg[16:
0]BGA1;
wireBTO_b=FT;//发送波特
wireBTO_R=FT8;//接收模块波特=发送*16
always(posedgeclk_bornegedgerst_b)
if(~rst_b)
beginBGA<=0;BGA1<=0;end
else
case(Wsec_b)
0:
begin
if(BGA1>1302)beginFT8=1'b1;BGA1<=0;end//接收波特=2400*16
elsebeginFT8=1'b0;BGA1<=BGA1+1;end
if(BGA>62500)beginFT=1'b1;FT8=1'b1;BGA1<=0;BGA<=0;end//发送波特=2400
elsebeginFT=1'b0;BGA<=BGA+3;end
end
1:
beginif(BGA1>651)beginFT8=1'b1;BGA1<=0;end//接收波特=4800*16
elsebeginFT8=1'b0;BGA1<=BGA1+1;end
if(BGA>62500)beginFT=1'b1;FT8=1'b1;BGA1<=0;BGA<=0;end//发送波特=4800
elsebeginFT=1'b0;BGA<=BGA+6;end
end
2:
beginif(BGA1>651)beginFT8=1'b1;BGA1<=0;end//接收波特=9600*16
elsebeginFT8=1'b0;BGA1<=BGA1+2;end
if(BGA>15625)beginFT=1'b1;FT8=1'b1;BGA1<=0;BGA<=0;end//发送波特=9600
elsebeginFT=1'b0;BGA<=BGA+3;end
end
3:
beginif(BGA1>217)beginFT8=1'b1;BGA1<=0;end//接收波特=14400*16
elsebeginFT8=1'b0;BGA1<=BGA1+1;end
if(BGA>17361)beginFT=1'b1;FT8=1'b1;BGA1<=0;BGA<=0;end//发送波特=14400
elsebeginFT=1'b0;BGA<=BGA+5;end
end
4:
beginif(BGA1>651)beginFT8=1'b1;BGA1<=0;end//接收波特=19200*16
elsebeginFT8=1'b0;BGA1<=BGA1+4;end
if(BGA>15625)beginFT=1'b1;FT8=1'b1;BGA1<=0;BGA<=0;end//发送波特=19200
elsebeginFT=1'b0;BGA<=BGA+6;end
end
5:
beginif(BGA1>244)beginFT8=1'b1;BGA1<=0;end//接收波特=38400*16
elsebeginFT8=1'b0;BGA1<=BGA1+3;end
if(BGA>15625)beginFT=1'b1;FT8=1'b1;BGA1<=0;BGA<=0;end//发送波特=38400
elsebeginFT=1'b0;BGA<=BGA+12;end
end
6:
beginif(BGA1>217)beginFT8=1'b1;BGA1<=0;end//接收波特=115200*16
elsebeginFT8=1'b0;BGA1<=BGA1+8;end
if(BGA>434)beginFT=1'b1;FT8=1'b1;BGA1<=0;BGA<=0;end//发送波特=115200
elsebeginFT=1'b0;BGA<=BGA+1;end
end
7:
beginif(BGA1>122)beginFT8=1'b1;BGA1<=0;end//接收波特=128000*16
elsebeginFT8=1'b0;BGA1<=BGA1+5;end
if(BGA>3125)beginFT=1'b1;BGA<=0;FT8=1'b1;BGA1<=0;end//发送波特=128000
elsebeginFT=1'b0;BGA<=BGA+8;end
end
default:
beginBGA<=0;FT=1'b0;end
endcase
endmodule
//接收模块
moduletrans_r(clk_r,rst_r,BTI_r,RxD_r,RxD_data_r,wren_r,addro_r,RxD_end);
inputclk_r,rst_r,RxD_r,BTI_r;
output[7:
0]RxD_data_r;
outputwren_r,RxD_end;
output[7:
0]addro_r;
reg[3:
0]bit_spacing;//两Bit间隔16
regRxD_end;//接收数据有效标志
regRxD_delay;//中间参量
regRxD_en;//接收使能
reg[7:
0]RxD_data_r;//接收数据输出
reg[7:
0]RxD_cach;//接收数据缓存
reg[3:
0]state;
reg[7:
0]addro_r;//地址
regwren_r;
assignBaud8Tick=BTI_r;//接收波特
always(posedgeclk_rornegedgerst_r)
if(~rst_r)
bit_spacing<=0;
else
case(state)
0:
bit_spacing<=0;
default:
if(Baud8Tick)bit_spacing<=bit_spacing+1;
endcase
wirenext_bit=(bit_spacing==5);//两bit间隔16波特
always(posedgeclk_r)
if(Baud8Tick)
begin
RxD_delay<=RxD_r;
RxD_en<=(Baud8Tick&RxD_delay&(~RxD_r));//检测接收信号是否有下降沿
end
//状态机接收
always(posedgeclk_rornegedgerst_r)
if(~rst_r)
state<=4'b0000;
elseif(Baud8Tick)
case(state)
4'b0000:
if(RxD_en)state<=4'b0001;//有下降沿开始接收
4'b0001:
if(next_bit)state<=4'b1000;//bit0
4'b1000:
if(next_bit)state<=4'b1001;//bit1
4'b1001:
if(next_bit)state<=4'b1010;//bit2
4'b1010:
if(next_bit)state<=4'b1011;//bit3
4'b1011:
if(next_bit)state<=4'b1100;//bit4
4'b1100:
if(next_bit)state<=4'b1101;//bit5
4'b1101:
if(next_bit)state<=4'b1110;//bit6
4'b1110:
if(next_bit)state<=4'b1111;//bit7
4'b1111:
if(next_bit)state<=4'b0010;//停止位
4'b0010:
if(next_bit)state<=4'b0000;
default:
state<=4'b0000;
endcase
//移位寄存器接收
always(posedgeclk_rornegedgerst_r)
if(~rst_r)
RxD_cach<=8'b00000000;
elseif(Baud8Tick&&next_bit&&state[3])
RxD_cach<={RxD_r,RxD_cach[7:
1]};
//停止位与接收结束标志位有效时将数据输出
always(posedgeclk_rornegedgerst_r)
if(~rst_r)
RxD_data_r<=8'b00000000;
elseif(RxD_end&&RxD_r)
RxD_data_r<=RxD_cach;
//产生接收结束标志位
always(posedgeclk_rornegedgerst_r)
if(~rst_r)
beginRxD_end<=0;end
else
beginRxD_end<=(Baud8Tick&&next_bit&&state==4'b0010&&RxD_r);
end
always(posedgeclk_rornegedgerst_r)
if(~rst_r)
beginwren_r<=0;end
elseif(RxD_end)wren_r<=1;
elsewren_r<=0;
//地址计数器ddress
always(posedgeclk_rornegedgerst_r)
if(~rst_r)
addro_r<=8'b11111111;
elseif(RxD_end)
addro_r<=addro_r+1;
endmodule
为了测试收发是否正常,写的TestBench
`timescale1ns/1ns
moduletrsb;
regclk,rst,en;
reg[7:
0]TxD_data;
reg[2:
0]Wsec;
wireTxD,TxD_busy,rcven;
wire[7:
0]RxD_data;
transtrsb(.clk(clk),
.rst(rst),
.en(en),
.TxD(TxD),
.Wsec(Wsec),
.TxD_busy(TxD_busy),
.TxD_data(TxD_data),
.rcven(rcven),
.RxD_data(RxD_data),
.RxD(TxD)
);
initialbegin
en=0;
TxD_data=0;
rst=1;
#1Wsec=2;
#54rst=0;
#70rst=1;
#10TxD_data=8'b11011001;
#10en=1'b1;
#1250000en=1'b1;
end
initialbegin
#3790000TxD_data=8'b01011010;
#10en=1'b1;
#2750000en=1'b0;
#1290000TxD_data=8'b1