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

Subversion Repositories openmsp430

[/] [openmsp430/] [trunk/] [core/] [bench/] [verilog/] [dma_tasks.v] - Blame information for rev 202

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 202 olivier.gi
//----------------------------------------------------------------------------
2
// Copyright (C) 2014 Authors
3
//
4
// This source file may be used and distributed without restriction provided
5
// that this copyright statement is not removed from the file and that any
6
// derivative work contains the original copyright notice and the associated
7
// disclaimer.
8
//
9
// This source file is free software; you can redistribute it and/or modify
10
// it under the terms of the GNU Lesser General Public License as published
11
// by the Free Software Foundation; either version 2.1 of the License, or
12
// (at your option) any later version.
13
//
14
// This source is distributed in the hope that it will be useful, but WITHOUT
15
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17
// License for more details.
18
//
19
// You should have received a copy of the GNU Lesser General Public License
20
// along with this source; if not, write to the Free Software Foundation,
21
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22
//
23
//----------------------------------------------------------------------------
24
//
25
// *File Name: dma_tasks.v
26
//
27
// *Module Description:
28
//                      generic tasks for using the Direct Memory Access interface
29
//
30
// *Author(s):
31
//              - Olivier Girard,    olgirard@gmail.com
32
//
33
//----------------------------------------------------------------------------
34
// $Rev$
35
// $LastChangedBy$
36
// $LastChangedDate$
37
//----------------------------------------------------------------------------
38
 
39
//============================================================================
40
// DMA Write access
41
//============================================================================
42
integer    dma_cnt_wr;
43
integer    dma_cnt_rd;
44
integer    dma_wr_error;
45
integer    dma_rd_error;
46
reg        dma_tfx_cancel;
47
 
48
//---------------------
49
// Generic write task
50
//---------------------
51
task dma_write;
52
   input  [15:0] addr;   // Address
53
   input  [15:0] data;   // Data
54
   input         resp;   // Expected transfer response (0: Okay / 1: Error)
55
   input         size;   // Access size (0: 8-bit / 1: 16-bit)
56
 
57
   begin
58
      dma_addr   = addr[15:1];
59
      dma_en     = 1'b1;
60
      dma_we     = size    ? 2'b11  :
61
                   addr[0] ? 2'b10  :  2'b01;
62
      dma_din    = data;
63
      @(posedge mclk or posedge dma_tfx_cancel);
64
      while(~dma_ready & ~dma_tfx_cancel) @(posedge mclk or posedge dma_tfx_cancel);
65
      dma_en     = 1'b0;
66
      dma_we     = 2'b00;
67
      dma_addr   = 15'h0000;
68
      dma_din    = 16'h0000;
69
      if (~dma_tfx_cancel) dma_cnt_wr = dma_cnt_wr+1;
70
 
71
      // Check transfer response
72
      if (~dma_tfx_cancel & (dma_resp != resp))
73
        begin
74
           $display("ERROR: DMA interface write response check -- address: 0x%h -- response: %h / expected: %h (%t ns)", addr, dma_resp, resp, $time);
75
           dma_wr_error = dma_wr_error+1;
76
        end
77
   end
78
endtask
79
 
80
//---------------------
81
// Write 16b task
82
//---------------------
83
task dma_write_16b;
84
   input  [15:0] addr;   // Address
85
   input  [15:0] data;   // Data
86
   input         resp;   // Expected transfer response (0: Okay / 1: Error)
87
 
88
   begin
89
      dma_write(addr, data, resp, 1'b1);
90
   end
91
endtask
92
 
93
//---------------------
94
// Write 8b task
95
//---------------------
96
task dma_write_8b;
97
   input  [15:0] addr;   // Address
98
   input   [7:0] data;   // Data
99
   input         resp;   // Expected transfer response (0: Okay / 1: Error)
100
 
101
   begin
102
      if (addr[0]) dma_write(addr, {data,  8'h00}, resp, 1'b0);
103
      else         dma_write(addr, {8'h00, data }, resp, 1'b0);
104
   end
105
endtask
106
 
107
 
108
//============================================================================
109
// DMA read access
110
//============================================================================
111
 
112
//---------------------
113
// Read check process
114
//---------------------
115
reg        dma_read_check_active;
116
reg [15:0] dma_read_check_addr;
117
reg [15:0] dma_read_check_data;
118
reg [15:0] dma_read_check_mask;
119
 
120
initial
121
  begin
122
     dma_read_check_active =  1'b0;
123
     dma_read_check_addr   = 16'h0000;
124
     dma_read_check_data   = 16'h0000;
125
     dma_read_check_mask   = 16'h0000;
126
     forever
127
       begin
128
          @(negedge (mclk & dma_read_check_active) or posedge dma_tfx_cancel);
129
          if (~dma_tfx_cancel & (dma_read_check_data !== (dma_read_check_mask & dma_dout)) & ~puc_rst)
130
            begin
131
               $display("ERROR: DMA interface read check -- address: 0x%h -- read: 0x%h / expected: 0x%h (%t ns)", dma_read_check_addr, (dma_read_check_mask & dma_dout), dma_read_check_data, $time);
132
               dma_rd_error = dma_rd_error+1;
133
            end
134
          dma_read_check_active =  1'b0;
135
       end
136
  end
137
 
138
//---------------------
139
// Generic read task
140
//---------------------
141
task dma_read;
142
   input  [15:0] addr;   // Address
143
   input  [15:0] data;   // Data to check against
144
   input         resp;   // Expected transfer response (0: Okay / 1: Error)
145
   input         check;  // Enable/disable read value check
146
   input         size;   // Access size (0: 8-bit / 1: 16-bit)
147
 
148
   begin
149
      // Perform read transfer
150
      dma_addr = addr[15:1];
151
      dma_en   = 1'b1;
152
      dma_we   = 2'b00;
153
      dma_din  = 16'h0000;
154
      @(posedge mclk or posedge dma_tfx_cancel);
155
      while(~dma_ready & ~dma_tfx_cancel) @(posedge mclk or posedge dma_tfx_cancel);
156
      dma_en   = 1'b0;
157
      dma_addr = 15'h0000;
158
 
159
      // Trigger read check
160
      dma_read_check_active =  check;
161
      dma_read_check_addr   =  addr;
162
      dma_read_check_data   =  data;
163
      dma_read_check_mask   =  size    ? 16'hFFFF :
164
                              (addr[0] ? 16'hFF00 : 16'h00FF);
165
      if (~dma_tfx_cancel) dma_cnt_rd = dma_cnt_rd+1;
166
 
167
      // Check transfer response
168
      if (~dma_tfx_cancel & (dma_resp != resp))
169
        begin
170
           $display("ERROR: DMA interface read response check -- address: 0x%h -- response: %h / expected: %h (%t ns)", addr, dma_resp, resp, $time);
171
           dma_rd_error = dma_rd_error+1;
172
        end
173
   end
174
endtask
175
 
176
//---------------------
177
// Read 16b task
178
//---------------------
179
task dma_read_16b;
180
   input  [15:0] addr;   // Address
181
   input  [15:0] data;   // Data to check against
182
   input         resp;   // Expected transfer response (0: Okay / 1: Error)
183
 
184
   begin
185
      dma_read(addr, data, resp, 1'b1, 1'b1);
186
   end
187
endtask
188
 
189
//---------------------
190
// Read 8b task
191
//---------------------
192
task dma_read_8b;
193
   input  [15:0] addr;   // Address
194
   input   [7:0] data;   // Data to check against
195
   input         resp;   // Expected transfer response (0: Okay / 1: Error)
196
 
197
   begin
198
      if (addr[0]) dma_read(addr, {data,  8'h00}, resp, 1'b1, 1'b0);
199
      else         dma_read(addr, {8'h00, data }, resp, 1'b1, 1'b0);
200
   end
201
endtask
202
 
203
//--------------------------------
204
// Read 16b value task (no check)
205
//--------------------------------
206
task dma_read_val_16b;
207
   input  [15:0] addr;   // Address
208
   input         resp;   // Expected transfer response (0: Okay / 1: Error)
209
 
210
   begin
211
      dma_read(addr, 16'h0000, resp, 1'b0, 1'b1);
212
   end
213
endtask
214
 
215
 
216
//============================================================================
217
// Ramdom DMA access process
218
//============================================================================
219
 
220
integer    dma_rand_wait;
221
integer    dma_rand_wait_disable;
222
reg        dma_rand_rdwr;
223
reg        dma_rand_if;
224
integer    dma_rand_data;
225
reg  [6:0] dma_rand_addr;
226
reg [15:0] dma_rand_addr_full;
227
integer    dma_mem_ref_idx;
228
reg [15:0] dma_pmem_reference[0:127];
229
reg [15:0] dma_dmem_reference[0:127];
230
reg        dma_verif_on;
231
reg        dma_verif_verbose;
232
 
233
initial
234
  begin
235
     // Initialize
236
   `ifdef NO_DMA_VERIF
237
     dma_verif_on      = 0;
238
   `else
239
     `ifdef DMA_IF_EN
240
     dma_verif_on      = 1;
241
     `else
242
     dma_verif_on      = 0;
243
     `endif
244
   `endif
245
     dma_rand_wait_disable = 0;
246
     dma_verif_verbose = 0;
247
     dma_cnt_wr        = 0;
248
     dma_cnt_rd        = 0;
249
     dma_wr_error      = 0;
250
     dma_rd_error      = 0;
251
     #20;
252
     dma_rand_wait     = $urandom;
253
     for (dma_mem_ref_idx=0; dma_mem_ref_idx < 128; dma_mem_ref_idx=dma_mem_ref_idx+1)
254
       begin
255
          dma_pmem_reference[dma_mem_ref_idx]             = $urandom;
256
          dma_dmem_reference[dma_mem_ref_idx]             = $urandom;
257
          if (dma_verif_on && (`PMEM_SIZE>=4092) && (`DMEM_SIZE>=1024))
258
            begin
259
               pmem_0.mem[(`PMEM_SIZE-512)/2+dma_mem_ref_idx] = dma_pmem_reference[dma_mem_ref_idx];
260
               dmem_0.mem[(`DMEM_SIZE-256)/2+dma_mem_ref_idx] = dma_dmem_reference[dma_mem_ref_idx];
261
            end
262
       end
263
 
264
     // Wait for reset release
265
     repeat(1) @(posedge dco_clk);
266
     @(negedge puc_rst);
267
 
268
     // Perform random read/write 16b memory accesses
269
     if (dma_verif_on && (`PMEM_SIZE>=4092) && (`DMEM_SIZE>=1024))
270
       begin
271
          forever
272
            begin
273
               // Randomize 1 or 0 wait states between accesses
274
               // (1/3 proba of getting 1 wait state)
275
               dma_rand_wait = dma_rand_wait_disable ? 0 : ($urandom_range(2,0)==0);
276
               repeat(dma_rand_wait) @(posedge mclk);
277
 
278
               // Randomize read/write accesses
279
               // (1/3 proba of getting a read access)
280
               dma_rand_rdwr = ($urandom_range(2,0)==0);
281
 
282
               // Randomize address to be accessed (between 128 addresses)
283
               dma_rand_addr = $urandom;
284
 
285
               // Randomize access through PMEM or DMEM memories
286
               dma_rand_if   = $urandom_range(1,0);
287
 
288
               // Make sure the core is not in reset
289
               while(puc_rst) @(posedge mclk);
290
 
291
               if (dma_rand_rdwr)
292
                 begin
293
                    if (dma_rand_if)            // Read from Program Memory
294
                      begin
295
                         dma_rand_addr_full = 16'hFE00+dma_rand_addr*2;
296
                         if (dma_verif_verbose) $display("READ  DMA interface -- address: 0x%h -- expected data: 0x%h", dma_rand_addr_full, dma_pmem_reference[dma_rand_addr]);
297
                         dma_read_16b(dma_rand_addr_full,  dma_pmem_reference[dma_rand_addr], 1'b0);
298
                      end
299
                    else                        // Read from Data Memory
300
                      begin
301
                         dma_rand_addr_full = `PER_SIZE+`DMEM_SIZE-256+dma_rand_addr*2;
302
                         if (dma_verif_verbose) $display("READ  DMA interface -- address: 0x%h -- expected data: 0x%h", dma_rand_addr_full, dma_dmem_reference[dma_rand_addr]);
303
                         dma_read_16b(dma_rand_addr_full,  dma_dmem_reference[dma_rand_addr], 1'b0);
304
                      end
305
                 end
306
               else
307
                 begin
308
                    dma_rand_data = $urandom;
309
 
310
                    if (dma_rand_if)            // Write to Program memory
311
                      begin
312
                         dma_rand_addr_full = 16'hFE00+dma_rand_addr*2;
313
                         if (dma_verif_verbose) $display("WRITE DMA interface -- address: 0x%h -- data: 0x%h", dma_rand_addr_full, dma_rand_data[15:0]);
314
                         dma_write_16b(dma_rand_addr_full, dma_rand_data[15:0], 1'b0);
315
                         dma_pmem_reference[dma_rand_addr] = dma_rand_data[15:0];
316
                         #1;
317
                         if (pmem_0.mem[(`PMEM_SIZE-512)/2+dma_rand_addr] !== dma_rand_data[15:0])
318
                           begin
319
                              $display("ERROR: DMA interface write -- address: 0x%h -- wrote: 0x%h / expected: 0x%h (%t ns)", dma_rand_addr_full, dma_rand_data[15:0], pmem_0.mem[(`PMEM_SIZE-512)/2+dma_rand_addr], $time);
320
                              dma_wr_error = dma_wr_error+1;
321
                           end
322
                      end
323
                    else                        // Write to Data Memory
324
                      begin
325
                         dma_rand_addr_full = `PER_SIZE+`DMEM_SIZE-256+dma_rand_addr*2;
326
                         if (dma_verif_verbose) $display("WRITE DMA interface -- address: 0x%h -- data: 0x%h", dma_rand_addr_full, dma_rand_data[15:0]);
327
                         dma_write_16b(dma_rand_addr_full, dma_rand_data[15:0], 1'b0);
328
                         dma_dmem_reference[dma_rand_addr] = dma_rand_data[15:0];
329
                         #1;
330
                         if (dmem_0.mem[(`DMEM_SIZE-256)/2+dma_rand_addr] !== dma_rand_data[15:0])
331
                           begin
332
                              $display("ERROR: DMA interface write -- address: 0x%h -- wrote: 0x%h / expected: 0x%h (%t ns)", dma_rand_addr_full, dma_rand_data[15:0], dmem_0.mem[(`DMEM_SIZE-256)/2+dma_rand_addr], $time);
333
                              dma_wr_error = dma_wr_error+1;
334
                           end
335
                      end
336
                 end
337
            end
338
       end
339
  end

powered by: WebSVN 2.1.0

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