OpenCores
URL https://opencores.org/ocsvn/qaz_libs/qaz_libs/trunk

Subversion Repositories qaz_libs

[/] [qaz_libs/] [trunk/] [axi4_stream_lib/] [src/] [axis_to_axi4_basic_dma.sv] - Blame information for rev 31

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 31 qaztronic
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
//// Copyright (C) 2015 Authors and OPENCORES.ORG                 ////
4
////                                                              ////
5
//// This source file may be used and distributed without         ////
6
//// restriction provided that this copyright statement is not    ////
7
//// removed from the file and that any derivative work contains  ////
8
//// the original copyright notice and the associated disclaimer. ////
9
////                                                              ////
10
//// This source file is free software; you can redistribute it   ////
11
//// and/or modify it under the terms of the GNU Lesser General   ////
12
//// Public License as published by the Free Software Foundation; ////
13
//// either version 2.1 of the License, or (at your option) any   ////
14
//// later version.                                               ////
15
////                                                              ////
16
//// This source is distributed in the hope that it will be       ////
17
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
18
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
19
//// PURPOSE.  See the GNU Lesser General Public License for more ////
20
//// details.                                                     ////
21
////                                                              ////
22
//// You should have received a copy of the GNU Lesser General    ////
23
//// Public License along with this source; if not, download it   ////
24
//// from http://www.opencores.org/lgpl.shtml                     ////
25
////                                                              ////
26
//////////////////////////////////////////////////////////////////////
27
 
28
module
29
  axis_to_axi4_basic_dma
30
  #(
31
    A, // address bus width
32
    N, // data bus width in bytes
33
    I, // ID width
34
    BASE_ADDRESS,       // must be on 4K boundry
35
    BUFFER_SIZE,
36
    BURST_LENGTH,
37
    MAX_BURSTS,
38
    BYTES_PER_TUSER = 0 //  bytes per tuser bit. Set to 0 for transfer based.
39
  )
40
  (
41
    axi4_if axi4_m,
42
    axis_if axis_in,    // tuser[0] indicates first words of buffer. The rest of tuser is not used.
43
    input   dma_enable,
44
    input   aclk,
45
    input   aresetn
46
  );
47
 
48
  // --------------------------------------------------------------------
49
  //
50
  localparam W_D = BURST_LENGTH * MAX_BURSTS;
51
  localparam AW_D = 2;
52
  localparam WATERMARK = BURST_LENGTH;
53
  localparam STRIDE = N * BURST_LENGTH;
54
  localparam ADDRESS_END = BASE_ADDRESS + BUFFER_SIZE;
55
  localparam ADDRESS_STOP = (ADDRESS_END % STRIDE == 0) ? ADDRESS_END : ADDRESS_END + STRIDE;
56
  // localparam U = N / BYTES_PER_TUSER;
57
 
58
 
59
// --------------------------------------------------------------------
60
// synthesis translate_off
61
  localparam N_4K = 'h1000 / 'h8; // number of bytes in 4K
62
  initial
63
  begin
64
    a_4k_mod_base_address: assert(BASE_ADDRESS % 'h1000 == 0) else $fatal;
65
    a_4k_gt_eq_stride: assert(N_4K >= STRIDE) else $fatal;
66
    a_4k_mod_stride: assert('h1000 % STRIDE == 0) else $fatal;
67
    a_burst_length: assert(BURST_LENGTH > 1) else $fatal;
68
    // a_bytes_per_tuser: assert(N % BYTES_PER_TUSER == 0) else $fatal;
69
  end
70
 
71
// synthesis translate_on
72
// --------------------------------------------------------------------
73
 
74
 
75
  // --------------------------------------------------------------------
76
  //
77
  axi4_if #(.A(A), .N(N), .I(I))  axi4_write_fifo(.*);
78
 
79
 
80
  // --------------------------------------------------------------------
81
  //
82
  wire axis_data_en = axis_in.tready  & axis_in.tvalid;
83
  wire start        = axis_data_en    & axis_in.tuser[0];
84
 
85
 
86
  // --------------------------------------------------------------------
87
  //
88
  reg [(A-1):0] awaddr_r;
89
  wire send_waddr;
90
  wire awaddr_en = (awaddr_r < ADDRESS_STOP);
91
  wire aw_wr_full;
92
  wire aw_wr_en = ~aw_wr_full & dma_enable & awaddr_en & send_waddr;
93
  wire w_wr_full;
94
  wire w_wr_en = axis_in.tready & axis_in.tvalid;
95
  wire w_topped_off;
96
  wire w_watermark;
97
  wire b_rd_empty;
98
  wire b_rd_en = ~b_rd_empty;
99
 
100
 
101
  // --------------------------------------------------------------------
102
  //
103
  reg [$clog2(W_D + 1):0] w_wr_counter;
104
  wire burst_ready = (w_wr_counter > BURST_LENGTH - 1);
105
  wire wlast = (w_wr_counter == BURST_LENGTH - 1);
106
 
107
  always_ff @(posedge aclk)
108
    if(~aresetn)
109
      w_wr_counter <= 0;
110
    else if(aw_wr_en)
111
      if(w_wr_en)
112
        w_wr_counter <= w_wr_counter - BURST_LENGTH + 1;
113
      else
114
        w_wr_counter <= w_wr_counter - BURST_LENGTH;
115
    else if(w_wr_en)
116
      w_wr_counter <= w_wr_counter + 1;
117
 
118
 
119
  // --------------------------------------------------------------------
120
  //
121
  // reg [$clog2(AW_D + 1):0] aw_wr_counter;
122
  // assign send_waddr = (aw_wr_counter > 0);
123
  assign send_waddr = burst_ready;
124
 
125
  // always_ff @(posedge aclk)
126
    // if(~aresetn)
127
      // aw_wr_counter <= 0;
128
    // else if(aw_wr_en & ~burst_ready)
129
      // aw_wr_counter <= aw_wr_counter - 1;
130
    // else if(~aw_wr_en & burst_ready)
131
      // aw_wr_counter <= aw_wr_counter + 1;
132
 
133
 
134
  // --------------------------------------------------------------------
135
  //
136
  always_ff @(posedge aclk)
137
    if(~aresetn | ~awaddr_en | start)
138
      awaddr_r <= BASE_ADDRESS;
139
    else if(aw_wr_en)
140
      awaddr_r <= awaddr_r + STRIDE;
141
 
142
 
143
  // --------------------------------------------------------------------
144
  //
145
  axi4_m_to_write_fifos
146
    #(
147
      .A(A),
148
      .N(N),
149
      .I(I),
150
      .W_D(W_D),
151
      .B_D(AW_D),
152
      .AW_D(AW_D),
153
      .WATERMARK(WATERMARK)
154
    )
155
    axi4_m_to_write_fifos_i(.*);
156
 
157
 
158
  // --------------------------------------------------------------------
159
  //
160
  assign axi4_write_fifo.awaddr    = awaddr_r;
161
  assign axi4_write_fifo.awid      = 0;
162
  assign axi4_write_fifo.awburst   = 2'b01;
163
  assign axi4_write_fifo.awsize    = $clog2(N);
164
  assign axi4_write_fifo.awlen     = BURST_LENGTH - 1;
165
 
166
 
167
  // --------------------------------------------------------------------
168
  //
169
  assign axi4_write_fifo.wdata  = axis_in.tdata;
170
  assign axi4_write_fifo.wid    = 0;
171
  assign axi4_write_fifo.wlast  = wlast;
172
  assign axi4_write_fifo.wstrb  = {N{1'b1}};
173
 
174
 
175
  // --------------------------------------------------------------------
176
  //
177
  assign axis_in.tready = ~w_wr_full & ~burst_ready;
178
 
179
  // --------------------------------------------------------------------
180
  //
181
  assign axi4_m.arvalid   = 0;
182
  assign axi4_m.rready    = 0;
183
  assign axi4_m.awcache   = 0;
184
  assign axi4_m.awlock    = 0;
185
  assign axi4_m.awprot    = 0;
186
  assign axi4_m.awqos     = 0;
187
  assign axi4_m.awregion  = 0;
188
 
189
 
190
// --------------------------------------------------------------------
191
//
192
endmodule
193
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.