1. 程式人生 > >基於Verilog的帶FIFO輸出緩沖的串口接收接口封裝

基於Verilog的帶FIFO輸出緩沖的串口接收接口封裝

控制 ase div2 else eight image wid pan 開發

一、模塊框圖及基本思路

技術分享

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<=1b1; 19 RX_r2<=1b1; 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<=16d0;
21         else if(Count_BPS==Baud_Div)
22             Count_BPS<=16d0;
23         else if(Count_Sig)
24             Count_BPS<=Count_BPS+1;
25         else Count_BPS<=16d0;
26     end
27     /************************/
28     assign BPS_CLK=(Count_BPS==Baud_Div2)?1b1:1b0;
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<=4d0;
22             isCount<=1b0;
23             isDone<=1b0;
24             rData<=8d0;
25         end
26         else if(RX_En_Sig)
27         begin
28             case(i)
29             4d0:if(H2L_Sig) begin i<=i+1b1;isCount<=1b1; end   //接收到下降沿開始啟動波特率計數
30             4d1:if(BPS_CLK) begin i<=i+1b1; end                 //起始位
31             4d2,4d3,4d4,4d5,4d6,4d7,4d8,4d9:
32             if(BPS_CLK) begin rData[i-2]<=RX_Pin_in;i<=i+1b1;end  //數據位
33             4d10:if(BPS_CLK) begin i<=i+1b1; end                 //校驗位
34             4d11:if(BPS_CLK) begin i<=i+1b1; end                 //停止位
35             4d12:if(BPS_CLK) begin i<=i+1b1;isDone<=1b1;isCount<=1b0; end       //一個時鐘脈沖的 isDone 信號 
36             4d13:begin i<=1b0;isDone<=1b0; 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<=1b0;
22             isWrite<=1b0;
23             i<=3d0;
24         end
25         else 
26         case(i)
27         3d0:if(RX_Done_Sig) begin i<=i+1b1;isRx<=1b0; end
28                 else isRx<=1b1;
29         3d1:if(!Full_Sig) begin isWrite<=1b1;i<=i+1b1;end
30         3d2:begin isWrite<=1b0;i<=3d0;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<=32d0;
        else if(Count_1s==T1S) Count_1s<=32d0;
        else if(isCount) Count_1s<=Count_1s+1b1;
        else Count_1s<=32d0;
     end
     /*******************************************/
     reg isRead;
     reg [2:0]i;
     reg isCount;
     always @(posedge CLK or negedge RSTn)
     begin
        if(!RSTn)
        begin
            isRead<=1b0;
            i<=3d0;
            isCount<=1b0;
        end
        else 
        case(i)
        3d0:if(Count_1s==T1S) begin isCount<=1b0;i<=i+1b1; end
            else isCount<=1b1;
        3d1:if(!Empty_Sig) begin isRead<=1b1; i<=i+1b1;end
        3d2:begin  isRead<=1b0;i<=3d0; 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輸出緩沖的串口接收接口封裝