试下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。
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());