基于Verilog的串口接收程序
一、模块框图及基本思路
detect_module:检测输入引脚的下降沿,以此判断一帧数据的开始
rx_bps_module:波特率时钟产生模块
rx_control_module:串口接收的核心控制模块
rx_module:前三个模块的组合
control_module2:接受控制模块,不断接收串口数据
rx_top_module:将接收到数据的第四位以LED的形式显示
二、软件部分
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:
1 module rx_module( 2 CLK,RSTn, 3 RX_Pin_in,RX_Done_Sig,RX_Data,RX_En_Sig 4 ); 5 6 input CLK,RSTn; 7 input RX_Pin_in,RX_En_Sig; 8 output RX_Done_Sig; 9 output [7:0] RX_Data; 10 11 wire Count_Sig; 12 wire BPS_CLK; 13 wire H2L_Sig; 14 15 16 rx_bps_module U0( 17 .CLK(CLK),.RSTn(RSTn), 18 .Count_Sig(Count_Sig), 19 .BPS_CLK(BPS_CLK) 20 ); 21 22 detect_module U1( 23 .CLK(CLK),.RSTn(RSTn), 24 .RX_Pin_in(RX_Pin_in), 25 .H2L_Sig(H2L_Sig) 26 ); 27 28 rx_control_module U2( 29 .CLK(CLK),.RSTn(RSTn), 30 .H2L_Sig(H2L_Sig),.BPS_CLK(BPS_CLK),.RX_Pin_in(RX_Pin_in), 31 .Count_Sig(Count_Sig),.RX_En_Sig(RX_En_Sig),.RX_Done_Sig(RX_Done_Sig),.RX_Data(RX_Data) 32 ); 33 34 endmodule
control_module2:
1 module control_module2( 2 CLK,RSTn, 3 RX_Done_Sig, 4 RX_En_Sig, 5 RX_Data, 6 Number_Data 7 ); 8 9 input CLK; 10 input RSTn; 11 input RX_Done_Sig; 12 input [7:0]RX_Data; 13 output RX_En_Sig; 14 output [7:0] Number_Data; 15 16 /***************************************/ 17 reg[7:0] rData; 18 reg rEn; 19 always @(posedge CLK or negedge RSTn) 20 begin 21 if(!RSTn) 22 begin 23 rData<=8'd0; 24 rEn<=1'b0; 25 end 26 else if(RX_Done_Sig) 27 begin 28 rEn<=1'b0; 29 rData<=RX_Data; 30 end 31 else rEn<=1'b1; 32 end 33 /***************************************/ 34 assign Number_Data=rData; 35 assign RX_En_Sig=rEn; 36 37 endmodule
rx_top_module:
1 module rx_top_module( 2 CLK,RSTn, 3 RX_Pin_in,Led 4 ); 5 input CLK,RSTn; 6 input RX_Pin_in; 7 output [3:0]Led; 8 9 wire RX_Done_Sig; 10 wire RX_En_Sig; 11 wire [7:0] Number_Data; 12 wire [7:0] RX_Data; 13 14 rx_module U0( 15 .CLK(CLK),.RSTn(RSTn), 16 .RX_Pin_in(RX_Pin_in),.RX_Done_Sig(RX_Done_Sig),.RX_Data(RX_Data),.RX_En_Sig(RX_En_Sig) 17 ); 18 19 control_module2 U1( 20 .CLK(CLK),.RSTn(RSTn), 21 .RX_Done_Sig(RX_Done_Sig), 22 .RX_En_Sig(RX_En_Sig), 23 .RX_Data(RX_Data), 24 .Number_Data(Number_Data) 25 ); 26 27 assign Led=Number_Data[3:0]; 28 endmodule
三、硬件部分
黑金SPARTAN-6开发板
NET "CLK" LOC = T8; NET "RSTn" LOC = L3; NET "RX_Pin_in" LOC = C11; NET "Led[0]" LOC = P4; NET "Led[1]" LOC = N5; NET "Led[2]" LOC = P5; NET "Led[3]" LOC = M6;