基于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;
原文地址:https://www.cnblogs.com/wt-seu/p/7445455.html