基于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;
时间: 2024-11-10 11:21:24

基于Verilog的带FIFO输出缓冲的串口接收接口封装的相关文章

基于Verilog的奇数偶数小数分频器设计

今天呢,由泡泡鱼工作室发布的微信公共号“硬件为王”(微信号:king_hardware)正式上线啦,关注有惊喜哦.在这个普天同庆的美好日子里,小编脑洞大开,决定写一首诗赞美一下我们背后伟大的团队,虽然连上我只有两个人,但丝毫不影响我们的工作热情和创业野心.合抱之木,生于毫末:九层之台,起于垒土:千里之行,始于足下! 首先小编在这里分享一个基于Verilog语言的分频器设计,该分频器实现了奇数.偶数.小数(0.5)分频,可综合,能跑700M左右的时钟,基本能够满足大部分应用需求. 一:背景 前天,

基于Verilog HDL整数乘法器设计与仿真验证

基于Verilog HDL整数乘法器设计与仿真验证 1.预备知识 整数分为短整数,中整数,长整数,本文只涉及到短整数.短整数:占用一个字节空间,8位,其中最高位为符号位(最高位为1表示为负数,最高位为0表示为正数),取值范围为-127~127. 负数的表示方法为正值的求反又加1.例如: 8’b0000_0100; //表示值:4,正值求反为:8’b1111_1011:再加1表示为:8’b1111_1100,这样便得到了-4的表示方法为:8’b1111_1100. 同理,负值变成正值的方法为:负值

基于jdk自带httpserver开发的最小完整MVC框架

基于jdk自带httpserver开发的最小完整MVC框架 410kb级的完整MVC:solon(83k) + jdkhttp(27k) + enjoy(227k) + snack3(73k) DEMO启动时间:0.1s solon 是一个插件框架,提供MVC,IOC,AOP,注解,插件机制. jdkhttp 基于jdk8自带com.sun.net.httpserver封装而成,有完整的http功能. snack3 提供json和序列化支持,也足够小. enjoy 很难再找到比它更小的模板引擎了

php flush()刷新不能输出缓冲的原因分析

在php程序编写中,flush()的使用率还是挺高的,它在网页表现即时信息效果时发挥了极为重要的作用,比如之前写的php实现限制文件下载速度的代码实例,flush()就起了举足轻重的作用,是进度条实现代码里的关键语句. 关于flash()的解释 语法: flush(); 作用: 刷新PHP程序的缓冲,而不论PHP执行在何种情况下(CGI ,web服务器等等).该函数将当前为止程序的所有输出发送到用户的浏览器. 问题: flush()刷新为什么不能输出缓冲? 很简单的程序代码 for ($i=10

PHP输出缓冲控制 - Output Control 函 应用详解

简介 说到输出缓冲,首先要说的是一个叫做缓冲器(buffer)的东西.举个简单的例子说明他的作用:我们在编辑一篇文档时,在我们没有保存之前,系统是不会向磁盘写入的,而是写到buffer中,当buffer写满或者执行了保存操作,才会将数据写入磁盘.对于PHP来说,每一次像 echo 这样的输出操作,同样是先写入到了 php buffer 里,在脚本执行完毕或者执行了强制输出缓存操作,数据才会在浏览器上显示. 其实对于PHP程序员来说,基本上每个脚本都涉及到了输出缓冲,只是在大多数情况下,我们都不需

PHP中输出缓冲

在PHP中,当执行echo,print的时候,输出并没有立即通过tcp传给客户端浏览器显示, 而是将数据写入php buffer.php output_buffering机制,意味在tcp buffer之前,建立了一新的队列,数据必须经过该队列.当一个php buffer写满的时候,脚本进程会将php buffer中的输出数据交给系统内核交由tcp传给浏览器显示.所以,数据会依次写到这几个地方echo/pring -> php buffer -> tcp buffer -> browse

PHP输出缓冲(Output Buffering)

什么是缓冲区? 简单而言,缓冲区的作用就是,把输入或者输出的内容先放进内存,而不显示或者读取.至于为什么要有缓冲区,这是一个很广泛的问题~其实缓冲区最本质的作用就是,协调高速CPU和相对缓慢的IO设备(磁盘等)的运作. PHP在执行的时候,在什么地方有用到缓冲区? 想要了解PHP的缓冲区,就要知道执行PHP的时候,缓冲区被设置到了什么地方. 当执行PHP的时候,如果碰到了echo print_r之类的会输出数据的代码,PHP就会将要输出的数据放到PHP自身的缓冲区,等待输出. 当PHP自身的缓冲

诡异的php 输出缓冲

我的本地环境 windows + apche + php5.2 今天,碰到一个诡异的问题,以前认为  php 脚本中调用 heade()函数之前不能有任何的如 echo,print ,print_r,var_dump等输出,否则的话就会报错. 但是, <?php header( 'Expires: Mon, 26 Jul 1998 05:00:00 GMT' ); echo "Expires: Mon, 26 Jul 1998 05:00:00 ;"; header( 'Expi

PHP中刷新输出缓冲

http://www.cnblogs.com/mutuan/archive/2012/03/18/2404957.html PHP中刷新输出缓冲buffer是一个内存地址空间,Linux系统默认大小一般为4096(1kb),即一个内存页.主要用于存储速度不同步的设备或者优先级不同的 设备之间传办理数据的区域.通过buffer,可以使进程这间的相互等待变少.这里说一个通俗一点的例子,你打开文本编辑器编辑一个文件的时候,你每输入 一个字符,操作系统并不会立即把这个字符直接写入到磁盘,而是先写入到bu