博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于FIFO的串口发送机设计
阅读量:5232 次
发布时间:2019-06-14

本文共 4041 字,大约阅读时间需要 13 分钟。

  选题缘由:前几天在黑金时序篇的陪伴下,对FIFO进行了大致的掌握,今天看特权同学的深入浅玩转FPGA进阶实验五:基于FIFO的串口发送机设计,想自己总该动手练练,总看别人的code也能学到东西,但那终究不是自己的,当自己独自面对时,会冒出不少原本看似没有问题的问题。可喜的是这次竟然没遇到多大困难,一个小时多一点写好代码,解决问题不到十分钟,然后搞定!难道自己水平有所提高了,哈哈!

  本实验RTL图:

  本实验实现如下功能:Data_gene模块每隔1s产生一个递增的8位数(在助手里边以16进制方式显示),然后每隔1s wrreq发送一个高电平,写入FIFO,本实验FIFO采用8 wide,256deepth,但是这个深度似乎是没有作用的,后边再解释。受黑金大大影响,发送模块采用仿顺序写法,并引出了Start_sig和Done_sig,Start_sig和FIFO的empty相连,一旦FIFO不为空,则启动串口发送过程,一旦完成发送则马上使能读FIFO,因此FIFO里边的数据就是进来一个马上发送出去的过程,因此深度在这里是无意义的……再说FIFO,FIFO是用向导生成的,在第一页选了同步读写时钟,第二页选择保留empty输出,第四页选择关闭电路保护,上面说“如不需要,数据溢出以及数据不足将不会被检查,如此以提高系统性能”,不明白的是,如果不检查下溢,怎么会输出empty?目前实验没问题,就先不纠结了。确实有时候很多细节要理清头绪,需要花太多的时间。

  “时序分析”:起始时刻--FIFO为空,empty输出为1,232模块停止,1s时刻在,wrreq赋值为1,Data_out赋值为1,下一个CLk时刻,wrreq赋值为0,但非阻塞赋值的特性使得FIFO写入一个Data_out的值,即1。此时FIFO不再为空,empty为0,232模块开始运行,但由于此刻FIFO没有输出,所以232模块运行但无发送数据,232发送完,Send_done产生一个高电平,读FIFO使能,此刻,FIFO有输出,但empty输出变为1(FIFO空),232模块停止,Q一直保持第一次的输出数据:1。约1s后,数据生成模块产生新的数据2读进FIFO,empty为0,232模块使能,将1发送出去,产生完成信号。。如此往复。也即:232模块发出Send_done后,离下次真正232发送数据的间隔为1s。

  下面给出2个.v文件及顶层的纯组合.v文件(FIFO文件就不给了):

1 module Data_gene(Clk,Rstn,wrreq,Data_out); 2  3 input Clk,Rstn; 4 output wrreq; 5 output [7:0] Data_out; 6  7 parameter T1s=26'd49_999_999; 8  9 reg [25:0] i;10 reg [7:0] Data;11 reg wrreq;12 always@(posedge Clk or negedge Rstn)13 if(!Rstn)14     begin15     Data<=1'b0;16     wrreq<=1'b0;17     end18 else if(i==T1s)19     begin20     wrreq<=1'b1;21     i<=1'b0;22     Data<=Data+1'b1;23     end24 else25     begin26     i<=i+1'b1;27     wrreq<=1'b0;28     end29     30 assign Data_out=Data;31 endmodule
Data_gene

  刚连接好各模块后进行的第一次实验时,发现串口助手并非接收到的是每隔1s的一个递增的2位16进制数,后来看RTL图,猛然意识到自己在程序中始终赋予wrreq为1,那么FIFO以及发送模块都是在系统Clk的拍子下,不停的读入FIFON多个相同的数,然后在发送模块不停的发送N多个相同的数……果断在一秒时赋予wrreq值为1,其他时刻均为0,问题完美解决!

1 module rx_232(Clk,Rstn,Data_in,Start_sig,Done_sig,Send_data); 2  3 input Clk,Rstn,Start_sig; 4 input [7:0] Data_in; 5 output Done_sig,Send_data; 6  7 reg isDone,Send_out; 8  9 /**********************************************/10 parameter Bps_9600=13'd5208;11 reg [12:0] count;12 always@(posedge Clk or negedge Rstn)13 if(!Rstn)14     count<=1'b0;15 else if(!Start_sig)16     if(count==Bps_9600)17         count<=1'b0;18     else19         count<=count+1'b1;20 else21     count<=1'b0;22 /**********************************************/23 reg [3:0] i;24 25 always@(posedge Clk or negedge Rstn)26 if(!Rstn)27 begin28     i<=1'b0;29     Send_out<=1'b0;30     isDone<=1'b0;31 end32 else33     case(i)34         0:if(count==Bps_9600) i<=i+1'b1;//Idle35             else Send_out<=1'b1;36         1:if(count==Bps_9600) i<=i+1'b1;//Startbit37             else Send_out<=1'b0;38         2,3,4,5,6,7,8,9:39           if(count==Bps_9600) i<=i+1'b1;//Zerobit to Sevenbit40             else Send_out<=Data_in[i-2];41         42         10:if(count==Bps_9600) i<=i+1'b1;//Checkout random43             else Send_out<=1'b0;44         11:if(count==Bps_9600) i<=i+1'b1;//Stopbit45             else Send_out<=1'b1;46         12:begin isDone<=1'b1;i<=i+1'b1;end47         13:begin isDone<=1'b0;i<=1'b0;end48     endcase 49     50 /**********************************************/51 assign Done_sig=isDone;52 assign Send_data=Send_out;53 54 endmodule 55 56 57
rx_232

  波特率为9600bps,含有一位校验位。

1 module FIFO_232(Clk,Rstn,Send_data); 2 input Clk,Rstn; 3 output Send_data; 4  5 wire wrreq; 6 wire [7:0] Data_out; 7  8 Data_gene U1( 9     .Clk(Clk),10     .Data_out(Data_out),11     .Rstn(Rstn),12     .wrreq(wrreq)13 );14 15 wire Done_sig,Start_sig;16 wire [7:0]Data_in;17 18 FIFO U2(19     .clock ( Clk ),20     .data ( Data_out ),21     .rdreq ( Done_sig ),22     .wrreq ( wrreq ),23     .empty ( Start_sig ),24     .q ( Data_in )25 );26 27 rx_232 U3(28 .Clk(Clk),29 .Rstn(Rstn),30 .Data_in(Data_in),31 .Start_sig(Start_sig),32 .Done_sig(Done_sig),33 .Send_data(Send_data)34 );35 36 endmodule
FIFO_232

  这个真的是纯组合模块…… 由于实例化的时候,不是实例化了一个文件,而是涉及多个模块之间的相互连接,那么wire连接线类型在这里边体现的淋漓尽致……

  最后给出串口助手图,下边的tx就像是秒针那样加一……

    

 

 

  这些都是基础的、粗略的、思路简单的…… 要走的路还有很长,离1W小时还有很远,但不放弃,终有一天可达到……

  ↖(^ω^)↗

转载于:https://www.cnblogs.com/fkl523/p/3422728.html

你可能感兴趣的文章
C++对vector里面的元素排序及取任意重叠区间
查看>>
软件测试——性能测试总结
查看>>
12.4站立会议
查看>>
Java Concurrentmodificationexception异常原因和解决方法
查看>>
客户端访问浏览器的流程
查看>>
codeforces水题100道 第二十二题 Codeforces Beta Round #89 (Div. 2) A. String Task (strings)
查看>>
c++||template
查看>>
[BZOJ 5323][Jxoi2018]游戏
查看>>
编程面试的10大算法概念汇总
查看>>
Vue
查看>>
python-三级菜单和购物车程序
查看>>
条件断点 符号断点
查看>>
VMware12 + Ubuntu16.04 虚拟磁盘扩容
查看>>
水平垂直居中
查看>>
CSS3教程:border-image属性
查看>>
SQL Server 2008连接字符串写法大全
查看>>
MySQL简介
查看>>
设计模式之桥接模式(Bridge)
查看>>
jquery的$(document).ready()和onload的加载顺序
查看>>
Python Web框架Django (五)
查看>>