verilog uart.docx
- 文档编号:23867348
- 上传时间:2023-05-21
- 格式:DOCX
- 页数:21
- 大小:19.01KB
verilog uart.docx
《verilog uart.docx》由会员分享,可在线阅读,更多相关《verilog uart.docx(21页珍藏版)》请在冰豆网上搜索。
veriloguart
/*基于FPGA的串口扩展模块
要求:
利用FPGA将PC机的串口扩展为5个子串口,5个子串口均为双向串口;
通过地址线选择子串口地址,实现PC机与子串口之间的双向通信;
可以方便的配置各个串口的通信参数,波特率可以设置为1200、2400、9600、57600、115200中的任意一个;
数据位可以设置为5、6、7、8;
校验位可以设置成:
N、O、E;
*/
//顶层模块
moduleuart(clk,rst_n,receive,addr,Cbps,Cstop,Cjy,Cdata,send,receive1,led,receive2,receive3,
receive4,receive5,send1,send2,send3,send4,send5,v3_3);
inputclk;//系统时钟50MHz
inputrst_n;//复位信号,高有效
inputreceive;//串口接收口
input[2:
0]addr;//串口地址
input[2:
0]Cbps;//波特率选择信号
inputCstop;//停止位选择信号
input[1:
0]Cjy;//校验位选择信号
input[1:
0]Cdata;//数据位选择信号
inputsend1,send2,send3,send4,send5;
outputreceive1,receive2,receive3,receive4,receive5;
outputsend;//串口发送端
output[7:
0]led;
output[1:
0]v3_3;
wire[7:
0]data1,data2;//连接接收模块与发送模块,以便数据传输
wirebaud_start1,baud_start2,baud_start3,baud_start4;
//baud_start1:
接收模块的波特率启动标志位;
//baud_start2:
发送模块的波特率启动标志位;
//baud_start3:
发送模块的波特率启动标志位;
//baud_start4:
发送模块的波特率启动标志位;
wiremid_flag1,mid_flag2,mid_flag3,mid_flag4;
//mid_flag1:
接收数据标志位,由接收波特率发生模块发来;
//mid_flag2:
发送数据标志位,由发送波特率发生模块发来;
//mid_flag3:
接收数据标志位,由接收波特率发生模块发来;
//mid_flag4:
发送数据标志位,由发送波特率发生模块发来;
wireinterrupt1,interrupt2;
//接收完数据的标志位,同时也是发送数据的启示标志位;
wiremreceive,msend;//中间接收与发送
/********************************************************************
本程序采用模块化设计,即模块例化,分为4个模块,其中两个
波特率发生模块共用;
注意:
例化的格式很重要~!
!
********************************************************************/
assignled=data1|data2;
speed_selectbaud_receive1(
.clk(clk),
.rst_n(rst_n),
.baud_start(baud_start1),
.Cbps(Cbps),
.mid_flag(mid_flag1)
);
//模块1:
接收数据的波特率发生模块;
//------------------------------------------------------------------
my_uart_rxrecsive1(
.clk(clk),
.rst_n(rst_n),
.receive(receive),
.Cstop(Cstop),
.Cjy(Cjy),
.Cdata(Cdata),
.baud_start(baud_start1),
.mid_flag(mid_flag1),
.rx_int(interrupt1),
.rx_data(data1)
);
//模块2:
数据接收模块;
//------------------------------------------------------------------
speed_selectbaud_send1(
.clk(clk),
.rst_n(rst_n),
.baud_start(baud_start2),
.Cbps(Cbps),
.mid_flag(mid_flag2)
);
//模块3:
发送数据的波特率发生模块;
//------------------------------------------------------------------
my_uart_txmidsend(
.clk(clk),
.rst_n(rst_n),
.send(msend),
.Cstop(Cstop),
.Cjy(Cjy),
.Cdata(Cdata),
.baud_start(baud_start2),
.mid_flag(mid_flag2),
.tx_int(interrupt1),
.tx_data(data1)
);
//模块4:
数据发送模块;
//------------------------------------------------------------------
speed_selectbaud_receive2(
.clk(clk),
.rst_n(rst_n),
.baud_start(baud_start3),
.Cbps(Cbps),
.mid_flag(mid_flag3)
);
//模块5:
接收数据的波特率发生模块;
//------------------------------------------------------------------
my_uart_rxrecsive2(
.clk(clk),
.rst_n(rst_n),
.receive(mreceive),
.Cstop(Cstop),
.Cjy(Cjy),
.Cdata(Cdata),
.baud_start(baud_start3),
.mid_flag(mid_flag3),
.rx_int(interrupt2),
.rx_data(data2)
);
//模块6:
数据接收模块;
//------------------------------------------------------------------
speed_selectbaud_send2(
.clk(clk),
.rst_n(rst_n),
.baud_start(baud_start4),
.Cbps(Cbps),
.mid_flag(mid_flag4)
);
//模块7:
发送数据的波特率发生模块;
//------------------------------------------------------------------
my_uart_txfsend(
.clk(clk),
.rst_n(rst_n),
.send(send),
.Cstop(Cstop),
.Cjy(Cjy),
.Cdata(Cdata),
.baud_start(baud_start4),
.mid_flag(mid_flag4),
.tx_int(interrupt2),
.tx_data(data2)
);
//模块8:
数据发送模块;
choosechoose1(
.addr(addr),
.msend(msend),
.send1(send1),
.send2(send2),
.send3(send3),
.send4(send4),
.send5(send5),
.mreceive(mreceive),
.receive1(receive1),
.receive2(receive2),
.receive3(receive3),
.receive4(receive4),
.receive5(receive5),
.v3_3(v3_3)
);
endmodule
//**************************over******************************//
//接收模块
modulemy_uart_rx(clk,rst_n,receive,mid_flag,Cstop,Cjy,Cdata,baud_start,rx_data,rx_int);
inputclk;
inputrst_n;
inputreceive;
inputCstop;//停止位位数选择。
input[1:
0]Cjy;
input[1:
0]Cdata;
inputmid_flag;
outputbaud_start;
outputreg[7:
0]rx_data;
outputrx_int;
//*************************************************************************
//利用按键消抖原理,先后采样接收端的的电平进行对比,以判断是否有下降沿;
regreceive0,receive1,receive2,receive3;
always@(posedgeclkorposedgerst_n)
begin
if(rst_n)
begin
receive0<=1'b0;
receive1<=1'b0;
receive2<=1'b0;
receive3<=1'b0;
end
elsebegin
receive0<=receive;
receive1<=receive0;
receive2<=receive1;
receive3<=receive2;
end
end
wireneg_receive=receive3&receive2&~receive1&~receive0;
//**************************************************************************
//如果有下降沿来临,即neg_receive为1时,波特率发生标志位置1,接收数据标志置1;
//一旦数据接收结束,即num为12时,关断波特率发生器,接收数据标志清零;
regbaud_start_r,rx_int_r;
reg[3:
0]num;
always@(posedgeclkorposedgerst_n)
begin
if(rst_n)
begin
baud_start_r<=1'b0;
rx_int_r<=1'b0;
end
elseif(neg_receive)
begin
baud_start_r<=1'b1;
rx_int_r<=1'b1;
end
elseif(num==4'd11)
begin
baud_start_r<=1'b0;
rx_int_r<=1'b0;
end
end
assignbaud_start=baud_start_r;
assignrx_int=rx_int_r;
//**************************************************************************
//num:
接收位数标志;
//buffer:
接收数据缓冲器;
//data:
数据寄存器;
//波特率发生模块发来采样标志信号(mid_flag为1)后就进行采样;
reg[7:
0]buffer;
always@(posedgeclkorposedgerst_n)
begin
if(rst_n)
begin
rx_data<=8'd0;
buffer<=8'd0;
num<=4'd0;
end
elseif(rx_int_r)
begin
if(mid_flag)
begin
num<=num+1'b1;
//注意:
此句与下面case语句是并行的,即case中的num是自加1之前的值;
case(num)
//num=0时为起始位,不存储
4'd1:
buffer[0]<=receive;
4'd2:
buffer[1]<=receive;
4'd3:
buffer[2]<=receive;
4'd4:
buffer[3]<=receive;
4'd5:
buffer[4]<=receive;
4'd6:
buffer[5]<=receive;
4'd7:
buffer[6]<=receive;
4'd8:
buffer[7]<=receive;
//num=9时为结束位,不存储
default:
;
endcase
end
elseif((num==6&&Cdata==0)||(num==7&&Cdata==1)||(num==8&&Cdata==2)||(num==9&&Cdata==3))
begin
if(Cjy!
=0)
num<=4'd9;
else
num<=4'd10;
end
elseif(num==4'd11)
begin
num<=4'd0;
rx_data<=buffer;
end
end
end
//**************************************************************************
endmodule
//******************************over************************************//
//发送模块
modulemy_uart_tx(clk,rst_n,send,mid_flag,Cstop,Cjy,Cdata,tx_data,tx_int,baud_start);
inputclk;
inputrst_n;
inputmid_flag;
inputCstop;//停止位位数选择。
input[1:
0]Cjy;
input[1:
0]Cdata;
input[7:
0]tx_data;
inputtx_int;
outputbaud_start;
outputsend;
//****************************************************************************
//利用按键消抖原理,先后采样接收数据标志位tx_int的电平,以判断是否有下降沿产生
regint0,int1,int2;
always@(posedgeclkorposedgerst_n)
begin
if(rst_n)
begin
int0<=1'b0;
int1<=1'b0;
int2<=1'b0;
end
elsebegin
int0<=tx_int;
int1<=int0;
int2<=int1;
end
end
wireint_lock=~int1&int2;
//****************************************************************************
//如果tx_int有下降沿产生,即int_lock为1,就启动波特率发生器,同时使能发送数据,
//并将接收模块发来的数据送入发送数据缓冲器;
//如果发送数据结束,即num=11时,波特率关断,发送使能清零,发送数据缓冲器清零;
regbaud_start_t,send_en;
reg[7:
0]data;
reg[3:
0]num;
always@(posedgeclkorposedgerst_n)
begin
if(rst_n)
begin
baud_start_t<=1'b0;
send_en<=1'b0;
data<=8'd0;
end
elseif(int_lock)
begin
baud_start_t<=1'b1;
send_en<=1'b1;
data<=tx_data;
end
elseif(num==4'd11)
begin
baud_start_t<=1'b0;
send_en<=1'b0;
data<=8'd0;
end
end
assignbaud_start=baud_start_t;
//****************************************************************************
//send_r:
数据输出寄存器;
//num:
发送数据位数;
regsend_r;
always@(posedgeclkorposedgerst_n)
begin
if(rst_n)
begin
num<=1'b0;
send_r<=1'b0;
end
elseif(send_en)
begin
if(mid_flag)
begin
num<=num+1'b1;
case(num)
4'd0:
send_r<=1'b0;//起始信号0;
4'd1:
send_r<=data[0];
4'd2:
send_r<=data[1];
4'd3:
send_r<=data[2];
4'd4:
send_r<=data[3];
4'd5:
send_r<=data[4];
4'd6:
send_r<=data[5];
4'd7:
send_r<=data[6];
4'd8:
send_r<=data[7];
4'd9:
begin
if(Cjy==1)//奇校验
begin
case(Cdata)
2'd0:
send_r<=data[0]^data[1]^data[2]^data[3]^data[4];
2'd1:
send_r<=data[0]^data[1]^data[2]^data[3]^data[4]^data[5];
2'd2:
send_r<=data[0]^data[1]^data[2]^data[3]^data[4]^data[5]^data[6];
2'd3:
send_r<=data[0]^data[1]^data[2]^data[3]^data[4]^data[5]^data[6]^data[7];
endcase
end
elseif(Cjy==2||Cjy==3)//偶校验
begin
case(Cdata)
2'd0:
send_r<=~(data[0]^data[1]^data[2]^data[3]^data[4]);
2'd1:
send_r<=~(data[0]^data[1]^data[2]^data[3]^data[4]^data[5]);
2'd2:
send_r<=~(data[0]^data[1]^data[2]^data[3]^data[4]^data[5]^data[6]);
2'd3:
send_r<=~(data[0]^data[1]^data[2]^data[3]^data[4]^data[5]^data[6]^data[7]);
endcase
e
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- verilog uart
![提示](https://static.bdocx.com/images/bang_tan.gif)