u@home:~$

试下AXI read channel

刚开始试着写axi的master和slave。看了下arm最近的手册,改叫manager和subordinate了。

先试了下read channel,ar和r,也就是address read和read。

arid,rid都没处理,也没有多条管道,每次只能一个读请求。

size,length也都没有,每次只能读bus width,也就是32bit。

所以主要是处理握手过程,valid和ready。

screenshot0

m_arvalid和m_rready都是testbench里force的,所以并不是对齐上升沿的,不过这样正好可以和手册里给出的例子一样。

前面的黄框,m_arready是在m_arvalid前面就已经high了,这个是允许的,表示slave随时可以接收地址,本身没有任何待处理的请求。

一但正在处理请求,m_arready就不能上来就high了,要看进来的m_arid和m_arvalid。如果m_arid不同,并且m_arvalid是high,那可以接收新的请求,这时才能给出m_arready。

如果m_arid和正在处理的请求一样,那就要需要等当前同id的请求处理完才能给出m_arready。

我这里是提前给出的m_arready,这时候m_arvalid也来了,在下一个上升沿信号采集到以后,m_arvalid就可以撤了,这里是testbench做的。

而slave这边一但成功的接收到一个读请求的地址,就把内部寄存器busy置high,同时拉低m_arready,表示不接收新请求。这时就算有新地址和m_arvalid,那也得一直valid等着。

一个cycle后,sram得数据就读出来了,同时给出m_rvalid,表示让master过来拿数据。

这里我特意让testbench过了很久才给出m_rready来拿数据。右边红框里,m_rvalid直到遇到m_rready,才拉低回0。

同时busy也变0,表示可以处理下一个读请求,这样上面的m_arready也马上拉到1了。


这里逻辑上又遇到以前的逻辑开关了。

m_rvalid要在ar_enter来到后的下一个cycle置high(因为sram读写需要1个cycle),直到看到m_rready后落回low。

ar_enter     __--______________

m_rready     ______________--__

rdata_valid  ____------------__
 100    wire rdata_valid_next;                                                                                                                    
 101                                                                                                                                              
 102    assign rdata_valid_next = (rdata_valid | ar_enter) & (~m_rready);                                                                         
 103                                                                                                                                              
 104    dff_s #(1) rdata_valid_reg (                                                                                                              
 105       .din (rdata_valid_next),                                                                                                               
 106       .clk (aclk),                                                                                                                           
 107       .q   (rdata_valid),                                                                                                                    
 108       .se(), .si(), .so());