基于Verilog的带FIFO输出缓冲的串口接收接口封装
Posted 笑着刻印在那一张泛黄
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于Verilog的带FIFO输出缓冲的串口接收接口封装相关的知识,希望对你有一定的参考价值。
一、模块框图及基本思路
rx_module:串口接收的核心模块,详细介绍请见“基于Verilog的串口接收实验”
rx2fifo_module:rx_module与rx_fifo之间的控制模块,其功能是不断接收并将数据写入rx_fifo
rx_interface:串口接收接口封装,也就是前两个模块的组合
rx_interface_control:串口接收接口控制模块,每隔1s读取一次串口rx_fifo,并将数据的低四位用Led显示出来
rx_interface_top:串口接收接口顶层模块
二、软件部分
detect_module:
1 module detect_module( 2 CLK,RSTn, 3 RX_Pin_in, 4 H2L_Sig 5 ); 6 input CLK,RSTn; 7 input RX_Pin_in; 8 output H2L_Sig; 9 10 /**********************************/ 11 reg RX_r1; 12 reg RX_r2; 13 14 always @(posedge CLK or negedge RSTn) 15 begin 16 if(!RSTn) 17 begin 18 RX_r1<=1\'b1; 19 RX_r2<=1\'b1; 20 end 21 else 22 begin 23 RX_r1<=RX_Pin_in; 24 RX_r2<=RX_r1; 25 end 26 end 27 /*********************************/ 28 29 assign H2L_Sig=RX_r2&(!RX_r1); 30 31 32 33 endmodule
rx_bps_module:
1 module rx_bps_module #(parameter Baud=9600)( 2 CLK,RSTn, 3 Count_Sig, 4 BPS_CLK 5 ); 6 input CLK; 7 input RSTn; 8 input Count_Sig; 9 output BPS_CLK; 10 11 /***************************/ 12 localparam Baud_Div=50_000_000/Baud-1; 13 localparam Baud_Div2=Baud_Div/2; 14 15 reg[15:0] Count_BPS; 16 /*************************/ 17 always @(posedge CLK or negedge RSTn) 18 begin 19 if(!RSTn) 20 Count_BPS<=16\'d0; 21 else if(Count_BPS==Baud_Div) 22 Count_BPS<=16\'d0; 23 else if(Count_Sig) 24 Count_BPS<=Count_BPS+1; 25 else Count_BPS<=16\'d0; 26 end 27 /************************/ 28 assign BPS_CLK=(Count_BPS==Baud_Div2)?1\'b1:1\'b0; 29 endmodule
rx_control_module:
1 module rx_control_module( 2 CLK,RSTn, 3 H2L_Sig,BPS_CLK,RX_Pin_in, 4 Count_Sig,RX_En_Sig,RX_Done_Sig,RX_Data 5 ); 6 7 input CLK,RSTn; 8 input H2L_Sig,BPS_CLK,RX_En_Sig,RX_Pin_in; 9 output Count_Sig,RX_Done_Sig; 10 output [7:0] RX_Data; 11 12 reg[3:0] i; 13 reg isCount; 14 reg isDone; 15 reg [7:0] rData; 16 /********************************************/ 17 always @(posedge CLK or negedge RSTn) 18 begin 19 if(!RSTn) 20 begin 21 i<=4\'d0; 22 isCount<=1\'b0; 23 isDone<=1\'b0; 24 rData<=8\'d0; 25 end 26 else if(RX_En_Sig) 27 begin 28 case(i) 29 4\'d0:if(H2L_Sig) begin i<=i+1\'b1;isCount<=1\'b1; end //接收到下降沿开始启动波特率计数 30 4\'d1:if(BPS_CLK) begin i<=i+1\'b1; end //起始位 31 4\'d2,4\'d3,4\'d4,4\'d5,4\'d6,4\'d7,4\'d8,4\'d9: 32 if(BPS_CLK) begin rData[i-2]<=RX_Pin_in;i<=i+1\'b1;end //数据位 33 4\'d10:if(BPS_CLK) begin i<=i+1\'b1; end //校验位 34 4\'d11:if(BPS_CLK) begin i<=i+1\'b1; end //停止位 35 4\'d12:if(BPS_CLK) begin i<=i+1\'b1;isDone<=1\'b1;isCount<=1\'b0; end //一个时钟脉冲的 isDone 信号 36 4\'d13:begin i<=1\'b0;isDone<=1\'b0; end 37 endcase 38 end 39 40 end 41 42 /********************************************/ 43 assign Count_Sig=isCount; 44 assign RX_Done_Sig=isDone; 45 assign RX_Data=rData; 46 47 48 endmodule
rx_module:
module rx_module( CLK,RSTn, RX_Pin_in,RX_Done_Sig,RX_Data,RX_En_Sig ); input CLK,RSTn; input RX_Pin_in,RX_En_Sig; output RX_Done_Sig; output [7:0] RX_Data; wire Count_Sig; wire BPS_CLK; wire H2L_Sig; rx_bps_module U0( .CLK(CLK),.RSTn(RSTn), .Count_Sig(Count_Sig), .BPS_CLK(BPS_CLK) ); detect_module U1( .CLK(CLK),.RSTn(RSTn), .RX_Pin_in(RX_Pin_in), .H2L_Sig(H2L_Sig) ); rx_control_module U2( .CLK(CLK),.RSTn(RSTn), .H2L_Sig(H2L_Sig),.BPS_CLK(BPS_CLK),.RX_Pin_in(RX_Pin_in), .Count_Sig(Count_Sig),.RX_En_Sig(RX_En_Sig),.RX_Done_Sig(RX_Done_Sig),.RX_Data(RX_Data) ); endmodule
rx2fifo_module:
1 module rx2fifo_module( 2 CLK,RSTn, 3 RX_Done_Sig,RX_En_Sig,RX_Data, 4 Write_Req_Sig,FIFO_Write_Data,Full_Sig 5 ); 6 input CLK,RSTn; 7 input RX_Done_Sig; 8 output RX_En_Sig; 9 input [7:0] RX_Data; 10 input Full_Sig; 11 output Write_Req_Sig; 12 output [7:0] FIFO_Write_Data; 13 14 reg isRx; 15 reg isWrite; 16 reg [2:0] i; 17 always @(posedge CLK or negedge RSTn) 18 begin 19 if(!RSTn) 20 begin 21 isRx<=1\'b0; 22 isWrite<=1\'b0; 23 i<=3\'d0; 24 end 25 else 26 case(i) 27 3\'d0:if(RX_Done_Sig) begin i<=i+1\'b1;isRx<=1\'b0; end 28 else isRx<=1\'b1; 29 3\'d1:if(!Full_Sig) begin isWrite<=1\'b1;i<=i+1\'b1;end 30 3\'d2:begin isWrite<=1\'b0;i<=3\'d0;end 31 endcase 32 33 end 34 35 assign FIFO_Write_Data=RX_Data; 36 assign RX_En_Sig=isRx; 37 assign Write_Req_Sig=isWrite; 38 39 endmodule
rx_interface:
module rx_interface( CLK,RSTn, RX_Pin_in, Read_Req_Sig,Empty_Sig,FIFO_Read_Data ); input CLK,RSTn; input RX_Pin_in; input Read_Req_Sig; output Empty_Sig; output [7:0] FIFO_Read_Data; wire RX_Done_Sig; wire [7:0]RX_Data; wire RX_En_Sig; rx_module U0 ( .CLK(CLK), .RSTn(RSTn), .RX_Pin_in(RX_Pin_in), .RX_Done_Sig(RX_Done_Sig), .RX_Data(RX_Data), .RX_En_Sig(RX_En_Sig) ); wire Write_Req_Sig; wire Full_Sig; wire [7:0]FIFO_Write_Data; rx2fifo_module U1 ( .CLK(CLK), .RSTn(RSTn), .RX_Done_Sig(RX_Done_Sig), .RX_En_Sig(RX_En_Sig), .RX_Data(RX_Data), .Write_Req_Sig(Write_Req_Sig), .FIFO_Write_Data(FIFO_Write_Data), .Full_Sig(Full_Sig) ); rx_fifo U2 ( .clk(CLK), // input clk .rst(!RSTn), // input rst .din(FIFO_Write_Data), // input [7 : 0] din .wr_en(Write_Req_Sig), // input wr_en .rd_en(Read_Req_Sig), // input rd_en .dout(FIFO_Read_Data), // output [7 : 0] dout .full(Full_Sig), // output full .empty(Empty_Sig) // output empty ); endmodule
rx_interface_control:
module rx_interface_control( CLK,RSTn, Read_Req_Sig,FIFO_Read_Data,Empty_Sig, Led ); input CLK,RSTn; output Read_Req_Sig; input [7:0] FIFO_Read_Data; input Empty_Sig; output [3:0]Led; /*******************************************/ localparam T1S=50_000_000-1; reg[31:0] Count_1s; always @(posedge CLK or negedge RSTn) begin if(!RSTn) Count_1s<=32\'d0; else if(Count_1s==T1S) Count_1s<=32\'d0; else if(isCount) Count_1s<=Count_1s+1\'b1; else Count_1s<=32\'d0; end /*******************************************/ reg isRead; reg [2:0]i; reg isCount; always @(posedge CLK or negedge RSTn) begin if(!RSTn) begin isRead<=1\'b0; i<=3\'d0; isCount<=1\'b0; end else case(i) 3\'d0:if(Count_1s==T1S) begin isCount<=1\'b0;i<=i+1\'b1; end else isCount<=1\'b1; 3\'d1:if(!Empty_Sig) begin isRead<=1\'b1; i<=i+1\'b1;end 3\'d2:begin isRead<=1\'b0;i<=3\'d0; end endcase end /*************************************************/ assign Read_Req_Sig=isRead; assign Led=FIFO_Read_Data[3:0]; endmodule
rx_interface_top:
1 module rx_interface_top( 2 CLK,RSTn,RX_Pin_in, 3 Led 4 ); 5 input RX_Pin_in; 6 input CLK,RSTn; 7 output [3:0]Led; 8 9 wire Read_Req_Sig; 10 wire Empty_Sig; 11 wire[7:0] FIFO_Read_Data; 12 rx_interface U0 ( 13 .CLK(CLK), 14 .RSTn(RSTn), 15 .RX_Pin_in(RX_Pin_in), 16 .Read_Req_Sig(Read_Req_Sig), 17 .Empty_Sig(Empty_Sig), 18 .FIFO_Read_Data(FIFO_Read_Data) 19 ); 20 rx_interface_control U1 ( 21 .CLK(CLK), 22 .RSTn(RSTn), 23 .Read_Req_Sig(Read_Req_Sig), 24 .FIFO_Read_Data(FIFO_Read_Data), 25 .Empty_Sig(Empty_Sig), 26 .Led(Led) 27 ); 28 29 30 endmodule
三、硬件部分
黑金SPARTAN-6开发板
1 NET "CLK" LOC = T8; 2 NET "RSTn" LOC = L3; 3 NET "RX_Pin_in" LOC = C11; 4 NET "Led[0]" LOC = P4; 5 NET "Led[1]" LOC = N5; 6 NET "Led[2]" LOC = P5; 7 NET "Led[3]" LOC = M6;
以上是关于基于Verilog的带FIFO输出缓冲的串口接收接口封装的主要内容,如果未能解决你的问题,请参考以下文章