usb-fifo-sdram读取数据
usb-fifo-sdram读取数据
注意 转载说明出处,版权所有.
最近两个月都在解决一个问题:将已存在sdram中的视频数据itu656通过USB读到PC; USB和sdram之间是异步,特权书上讲了用fifo,所以之间加了fifo.
现在的现象时PC采集到的数据生成iamge后,连续采集时image会在水平方向来回移动,很是郁闷; 看起来很简单,但....两个月啊
相当于记录日志吧:
1.这一定是设计成按frame读. 并且为了避免USB端fifo读不进 读不够问题 最好读取量是512的整数倍, 如果1frame最后一点不足512则丢弃;
2.USB.v设计出一个usb_frame_active信号,相当于场同步. 当视频A/D的VS上升沿时 usb_farme_active=1,(为什么这样做?防止写入视频数据端同时访问一个fifo的措施之一); 当读到1frame数据量时,usb_frame_active=0; -----这是连接在fifo的写出端,下面就是连接fifo的读入端.
3.fifo的读入端, sdram的bank容量肯定是按frame, 当系统商店复位后, fifo读入端的地址 应该指向某个bank的首地址; 当读完1frame数据量成后,这时fifo_frame_read_done信号有效; 因为fifo,usb_frame_active=0是滞后于fifo byte个clk fifo_frame_read_done; 为了同步,理所当然,在当fifo_frame_read_done,usb_frame_active都有效表示都完成后,等到下一个vs'falling 时,切bank,以便指向下一个frame或叫做bank.(frame_write_done_cnt)
4. 但是第3点没有错,错就错在,PC端不是立即在VSfalling的下一个相邻的VSrising就开始读! 什么时候读我也不知道? 那怎么办呢?
现在有必要梳理一下usb.v读数据的时机,准确讲什么条件具备才让USB和fifo发生关系? 现在是通过flagd,slwr来控制; 想当然flagd (ep6full flag active low)只要低电平且检测到VSrising就开始读了;----这是错误的条件, 为什么? 1. 因上一次PC读的数据量1frame,而fifo读入端从sdram读出来也是1frame,这绝对是当pc读完1frame时USB fifo是空的,flagd是low; 2.而此时fifo读入端指向的bank,不是PC下一次要读的bank.所以现在联想的flagd是由low-high接着的某个时刻即PC真正读的时刻开始变low.而这个bank可能被面临有读有写.3.PC此时还忙着处理raw2image,当然多流水线另当别论.
5.基于以上,PC端来个control传输,给一个信号,当fpga检测的该电平 & VSrising & FlagD 时才"开闸", 在没有检测到该信号时默数被写到那个bank了,这为了防止撞车做准备.
......