你好,AN65974附带的FPGA代码--StreamIN的代码中,当填满缓冲区之后经过了一个时钟周期的
always @(*)begin
next_stream_in_state = current_stream_in_state;
case(current_stream_in_state)
stream_in_idle:begin
if((stream_in_mode_selected) & (flaga_d == 1'b1))begin
next_stream_in_state = stream_in_wait_flagb;
end else begin
next_stream_in_state = stream_in_idle;
end
end
stream_in_wait_flagb :begin
if (flagb_d == 1'b1)begin
next_stream_in_state = stream_in_write;
end else begin
next_stream_in_state = stream_in_wait_flagb;
end
end
stream_in_write:begin
if(flagb_d == 1'b0)begin
next_stream_in_state = stream_in_write_wr_delay;
end else begin
next_stream_in_state = stream_in_write;
end
end
stream_in_write_wr_delay:begin
next_stream_in_state = stream_in_idle;
end
endcase
end
Jack chen
已解决! 转到解答。
咨询了一下印度的专家,这个问题的解释可以参考AN 11.4.3节
11.4.3 State stream_in_write_wr_delay:
Whenever flagb_d = 0, the state machine will enter this state. The Slave FIFO control line status is:
PKTEND# = 1; SLOE# = 1; SLRD# = 1; SLCS# = 0; SLWR# = 1; A[1:0] = 0
After one clock cycle, the state machine will enter the stream_in_idle state.
According to formula (1) in the General Formulae for Using Partial Flags section, FX3 should sample SLWR# asserted for two cycles after the partial flag (flagb) goes to 0. Considering a one-cycle propagation delay through the FPGA and to the interface, the FPGA asserts SLWR# for a count of one cycle after sampling the flagb_d (flopped output of flagb) as 0.
flag_b一旦拉低后,状态机进入stream_in_write_wr_delay,1一个时钟周期的延迟后进入stream_in_idle,此处有一个时钟周期的传播延迟。因此在Flagb被拉低后,SLWR会被拉低两个周期
Hi Jack,
这里slwr_streamIN_需要在current_stream_in_state == stream_in_write的情况下才会拉低,所以即使进入stream_in_idle状态判断flaga_d ==1,也不会立刻将slwr_streamIN_拉低,下一个状态是stream_in_wait_flagb,判断完flagb_d 后的再下一个状态才是stream_in_write,这样三个clock就过去了。
Regards,
Eddie
Hi Eddie,
你好,关于同步FIFO写操作时序,想请你帮我明确以下几点。(flaga、flagb为实际物理连接信号,flagb_d为采样一拍信号)
1.参考AN65974的设计,水印值为6,总线位宽32bit,依据公式AN65974 8.3节第1公式,t0时刻水印值标志flagb拉低,到t2时刻缓冲区应该写满了数据。
2.依据AN65974 7.2.1节 表4,“从最后一次激活SLWR#到激活满标志的延迟是3”,那t2-t5,flaga依旧是高电平,直到t6时刻 flaga拉低。
3.根据AN65974FPGA代码,t3时刻,进入“stream_in_idle”状态,此时flaga=1,t4时刻进入“
Jack chen
Hi Jack,
首先你看的中文版的AN已经很久没更新了,可能与release的代码存在差异,请查看英文版
你可以使用GPIF designer查看仿真波形:
这个watermark的设置与buffer size是息息相关的,如我这里把flag a配置成DMA_ready, flag b配置成watermark ,值为6,buffer size设置为最小的16,水印设置为6,则波形是这样的:
1.是
2.是
3.水印值恢复要看DMA另一端也就是USB的读取情况。
4. flag a何时写满触发flag a与DMA buffer size相关, FPGA只需要检查这个引脚的状态再写入,这里应该没有这个持续时间的数据。
5. 我觉得官方的这个demo,flag a与flag b应该是配成了同一个thread的ready 与watermark。所以,先根据ready信号开始写入,再依据watermark停止写入。这样就说得通了。
Hi Eddie,
感谢您的耐心回复。
您回复说,我的1 2提问都是对的,但是根据1 2 的理解,却理解不了你给出的波形图。给出的波形图中,flagb拉低之后,就没有写入了(slwr拉高了),为何flaga还能变低(flaga拉低意味着缓冲区写满了)?slwr拉低了6个时钟周期,总线位宽为16bit的话,写入了12B数据,而缓冲区size设置的是16B,怎么出现了写满(flaga拉低)的情况呢?另外,水印值是6,那当水印值拉低时,应该还能写入(6*(32/16)-4=8)个数据字,才能将缓冲区写满,可是这里水印值拉低时,就不在写入了,flaga还是拉低了。我觉得可能是我的理解还有问题,请您在帮我解释一下这个波形图,谢谢。
关于问题5,您提到 “先根据ready信号开始写入,再依据watermark停止写入”,按照这个理解,那按照官方的状态机,由于flaga与实际缓冲区的状态有延迟,与最后一个slwr写入周期间隔三个时钟周期,此时状态机不是已经进入“stream_in_wait_flagb”了吗?那不就不在依据ready写入了,而是依据watermark了。
Jack chen
咨询了一下印度的专家,这个问题的解释可以参考AN 11.4.3节
11.4.3 State stream_in_write_wr_delay:
Whenever flagb_d = 0, the state machine will enter this state. The Slave FIFO control line status is:
PKTEND# = 1; SLOE# = 1; SLRD# = 1; SLCS# = 0; SLWR# = 1; A[1:0] = 0
After one clock cycle, the state machine will enter the stream_in_idle state.
According to formula (1) in the General Formulae for Using Partial Flags section, FX3 should sample SLWR# asserted for two cycles after the partial flag (flagb) goes to 0. Considering a one-cycle propagation delay through the FPGA and to the interface, the FPGA asserts SLWR# for a count of one cycle after sampling the flagb_d (flopped output of flagb) as 0.
flag_b一旦拉低后,状态机进入stream_in_write_wr_delay,1一个时钟周期的延迟后进入stream_in_idle,此处有一个时钟周期的传播延迟。因此在Flagb被拉低后,SLWR会被拉低两个周期