首先我们看BLOCK DESIGN里面实际的接口图:
我们看到总体的数据流向是:给模块输入64位数据,之后分成了4组16位的数据数据输出。结合unpack这个模块名,我们都可以想到是64位并列分成4组。主要是是看看控制和标志部分是如何工作的。
我们看到dac_valid_[0...3]和dac_enale[0:3]以及4组16位数据总线都接在AXI_9361的接口模块上。我们就想,这个AXI_9361应该是有点霸道,不需要询问 util_upack_dmx 这个模块的状态,直接发送读数命令,之后就要数据。
数据是从哪里来的呢,如下图:
看到util_upack_dmx这个模块也因为axi_9361的只读不询问也变得只读不询问了: util_upack_dmx接在一个fifo接口上,正常说你要读FIFO要先确保FIFO内有数据吧,具体说要询问fifo_rd_valid吧,但是 util_upack_dmx模块不管直接假设你有数据可以读,之后直接读。而一旦出现读空FIFO怎么处理?我们看一下fifo_rd_underflow这个信号,当对空的fifo进行读的时候此端口输出1.
可以看到一旦发出“读空”就会通过dac_dunf引脚告知axi_9361这个模块。
看来axi_9361的控制还是比较豪放的,尽管按照我的节奏发数据,数据不够了出错了告诉我就行。我不会将就你数据流的节奏(不考察FIFO是否就绪),可劲发就完了,错了就错了。
其实这种霸道的控制思路我也用过,就是在500M 32通道逻辑分析仪用。固定的采样率采集数据,必须要保存,我这边通过FIFO进行位的整理以及压缩等多级FIFO传到DDR2存储器。我这边采集的数据必须固定速率传递下去,如果你FIFO接收不了我也没有缓存,你让我丢弃那就是出错了,整个后续的数据都没有意义了。所以我就必须假设你有足够的存储带宽处理得了这些数据。当然万一出现overflow也就是写满状态,你告诉我就好了,整个采集的数据包都就丢弃好了。这是不可恢复的错误,是要避免的。
我举的例子是overflow,这里看到的是underflow,是一样道理。
另外我们看到此模块的dac_clk时钟是用axi_9361这个模块输出出来的。这个时钟同时输出给了:dac_dma,dac_unpack,以及adc_fifo(这里双时钟fifo就让数据穿越时钟域的,穿越到本地时钟进行对收到数据的处理)。这些都是跟9361接口速率部分紧密相关的。
关于9361的接口时钟部分,我们会有专门的blog进行表述,会专门谈。
这种霸道控制思路也可以认为是先斩后奏的处理方式,操作起来简单,省掉了数据通路之间各级反馈的磨磨唧唧。
好像有点跑题。我们继续分析这个模块。看到64位数据应该就是axi总线的64位数据总线对应出来的,而4个16位总线,应该就是分别对应的I,Q信号数据位,具体怎么对应还没有分析到。但是觉得4路确实不少,因为2路IQ才占据2路(IQ的DDS数据只有12位,就算16位)。可能是双发模式,就4了路了。很多情况下我们并不要求AD9361两个发送器同时工作,所以就估计这种情况下就需要用多个控制脚en和valid进行数据的选择了。
总结一下,我们这个BLOG看了ad9361_dac_upack 这模块外部接口,以及猜测他的实现功能。下个微博我们看看对应的ad9361_adc_pack模块所处的位置所起的作用以及对内部功能的猜测。