ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

用Verilog写AXI4_lite从机协议

2022-03-30 14:04:47  阅读:428  来源: 互联网

标签:wire s00 axi lite 从机 AXI4 input AXI reg


  用过Xilinx Z7系列的过来人应该都很熟悉AXI4_lite协议,Z7的优点就在于有了soc,而如何将PL,PS端的信号互联,Xilinx就用到了AMBA协议的AXI部分。现在就AXI4_lite协议来分析下,AXI4_lite属于AXI4协议的轻量级形式,是简化版的 AXI4 接口, 用于较少数据量的存储映射通信。

  AXI4是一种READY,VALID握手机制的通信协议,就是在信息传输中有一个握手的过程。传输源发出VALID信号来表示当前哪些数据为有效,目的源则产生READY信号来表明当前已做好接受数据的准备。信息的有效传输发生在VALID与READY同为高的时候。此时会出现以下三种情况。

  1.VALID和READY信号同时变高:

  2.VALID先变高READY后变高:

  3.READY先变高VALID后变高:

 

  根据时序图,我们可以初步了解握手的有效情况。然后我们可以看看官方软件Vivado生成的AXI4_lite代码,以下是Vivado2017.4生成AXI4_lite slave 的步骤:

1.打开Vivado软件,新建工程后,单击菜单栏Tools->Create and Package New IP,开始创建一个AXI4-Lite接口总线IP

 

选择使用vivado自带的AXI总线模板创建一个AXI4-Lite接口IP

 

名称改为axi4_lite

 

点击next之后

继续next

 

然后就跳出编辑IP的界面

代码如下:

axi4_lite_v1_0 
 1 `timescale 1 ns / 1 ps
 2 
 3     module axi4_lite_v1_0 #
 4     (
 5         // Users to add parameters here
 6 
 7         // User parameters ends
 8         // Do not modify the parameters beyond this line
 9 
10 
11         // Parameters of Axi Slave Bus Interface S00_AXI
12         parameter integer C_S00_AXI_DATA_WIDTH    = 32,
13         parameter integer C_S00_AXI_ADDR_WIDTH    = 4
14     )
15     (
16         // Users to add ports here
17 
18         // User ports ends
19         // Do not modify the ports beyond this line
20 
21 
22         // Ports of Axi Slave Bus Interface S00_AXI
23         input wire  s00_axi_aclk,
24         input wire  s00_axi_aresetn,
25         input wire [C_S00_AXI_ADDR_WIDTH-1 : 0] s00_axi_awaddr,
26         input wire [2 : 0] s00_axi_awprot,
27         input wire  s00_axi_awvalid,
28         output wire  s00_axi_awready,
29         input wire [C_S00_AXI_DATA_WIDTH-1 : 0] s00_axi_wdata,
30         input wire [(C_S00_AXI_DATA_WIDTH/8)-1 : 0] s00_axi_wstrb,
31         input wire  s00_axi_wvalid,
32         output wire  s00_axi_wready,
33         output wire [1 : 0] s00_axi_bresp,
34         output wire  s00_axi_bvalid,
35         input wire  s00_axi_bready,
36         input wire [C_S00_AXI_ADDR_WIDTH-1 : 0] s00_axi_araddr,
37         input wire [2 : 0] s00_axi_arprot,
38         input wire  s00_axi_arvalid,
39         output wire  s00_axi_arready,
40         output wire [C_S00_AXI_DATA_WIDTH-1 : 0] s00_axi_rdata,
41         output wire [1 : 0] s00_axi_rresp,
42         output wire  s00_axi_rvalid,
43         input wire  s00_axi_rready
44     );
45 // Instantiation of Axi Bus Interface S00_AXI
46     axi4_lite_v1_0_S00_AXI # ( 
47         .C_S_AXI_DATA_WIDTH(C_S00_AXI_DATA_WIDTH),
48         .C_S_AXI_ADDR_WIDTH(C_S00_AXI_ADDR_WIDTH)
49     ) axi4_lite_v1_0_S00_AXI_inst (
50         .S_AXI_ACLK(s00_axi_aclk),
51         .S_AXI_ARESETN(s00_axi_aresetn),
52         .S_AXI_AWADDR(s00_axi_awaddr),
53         .S_AXI_AWPROT(s00_axi_awprot),
54         .S_AXI_AWVALID(s00_axi_awvalid),
55         .S_AXI_AWREADY(s00_axi_awready),
56         .S_AXI_WDATA(s00_axi_wdata),
57         .S_AXI_WSTRB(s00_axi_wstrb),
58         .S_AXI_WVALID(s00_axi_wvalid),
59         .S_AXI_WREADY(s00_axi_wready),
60         .S_AXI_BRESP(s00_axi_bresp),
61         .S_AXI_BVALID(s00_axi_bvalid),
62         .S_AXI_BREADY(s00_axi_bready),
63         .S_AXI_ARADDR(s00_axi_araddr),
64         .S_AXI_ARPROT(s00_axi_arprot),
65         .S_AXI_ARVALID(s00_axi_arvalid),
66         .S_AXI_ARREADY(s00_axi_arready),
67         .S_AXI_RDATA(s00_axi_rdata),
68         .S_AXI_RRESP(s00_axi_rresp),
69         .S_AXI_RVALID(s00_axi_rvalid),
70         .S_AXI_RREADY(s00_axi_rready)
71     );
72 
73     // Add user logic here
74 
75     // User logic ends
76 
77     endmodule
axi4_lite_v1_0_S00_AXI
  1 `timescale 1 ns / 1 ps
  2 
  3     module axi4_lite_v1_0_S00_AXI #
  4     (
  5         // Users to add parameters here
  6 
  7         // User parameters ends
  8         // Do not modify the parameters beyond this line
  9 
 10         // Width of S_AXI data bus
 11         parameter integer C_S_AXI_DATA_WIDTH    = 32,
 12         // Width of S_AXI address bus
 13         parameter integer C_S_AXI_ADDR_WIDTH    = 4
 14     )
 15     (
 16         // Users to add ports here
 17 
 18         // User ports ends
 19         // Do not modify the ports beyond this line
 20 
 21         // Global Clock Signal
 22         input wire  S_AXI_ACLK,
 23         // Global Reset Signal. This Signal is Active LOW
 24         input wire  S_AXI_ARESETN,
 25         // Write address (issued by master, acceped by Slave)
 26         input wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_AWADDR,
 27         // Write channel Protection type. This signal indicates the
 28             // privilege and security level of the transaction, and whether
 29             // the transaction is a data access or an instruction access.
 30         input wire [2 : 0] S_AXI_AWPROT,
 31         // Write address valid. This signal indicates that the master signaling
 32             // valid write address and control information.
 33         input wire  S_AXI_AWVALID,
 34         // Write address ready. This signal indicates that the slave is ready
 35             // to accept an address and associated control signals.
 36         output wire  S_AXI_AWREADY,
 37         // Write data (issued by master, acceped by Slave) 
 38         input wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_WDATA,
 39         // Write strobes. This signal indicates which byte lanes hold
 40             // valid data. There is one write strobe bit for each eight
 41             // bits of the write data bus.    
 42         input wire [(C_S_AXI_DATA_WIDTH/8)-1 : 0] S_AXI_WSTRB,
 43         // Write valid. This signal indicates that valid write
 44             // data and strobes are available.
 45         input wire  S_AXI_WVALID,
 46         // Write ready. This signal indicates that the slave
 47             // can accept the write data.
 48         output wire  S_AXI_WREADY,
 49         // Write response. This signal indicates the status
 50             // of the write transaction.
 51         output wire [1 : 0] S_AXI_BRESP,
 52         // Write response valid. This signal indicates that the channel
 53             // is signaling a valid write response.
 54         output wire  S_AXI_BVALID,
 55         // Response ready. This signal indicates that the master
 56             // can accept a write response.
 57         input wire  S_AXI_BREADY,
 58         // Read address (issued by master, acceped by Slave)
 59         input wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_ARADDR,
 60         // Protection type. This signal indicates the privilege
 61             // and security level of the transaction, and whether the
 62             // transaction is a data access or an instruction access.
 63         input wire [2 : 0] S_AXI_ARPROT,
 64         // Read address valid. This signal indicates that the channel
 65             // is signaling valid read address and control information.
 66         input wire  S_AXI_ARVALID,
 67         // Read address ready. This signal indicates that the slave is
 68             // ready to accept an address and associated control signals.
 69         output wire  S_AXI_ARREADY,
 70         // Read data (issued by slave)
 71         output wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_RDATA,
 72         // Read response. This signal indicates the status of the
 73             // read transfer.
 74         output wire [1 : 0] S_AXI_RRESP,
 75         // Read valid. This signal indicates that the channel is
 76             // signaling the required read data.
 77         output wire  S_AXI_RVALID,
 78         // Read ready. This signal indicates that the master can
 79             // accept the read data and response information.
 80         input wire  S_AXI_RREADY
 81     );
 82 
 83     // AXI4LITE signals
 84     reg [C_S_AXI_ADDR_WIDTH-1 : 0]     axi_awaddr;
 85     reg      axi_awready;
 86     reg      axi_wready;
 87     reg [1 : 0]     axi_bresp;
 88     reg      axi_bvalid;
 89     reg [C_S_AXI_ADDR_WIDTH-1 : 0]     axi_araddr;
 90     reg      axi_arready;
 91     reg [C_S_AXI_DATA_WIDTH-1 : 0]     axi_rdata;
 92     reg [1 : 0]     axi_rresp;
 93     reg      axi_rvalid;
 94 
 95     // Example-specific design signals
 96     // local parameter for addressing 32 bit / 64 bit C_S_AXI_DATA_WIDTH
 97     // ADDR_LSB is used for addressing 32/64 bit registers/memories
 98     // ADDR_LSB = 2 for 32 bits (n downto 2)
 99     // ADDR_LSB = 3 for 64 bits (n downto 3)
100     localparam integer ADDR_LSB = (C_S_AXI_DATA_WIDTH/32) + 1;
101     localparam integer OPT_MEM_ADDR_BITS = 1;
102     //----------------------------------------------
103     //-- Signals for user logic register space example
104     //------------------------------------------------
105     //-- Number of Slave Registers 4
106     reg [C_S_AXI_DATA_WIDTH-1:0]    slv_reg0;
107     reg [C_S_AXI_DATA_WIDTH-1:0]    slv_reg1;
108     reg [C_S_AXI_DATA_WIDTH-1:0]    slv_reg2;
109     reg [C_S_AXI_DATA_WIDTH-1:0]    slv_reg3;
110     wire     slv_reg_rden;
111     wire     slv_reg_wren;
112     reg [C_S_AXI_DATA_WIDTH-1:0]     reg_data_out;
113     integer     byte_index;
114     reg     aw_en;
115 
116     // I/O Connections assignments
117 
118     assign S_AXI_AWREADY    = axi_awready;
119     assign S_AXI_WREADY    = axi_wready;
120     assign S_AXI_BRESP    = axi_bresp;
121     assign S_AXI_BVALID    = axi_bvalid;
122     assign S_AXI_ARREADY    = axi_arready;
123     assign S_AXI_RDATA    = axi_rdata;
124     assign S_AXI_RRESP    = axi_rresp;
125     assign S_AXI_RVALID    = axi_rvalid;
126     // Implement axi_awready generation
127     // axi_awready is asserted for one S_AXI_ACLK clock cycle when both
128     // S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_awready is
129     // de-asserted when reset is low.
130 
131     always @( posedge S_AXI_ACLK )
132     begin
133       if ( S_AXI_ARESETN == 1'b0 )
134         begin
135           axi_awready <= 1'b0;
136           aw_en <= 1'b1;
137         end 
138       else
139         begin    
140           if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID && aw_en)
141             begin
142               // slave is ready to accept write address when 
143               // there is a valid write address and write data
144               // on the write address and data bus. This design 
145               // expects no outstanding transactions. 
146               axi_awready <= 1'b1;
147               aw_en <= 1'b0;
148             end
149             else if (S_AXI_BREADY && axi_bvalid)
150                 begin
151                   aw_en <= 1'b1;
152                   axi_awready <= 1'b0;
153                 end
154           else           
155             begin
156               axi_awready <= 1'b0;
157             end
158         end 
159     end       
160 
161     // Implement axi_awaddr latching
162     // This process is used to latch the address when both 
163     // S_AXI_AWVALID and S_AXI_WVALID are valid. 
164 
165     always @( posedge S_AXI_ACLK )
166     begin
167       if ( S_AXI_ARESETN == 1'b0 )
168         begin
169           axi_awaddr <= 0;
170         end 
171       else
172         begin    
173           if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID && aw_en)
174             begin
175               // Write Address latching 
176               axi_awaddr <= S_AXI_AWADDR;
177             end
178         end 
179     end       
180 
181     // Implement axi_wready generation
182     // axi_wready is asserted for one S_AXI_ACLK clock cycle when both
183     // S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_wready is 
184     // de-asserted when reset is low. 
185 
186     always @( posedge S_AXI_ACLK )
187     begin
188       if ( S_AXI_ARESETN == 1'b0 )
189         begin
190           axi_wready <= 1'b0;
191         end 
192       else
193         begin    
194           if (~axi_wready && S_AXI_WVALID && S_AXI_AWVALID && aw_en )
195             begin
196               // slave is ready to accept write data when 
197               // there is a valid write address and write data
198               // on the write address and data bus. This design 
199               // expects no outstanding transactions. 
200               axi_wready <= 1'b1;
201             end
202           else
203             begin
204               axi_wready <= 1'b0;
205             end
206         end 
207     end       
208 
209     // Implement memory mapped register select and write logic generation
210     // The write data is accepted and written to memory mapped registers when
211     // axi_awready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. Write strobes are used to
212     // select byte enables of slave registers while writing.
213     // These registers are cleared when reset (active low) is applied.
214     // Slave register write enable is asserted when valid address and data are available
215     // and the slave is ready to accept the write address and write data.
216     assign slv_reg_wren = axi_wready && S_AXI_WVALID && axi_awready && S_AXI_AWVALID;
217 
218     always @( posedge S_AXI_ACLK )
219     begin
220       if ( S_AXI_ARESETN == 1'b0 )
221         begin
222           slv_reg0 <= 0;
223           slv_reg1 <= 0;
224           slv_reg2 <= 0;
225           slv_reg3 <= 0;
226         end 
227       else begin
228         if (slv_reg_wren)
229           begin
230             case ( axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
231               2'h0:
232                 for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
233                   if ( S_AXI_WSTRB[byte_index] == 1 ) begin
234                     // Respective byte enables are asserted as per write strobes 
235                     // Slave register 0
236                     slv_reg0[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
237                   end  
238               2'h1:
239                 for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
240                   if ( S_AXI_WSTRB[byte_index] == 1 ) begin
241                     // Respective byte enables are asserted as per write strobes 
242                     // Slave register 1
243                     slv_reg1[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
244                   end  
245               2'h2:
246                 for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
247                   if ( S_AXI_WSTRB[byte_index] == 1 ) begin
248                     // Respective byte enables are asserted as per write strobes 
249                     // Slave register 2
250                     slv_reg2[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
251                   end  
252               2'h3:
253                 for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
254                   if ( S_AXI_WSTRB[byte_index] == 1 ) begin
255                     // Respective byte enables are asserted as per write strobes 
256                     // Slave register 3
257                     slv_reg3[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
258                   end  
259               default : begin
260                           slv_reg0 <= slv_reg0;
261                           slv_reg1 <= slv_reg1;
262                           slv_reg2 <= slv_reg2;
263                           slv_reg3 <= slv_reg3;
264                         end
265             endcase
266           end
267       end
268     end    
269 
270     // Implement write response logic generation
271     // The write response and response valid signals are asserted by the slave 
272     // when axi_wready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted.  
273     // This marks the acceptance of address and indicates the status of 
274     // write transaction.
275 
276     always @( posedge S_AXI_ACLK )
277     begin
278       if ( S_AXI_ARESETN == 1'b0 )
279         begin
280           axi_bvalid  <= 0;
281           axi_bresp   <= 2'b0;
282         end 
283       else
284         begin    
285           if (axi_awready && S_AXI_AWVALID && ~axi_bvalid && axi_wready && S_AXI_WVALID)
286             begin
287               // indicates a valid write response is available
288               axi_bvalid <= 1'b1;
289               axi_bresp  <= 2'b0; // 'OKAY' response 
290             end                   // work error responses in future
291           else
292             begin
293               if (S_AXI_BREADY && axi_bvalid) 
294                 //check if bready is asserted while bvalid is high) 
295                 //(there is a possibility that bready is always asserted high)   
296                 begin
297                   axi_bvalid <= 1'b0; 
298                 end  
299             end
300         end
301     end   
302 
303     // Implement axi_arready generation
304     // axi_arready is asserted for one S_AXI_ACLK clock cycle when
305     // S_AXI_ARVALID is asserted. axi_awready is 
306     // de-asserted when reset (active low) is asserted. 
307     // The read address is also latched when S_AXI_ARVALID is 
308     // asserted. axi_araddr is reset to zero on reset assertion.
309 
310     always @( posedge S_AXI_ACLK )
311     begin
312       if ( S_AXI_ARESETN == 1'b0 )
313         begin
314           axi_arready <= 1'b0;
315           axi_araddr  <= 32'b0;
316         end 
317       else
318         begin    
319           if (~axi_arready && S_AXI_ARVALID)
320             begin
321               // indicates that the slave has acceped the valid read address
322               axi_arready <= 1'b1;
323               // Read address latching
324               axi_araddr  <= S_AXI_ARADDR;
325             end
326           else
327             begin
328               axi_arready <= 1'b0;
329             end
330         end 
331     end       
332 
333     // Implement axi_arvalid generation
334     // axi_rvalid is asserted for one S_AXI_ACLK clock cycle when both 
335     // S_AXI_ARVALID and axi_arready are asserted. The slave registers 
336     // data are available on the axi_rdata bus at this instance. The 
337     // assertion of axi_rvalid marks the validity of read data on the 
338     // bus and axi_rresp indicates the status of read transaction.axi_rvalid 
339     // is deasserted on reset (active low). axi_rresp and axi_rdata are 
340     // cleared to zero on reset (active low).  
341     always @( posedge S_AXI_ACLK )
342     begin
343       if ( S_AXI_ARESETN == 1'b0 )
344         begin
345           axi_rvalid <= 0;
346           axi_rresp  <= 0;
347         end 
348       else
349         begin    
350           if (axi_arready && S_AXI_ARVALID && ~axi_rvalid)
351             begin
352               // Valid read data is available at the read data bus
353               axi_rvalid <= 1'b1;
354               axi_rresp  <= 2'b0; // 'OKAY' response
355             end   
356           else if (axi_rvalid && S_AXI_RREADY)
357             begin
358               // Read data is accepted by the master
359               axi_rvalid <= 1'b0;
360             end                
361         end
362     end    
363 
364     // Implement memory mapped register select and read logic generation
365     // Slave register read enable is asserted when valid address is available
366     // and the slave is ready to accept the read address.
367     assign slv_reg_rden = axi_arready & S_AXI_ARVALID & ~axi_rvalid;
368     always @(*)
369     begin
370           // Address decoding for reading registers
371           case ( axi_araddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
372             2'h0   : reg_data_out <= slv_reg0;
373             2'h1   : reg_data_out <= slv_reg1;
374             2'h2   : reg_data_out <= slv_reg2;
375             2'h3   : reg_data_out <= slv_reg3;
376             default : reg_data_out <= 0;
377           endcase
378     end
379 
380     // Output register or memory read data
381     always @( posedge S_AXI_ACLK )
382     begin
383       if ( S_AXI_ARESETN == 1'b0 )
384         begin
385           axi_rdata  <= 0;
386         end 
387       else
388         begin    
389           // When there is a valid read address (S_AXI_ARVALID) with 
390           // acceptance of read address by the slave (axi_arready), 
391           // output the read dada 
392           if (slv_reg_rden)
393             begin
394               axi_rdata <= reg_data_out;     // register read data
395             end   
396         end
397     end    
398 
399     // Add user logic here
400 
401     // User logic ends
402 
403     endmodule

以上便是通过官方生成的AXI4_lite接口的代码,看得挺烦,可拓展性差,因此明白了其中时序原理后,自己便可以动手写下该模块取代官方这些冗余的代码。
  1 //**************************************************************************
  2 // *** file name   : Axi4_lite_slave.v
  3 // *** version     : 1.0
  4 // *** Description : AXI4-Lite slave interface 
  5 // *** Blogs       : https://www.cnblogs.com/WenGalois123/
  6 // *** Author      : Galois_V
  7 // *** Date          : 2022.3.29        
  8 // *** Changes     :       
  9 //**************************************************************************
 10 `timescale 1ns/1ps
 11 module Axi4_lite_slave
 12 (
 13     input        wire                i_s_axi_aclk            ,
 14     input        wire                i_s_axi_aresetn            ,
 15     input        wire    [31:0]        i_s_axi_awaddr            ,
 16     input        wire    [2:0]        i_s_axi_awprot            ,
 17     input        wire                i_s_axi_awvalid            ,
 18     output        reg                 o_s_axi_awready            ,
 19     input        wire    [31:0]        i_s_axi_wdata            ,
 20     input        wire    [3:0]        i_s_axi_wstrb            ,
 21     input        wire                i_s_axi_wvalid            ,
 22     output        reg                    o_s_axi_wready            ,
 23     output        wire     [1:0]        o_s_axi_bresp            ,
 24     output        reg                    o_s_axi_bvalid            ,
 25     input        wire                i_s_axi_bready            ,
 26     input        wire    [31:0]        i_s_axi_araddr            ,
 27     input        wire    [2:0]        i_s_axi_arprot            ,
 28     input        wire                i_s_axi_arvalid            ,
 29     output        reg                    o_s_axi_arready            ,
 30     output        reg        [31:0]        o_s_axi_rdata            ,
 31     output        wire    [1:0]        o_s_axi_rresp            ,
 32     output        reg                    o_s_axi_rvalid            ,
 33     input        wire                i_s_axi_rready            ,
 34     output        reg        [31:0]        o_ctrl_wr_addr            ,
 35     output        wire                o_ctrl_wr_en            ,
 36     output        wire    [31:0]        o_ctrl_wr_data            ,
 37     output        wire    [3:0]        o_ctrl_wr_mask            ,
 38     output        reg        [31:0]        o_ctrl_rd_addr            ,
 39     input        wire    [31:0]        i_ctrl_rd_data            
 40 );
 41 
 42     reg                                r_wr_en;
 43     reg                                r_rd_en;
 44     wire                            w_raddr_en;
 45 /******************************************************************************\
 46 Write Address operation
 47 \******************************************************************************/
 48     always@(posedge i_s_axi_aclk)
 49     begin
 50         if(~i_s_axi_aresetn)
 51         begin
 52             r_wr_en <= 1'b1;
 53         end
 54         else if(o_ctrl_wr_en)
 55         begin
 56             r_wr_en <= 1'b0;
 57         end
 58         else if(o_s_axi_bvalid & i_s_axi_bready)
 59         begin
 60             r_wr_en <= 1'b1;
 61         end
 62     end
 63     
 64     always@(posedge i_s_axi_aclk)
 65     begin
 66         if(~i_s_axi_aresetn)
 67         begin
 68             o_s_axi_awready <= 'd0;
 69         end
 70         else if(~o_s_axi_awready & i_s_axi_wvalid & i_s_axi_awvalid & r_wr_en)
 71         begin
 72             o_s_axi_awready <= 1'b1;
 73         end
 74         else
 75         begin
 76             o_s_axi_awready <= 'd0;
 77         end
 78     end
 79     
 80     always@(posedge i_s_axi_aclk)
 81     begin
 82         if(~i_s_axi_aresetn)
 83         begin
 84             o_ctrl_wr_addr <= 'd0;
 85         end
 86         else if(~o_s_axi_awready & i_s_axi_awvalid & i_s_axi_wvalid)
 87         begin 
 88             o_ctrl_wr_addr <= i_s_axi_awaddr;
 89         end
 90     end
 91 /******************************************************************************\
 92 Write data operation
 93 \******************************************************************************/
 94     always@(posedge i_s_axi_aclk)
 95     begin
 96         if(~i_s_axi_aresetn)
 97         begin
 98             o_s_axi_wready <= 'd0;
 99         end
100         else if(~o_s_axi_wready & i_s_axi_wvalid & i_s_axi_awvalid & r_wr_en)
101         begin
102             o_s_axi_wready <= 1'b1;
103         end
104         else
105         begin
106             o_s_axi_wready <= 'd0;
107         end
108     end
109     
110     assign o_ctrl_wr_data = i_s_axi_wdata;
111     assign o_ctrl_wr_mask = i_s_axi_wstrb;
112     assign o_ctrl_wr_en = o_s_axi_awready & i_s_axi_awvalid & i_s_axi_wvalid & o_s_axi_wready;
113     
114 /******************************************************************************\
115 write response and response
116 \******************************************************************************/
117     always@(posedge i_s_axi_aclk)
118     begin
119         if(~i_s_axi_aresetn)
120         begin
121             o_s_axi_bvalid <= 'd0;
122         end
123         else if(~o_s_axi_bvalid & o_ctrl_wr_en)
124         begin
125             o_s_axi_bvalid <= 1'b1;
126         end
127         else if(o_s_axi_bvalid & i_s_axi_bready)
128         begin
129             o_s_axi_bvalid <= 'd0;
130         end
131     end
132     
133 /******************************************************************************\
134 Read Address operation
135 \******************************************************************************/
136     always@(posedge i_s_axi_aclk)
137     begin
138         if(~i_s_axi_aresetn)
139         begin
140             r_rd_en <= 1'b1;
141         end
142         else if(w_raddr_en)
143         begin
144             r_rd_en <= 1'b0;
145         end
146         else if(o_s_axi_rvalid & i_s_axi_rready)
147         begin
148             r_rd_en <= 1'b1;
149         end
150     end
151 
152     always@(posedge i_s_axi_aclk)
153     begin
154         if(~i_s_axi_aresetn)
155         begin
156             o_s_axi_arready <= 'd0;
157         end
158         else if(~o_s_axi_arready & i_s_axi_arvalid & r_rd_en)
159         begin
160             o_s_axi_arready <= 1'b1;
161         end
162         else
163         begin
164             o_s_axi_arready <= 'd0;
165         end
166     end
167 
168     always@(posedge i_s_axi_aclk)
169     begin
170         if(~i_s_axi_aresetn)
171         begin
172             o_ctrl_rd_addr <= 'd0;
173         end
174         else if(~o_s_axi_arready & i_s_axi_arvalid)
175         begin
176             o_ctrl_rd_addr <= i_s_axi_araddr;
177         end
178     end
179 
180     assign w_raddr_en = o_s_axi_arready & i_s_axi_arvalid & (~o_s_axi_rvalid);
181 /******************************************************************************\
182 Read data operation
183 \******************************************************************************/
184     always@(posedge i_s_axi_aclk)
185     begin
186         if(~i_s_axi_aresetn)
187         begin
188             o_s_axi_rvalid <= 'd0;
189         end
190         else if(w_raddr_en)
191         begin
192             o_s_axi_rvalid <= 1'b1;
193         end
194         else if(o_s_axi_rvalid & i_s_axi_rready)
195         begin
196             o_s_axi_rvalid <= 'd0;
197         end
198     end
199     
200     always@(posedge i_s_axi_aclk)
201     begin
202         if(~i_s_axi_aresetn)
203         begin
204             o_s_axi_rdata <= 'd0;
205         end
206         else if(w_raddr_en)
207         begin
208             o_s_axi_rdata <= i_ctrl_rd_data;
209         end
210     end
211     
212 
213     assign o_s_axi_rresp = 2'b00;
214     assign o_s_axi_bresp = 2'b00;
215     
216 endmodule
下图为仿真后的axi4_lite从机的时序,暂时没发现什么问题。

后续将使用该模块的代码进行IP核的编写。
 

 

标签:wire,s00,axi,lite,从机,AXI4,input,AXI,reg
来源: https://www.cnblogs.com/WenGalois123/p/16071850.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有