• 基于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;
  • 相关阅读:
    hdu--4027--不错的线段树
    hdu--3275--线段树<again>
    hdu--2795--又是线段树
    hdu--4407--一不留神就TLE了
    zoj--3822--第二题概率dp
    hdu--3911--线段树<我最近爱上她了>
    hdu--1710--二叉树的各种遍历间的联系
    hdu--1712--分组背包<如果你真的明白了背包..>
    hdu--4576--概率dp<见过最简单的概率dp>
    list remove object
  • 原文地址:https://www.cnblogs.com/wt-seu/p/7462469.html
Copyright © 2020-2023  润新知