转载:原文  http://www.eefocus.com/antaur/blog/17-08/423751_6cc0d.html

0. 引言

通过之前的学习,可以在PL端创建从机模式的AXI接口IP核。但是从机模式是被动接收数据,而不能主动的去获取数据,因此计划研究一下AXI Master接口的IP核的构建方法。

1. 利用向导创建AXI Lite Master测试用例

在这一步,AXI类型为Lite型的,可选参数如下所示:

在这里,重点是Interface Mode,前面的实验中采用的是默认配置Slave,即设计的IP接口为从机。本实验中,要将其设置为Master。

下面的三个参数跟Sl**e模式下可配置的参数类型是相同的。具体的说明如下所示:

Data Width:为数据总线的位宽,单位为bits

Memory Size:只有在IP类型为AXI FULL Slave模式下才有效,目前不讨论。

Number of Registers:只有在IP接口类型为AXI Lite Slave模式下才有效,可以参看之前的实验说明。

至此,利用向导工具创建一个AXI Lite Master类型的IP接口配置完毕。

2. 源码分析

2.1 顶层源码解析

系统会自动生成一个该IP的工程,可以查看生成的源代码,并在此基础上进行修改。

从上图可以看出,向导工具就生成了两个模块。直接综合后,查看RTL级图的操作入口如下所示:

显示结果如下:

可以看出顶层模块只是做了简单的直连封装,内部没有任何逻辑设计,查看代码(附录1)也是如此,唯一有用的操作配置了内层模块实例的参数。

具体配置测参数如下所示:

可以看到配置了5个参数,其中:

C_M00_AXI_ADDR_WIDTH表示地址总线的位宽,这里配置为32bits,由于涉及到总线的协议,建议不要动这个参数。

C_M00_AXI_DATA_WIDTH表示数据总线的位宽,这里配置为32bits,同样的原因,建议不要动这个参数。

其余的三个参数是根据测试用例的用户逻辑相关的,具体意义在底层模块的源码分析(附录2)中会详细解释,这里简单说明一下:

C_M00_AXI_TARGET_SLAVE BASE_ADDR表示本IP作为主机欲访问的从机内存的基地址。

C_M00_AXI_START_DATA_VALUE表示对从机寄存器进行写入操作的测试数据

C_M00_AXI_TRANSACTIONS_NUM表示测试的次数

具体逻辑及各参数的意义见下文对底层模块的解析。

2.2 底层源码解析

向导自动生成的示例程序中底层模块为AzIP_AXI_Master_Ex1_v1_0_M00_AXI,该模块并不是一个Master型的IO标准接口,而只是一个用户测试用例的逻辑操作。而Master的Write和Read读写逻辑并没有很完毕的封装,需要仔细分析示例代码进行拆分。

具体的代码解析详见后面附录2的注释说明,这里给出的仅是本人对此分析得到的笔记。

  1. 测试业务逻辑

测试业务逻辑的本质如下图所示,就是一个典型的内存读写操作的测试流程。

代码编写时采用状态机的方式。

其中:

【地址操作分析】:

从机寄存器的初始地址有变量C_M00_AXI_TARGET_SLAVE_BASE_ADDR定义,在构建集成系统时,对应从机的内存映射必须于配置相同。

AXI总线上写操作地址总线绑定如下,C_M00_AXI_TARGET_SLAVE_BASE_ADDR为基地址,而axi_awaddr定义地址偏移量。

段内地址偏移量初始化值为0,每次写入成功后,地址偏移量+4,这是因为地址定义的单位是字节Byte,而数据总线为32bits,即4个字节,因此没写入32bits,会用掉从机4个地址的存储空间。

关于读取操作指定寄存器的地址定义及处理过程是类似的。

【数据操作分析】:

写操作使用的数据总线绑定到一个内部寄存器上。

初始化时,测试数据寄存器被设置为参数配置的数值,之后每次加1。

测试数据向从机写入之后,内部备份保存一份,存在寄存器expected_rdata中,代码如下:

可以看到代码逻辑完全相同,但是整个代码架构真的不敢苟同。

数据比较段的代码如下:

相应的逻辑应该是一旦有一次出错,read_mismatch就置为1,如果下次对了,该状态寄存器仍然保持数据为1,直到复位操作。

(2)AXI4-Lite总线接口定义

在进行AXI4-Lite总线读写时序操作时,首先要明确总线的读写操作接口。

查看相关技术文档,这里主要用到以下两个技术文档:

  • ARM公司发布的《ARM AMBA AXI Protocol v2.0 Specification》
  • Xilinx公司发布的《Vivado Design Suite : AXI Reference Guide》UG1037(v3.0)2015

    可以看到,无论是AXI4总线还是精简版的AXI4-Lite总线接口分成5大类,这5大类又分别****于Write操作核Read操作。

    Write操作

    1. 写地址:主机-->从机
    2. 写数据:主机-->从机
    3. 写应答:从机-->主机

    Read操作

    1. 读地址:主机-->从机
    2. 读数据:从机-->主机
     

下面重点研究一下AXI4-Lite总线具体是如何定义的,它与AXI4总线协议有什么不同?

首先看一下AXI4总线协议的官方定义:

再看一下AXI4-Lite总线协议的官方定义:

不支持突发(burst)传输模式,及burst length=1

数据总线宽度只能为32bit或则64bits

不支持独家访问(exclusive accesses)

即AXI4-Lite不支持突发(burst)传输模式。

【说明】关于突发(burst)传输模式是否采用将在后面分析读写时序时重点讨论。这里先铺垫一下。

AXI4总线,由于读写通道是分离的,可以提供实时双向的数据传输。

采用突发(burst)传输模式,可以在发送1个地址之后,最多支持突发256words的数据。(Words??2字节吗??)

下面看一下AXI4-Lite总线协议的物理接口Port的定义:

可以看出除了时钟和复位信号后,也是前文介绍的5类信号通道。

但是作为一个简化的总线协议,其物理接口应该比完整版的AXI4总线要少,具体精简掉了哪些?详见下表。

学习完原理性的基础知识之后,我们来看一下示例程序代码是否符合官方标准。

分析AXI Master示例IP源代码的Port定义,代码即注释说明如下所示:

【AXI4-Lite Write Address Channel】

在示例程序中,AXI Master模块的M_AXI_AWPROT管脚始终输出为:3’b000

【AXI4-Lite Write data Channel】

其中端口M_AXI_ARPROT,参见【AXI4-Lite Write Address Channel】中的M_AXI_AWPROT

【AXI4-Lite Read Data Channel】

在示例程序中,AXI Master模块由于数据总线位宽为32bit,因此M_AXI_WSTRB管脚始终输出为:4’b1111

【AXI4-Lite Write response Channel】

【AXI4-Lite Read Address Channel】

其中端口M_AXI_ARPROT,参见【AXI4-Lite Write Address Channel】中的M_AXI_AWPROT

【AXI4-Lite Read Data Channel】

其中端口M_AXI_RRESP,参见【AXI4-Lite Write response Channel】中的M_AXI_BRESP

其中端口M_AXI_RRESP,参见【AXI4-Lite Write response Channel】中的M_AXI_BRESP

(3)AXI4-Lite总线读写时序分析1--写入操作时序

研究总线协议的交互时序,必须依赖协议标准,但是能够查到的官方协议标准均没有对AXI4-Lite总线的读写时序进行独立的时序设定。

Xilinx公司发布的文档,引用的还是ARM公司发布的文档,对于总线写入时序逻辑示意图如下:

表示,主机需要先写地址,然后写入一系列数据,为什么是四个暂时不确定,从机处理完毕后回复一个应答响应。

ARM公司发布的文档《ARM AMBA AXI Protocol v2.0 Specification》中没有AXI4-Lits的写入时序逻辑,只有Write brust的时序示意图。如下所示

经过前面的研究,知道AXI4-Lite是brust length=1的Write brust,因此我自行简化上述时序图如下:

如果主机连续发送两次数据写入操作,我猜测的时序逻辑图应该如下所示:

分析示例程序中,AXI Master模块的源代码,绘制相应的主机向从机写入数据的时序逻辑如下图所示:

查看代码,分析得到的时序与个人分析得到的原理时序并不完全匹配。这里先铺垫一下,后文将会对示例源码的时序进行仿真分析,得到对应可用的时序,用于将来自行编写接口时使用。记得看下文。

(4) AXI4-Lite总线读写时序分析2--读取操作时序

同样先学习一下官方协议。

以及来自官方文档的读取操作时序图。

同样自行分析对于brust length=1的AXI4-Lite总线,读取操作的时序图如下所示

示例代码的操作时序这里就不在画处理流程图了。下文会通过时序仿真给出示例中采用的时序关系。

(5) 示例工程的时序分析

【工程创建的原始出发点】:

根据上述对AXI4-Lite总线接口的分析,其实就是主机和从机之间的数据通信。联想到之间创建的AXI4-Lite Sl**e示例IP核,是否能创建一个顶层模块直接将AXI4-Lite Sl**e示例IP核与AXI4-Lite Sl**e示例IP核直接相连,完成AXI4-Lite总线读写操作?

为了验证上述想法,首先再创建一个AXI4-Lite Sl**e示例IP核,参数要与AXI4-Lite Master示例IP核的参数向对应,下面将端口定义对比如下:

从上图的对比中,可以看出AXI4-Lite主从机的接口其实是一一匹配的。

创建一个顶层文件Top_AXI4_Lite_Interfce_Demo,将生成的主从示例直接对连。代码见附录3.相应的层级结构如下图所示。

综合完的RTL级连接图如下所示。

对该顶层文件创建仿真驱动,代码如下所示:

  1. `timescale 1ns / 1ps
  2. module Sim_AXI4_Lite_Interface();
  3. reg axi_ACLK; // AXI总线时钟
  4. reg axi_ARESETn; // 系统复位信号,低电平有效
  5. reg r_app_txn; // 应用级复位信号,负脉冲,上升沿复位
  6. wire w_err; // 状态指示,异常
  7. wire w_txn_done; // 状态指示,发送完毕
  8. Top_AXI4_Lite_Interfce_Demo Ut1 (
  9. .axi_ACLK(axi_ACLK),
  10. .axi_ARESETn(axi_ARESETn),
  11. .app_TXn(r_app_txn),
  12. .state_err(w_err),
  13. .state_done(w_txn_done)
  14. );
  15.  
  16. parameter PERIOD = ;
  17.  
  18. always begin
  19. #(PERIOD/);
  20. axi_ACLK = ~axi_ACLK;
  21. end
  22.  
  23. initial begin
  24. axi_ACLK = 'b0;
  25. axi_ARESETn = 'b1;
  26. r_app_txn = 'b1;
  27. #(*PERIOD);
  28. axi_ARESETn = 'b0;
  29. #(*PERIOD);
  30. r_app_txn = 'b0;
  31. #(*PERIOD);
  32. axi_ARESETn = 'b1;
  33. #(*PERIOD);
  34. r_app_txn = 'b1;
  35. end
  36. endmodule

运行后的仿真结果如下所示:

仿真结果1:先写入4次,然后读取4次的时序仿真结果

仿真结果2:先写入1次,然后读取1次的时序仿真结果

仿真结果3:仅写入1次时序仿真结果

仿真结果4:仅读取1次时序仿真结果

仿真结果5:先写入2次,再读取2次时序仿真结果

  • 对比仿真得到的写入操作时序和从官网文档分析得到的时序

【个人心得】

可以看出,AXI4中设定的5类通道都是相互独立的,示例仿真中,应为AWVALID和WVALID是同时给从机的,从机就同时采样AWADDR总线和WDATA总线数据,并同时给出了应答AWREADY和WREADY。

从机在匹配完Address和Data后,给出应答BVALID。

而官方文档上的时序时先发地址后发数据,正常的从机也是能够正确响应的。

结论,自行编写接口时,每个通道要独立处理,不要耦合到一起。

  • 对比仿真得到的读取操作时序和从官网文档分析得到的时序

【个人心得】

由于没有经过总线控制器,而是直连的,因此时序仿真结果图中从机的响应速度很快,而原理图中有个响应处理延时。

2. 总结

通过本学习笔记,详细分析了AXI4-Lite总线主机端的交互处理时序,以后就可以自行编写主从机的接口了。

附录1:顶层模块源代码:

  1. `timescale 1ns / 1ps
  2. module Top_AXI4_Lite_Interfce_Demo
  3. #(
  4. parameter C_AXI_START_DATA_VALUE = 'hAA000000,
  5. parameter C_AXI_TARGET_SLAVE_BASE_ADDR = 'h40000000,
  6. parameter integer C_AXI_ADDR_WIDTH = ,
  7. parameter integer C_AXI_DATA_WIDTH = ,
  8. parameter integer C_AXI_TRANSACTIONS_NUM =
  9. )
  10. (
  11. input axi_ACLK,
  12. input axi_ARESETn,
  13. input app_TXn,
  14. output state_err,
  15. output state_done
  16. );
  17. wire w_err; // 状态指示,异常
  18. wire w_txn_done; // 状态指示,发送完毕
  19. assign state_err = w_err;
  20. assign state_done = w_txn_done;
  21. wire [C_AXI_ADDR_WIDTH- : ] axi_AWADDR; // AXI总线信号:AWADDR
  22. wire [ : ] axi_AWPROT; // AXI总线信号:AWPROT
  23. wire axi_AWVALID; // AXI总线信号:AWVALID
  24. wire axi_AWREADY; // AXI总线信号:AWREAD
  25. wire [C_AXI_DATA_WIDTH- : ] axi_WDATA; // AXI总线信号:WDATA
  26. wire [C_AXI_DATA_WIDTH/- : ] axi_WSTRB; // AXI总线信号:WSTRB
  27. wire axi_WVALID; // AXI总线信号:WVALID
  28. wire axi_WREADY; // AXI总线信号:WREADY
  29. wire [ : ] axi_BRESP; // AXI总线信号:BRESP
  30. wire axi_BVALID; // AXI总线信号:BVALID
  31. wire axi_BREADY; // AXI总线信号:BREADY
  32. wire [C_AXI_ADDR_WIDTH- : ] axi_ARADDR; // AXI总线信号:ARADDR
  33. wire [ : ] axi_ARPROT; // AXI总线信号:ARPROT
  34. wire axi_ARVALID; // AXI总线信号:ARVALID
  35. wire axi_ARREADY; // AXI总线信号:ARREADY
  36. wire [C_AXI_DATA_WIDTH- : ] axi_RDATA; // AXI总线信号:RDATA
  37. wire [ : ] axi_RRESP; // AXI总线信号:RRESP
  38. wire axi_RVAILD; // AXI总线信号:RVAILD
  39. wire axi_RREADY; // AXI总线信号:RREADY
  40.  
  41. axi_ip_master_v1_0 #
  42. (
  43. .C_M00_AXI_START_DATA_VALUE(C_AXI_START_DATA_VALUE),
  44. .C_M00_AXI_TARGET_SLAVE_BASE_ADDR(C_AXI_TARGET_SLAVE_BASE_ADDR),
  45. .C_M00_AXI_ADDR_WIDTH(C_AXI_ADDR_WIDTH),
  46. .C_M00_AXI_DATA_WIDTH(C_AXI_DATA_WIDTH),
  47. .C_M00_AXI_TRANSACTIONS_NUM(C_AXI_TRANSACTIONS_NUM)
  48. ) Ut1 (
  49. //-- AXI4-Lite Global ----------------------------------------------
  50. .m00_axi_aclk(axi_ACLK),
  51. .m00_axi_aresetn(axi_ARESETn),
  52. //------------------------------------------------------------------
  53. .m00_axi_init_axi_txn(app_TXn),
  54. .m00_axi_error(w_err),
  55. .m00_axi_txn_done(w_txn_done),
  56. //--- AXI4-Lite Write Address Channel ------------------------------
  57. .m00_axi_awaddr(axi_AWADDR),
  58. .m00_axi_awprot(axi_AWPROT),
  59. .m00_axi_awvalid(axi_AWVALID),
  60. .m00_axi_awready(axi_AWREADY),
  61. //--- AXI4-Lite Write data Channel ------------------------------
  62. .m00_axi_wdata(axi_WDATA),
  63. .m00_axi_wstrb(axi_WSTRB),
  64. .m00_axi_wvalid(axi_WVALID),
  65. .m00_axi_wready(axi_WREADY),
  66. //--- AXI4-Lite Write response Channel ------------------------------
  67. .m00_axi_bresp(axi_BRESP),
  68. .m00_axi_bvalid(axi_BVALID),
  69. .m00_axi_bready(axi_BREADY),
  70. //--- AXI4-Lite Read Address Channel ------------------------------
  71. .m00_axi_araddr(axi_ARADDR),
  72. .m00_axi_arprot(axi_ARPROT),
  73. .m00_axi_arvalid(axi_ARVALID),
  74. .m00_axi_arready(axi_ARREADY),
  75. //--- AXI4-Lite Read Data Channel ------------------------------
  76. .m00_axi_rdata(axi_RDATA),
  77. .m00_axi_rresp(axi_RRESP),
  78. .m00_axi_rvalid(axi_RVAILD),
  79. .m00_axi_rready(axi_RREADY)
  80. );
  81.  
  82. axi_ip_slave_v1_0 #
  83. (
  84. .C_S00_AXI_DATA_WIDTH(C_AXI_ADDR_WIDTH),
  85. .C_S00_AXI_ADDR_WIDTH()
  86. ) Ut2 (
  87. //-- AXI4-Lite Global ----------------------------------------------
  88. .s00_axi_aclk(axi_ACLK),
  89. .s00_axi_aresetn(axi_ARESETn),
  90. //--- AXI4-Lite Write Address Channel ------------------------------
  91. .s00_axi_awaddr(axi_AWADDR[:]), //注意:只有段地址!!!!!,做的axi_slave_ip的地址位宽为7,寄存器个数为32
  92. .s00_axi_awprot(axi_AWPROT),
  93. .s00_axi_awvalid(axi_AWVALID),
  94. .s00_axi_awready(axi_AWREADY),
  95. //--- AXI4-Lite Write data Channel --------------------------------
  96. .s00_axi_wdata(axi_WDATA),
  97. .s00_axi_wstrb(axi_WSTRB),
  98. .s00_axi_wvalid(axi_WVALID),
  99. .s00_axi_wready(axi_WREADY),
  100. //--- AXI4-Lite Write response Channel ------------------------------
  101. .s00_axi_bresp(axi_BRESP),
  102. .s00_axi_bvalid(axi_BVALID),
  103. .s00_axi_bready(axi_BREADY),
  104. //--- AXI4-Lite Read Address Channel ------------------------------
  105. .s00_axi_araddr(axi_ARADDR),
  106. .s00_axi_arprot(axi_ARPROT),
  107. .s00_axi_arvalid(axi_ARVALID),
  108. .s00_axi_arready(axi_ARREADY),
  109. //--- AXI4-Lite Read Data Channel ------------------------------
  110. .s00_axi_rdata(axi_RDATA),
  111. .s00_axi_rresp(axi_RRESP),
  112. .s00_axi_rvalid(axi_RVAILD),
  113. .s00_axi_rready(axi_RREADY)
  114. );
  115. endmodule
  116. 附录2:底层模块MASTER 顶层源代码:
  117.  
  118. `timescale ns / ps
  119.  
  120. module axi_ip_master_v1_0 #
  121. (
  122. // Users to add parameters here
  123.  
  124. // User parameters ends
  125. // Do not modify the parameters beyond this line
  126. // Parameters of Axi Master Bus Interface M00_AXI
  127. parameter C_M00_AXI_START_DATA_VALUE = 'hAA000000,
  128. parameter C_M00_AXI_TARGET_SLAVE_BASE_ADDR = 'h40000000,
  129. parameter integer C_M00_AXI_ADDR_WIDTH = ,
  130. parameter integer C_M00_AXI_DATA_WIDTH = ,
  131. parameter integer C_M00_AXI_TRANSACTIONS_NUM =
  132. )
  133. (
  134. // Users to add ports here
  135. // User ports ends
  136. // Do not modify the ports beyond this line
  137. // Ports of Axi Master Bus Interface M00_AXI
  138. input wire m00_axi_init_axi_txn,
  139. output wire m00_axi_error,
  140. output wire m00_axi_txn_done,
  141. input wire m00_axi_aclk,
  142. input wire m00_axi_aresetn,
  143. output wire [C_M00_AXI_ADDR_WIDTH- : ] m00_axi_awaddr,
  144. output wire [ : ] m00_axi_awprot,
  145. output wire m00_axi_awvalid,
  146. input wire m00_axi_awready,
  147. output wire [C_M00_AXI_DATA_WIDTH- : ] m00_axi_wdata,
  148. output wire [C_M00_AXI_DATA_WIDTH/- : ] m00_axi_wstrb,
  149. output wire m00_axi_wvalid,
  150. input wire m00_axi_wready,
  151. input wire [ : ] m00_axi_bresp,
  152. input wire m00_axi_bvalid,
  153. output wire m00_axi_bready,
  154. output wire [C_M00_AXI_ADDR_WIDTH- : ] m00_axi_araddr,
  155. output wire [ : ] m00_axi_arprot,
  156. output wire m00_axi_arvalid,
  157. input wire m00_axi_arready,
  158. input wire [C_M00_AXI_DATA_WIDTH- : ] m00_axi_rdata,
  159. input wire [ : ] m00_axi_rresp,
  160. input wire m00_axi_rvalid,
  161. output wire m00_axi_rready
  162. );
  163. // Instantiation of Axi Bus Interface M00_AXI
  164. axi_ip_master_v1_0_M00_AXI # (
  165. .C_M_START_DATA_VALUE(C_M00_AXI_START_DATA_VALUE),
  166. .C_M_TARGET_SLAVE_BASE_ADDR(C_M00_AXI_TARGET_SLAVE_BASE_ADDR),
  167. .C_M_AXI_ADDR_WIDTH(C_M00_AXI_ADDR_WIDTH),
  168. .C_M_AXI_DATA_WIDTH(C_M00_AXI_DATA_WIDTH),
  169. .C_M_TRANSACTIONS_NUM(C_M00_AXI_TRANSACTIONS_NUM)
  170. ) axi_ip_master_v1_0_M00_AXI_inst (
  171. .INIT_AXI_TXN(m00_axi_init_axi_txn),
  172. .ERROR(m00_axi_error),
  173. .TXN_DONE(m00_axi_txn_done),
  174. .M_AXI_ACLK(m00_axi_aclk),
  175. .M_AXI_ARESETN(m00_axi_aresetn),
  176. .M_AXI_AWADDR(m00_axi_awaddr),
  177. .M_AXI_AWPROT(m00_axi_awprot),
  178. .M_AXI_AWVALID(m00_axi_awvalid),
  179. .M_AXI_AWREADY(m00_axi_awready),
  180. .M_AXI_WDATA(m00_axi_wdata),
  181. .M_AXI_WSTRB(m00_axi_wstrb),
  182. .M_AXI_WVALID(m00_axi_wvalid),
  183. .M_AXI_WREADY(m00_axi_wready),
  184. .M_AXI_BRESP(m00_axi_bresp),
  185. .M_AXI_BVALID(m00_axi_bvalid),
  186. .M_AXI_BREADY(m00_axi_bready),
  187. .M_AXI_ARADDR(m00_axi_araddr),
  188. .M_AXI_ARPROT(m00_axi_arprot),
  189. .M_AXI_ARVALID(m00_axi_arvalid),
  190. .M_AXI_ARREADY(m00_axi_arready),
  191. .M_AXI_RDATA(m00_axi_rdata),
  192. .M_AXI_RRESP(m00_axi_rresp),
  193. .M_AXI_RVALID(m00_axi_rvalid),
  194. .M_AXI_RREADY(m00_axi_rready)
  195. );
  196.  
  197. // Add user logic here
  198. // User logic ends
  199.  
  200. endmodule
  201. 附录3:底层模块MASTER 底层源代码:
  202.  
  203. `timescale ns / ps
  204.  
  205. module axi_ip_master_v1_0_M00_AXI #
  206. (
  207. // Users to add parameters here
  208.  
  209. // User parameters ends
  210. // Do not modify the parameters beyond this line
  211.  
  212. // The master will start generating data from the C_M_START_DATA_VALUE value
  213. parameter C_M_START_DATA_VALUE = 'hAA000000,
  214. // The master requires a target slave base address.
  215. // The master will initiate read and write transactions on the slave with base address specified here as a parameter.
  216. parameter C_M_TARGET_SLAVE_BASE_ADDR = 'h40000000,
  217. // Width of M_AXI address bus.
  218. // The master generates the read and write addresses of width specified as C_M_AXI_ADDR_WIDTH.
  219. parameter integer C_M_AXI_ADDR_WIDTH = ,
  220. // Width of M_AXI data bus.
  221. // The master issues write data and accept read data where the width of the data bus is C_M_AXI_DATA_WIDTH
  222. parameter integer C_M_AXI_DATA_WIDTH = ,
  223. // Transaction number is the number of write
  224. // and read transactions the master will perform as a part of this example memory test.
  225. parameter integer C_M_TRANSACTIONS_NUM =
  226. )
  227. (
  228. // Users to add ports here
  229.  
  230. // User ports ends
  231. // Do not modify the ports beyond this line
  232.  
  233. // Initiate AXI transactions
  234. input wire INIT_AXI_TXN,
  235. // Asserts when ERROR is detected
  236. output reg ERROR,
  237. // Asserts when AXI transactions is complete
  238. output wire TXN_DONE,
  239. // AXI clock signal
  240. input wire M_AXI_ACLK,
  241. // AXI active low reset signal
  242. input wire M_AXI_ARESETN,
  243. // Master Interface Write Address Channel ports. Write address (issued by master)
  244. output wire [C_M_AXI_ADDR_WIDTH- : ] M_AXI_AWADDR,
  245. // Write channel Protection type.
  246. // This signal indicates the privilege and security level of the transaction,
  247. // and whether the transaction is a data access or an instruction access.
  248. output wire [ : ] M_AXI_AWPROT,
  249. // Write address valid.
  250. // This signal indicates that the master signaling valid write address and control information.
  251. output wire M_AXI_AWVALID,
  252. // Write address ready.
  253. // This signal indicates that the slave is ready to accept an address and associated control signals.
  254. input wire M_AXI_AWREADY,
  255. // Master Interface Write Data Channel ports. Write data (issued by master)
  256. output wire [C_M_AXI_DATA_WIDTH- : ] M_AXI_WDATA,
  257. // Write strobes.
  258. // This signal indicates which byte lanes hold valid data.
  259. // There is one write strobe bit for each eight bits of the write data bus.
  260. output wire [C_M_AXI_DATA_WIDTH/- : ] M_AXI_WSTRB,
  261. // Write valid. This signal indicates that valid write data and strobes are available.
  262. output wire M_AXI_WVALID,
  263. // Write ready. This signal indicates that the slave can accept the write data.
  264. input wire M_AXI_WREADY,
  265. // Master Interface Write Response Channel ports.
  266. // This signal indicates the status of the write transaction.
  267. input wire [ : ] M_AXI_BRESP,
  268. // Write response valid.
  269. // This signal indicates that the channel is signaling a valid write response
  270. input wire M_AXI_BVALID,
  271. // Response ready. This signal indicates that the master can accept a write response.
  272. output wire M_AXI_BREADY,
  273. // Master Interface Read Address Channel ports. Read address (issued by master)
  274. output wire [C_M_AXI_ADDR_WIDTH- : ] M_AXI_ARADDR,
  275. // Protection type.
  276. // This signal indicates the privilege and security level of the transaction,
  277. // and whether the transaction is a data access or an instruction access.
  278. output wire [ : ] M_AXI_ARPROT,
  279. // Read address valid.
  280. // This signal indicates that the channel is signaling valid read address and control information.
  281. output wire M_AXI_ARVALID,
  282. // Read address ready.
  283. // This signal indicates that the slave is ready to accept an address and associated control signals.
  284. input wire M_AXI_ARREADY,
  285. // Master Interface Read Data Channel ports. Read data (issued by slave)
  286. input wire [C_M_AXI_DATA_WIDTH- : ] M_AXI_RDATA,
  287. // Read response. This signal indicates the status of the read transfer.
  288. input wire [ : ] M_AXI_RRESP,
  289. // Read valid. This signal indicates that the channel is signaling the required read data.
  290. input wire M_AXI_RVALID,
  291. // Read ready. This signal indicates that the master can accept the read data and response information.
  292. output wire M_AXI_RREADY
  293. );
  294.  
  295. // function called clogb2 that returns an integer which has the
  296. // value of the ceiling of the log base 2
  297.  
  298. function integer clogb2 (input integer bit_depth);
  299. begin
  300. for(clogb2=; bit_depth>; clogb2=clogb2+)
  301. bit_depth = bit_depth >> ;
  302. end
  303. endfunction
  304.  
  305. // TRANS_NUM_BITS is the width of the index counter for
  306. // number of write or read transaction.
  307. localparam integer TRANS_NUM_BITS = clogb2(C_M_TRANSACTIONS_NUM-);
  308.  
  309. // Example State machine to initialize counter, initialize write transactions,
  310. // initialize read transactions and comparison of read data with the
  311. // written data words.
  312. parameter [:] IDLE = 'b00, // This state initiates AXI4Lite transaction
  313. // after the state machine changes state to INIT_WRITE
  314. // when there is 0 to 1 transition on INIT_AXI_TXN
  315. INIT_WRITE = 'b01, // This state initializes write transaction,
  316. // once writes are done, the state machine
  317. // changes state to INIT_READ
  318. INIT_READ = 'b10, // This state initializes read transaction
  319. // once reads are done, the state machine
  320. // changes state to INIT_COMPARE
  321. INIT_COMPARE = 'b11; // This state issues the status of comparison
  322. // of the written data with the read data
  323.  
  324. reg [:] mst_exec_state;
  325.  
  326. // AXI4LITE signals
  327. //write address valid
  328. reg axi_awvalid;
  329. //write data valid
  330. reg axi_wvalid;
  331. //read address valid
  332. reg axi_arvalid;
  333. //read data acceptance
  334. reg axi_rready;
  335. //write response acceptance
  336. reg axi_bready;
  337. //write address
  338. reg [C_M_AXI_ADDR_WIDTH- : ] axi_awaddr;
  339. //write data
  340. reg [C_M_AXI_DATA_WIDTH- : ] axi_wdata;
  341. //read addresss
  342. reg [C_M_AXI_ADDR_WIDTH- : ] axi_araddr;
  343. //Asserts when there is a write response error
  344. wire write_resp_error;
  345. //Asserts when there is a read response error
  346. wire read_resp_error;
  347. //A pulse to initiate a write transaction
  348. reg start_single_write;
  349. //A pulse to initiate a read transaction
  350. reg start_single_read;
  351. //Asserts when a single beat write transaction is issued and remains asserted till the completion of write trasaction.
  352. reg write_issued;
  353. //Asserts when a single beat read transaction is issued and remains asserted till the completion of read trasaction.
  354. reg read_issued;
  355. //flag that marks the completion of write trasactions. The number of write transaction is user selected by the parameter C_M_TRANSACTIONS_NUM.
  356. reg writes_done;
  357. //flag that marks the completion of read trasactions. The number of read transaction is user selected by the parameter C_M_TRANSACTIONS_NUM
  358. reg reads_done;
  359. //The error register is asserted when any of the write response error, read response error or the data mismatch flags are asserted.
  360. reg error_reg;
  361. //index counter to track the number of write transaction issued
  362. reg [TRANS_NUM_BITS : ] write_index;
  363. //index counter to track the number of read transaction issued
  364. reg [TRANS_NUM_BITS : ] read_index;
  365. //Expected read data used to compare with the read data.
  366. reg [C_M_AXI_DATA_WIDTH- : ] expected_rdata;
  367. //Flag marks the completion of comparison of the read data with the expected read data
  368. reg compare_done;
  369. //This flag is asserted when there is a mismatch of the read data with the expected read data.
  370. reg read_mismatch;
  371. //Flag is asserted when the write index reaches the last write transction number
  372. reg last_write;
  373. //Flag is asserted when the read index reaches the last read transction number
  374. reg last_read;
  375. reg init_txn_ff;
  376. reg init_txn_ff2;
  377. reg init_txn_edge;
  378. wire init_txn_pulse;
  379.  
  380. // I/O Connections assignments
  381.  
  382. //Adding the offset address to the base addr of the slave
  383. assign M_AXI_AWADDR = C_M_TARGET_SLAVE_BASE_ADDR + axi_awaddr;
  384. //AXI 4 write data
  385. assign M_AXI_WDATA = axi_wdata;
  386. assign M_AXI_AWPROT = 'b000;
  387. assign M_AXI_AWVALID = axi_awvalid;
  388. //Write Data(W)
  389. assign M_AXI_WVALID = axi_wvalid;
  390. //Set all byte strobes in this example
  391. assign M_AXI_WSTRB = 'b1111;
  392. //Write Response (B)
  393. assign M_AXI_BREADY = axi_bready;
  394. //Read Address (AR)
  395. assign M_AXI_ARADDR = C_M_TARGET_SLAVE_BASE_ADDR + axi_araddr;
  396. assign M_AXI_ARVALID = axi_arvalid;
  397. assign M_AXI_ARPROT = 'b001;
  398. //Read and Read Response (R)
  399. assign M_AXI_RREADY = axi_rready;
  400. //Example design I/O
  401. assign TXN_DONE = compare_done;
  402. assign init_txn_pulse = (!init_txn_ff2) && init_txn_ff;
  403.  
  404. //Generate a pulse to initiate AXI transaction.
  405. always @(posedge M_AXI_ACLK)
  406. begin
  407. // Initiates AXI transaction delay
  408. if (M_AXI_ARESETN == )
  409. begin
  410. init_txn_ff <= 'b0;
  411. init_txn_ff2 <= 'b0;
  412. end
  413. else
  414. begin
  415. init_txn_ff <= INIT_AXI_TXN;
  416. init_txn_ff2 <= init_txn_ff;
  417. end
  418. end
  419.  
  420. //--------------------
  421. //Write Address Channel
  422. //--------------------
  423.  
  424. // The purpose of the write address channel is to request the address and
  425. // command information for the entire transaction. It is a single beat
  426. // of information.
  427.  
  428. // Note for this example the axi_awvalid/axi_wvalid are asserted at the same
  429. // time, and then each is deasserted independent from each other.
  430. // This is a lower-performance, but simplier control scheme.
  431.  
  432. // AXI VALID signals must be held active until accepted by the partner.
  433.  
  434. // A data transfer is accepted by the slave when a master has
  435. // VALID data and the slave acknoledges it is also READY. While the master
  436. // is allowed to generated multiple, back-to-back requests by not
  437. // deasserting VALID, this design will add rest cycle for
  438. // simplicity.
  439.  
  440. // Since only one outstanding transaction is issued by the user design,
  441. // there will not be a collision between a new request and an accepted
  442. // request on the same clock cycle.
  443.  
  444. always @(posedge M_AXI_ACLK)
  445. begin
  446. //Only VALID signals must be deasserted during reset per AXI spec
  447. //Consider inverting then registering active-low reset for higher fmax
  448. if (M_AXI_ARESETN == || init_txn_pulse == 'b1)
  449. begin
  450. axi_awvalid <= 'b0;
  451. end
  452. //Signal a new address/data command is available by user logic
  453. else
  454. begin
  455. if (start_single_write)
  456. begin
  457. axi_awvalid <= 'b1;
  458. end
  459. //Address accepted by interconnect/slave (issue of M_AXI_AWREADY by slave)
  460. else if (M_AXI_AWREADY && axi_awvalid)
  461. begin
  462. axi_awvalid <= 'b0;
  463. end
  464. end
  465. end
  466.  
  467. // start_single_write triggers a new write
  468. // transaction. write_index is a counter to
  469. // keep track with number of write transaction
  470. // issued/initiated
  471. always @(posedge M_AXI_ACLK)
  472. begin
  473. if (M_AXI_ARESETN == || init_txn_pulse == 'b1)
  474. begin
  475. write_index <= ;
  476. end
  477. // Signals a new write address/ write data is
  478. // available by user logic
  479. else if (start_single_write)
  480. begin
  481. write_index <= write_index + ;
  482. end
  483. end
  484.  
  485. //--------------------
  486. //Write Data Channel
  487. //--------------------
  488.  
  489. //The write data channel is for transfering the actual data.
  490. //The data generation is speific to the example design, and
  491. //so only the WVALID/WREADY handshake is shown here
  492.  
  493. always @(posedge M_AXI_ACLK)
  494. begin
  495. if (M_AXI_ARESETN == || init_txn_pulse == 'b1)
  496. begin
  497. axi_wvalid <= 'b0;
  498. end
  499. //Signal a new address/data command is available by user logic
  500. else if (start_single_write)
  501. begin
  502. axi_wvalid <= 'b1;
  503. end
  504. //Data accepted by interconnect/slave (issue of M_AXI_WREADY by slave)
  505. else if (M_AXI_WREADY && axi_wvalid)
  506. begin
  507. axi_wvalid <= 'b0;
  508. end
  509. end
  510.  
  511. //----------------------------
  512. //Write Response (B) Channel
  513. //----------------------------
  514.  
  515. //The write response channel provides feedback that the write has committed
  516. //to memory. BREADY will occur after both the data and the write address
  517. //has arrived and been accepted by the slave, and can guarantee that no
  518. //other accesses launched afterwards will be able to be reordered before it.
  519.  
  520. //The BRESP bit [1] is used indicate any errors from the interconnect or
  521. //slave for the entire write burst. This example will capture the error.
  522.  
  523. //While not necessary per spec, it is advisable to reset READY signals in
  524. //case of differing reset latencies between master/slave.
  525.  
  526. always @(posedge M_AXI_ACLK)
  527. begin
  528. if (M_AXI_ARESETN == || init_txn_pulse == 'b1)
  529. begin
  530. axi_bready <= 'b0;
  531. end
  532. // accept/acknowledge bresp with axi_bready by the master
  533. // when M_AXI_BVALID is asserted by slave
  534. else if (M_AXI_BVALID && ~axi_bready)
  535. begin
  536. axi_bready <= 'b1;
  537. end
  538. // deassert after one clock cycle
  539. else if (axi_bready)
  540. begin
  541. axi_bready <= 'b0;
  542. end
  543. // retain the previous value
  544. else
  545. axi_bready <= axi_bready;
  546. end
  547.  
  548. //Flag write errors
  549. assign write_resp_error = (axi_bready & M_AXI_BVALID & M_AXI_BRESP[]);
  550.  
  551. //----------------------------
  552. //Read Address Channel
  553. //----------------------------
  554.  
  555. //start_single_read triggers a new read transaction. read_index is a counter to
  556. //keep track with number of read transaction issued/initiated
  557.  
  558. always @(posedge M_AXI_ACLK)
  559. begin
  560. if (M_AXI_ARESETN == || init_txn_pulse == 'b1)
  561. begin
  562. read_index <= ;
  563. end
  564. // Signals a new read address is
  565. // available by user logic
  566. else if (start_single_read)
  567. begin
  568. read_index <= read_index + ;
  569. end
  570. end
  571.  
  572. // A new axi_arvalid is asserted when there is a valid read address
  573. // available by the master. start_single_read triggers a new read
  574. // transaction
  575. always @(posedge M_AXI_ACLK)
  576. begin
  577. if (M_AXI_ARESETN == || init_txn_pulse == 'b1)
  578. begin
  579. axi_arvalid <= 'b0;
  580. end
  581. //Signal a new read address command is available by user logic
  582. else if (start_single_read)
  583. begin
  584. axi_arvalid <= 'b1;
  585. end
  586. //RAddress accepted by interconnect/slave (issue of M_AXI_ARREADY by slave)
  587. else if (M_AXI_ARREADY && axi_arvalid)
  588. begin
  589. axi_arvalid <= 'b0;
  590. end
  591. // retain the previous value
  592. end
  593.  
  594. //--------------------------------
  595. //Read Data (and Response) Channel
  596. //--------------------------------
  597.  
  598. //The Read Data channel returns the results of the read request
  599. //The master will accept the read data by asserting axi_rready
  600. //when there is a valid read data available.
  601. //While not necessary per spec, it is advisable to reset READY signals in
  602. //case of differing reset latencies between master/slave.
  603.  
  604. always @(posedge M_AXI_ACLK)
  605. begin
  606. if (M_AXI_ARESETN == || init_txn_pulse == 'b1)
  607. begin
  608. axi_rready <= 'b0;
  609. end
  610. // accept/acknowledge rdata/rresp with axi_rready by the master
  611. // when M_AXI_RVALID is asserted by slave
  612. else if (M_AXI_RVALID && ~axi_rready)
  613. begin
  614. axi_rready <= 'b1;
  615. end
  616. // deassert after one clock cycle
  617. else if (axi_rready)
  618. begin
  619. axi_rready <= 'b0;
  620. end
  621. // retain the previous value
  622. end
  623.  
  624. //Flag write errors
  625. assign read_resp_error = (axi_rready & M_AXI_RVALID & M_AXI_RRESP[]);
  626.  
  627. //--------------------------------
  628. //User Logic
  629. //--------------------------------
  630.  
  631. //Address/Data Stimulus
  632.  
  633. //Address/data pairs for this example. The read and write values should
  634. //match.
  635. //Modify these as desired for different address patterns.
  636.  
  637. //Write Addresses
  638. always @(posedge M_AXI_ACLK)
  639. begin
  640. if (M_AXI_ARESETN == || init_txn_pulse == 'b1)
  641. begin
  642. axi_awaddr <= ;
  643. end
  644. // Signals a new write address/ write data is
  645. // available by user logic
  646. else if (M_AXI_AWREADY && axi_awvalid)
  647. begin
  648. axi_awaddr <= axi_awaddr + 'h00000004;
  649.  
  650. end
  651. end
  652.  
  653. // Write data generation
  654. always @(posedge M_AXI_ACLK)
  655. begin
  656. if (M_AXI_ARESETN == || init_txn_pulse == 'b1 )
  657. begin
  658. axi_wdata <= C_M_START_DATA_VALUE;
  659. end
  660. // Signals a new write address/ write data is
  661. // available by user logic
  662. else if (M_AXI_WREADY && axi_wvalid)
  663. begin
  664. axi_wdata <= C_M_START_DATA_VALUE + write_index;
  665. end
  666. end
  667.  
  668. //Read Addresses
  669. always @(posedge M_AXI_ACLK)
  670. begin
  671. if (M_AXI_ARESETN == || init_txn_pulse == 'b1)
  672. begin
  673. axi_araddr <= ;
  674. end
  675. // Signals a new write address/ write data is
  676. // available by user logic
  677. else if (M_AXI_ARREADY && axi_arvalid)
  678. begin
  679. axi_araddr <= axi_araddr + 'h00000004;
  680. end
  681. end
  682.  
  683. always @(posedge M_AXI_ACLK)
  684. begin
  685. if (M_AXI_ARESETN == || init_txn_pulse == 'b1)
  686. begin
  687. expected_rdata <= C_M_START_DATA_VALUE;
  688. end
  689. // Signals a new write address/ write data is
  690. // available by user logic
  691. else if (M_AXI_RVALID && axi_rready)
  692. begin
  693. expected_rdata <= C_M_START_DATA_VALUE + read_index;
  694. end
  695. end
  696. //implement master command interface state machine
  697. always @ ( posedge M_AXI_ACLK)
  698. begin
  699. if (M_AXI_ARESETN == 'b0)
  700. begin
  701. // reset condition
  702. // All the signals are assigned default values under reset condition
  703. mst_exec_state <= IDLE;
  704. start_single_write <= 'b0;
  705. write_issued <= 'b0;
  706. start_single_read <= 'b0;
  707. read_issued <= 'b0;
  708. compare_done <= 'b0;
  709. ERROR <= 'b0;
  710. end
  711. else
  712. begin
  713. // state transition
  714. case (mst_exec_state)
  715.  
  716. IDLE:
  717. // This state is responsible to initiate
  718. // AXI transaction when init_txn_pulse is asserted
  719. if ( init_txn_pulse == 'b1 )
  720. begin
  721. mst_exec_state <= INIT_WRITE;
  722. ERROR <= 'b0;
  723. compare_done <= 'b0;
  724. end
  725. else
  726. begin
  727. mst_exec_state <= IDLE;
  728. end
  729.  
  730. INIT_WRITE:
  731. // This state is responsible to issue start_single_write pulse to
  732. // initiate a write transaction. Write transactions will be
  733. // issued until last_write signal is asserted.
  734. // write controller
  735. if (writes_done)
  736. begin
  737. mst_exec_state <= INIT_READ;//
  738. end
  739. else
  740. begin
  741. mst_exec_state <= INIT_WRITE;
  742.  
  743. if (~axi_awvalid && ~axi_wvalid && ~M_AXI_BVALID && ~last_write && ~start_single_write && ~write_issued)
  744. begin
  745. start_single_write <= 'b1;
  746. write_issued <= 'b1;
  747. end
  748. else if (axi_bready)
  749. begin
  750. write_issued <= 'b0;
  751. end
  752. else
  753. begin
  754. start_single_write <= 'b0; //Negate to generate a pulse
  755. end
  756. end
  757.  
  758. INIT_READ:
  759. // This state is responsible to issue start_single_read pulse to
  760. // initiate a read transaction. Read transactions will be
  761. // issued until last_read signal is asserted.
  762. // read controller
  763. if (reads_done)
  764. begin
  765. mst_exec_state <= INIT_COMPARE;
  766. end
  767. else
  768. begin
  769. mst_exec_state <= INIT_READ;
  770.  
  771. if (~axi_arvalid && ~M_AXI_RVALID && ~last_read && ~start_single_read && ~read_issued)
  772. begin
  773. start_single_read <= 'b1;
  774. read_issued <= 'b1;
  775. end
  776. else if (axi_rready)
  777. begin
  778. read_issued <= 'b0;
  779. end
  780. else
  781. begin
  782. start_single_read <= 'b0; //Negate to generate a pulse
  783. end
  784. end
  785.  
  786. INIT_COMPARE:
  787. begin
  788. // This state is responsible to issue the state of comparison
  789. // of written data with the read data. If no error flags are set,
  790. // compare_done signal will be asseted to indicate success.
  791. ERROR <= error_reg;
  792. mst_exec_state <= IDLE;
  793. compare_done <= 'b1;
  794. end
  795. default :
  796. begin
  797. mst_exec_state <= IDLE;
  798. end
  799. endcase
  800. end
  801. end //MASTER_EXECUTION_PROC
  802.  
  803. //Terminal write count
  804.  
  805. always @(posedge M_AXI_ACLK)
  806. begin
  807. if (M_AXI_ARESETN == || init_txn_pulse == 'b1)
  808. last_write <= 'b0;
  809.  
  810. //The last write should be associated with a write address ready response
  811. else if ((write_index == C_M_TRANSACTIONS_NUM) && M_AXI_AWREADY)
  812. last_write <= 'b1;
  813. else
  814. last_write <= last_write;
  815. end
  816.  
  817. //Check for last write completion.
  818.  
  819. //This logic is to qualify the last write count with the final write
  820. //response. This demonstrates how to confirm that a write has been
  821. //committed.
  822.  
  823. always @(posedge M_AXI_ACLK)
  824. begin
  825. if (M_AXI_ARESETN == || init_txn_pulse == 'b1)
  826. writes_done <= 'b0;
  827.  
  828. //The writes_done should be associated with a bready response
  829. else if (last_write && M_AXI_BVALID && axi_bready)
  830. writes_done <= 'b1;
  831. else
  832. writes_done <= writes_done;
  833. end
  834.  
  835. //------------------
  836. //Read example
  837. //------------------
  838.  
  839. //Terminal Read Count
  840.  
  841. always @(posedge M_AXI_ACLK)
  842. begin
  843. if (M_AXI_ARESETN == || init_txn_pulse == 'b1)
  844. last_read <= 'b0;
  845.  
  846. //The last read should be associated with a read address ready response
  847. else if ((read_index == C_M_TRANSACTIONS_NUM) && (M_AXI_ARREADY) )
  848. last_read <= 'b1;
  849. else
  850. last_read <= last_read;
  851. end
  852.  
  853. /*
  854. Check for last read completion.
  855.  
  856. This logic is to qualify the last read count with the final read
  857. response/data.
  858. */
  859. always @(posedge M_AXI_ACLK)
  860. begin
  861. if (M_AXI_ARESETN == || init_txn_pulse == 'b1)
  862. reads_done <= 'b0;
  863.  
  864. //The reads_done should be associated with a read ready response
  865. else if (last_read && M_AXI_RVALID && axi_rready)
  866. reads_done <= 'b1;
  867. else
  868. reads_done <= reads_done;
  869. end
  870.  
  871. //-----------------------------
  872. //Example design error register
  873. //-----------------------------
  874.  
  875. //Data Comparison
  876. always @(posedge M_AXI_ACLK)
  877. begin
  878. if (M_AXI_ARESETN == || init_txn_pulse == 'b1)
  879. read_mismatch <= 'b0;
  880.  
  881. //The read data when available (on axi_rready) is compared with the expected data
  882. else if ((M_AXI_RVALID && axi_rready) && (M_AXI_RDATA != expected_rdata))
  883. read_mismatch <= 'b1;
  884. else
  885. read_mismatch <= read_mismatch;
  886. end
  887.  
  888. // Register and hold any data mismatches, or read/write interface errors
  889. always @(posedge M_AXI_ACLK)
  890. begin
  891. if (M_AXI_ARESETN == || init_txn_pulse == 'b1)
  892. error_reg <= 'b0;
  893.  
  894. //Capture any error types
  895. else if (read_mismatch || write_resp_error || read_resp_error)
  896. error_reg <= 'b1;
  897. else
  898. error_reg <= error_reg;
  899. end
  900. // Add user logic here
  901.  
  902. // User logic ends
  903.  
  904. endmodule
  905. 附录4:底层模块Slave 顶层源代码:
  906.  
  907. `timescale ns / ps
  908. module axi_ip_slave_v1_0 #
  909. (
  910. // Users to add parameters here
  911. // User parameters ends
  912. // Do not modify the parameters beyond this line
  913.  
  914. // Parameters of Axi Slave Bus Interface S00_AXI
  915. parameter integer C_S00_AXI_DATA_WIDTH = ,
  916. parameter integer C_S00_AXI_ADDR_WIDTH =
  917. )
  918. (
  919. // Users to add ports here
  920. // User ports ends
  921. // Do not modify the ports beyond this line
  922. // Ports of Axi Slave Bus Interface S00_AXI
  923. input wire s00_axi_aclk,
  924. input wire s00_axi_aresetn,
  925. input wire [C_S00_AXI_ADDR_WIDTH- : ] s00_axi_awaddr,
  926. input wire [ : ] s00_axi_awprot,
  927. input wire s00_axi_awvalid,
  928. output wire s00_axi_awready,
  929. input wire [C_S00_AXI_DATA_WIDTH- : ] s00_axi_wdata,
  930. input wire [(C_S00_AXI_DATA_WIDTH/)- : ] s00_axi_wstrb,
  931. input wire s00_axi_wvalid,
  932. output wire s00_axi_wready,
  933. output wire [ : ] s00_axi_bresp,
  934. output wire s00_axi_bvalid,
  935. input wire s00_axi_bready,
  936. input wire [C_S00_AXI_ADDR_WIDTH- : ] s00_axi_araddr,
  937. input wire [ : ] s00_axi_arprot,
  938. input wire s00_axi_arvalid,
  939. output wire s00_axi_arready,
  940. output wire [C_S00_AXI_DATA_WIDTH- : ] s00_axi_rdata,
  941. output wire [ : ] s00_axi_rresp,
  942. output wire s00_axi_rvalid,
  943. input wire s00_axi_rready
  944. );
  945. // Instantiation of Axi Bus Interface S00_AXI
  946. axi_ip_slave_v1_0_S00_AXI # (
  947. .C_S_AXI_DATA_WIDTH(C_S00_AXI_DATA_WIDTH),
  948. .C_S_AXI_ADDR_WIDTH(C_S00_AXI_ADDR_WIDTH)
  949. ) axi_ip_slave_v1_0_S00_AXI_inst (
  950. .S_AXI_ACLK(s00_axi_aclk),
  951. .S_AXI_ARESETN(s00_axi_aresetn),
  952. .S_AXI_AWADDR(s00_axi_awaddr),
  953. .S_AXI_AWPROT(s00_axi_awprot),
  954. .S_AXI_AWVALID(s00_axi_awvalid),
  955. .S_AXI_AWREADY(s00_axi_awready),
  956. .S_AXI_WDATA(s00_axi_wdata),
  957. .S_AXI_WSTRB(s00_axi_wstrb),
  958. .S_AXI_WVALID(s00_axi_wvalid),
  959. .S_AXI_WREADY(s00_axi_wready),
  960. .S_AXI_BRESP(s00_axi_bresp),
  961. .S_AXI_BVALID(s00_axi_bvalid),
  962. .S_AXI_BREADY(s00_axi_bready),
  963. .S_AXI_ARADDR(s00_axi_araddr),
  964. .S_AXI_ARPROT(s00_axi_arprot),
  965. .S_AXI_ARVALID(s00_axi_arvalid),
  966. .S_AXI_ARREADY(s00_axi_arready),
  967. .S_AXI_RDATA(s00_axi_rdata),
  968. .S_AXI_RRESP(s00_axi_rresp),
  969. .S_AXI_RVALID(s00_axi_rvalid),
  970. .S_AXI_RREADY(s00_axi_rready)
  971. );
  972.  
  973. // Add user logic here
  974.  
  975. // User logic ends
  976.  
  977. endmodule
  978.  
  979. 附录5:底层模块Slave 底层源代码:
  980.  
  981. ////////此处需要说明一下:做的slave核时,寄存器个数为32,生成核后,地址宽度为7,为什么呢?因为一个寄存器为32位,4个字节,所以一个寄存器占用4个地址。2^7=128个地址,一个寄存器占4个。
  982.  
  983. `timescale ns / ps
  984.  
  985. module axi_ip_slave_v1_0_S00_AXI #
  986. (
  987. // Users to add parameters here
  988.  
  989. // User parameters ends
  990. // Do not modify the parameters beyond this line
  991.  
  992. // Width of S_AXI data bus
  993. parameter integer C_S_AXI_DATA_WIDTH = ,
  994. // Width of S_AXI address bus
  995. parameter integer C_S_AXI_ADDR_WIDTH =
  996. )
  997. (
  998. // Users to add ports here
  999.  
  1000. // User ports ends
  1001. // Do not modify the ports beyond this line
  1002.  
  1003. // Global Clock Signal
  1004. input wire S_AXI_ACLK,
  1005. // Global Reset Signal. This Signal is Active LOW
  1006. input wire S_AXI_ARESETN,
  1007. // Write address (issued by master, acceped by Slave)
  1008. input wire [C_S_AXI_ADDR_WIDTH- : ] S_AXI_AWADDR,
  1009. // Write channel Protection type. This signal indicates the
  1010. // privilege and security level of the transaction, and whether
  1011. // the transaction is a data access or an instruction access.
  1012. input wire [ : ] S_AXI_AWPROT,
  1013. // Write address valid. This signal indicates that the master signaling
  1014. // valid write address and control information.
  1015. input wire S_AXI_AWVALID,
  1016. // Write address ready. This signal indicates that the slave is ready
  1017. // to accept an address and associated control signals.
  1018. output wire S_AXI_AWREADY,
  1019. // Write data (issued by master, acceped by Slave)
  1020. input wire [C_S_AXI_DATA_WIDTH- : ] S_AXI_WDATA,
  1021. // Write strobes. This signal indicates which byte lanes hold
  1022. // valid data. There is one write strobe bit for each eight
  1023. // bits of the write data bus.
  1024. input wire [(C_S_AXI_DATA_WIDTH/)- : ] S_AXI_WSTRB,
  1025. // Write valid. This signal indicates that valid write
  1026. // data and strobes are available.
  1027. input wire S_AXI_WVALID,
  1028. // Write ready. This signal indicates that the slave
  1029. // can accept the write data.
  1030. output wire S_AXI_WREADY,
  1031. // Write response. This signal indicates the status
  1032. // of the write transaction.
  1033. output wire [ : ] S_AXI_BRESP,
  1034. // Write response valid. This signal indicates that the channel
  1035. // is signaling a valid write response.
  1036. output wire S_AXI_BVALID,
  1037. // Response ready. This signal indicates that the master
  1038. // can accept a write response.
  1039. input wire S_AXI_BREADY,
  1040. // Read address (issued by master, acceped by Slave)
  1041. input wire [C_S_AXI_ADDR_WIDTH- : ] S_AXI_ARADDR,
  1042. // Protection type. This signal indicates the privilege
  1043. // and security level of the transaction, and whether the
  1044. // transaction is a data access or an instruction access.
  1045. input wire [ : ] S_AXI_ARPROT,
  1046. // Read address valid. This signal indicates that the channel
  1047. // is signaling valid read address and control information.
  1048. input wire S_AXI_ARVALID,
  1049. // Read address ready. This signal indicates that the slave is
  1050. // ready to accept an address and associated control signals.
  1051. output wire S_AXI_ARREADY,
  1052. // Read data (issued by slave)
  1053. output wire [C_S_AXI_DATA_WIDTH- : ] S_AXI_RDATA,
  1054. // Read response. This signal indicates the status of the
  1055. // read transfer.
  1056. output wire [ : ] S_AXI_RRESP,
  1057. // Read valid. This signal indicates that the channel is
  1058. // signaling the required read data.
  1059. output wire S_AXI_RVALID,
  1060. // Read ready. This signal indicates that the master can
  1061. // accept the read data and response information.
  1062. input wire S_AXI_RREADY
  1063. );
  1064.  
  1065. // AXI4LITE signals
  1066. reg [C_S_AXI_ADDR_WIDTH- : ] axi_awaddr;
  1067. reg axi_awready;
  1068. reg axi_wready;
  1069. reg [ : ] axi_bresp;
  1070. reg axi_bvalid;
  1071. reg [C_S_AXI_ADDR_WIDTH- : ] axi_araddr;
  1072. reg axi_arready;
  1073. reg [C_S_AXI_DATA_WIDTH- : ] axi_rdata;
  1074. reg [ : ] axi_rresp;
  1075. reg axi_rvalid;
  1076.  
  1077. // Example-specific design signals
  1078. // local parameter for addressing 32 bit / 64 bit C_S_AXI_DATA_WIDTH
  1079. // ADDR_LSB is used for addressing 32/64 bit registers/memories
  1080. // ADDR_LSB = 2 for 32 bits (n downto 2)
  1081. // ADDR_LSB = 3 for 64 bits (n downto 3)
  1082. localparam integer ADDR_LSB = (C_S_AXI_DATA_WIDTH/) + ;
  1083. localparam integer OPT_MEM_ADDR_BITS = ;
  1084. //----------------------------------------------
  1085. //-- Signals for user logic register space example
  1086. //------------------------------------------------
  1087. //-- Number of Slave Registers 32
  1088. reg [C_S_AXI_DATA_WIDTH-:] slv_reg0;
  1089. reg [C_S_AXI_DATA_WIDTH-:] slv_reg1;
  1090. reg [C_S_AXI_DATA_WIDTH-:] slv_reg2;
  1091. reg [C_S_AXI_DATA_WIDTH-:] slv_reg3;
  1092. reg [C_S_AXI_DATA_WIDTH-:] slv_reg4;
  1093. reg [C_S_AXI_DATA_WIDTH-:] slv_reg5;
  1094. reg [C_S_AXI_DATA_WIDTH-:] slv_reg6;
  1095. reg [C_S_AXI_DATA_WIDTH-:] slv_reg7;
  1096. reg [C_S_AXI_DATA_WIDTH-:] slv_reg8;
  1097. reg [C_S_AXI_DATA_WIDTH-:] slv_reg9;
  1098. reg [C_S_AXI_DATA_WIDTH-:] slv_reg10;
  1099. reg [C_S_AXI_DATA_WIDTH-:] slv_reg11;
  1100. reg [C_S_AXI_DATA_WIDTH-:] slv_reg12;
  1101. reg [C_S_AXI_DATA_WIDTH-:] slv_reg13;
  1102. reg [C_S_AXI_DATA_WIDTH-:] slv_reg14;
  1103. reg [C_S_AXI_DATA_WIDTH-:] slv_reg15;
  1104. reg [C_S_AXI_DATA_WIDTH-:] slv_reg16;
  1105. reg [C_S_AXI_DATA_WIDTH-:] slv_reg17;
  1106. reg [C_S_AXI_DATA_WIDTH-:] slv_reg18;
  1107. reg [C_S_AXI_DATA_WIDTH-:] slv_reg19;
  1108. reg [C_S_AXI_DATA_WIDTH-:] slv_reg20;
  1109. reg [C_S_AXI_DATA_WIDTH-:] slv_reg21;
  1110. reg [C_S_AXI_DATA_WIDTH-:] slv_reg22;
  1111. reg [C_S_AXI_DATA_WIDTH-:] slv_reg23;
  1112. reg [C_S_AXI_DATA_WIDTH-:] slv_reg24;
  1113. reg [C_S_AXI_DATA_WIDTH-:] slv_reg25;
  1114. reg [C_S_AXI_DATA_WIDTH-:] slv_reg26;
  1115. reg [C_S_AXI_DATA_WIDTH-:] slv_reg27;
  1116. reg [C_S_AXI_DATA_WIDTH-:] slv_reg28;
  1117. reg [C_S_AXI_DATA_WIDTH-:] slv_reg29;
  1118. reg [C_S_AXI_DATA_WIDTH-:] slv_reg30;
  1119. reg [C_S_AXI_DATA_WIDTH-:] slv_reg31;
  1120. wire slv_reg_rden;
  1121. wire slv_reg_wren;
  1122. reg [C_S_AXI_DATA_WIDTH-:] reg_data_out;
  1123. integer byte_index;
  1124.  
  1125. // I/O Connections assignments
  1126.  
  1127. assign S_AXI_AWREADY = axi_awready;
  1128. assign S_AXI_WREADY = axi_wready;
  1129. assign S_AXI_BRESP = axi_bresp;
  1130. assign S_AXI_BVALID = axi_bvalid;
  1131. assign S_AXI_ARREADY = axi_arready;
  1132. assign S_AXI_RDATA = axi_rdata;
  1133. assign S_AXI_RRESP = axi_rresp;
  1134. assign S_AXI_RVALID = axi_rvalid;
  1135. // Implement axi_awready generation
  1136. // axi_awready is asserted for one S_AXI_ACLK clock cycle when both
  1137. // S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_awready is
  1138. // de-asserted when reset is low.
  1139.  
  1140. always @( posedge S_AXI_ACLK )
  1141. begin
  1142. if ( S_AXI_ARESETN == 'b0 )
  1143. begin
  1144. axi_awready <= 'b0;
  1145. end
  1146. else
  1147. begin
  1148. if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID)
  1149. begin
  1150. // slave is ready to accept write address when
  1151. // there is a valid write address and write data
  1152. // on the write address and data bus. This design
  1153. // expects no outstanding transactions.
  1154. axi_awready <= 'b1;
  1155. end
  1156. else
  1157. begin
  1158. axi_awready <= 'b0;
  1159. end
  1160. end
  1161. end
  1162.  
  1163. // Implement axi_awaddr latching
  1164. // This process is used to latch the address when both
  1165. // S_AXI_AWVALID and S_AXI_WVALID are valid.
  1166.  
  1167. always @( posedge S_AXI_ACLK )
  1168. begin
  1169. if ( S_AXI_ARESETN == 'b0 )
  1170. begin
  1171. axi_awaddr <= ;
  1172. end
  1173. else
  1174. begin
  1175. if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID)
  1176. begin
  1177. // Write Address latching
  1178. axi_awaddr <= S_AXI_AWADDR;
  1179. end
  1180. end
  1181. end
  1182.  
  1183. // Implement axi_wready generation
  1184. // axi_wready is asserted for one S_AXI_ACLK clock cycle when both
  1185. // S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_wready is
  1186. // de-asserted when reset is low.
  1187.  
  1188. always @( posedge S_AXI_ACLK )
  1189. begin
  1190. if ( S_AXI_ARESETN == 'b0 )
  1191. begin
  1192. axi_wready <= 'b0;
  1193. end
  1194. else
  1195. begin
  1196. if (~axi_wready && S_AXI_WVALID && S_AXI_AWVALID)
  1197. begin
  1198. // slave is ready to accept write data when
  1199. // there is a valid write address and write data
  1200. // on the write address and data bus. This design
  1201. // expects no outstanding transactions.
  1202. axi_wready <= 'b1;
  1203. end
  1204. else
  1205. begin
  1206. axi_wready <= 'b0;
  1207. end
  1208. end
  1209. end
  1210.  
  1211. // Implement memory mapped register select and write logic generation
  1212. // The write data is accepted and written to memory mapped registers when
  1213. // axi_awready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. Write strobes are used to
  1214. // select byte enables of slave registers while writing.
  1215. // These registers are cleared when reset (active low) is applied.
  1216. // Slave register write enable is asserted when valid address and data are available
  1217. // and the slave is ready to accept the write address and write data.
  1218. assign slv_reg_wren = axi_wready && S_AXI_WVALID && axi_awready && S_AXI_AWVALID;
  1219.  
  1220. always @( posedge S_AXI_ACLK )
  1221. begin
  1222. if ( S_AXI_ARESETN == 'b0 )
  1223. begin
  1224. slv_reg0 <= ;
  1225. slv_reg1 <= ;
  1226. slv_reg2 <= ;
  1227. slv_reg3 <= ;
  1228. slv_reg4 <= ;
  1229. slv_reg5 <= ;
  1230. slv_reg6 <= ;
  1231. slv_reg7 <= ;
  1232. slv_reg8 <= ;
  1233. slv_reg9 <= ;
  1234. slv_reg10 <= ;
  1235. slv_reg11 <= ;
  1236. slv_reg12 <= ;
  1237. slv_reg13 <= ;
  1238. slv_reg14 <= ;
  1239. slv_reg15 <= ;
  1240. slv_reg16 <= ;
  1241. slv_reg17 <= ;
  1242. slv_reg18 <= ;
  1243. slv_reg19 <= ;
  1244. slv_reg20 <= ;
  1245. slv_reg21 <= ;
  1246. slv_reg22 <= ;
  1247. slv_reg23 <= ;
  1248. slv_reg24 <= ;
  1249. slv_reg25 <= ;
  1250. slv_reg26 <= ;
  1251. slv_reg27 <= ;
  1252. slv_reg28 <= ;
  1253. slv_reg29 <= ;
  1254. slv_reg30 <= ;
  1255. slv_reg31 <= ;
  1256. end
  1257. else begin
  1258. if (slv_reg_wren)
  1259. begin
  1260. case ( axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
  1261. 'h00:
  1262. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1263. if ( S_AXI_WSTRB[byte_index] == ) begin
  1264. // Respective byte enables are asserted as per write strobes
  1265. // Slave register 0
  1266. slv_reg0[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1267. end
  1268. 'h01:
  1269. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1270. if ( S_AXI_WSTRB[byte_index] == ) begin
  1271. // Respective byte enables are asserted as per write strobes
  1272. // Slave register 1
  1273. slv_reg1[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1274. end
  1275. 'h02:
  1276. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1277. if ( S_AXI_WSTRB[byte_index] == ) begin
  1278. // Respective byte enables are asserted as per write strobes
  1279. // Slave register 2
  1280. slv_reg2[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1281. end
  1282. 'h03:
  1283. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1284. if ( S_AXI_WSTRB[byte_index] == ) begin
  1285. // Respective byte enables are asserted as per write strobes
  1286. // Slave register 3
  1287. slv_reg3[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1288. end
  1289. 'h04:
  1290. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1291. if ( S_AXI_WSTRB[byte_index] == ) begin
  1292. // Respective byte enables are asserted as per write strobes
  1293. // Slave register 4
  1294. slv_reg4[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1295. end
  1296. 'h05:
  1297. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1298. if ( S_AXI_WSTRB[byte_index] == ) begin
  1299. // Respective byte enables are asserted as per write strobes
  1300. // Slave register 5
  1301. slv_reg5[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1302. end
  1303. 'h06:
  1304. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1305. if ( S_AXI_WSTRB[byte_index] == ) begin
  1306. // Respective byte enables are asserted as per write strobes
  1307. // Slave register 6
  1308. slv_reg6[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1309. end
  1310. 'h07:
  1311. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1312. if ( S_AXI_WSTRB[byte_index] == ) begin
  1313. // Respective byte enables are asserted as per write strobes
  1314. // Slave register 7
  1315. slv_reg7[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1316. end
  1317. 'h08:
  1318. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1319. if ( S_AXI_WSTRB[byte_index] == ) begin
  1320. // Respective byte enables are asserted as per write strobes
  1321. // Slave register 8
  1322. slv_reg8[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1323. end
  1324. 'h09:
  1325. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1326. if ( S_AXI_WSTRB[byte_index] == ) begin
  1327. // Respective byte enables are asserted as per write strobes
  1328. // Slave register 9
  1329. slv_reg9[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1330. end
  1331. 'h0A:
  1332. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1333. if ( S_AXI_WSTRB[byte_index] == ) begin
  1334. // Respective byte enables are asserted as per write strobes
  1335. // Slave register 10
  1336. slv_reg10[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1337. end
  1338. 'h0B:
  1339. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1340. if ( S_AXI_WSTRB[byte_index] == ) begin
  1341. // Respective byte enables are asserted as per write strobes
  1342. // Slave register 11
  1343. slv_reg11[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1344. end
  1345. 'h0C:
  1346. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1347. if ( S_AXI_WSTRB[byte_index] == ) begin
  1348. // Respective byte enables are asserted as per write strobes
  1349. // Slave register 12
  1350. slv_reg12[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1351. end
  1352. 'h0D:
  1353. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1354. if ( S_AXI_WSTRB[byte_index] == ) begin
  1355. // Respective byte enables are asserted as per write strobes
  1356. // Slave register 13
  1357. slv_reg13[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1358. end
  1359. 'h0E:
  1360. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1361. if ( S_AXI_WSTRB[byte_index] == ) begin
  1362. // Respective byte enables are asserted as per write strobes
  1363. // Slave register 14
  1364. slv_reg14[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1365. end
  1366. 'h0F:
  1367. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1368. if ( S_AXI_WSTRB[byte_index] == ) begin
  1369. // Respective byte enables are asserted as per write strobes
  1370. // Slave register 15
  1371. slv_reg15[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1372. end
  1373. 'h10:
  1374. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1375. if ( S_AXI_WSTRB[byte_index] == ) begin
  1376. // Respective byte enables are asserted as per write strobes
  1377. // Slave register 16
  1378. slv_reg16[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1379. end
  1380. 'h11:
  1381. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1382. if ( S_AXI_WSTRB[byte_index] == ) begin
  1383. // Respective byte enables are asserted as per write strobes
  1384. // Slave register 17
  1385. slv_reg17[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1386. end
  1387. 'h12:
  1388. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1389. if ( S_AXI_WSTRB[byte_index] == ) begin
  1390. // Respective byte enables are asserted as per write strobes
  1391. // Slave register 18
  1392. slv_reg18[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1393. end
  1394. 'h13:
  1395. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1396. if ( S_AXI_WSTRB[byte_index] == ) begin
  1397. // Respective byte enables are asserted as per write strobes
  1398. // Slave register 19
  1399. slv_reg19[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1400. end
  1401. 'h14:
  1402. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1403. if ( S_AXI_WSTRB[byte_index] == ) begin
  1404. // Respective byte enables are asserted as per write strobes
  1405. // Slave register 20
  1406. slv_reg20[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1407. end
  1408. 'h15:
  1409. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1410. if ( S_AXI_WSTRB[byte_index] == ) begin
  1411. // Respective byte enables are asserted as per write strobes
  1412. // Slave register 21
  1413. slv_reg21[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1414. end
  1415. 'h16:
  1416. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1417. if ( S_AXI_WSTRB[byte_index] == ) begin
  1418. // Respective byte enables are asserted as per write strobes
  1419. // Slave register 22
  1420. slv_reg22[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1421. end
  1422. 'h17:
  1423. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1424. if ( S_AXI_WSTRB[byte_index] == ) begin
  1425. // Respective byte enables are asserted as per write strobes
  1426. // Slave register 23
  1427. slv_reg23[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1428. end
  1429. 'h18:
  1430. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1431. if ( S_AXI_WSTRB[byte_index] == ) begin
  1432. // Respective byte enables are asserted as per write strobes
  1433. // Slave register 24
  1434. slv_reg24[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1435. end
  1436. 'h19:
  1437. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1438. if ( S_AXI_WSTRB[byte_index] == ) begin
  1439. // Respective byte enables are asserted as per write strobes
  1440. // Slave register 25
  1441. slv_reg25[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1442. end
  1443. 'h1A:
  1444. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1445. if ( S_AXI_WSTRB[byte_index] == ) begin
  1446. // Respective byte enables are asserted as per write strobes
  1447. // Slave register 26
  1448. slv_reg26[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1449. end
  1450. 'h1B:
  1451. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1452. if ( S_AXI_WSTRB[byte_index] == ) begin
  1453. // Respective byte enables are asserted as per write strobes
  1454. // Slave register 27
  1455. slv_reg27[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1456. end
  1457. 'h1C:
  1458. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1459. if ( S_AXI_WSTRB[byte_index] == ) begin
  1460. // Respective byte enables are asserted as per write strobes
  1461. // Slave register 28
  1462. slv_reg28[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1463. end
  1464. 'h1D:
  1465. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1466. if ( S_AXI_WSTRB[byte_index] == ) begin
  1467. // Respective byte enables are asserted as per write strobes
  1468. // Slave register 29
  1469. slv_reg29[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1470. end
  1471. 'h1E:
  1472. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1473. if ( S_AXI_WSTRB[byte_index] == ) begin
  1474. // Respective byte enables are asserted as per write strobes
  1475. // Slave register 30
  1476. slv_reg30[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1477. end
  1478. 'h1F:
  1479. for ( byte_index = ; byte_index <= (C_S_AXI_DATA_WIDTH/)-; byte_index = byte_index+ )
  1480. if ( S_AXI_WSTRB[byte_index] == ) begin
  1481. // Respective byte enables are asserted as per write strobes
  1482. // Slave register 31
  1483. slv_reg31[(byte_index*) +: ] <= S_AXI_WDATA[(byte_index*) +: ];
  1484. end
  1485. default : begin
  1486. slv_reg0 <= slv_reg0;
  1487. slv_reg1 <= slv_reg1;
  1488. slv_reg2 <= slv_reg2;
  1489. slv_reg3 <= slv_reg3;
  1490. slv_reg4 <= slv_reg4;
  1491. slv_reg5 <= slv_reg5;
  1492. slv_reg6 <= slv_reg6;
  1493. slv_reg7 <= slv_reg7;
  1494. slv_reg8 <= slv_reg8;
  1495. slv_reg9 <= slv_reg9;
  1496. slv_reg10 <= slv_reg10;
  1497. slv_reg11 <= slv_reg11;
  1498. slv_reg12 <= slv_reg12;
  1499. slv_reg13 <= slv_reg13;
  1500. slv_reg14 <= slv_reg14;
  1501. slv_reg15 <= slv_reg15;
  1502. slv_reg16 <= slv_reg16;
  1503. slv_reg17 <= slv_reg17;
  1504. slv_reg18 <= slv_reg18;
  1505. slv_reg19 <= slv_reg19;
  1506. slv_reg20 <= slv_reg20;
  1507. slv_reg21 <= slv_reg21;
  1508. slv_reg22 <= slv_reg22;
  1509. slv_reg23 <= slv_reg23;
  1510. slv_reg24 <= slv_reg24;
  1511. slv_reg25 <= slv_reg25;
  1512. slv_reg26 <= slv_reg26;
  1513. slv_reg27 <= slv_reg27;
  1514. slv_reg28 <= slv_reg28;
  1515. slv_reg29 <= slv_reg29;
  1516. slv_reg30 <= slv_reg30;
  1517. slv_reg31 <= slv_reg31;
  1518. end
  1519. endcase
  1520. end
  1521. end
  1522. end
  1523.  
  1524. // Implement write response logic generation
  1525. // The write response and response valid signals are asserted by the slave
  1526. // when axi_wready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted.
  1527. // This marks the acceptance of address and indicates the status of
  1528. // write transaction.
  1529.  
  1530. always @( posedge S_AXI_ACLK )
  1531. begin
  1532. if ( S_AXI_ARESETN == 'b0 )
  1533. begin
  1534. axi_bvalid <= ;
  1535. axi_bresp <= 'b0;
  1536. end
  1537. else
  1538. begin
  1539. if (axi_awready && S_AXI_AWVALID && ~axi_bvalid && axi_wready && S_AXI_WVALID)
  1540. begin
  1541. // indicates a valid write response is available
  1542. axi_bvalid <= 'b1;
  1543. axi_bresp <= 'b0; // 'OKAY' response
  1544. end // work error responses in future
  1545. else
  1546. begin
  1547. if (S_AXI_BREADY && axi_bvalid)
  1548. //check if bready is asserted while bvalid is high)
  1549. //(there is a possibility that bready is always asserted high)
  1550. begin
  1551. axi_bvalid <= 'b0;
  1552. end
  1553. end
  1554. end
  1555. end
  1556.  
  1557. // Implement axi_arready generation
  1558. // axi_arready is asserted for one S_AXI_ACLK clock cycle when
  1559. // S_AXI_ARVALID is asserted. axi_awready is
  1560. // de-asserted when reset (active low) is asserted.
  1561. // The read address is also latched when S_AXI_ARVALID is
  1562. // asserted. axi_araddr is reset to zero on reset assertion.
  1563.  
  1564. always @( posedge S_AXI_ACLK )
  1565. begin
  1566. if ( S_AXI_ARESETN == 'b0 )
  1567. begin
  1568. axi_arready <= 'b0;
  1569. axi_araddr <= 'b0;
  1570. end
  1571. else
  1572. begin
  1573. if (~axi_arready && S_AXI_ARVALID)
  1574. begin
  1575. // indicates that the slave has acceped the valid read address
  1576. axi_arready <= 'b1;
  1577. // Read address latching
  1578. axi_araddr <= S_AXI_ARADDR;
  1579. end
  1580. else
  1581. begin
  1582. axi_arready <= 'b0;
  1583. end
  1584. end
  1585. end
  1586.  
  1587. // Implement axi_arvalid generation
  1588. // axi_rvalid is asserted for one S_AXI_ACLK clock cycle when both
  1589. // S_AXI_ARVALID and axi_arready are asserted. The slave registers
  1590. // data are available on the axi_rdata bus at this instance. The
  1591. // assertion of axi_rvalid marks the validity of read data on the
  1592. // bus and axi_rresp indicates the status of read transaction.axi_rvalid
  1593. // is deasserted on reset (active low). axi_rresp and axi_rdata are
  1594. // cleared to zero on reset (active low).
  1595. always @( posedge S_AXI_ACLK )
  1596. begin
  1597. if ( S_AXI_ARESETN == 'b0 )
  1598. begin
  1599. axi_rvalid <= ;
  1600. axi_rresp <= ;
  1601. end
  1602. else
  1603. begin
  1604. if (axi_arready && S_AXI_ARVALID && ~axi_rvalid)
  1605. begin
  1606. // Valid read data is available at the read data bus
  1607. axi_rvalid <= 'b1;
  1608. axi_rresp <= 'b0; // 'OKAY' response
  1609. end
  1610. else if (axi_rvalid && S_AXI_RREADY)
  1611. begin
  1612. // Read data is accepted by the master
  1613. axi_rvalid <= 'b0;
  1614. end
  1615. end
  1616. end
  1617.  
  1618. // Implement memory mapped register select and read logic generation
  1619. // Slave register read enable is asserted when valid address is available
  1620. // and the slave is ready to accept the read address.
  1621. assign slv_reg_rden = axi_arready & S_AXI_ARVALID & ~axi_rvalid;
  1622. always @(*)
  1623. begin
  1624. // Address decoding for reading registers
  1625. case ( axi_araddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
  1626. 'h00 : reg_data_out <= slv_reg0;
  1627. 'h01 : reg_data_out <= slv_reg1;
  1628. 'h02 : reg_data_out <= slv_reg2;
  1629. 'h03 : reg_data_out <= slv_reg3;
  1630. 'h04 : reg_data_out <= slv_reg4;
  1631. 'h05 : reg_data_out <= slv_reg5;
  1632. 'h06 : reg_data_out <= slv_reg6;
  1633. 'h07 : reg_data_out <= slv_reg7;
  1634. 'h08 : reg_data_out <= slv_reg8;
  1635. 'h09 : reg_data_out <= slv_reg9;
  1636. 'h0A : reg_data_out <= slv_reg10;
  1637. 'h0B : reg_data_out <= slv_reg11;
  1638. 'h0C : reg_data_out <= slv_reg12;
  1639. 'h0D : reg_data_out <= slv_reg13;
  1640. 'h0E : reg_data_out <= slv_reg14;
  1641. 'h0F : reg_data_out <= slv_reg15;
  1642. 'h10 : reg_data_out <= slv_reg16;
  1643. 'h11 : reg_data_out <= slv_reg17;
  1644. 'h12 : reg_data_out <= slv_reg18;
  1645. 'h13 : reg_data_out <= slv_reg19;
  1646. 'h14 : reg_data_out <= slv_reg20;
  1647. 'h15 : reg_data_out <= slv_reg21;
  1648. 'h16 : reg_data_out <= slv_reg22;
  1649. 'h17 : reg_data_out <= slv_reg23;
  1650. 'h18 : reg_data_out <= slv_reg24;
  1651. 'h19 : reg_data_out <= slv_reg25;
  1652. 'h1A : reg_data_out <= slv_reg26;
  1653. 'h1B : reg_data_out <= slv_reg27;
  1654. 'h1C : reg_data_out <= slv_reg28;
  1655. 'h1D : reg_data_out <= slv_reg29;
  1656. 'h1E : reg_data_out <= slv_reg30;
  1657. 'h1F : reg_data_out <= slv_reg31;
  1658. default : reg_data_out <= ;
  1659. endcase
  1660. end
  1661.  
  1662. // Output register or memory read data
  1663. always @( posedge S_AXI_ACLK )
  1664. begin
  1665. if ( S_AXI_ARESETN == 'b0 )
  1666. begin
  1667. axi_rdata <= ;
  1668. end
  1669. else
  1670. begin
  1671. // When there is a valid read address (S_AXI_ARVALID) with
  1672. // acceptance of read address by the slave (axi_arready),
  1673. // output the read dada
  1674. if (slv_reg_rden)
  1675. begin
  1676. axi_rdata <= reg_data_out; // register read data
  1677. end
  1678. end
  1679. end
  1680.  
  1681. // Add user logic here
  1682. // User logic ends
  1683. endmodule
 

Zynq-PL中创建AXI Master接口IP及AXI4-Lite总线主从读写时序测试(转)的更多相关文章

  1. 每天进步一点点------SOPC的Avalon-MM IP核(一) avalon总线的信号时序

    在SOPC中自定义外设时.可以设置avalon总线的信号时序,以满足外设的要求.一般情况下,可以设为: 其中setup为read和write信号之前,address和writedata信号提前建立的时 ...

  2. Vivado设计二:zynq的PS访问PL中的自带IP核(基于zybo)

    1.建立工程 首先和Vivado设计一中一样,先建立工程(这部分就忽略了) 2.create block design 同样,Add IP 同样,也添加配置文件,这些都和设计一是一样的,没什么区别. ...

  3. linux中MySQL主从配置(Django实现主从读写分离)

    一 linux中MySQL主从配置原理(主从分离,主从同步) mysql主从配置的流程大体如图: 1)master会将变动记录到二进制日志里面: 2)master有一个I/O线程将二进制日志发送到sl ...

  4. 一步一步学ZedBoard & Zynq(四):基于AXI Lite 总线的从设备IP设计

    本帖最后由 xinxincaijq 于 2013-1-9 10:27 编辑 一步一步学ZedBoard & Zynq(四):基于AXI Lite 总线的从设备IP设计 转自博客:http:// ...

  5. ZYNQ工程PL顶层创建block module报错解决

    参考文档 https://www.cnblogs.com/chengqi521/p/7977616.html 前言 对于ZYNQ的开发,顶层一般为PS+PL,而PL一般会封装成顶层,只露出接口. 而P ...

  6. 在Qsys中创建用户自定义IP

    在SOC FPGA的设计中,必须使用Qsys软件才能将ARM和FPGA之间的接口引入到FPGA设计中.为了设计上的方便,客户经常希望将Qsys中的一些接口信号引入到FPGA顶层设计文件中.本文以Ava ...

  7. php中创建和调用webservice接口示例

    php中创建和调用webservice接口示例   这篇文章主要介绍了php中创建和调用webservice接口示例,包括webservice基本知识.webservice服务端例子.webservi ...

  8. PL/Sql 中创建、调试、调用存储过程

    存储过程的详细建立方法 1.先建存储过程 左边的浏览窗口选择 procedures ,会列出所有的存储过程,右击文件夹procedures单击菜单"new",弹出 template ...

  9. 在Drupal7中创建web接口

    Services 模块允许您从一个主要模块后端配置和管理区域启用您 Drupal 站点上自定义构建的内容服务器和服务.该模块中包含的服务允许您调用内容,从 Drupal 的默认和分配的 File.Co ...

随机推荐

  1. CSS3实现烟花特效 --web前端

    烟花特效,比较简单,直接贴代码了…… <!DOCTYPE html><html lang="en"><head> <meta charse ...

  2. Shell脚本管理

    sh test.sh../test.sh与source test.sh.. test.sh执行命令的区别:sh是启用子shell执行而source或点是在当前窗口执行export A=123:定义全局 ...

  3. 20170824xlVBA出车对账单

    Private Sub GetClientAccountList() Dim EndRow As Long Dim i As Long, j As Long Dim m As Long, n As L ...

  4. DAG最长路问题 hdu-1224

    用DFS+记忆化写了一下,拓扑排序+DP的我还没弄明白.据说Codeforces 721C就是这类题目,因为有费用限制,DFS不太好写,有时间把DP法想明白来. #include <iostre ...

  5. scrapy 爬虫框架(一)

    一 . scrapy 的安装 安装scrapy框架时,需要先安装依赖包. #Linux: pip3 install scrapy #Windows: a. pip3 install wheel b. ...

  6. redis 持久化方式

    对于persistence持久化存储,Redis提供了两种持久化方法: Redis DataBase(简称RDB) 执行机制:快照,直接将databases中的key-value的二进制形式存储在了r ...

  7. python记录_day30 多进程

    1.什么是进程 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础. 同一个程序执行两次,就会产生两个进程 ## 进程调度算 ...

  8. 【Java】【1】List的几种排序写法

    前言: 1,实现Comparator接口的类的对象作为sort的入参 2,在方法的局部使用局部类 3,基于第二种方法,局部类改为匿名类 4,使用lamdba表达式->这种形式 5,借助Compa ...

  9. git push 失败出现error: src refspec master does not match any.解决方案

    今天写好一个demo往GitHub上传时报错 错误提示: error: src refspec master does not match any. error: failed to push som ...

  10. sonar-gerrit plugin配置

    配置 sonar-gerrit plugins stepspre-condition:1. Sonarqube(5.5及以上,本文使用的版本为6.1.3)关于如何安装配置Sonarqube,请参考其他 ...