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

Subversion Repositories openmsp430

[/] [openmsp430/] [trunk/] [fpga/] [altera_de0_nano_soc/] [doc/] [Terasic/] [DE0_NANO_SOC/] [Demonstrations/] [FPGA/] [DE0_NANO_SOC_ADC/] [DE0_NANO_SOC_QSYS/] [synthesis/] [submodules/] [altera_merlin_slave_translator.sv] - Blame information for rev 221

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 221 olivier.gi
// (C) 2001-2014 Altera Corporation. All rights reserved.
2
// Your use of Altera Corporation's design tools, logic functions and other
3
// software and tools, and its AMPP partner logic functions, and any output
4
// files any of the foregoing (including device programming or simulation
5
// files), and any associated documentation or information are expressly subject
6
// to the terms and conditions of the Altera Program License Subscription
7
// Agreement, Altera MegaCore Function License Agreement, or other applicable
8
// license agreement, including, without limitation, that your use is for the
9
// sole purpose of programming logic devices manufactured by Altera and sold by
10
// Altera or its authorized distributors.  Please refer to the applicable
11
// agreement for further details.
12
 
13
 
14
 
15
// $Id: //acds/rel/14.0/ip/merlin/altera_merlin_slave_translator/altera_merlin_slave_translator.sv#1 $
16
// $Revision: #1 $
17
// $Date: 2014/02/16 $
18
// $Author: swbranch $
19
 
20
// -------------------------------------
21
// Merlin Slave Translator
22
//
23
// Translates Universal Avalon  MM Slave
24
// to any Avalon MM Slave
25
// -------------------------------------
26
//
27
//Notable Note: 0 AV_READLATENCY is not allowed and will be converted to a 1 cycle readlatency in all cases but one
28
//If you declare a slave with fixed read timing requirements, the readlatency of such a slave will be allowed to be zero
29
//The key feature here is that no same cycle turnaround data is processed through the fabric.
30
 
31
//import avalon_utilities_pkg::*;
32
 
33
`timescale 1 ns / 1 ns
34
 
35
module altera_merlin_slave_translator
36
  #(
37
    parameter
38
    //Widths
39
    AV_ADDRESS_W           = 32,
40
    AV_DATA_W              = 32,
41
    AV_BURSTCOUNT_W        = 4,
42
    AV_BYTEENABLE_W        = 4,
43
    UAV_BYTEENABLE_W       = 4,
44
 
45
    //Read Latency
46
    AV_READLATENCY          = 1,
47
 
48
    //Timing
49
    AV_READ_WAIT_CYCLES     = 0,
50
    AV_WRITE_WAIT_CYCLES    = 0,
51
    AV_SETUP_WAIT_CYCLES    = 0,
52
    AV_DATA_HOLD_CYCLES     = 0,
53
 
54
    //Optional Port Declarations
55
    USE_READDATAVALID       = 1,
56
    USE_WAITREQUEST         = 1,
57
    USE_READRESPONSE        = 0,
58
    USE_WRITERESPONSE       = 0,
59
 
60
    //Variable Addressing
61
    AV_SYMBOLS_PER_WORD     = 4,
62
    AV_ADDRESS_SYMBOLS      = 0,
63
    AV_BURSTCOUNT_SYMBOLS   = 0,
64
    BITS_PER_WORD           = clog2_plusone(AV_SYMBOLS_PER_WORD - 1),
65
    UAV_ADDRESS_W           = 38,
66
    UAV_BURSTCOUNT_W        = 10,
67
    UAV_DATA_W              = 32,
68
 
69
    AV_CONSTANT_BURST_BEHAVIOR       = 0,
70
    UAV_CONSTANT_BURST_BEHAVIOR      = 0,
71
    CHIPSELECT_THROUGH_READLATENCY   = 0,
72
 
73
    // Tightly-Coupled Options
74
    USE_UAV_CLKEN           = 0,
75
    AV_REQUIRE_UNALIGNED_ADDRESSES = 0
76
    )
77
  (
78
 
79
   // -------------------
80
   // Clock & Reset
81
   // -------------------
82
   input wire                             clk,
83
   input wire                             reset,
84
 
85
   // -------------------
86
   // Universal Avalon Slave
87
   // -------------------
88
 
89
   input wire [UAV_ADDRESS_W - 1 : 0]     uav_address,
90
   input wire [UAV_DATA_W - 1 : 0]        uav_writedata,
91
   input wire                             uav_write,
92
   input wire                             uav_read,
93
   input wire [UAV_BURSTCOUNT_W - 1 : 0]  uav_burstcount,
94
   input wire [UAV_BYTEENABLE_W - 1 : 0]  uav_byteenable,
95
   input wire                             uav_lock,
96
   input wire                             uav_debugaccess,
97
   input wire                             uav_clken,
98
 
99
   output logic                           uav_readdatavalid,
100
   output logic                           uav_waitrequest,
101
   output logic [UAV_DATA_W - 1 : 0]      uav_readdata,
102
   output logic [1:0]                     uav_response,
103
   input wire                             uav_writeresponserequest,
104
   output logic                           uav_writeresponsevalid,
105
 
106
   // -------------------
107
   // Customizable Avalon Master
108
   // -------------------
109
   output logic [AV_ADDRESS_W - 1 : 0]    av_address,
110
   output logic [AV_DATA_W - 1 : 0]       av_writedata,
111
   output logic                           av_write,
112
   output logic                           av_read,
113
   output logic [AV_BURSTCOUNT_W - 1 : 0] av_burstcount,
114
   output logic [AV_BYTEENABLE_W - 1 : 0] av_byteenable,
115
   output logic [AV_BYTEENABLE_W - 1 : 0] av_writebyteenable,
116
   output logic                           av_begintransfer,
117
   output wire                            av_chipselect,
118
   output logic                           av_beginbursttransfer,
119
   output logic                           av_lock,
120
   output wire                            av_clken,
121
   output wire                            av_debugaccess,
122
   output wire                            av_outputenable,
123
 
124
   input logic [AV_DATA_W - 1 : 0]        av_readdata,
125
   input logic                            av_readdatavalid,
126
   input logic                            av_waitrequest,
127
 
128
   input logic [1:0]                      av_response,
129
   output logic                           av_writeresponserequest,
130
   input wire                             av_writeresponsevalid
131
 
132
   );
133
 
134
   function integer clog2_plusone;
135
      input [31:0] Depth;
136
      integer i;
137
      begin
138
         i = Depth;
139
         for(clog2_plusone = 0; i > 0; clog2_plusone = clog2_plusone + 1)
140
           i = i >> 1;
141
      end
142
 
143
   endfunction
144
 
145
   function integer max;
146
      //returns the larger of two passed arguments
147
      input [31:0] one;
148
      input [31:0] two;
149
 
150
      if(one > two)
151
        max=one;
152
      else
153
        max=two;
154
   endfunction // int
155
 
156
   localparam      AV_READ_WAIT_INDEXED      = (AV_SETUP_WAIT_CYCLES + AV_READ_WAIT_CYCLES);
157
   localparam      AV_WRITE_WAIT_INDEXED     = (AV_SETUP_WAIT_CYCLES + AV_WRITE_WAIT_CYCLES);
158
   localparam      AV_DATA_HOLD_INDEXED      = (AV_WRITE_WAIT_INDEXED + AV_DATA_HOLD_CYCLES);
159
   localparam      LOG2_OF_LATENCY_SUM       = max(clog2_plusone(AV_READ_WAIT_INDEXED + 1),clog2_plusone(AV_DATA_HOLD_INDEXED + 1));
160
   localparam      BURSTCOUNT_SHIFT_SELECTOR = AV_BURSTCOUNT_SYMBOLS ? 0 : BITS_PER_WORD;
161
   localparam      ADDRESS_SHIFT_SELECTOR    = AV_ADDRESS_SYMBOLS ? 0 : BITS_PER_WORD;
162
 
163
   localparam      ADDRESS_HIGH              = ( UAV_ADDRESS_W > AV_ADDRESS_W + ADDRESS_SHIFT_SELECTOR ) ?
164
                                                   AV_ADDRESS_W :
165
                                                   UAV_ADDRESS_W - ADDRESS_SHIFT_SELECTOR;
166
 
167
   localparam      BURSTCOUNT_HIGH           = ( UAV_BURSTCOUNT_W > AV_BURSTCOUNT_W + BURSTCOUNT_SHIFT_SELECTOR ) ?
168
                                                   AV_BURSTCOUNT_W :
169
                                                   UAV_BURSTCOUNT_W - BURSTCOUNT_SHIFT_SELECTOR;
170
   localparam      BYTEENABLE_ADDRESS_BITS   = ( clog2_plusone(UAV_BYTEENABLE_W) - 1 ) >= 1 ? clog2_plusone(UAV_BYTEENABLE_W) - 1 : 1;
171
 
172
 
173
   // Calculate the symbols per word as the power of 2 extended symbols per word
174
   wire [31 : 0] symbols_per_word_int = 2**(clog2_plusone(AV_SYMBOLS_PER_WORD[UAV_BURSTCOUNT_W : 0] - 1));
175
   wire [UAV_BURSTCOUNT_W-1 : 0] symbols_per_word = symbols_per_word_int[UAV_BURSTCOUNT_W-1 : 0];
176
 
177
   // +--------------------------------
178
   // |Backwards Compatibility Signals
179
   // +--------------------------------
180
   assign av_clken = (USE_UAV_CLKEN) ? uav_clken : 1'b1;
181
   assign av_debugaccess = uav_debugaccess;
182
 
183
   // +-------------------
184
   // |Passthru Signals
185
   // +-------------------
186
    always_comb
187
        begin
188
            if (!USE_READRESPONSE && !USE_WRITERESPONSE) begin
189
                uav_response  = '0;
190
            end else begin
191
                uav_response  = av_response;
192
            end
193
        end
194
    assign av_writeresponserequest  = uav_writeresponserequest;
195
    assign uav_writeresponsevalid   = av_writeresponsevalid;
196
 
197
   //-------------------------
198
   //Writedata and Byteenable
199
   //-------------------------
200
 
201
   always@* begin
202
      av_byteenable = '0;
203
      av_byteenable = uav_byteenable[AV_BYTEENABLE_W - 1 : 0];
204
   end
205
 
206
   always@* begin
207
      av_writedata = '0;
208
      av_writedata = uav_writedata[AV_DATA_W - 1 : 0];
209
   end
210
 
211
   // +-------------------
212
   // |Calculated Signals
213
   // +-------------------
214
 
215
   logic [UAV_ADDRESS_W - 1 : 0 ] real_uav_address;
216
 
217
   function [BYTEENABLE_ADDRESS_BITS - 1 : 0 ] decode_byteenable;
218
      input [UAV_BYTEENABLE_W - 1 : 0 ] byteenable;
219
 
220
      for(int i = 0 ; i < UAV_BYTEENABLE_W; i++ ) begin
221
         if(byteenable[i] == 1) begin
222
            return i;
223
         end
224
      end
225
 
226
      return '0;
227
 
228
   endfunction
229
 
230
   reg [AV_BURSTCOUNT_W - 1 : 0]  burstcount_reg;
231
   reg [AV_ADDRESS_W    - 1 : 0]  address_reg;
232
 
233
 
234
   always@(posedge clk, posedge reset) begin
235
      if(reset) begin
236
         burstcount_reg <= '0;
237
         address_reg    <= '0;
238
      end
239
      else begin
240
         burstcount_reg <= burstcount_reg;
241
         address_reg    <= address_reg;
242
 
243
         if(av_beginbursttransfer) begin
244
            burstcount_reg <= uav_burstcount [BURSTCOUNT_HIGH - 1 + BURSTCOUNT_SHIFT_SELECTOR : BURSTCOUNT_SHIFT_SELECTOR ];
245
            address_reg    <= real_uav_address    [ADDRESS_HIGH    - 1 + ADDRESS_SHIFT_SELECTOR    : ADDRESS_SHIFT_SELECTOR    ];
246
 
247
         end
248
      end
249
   end
250
 
251
 
252
   logic [BYTEENABLE_ADDRESS_BITS-1:0] temp_wire;
253
 
254
   always@* begin
255
      if( AV_REQUIRE_UNALIGNED_ADDRESSES == 1) begin
256
         temp_wire = decode_byteenable(uav_byteenable);
257
 
258
         real_uav_address = { uav_address[UAV_ADDRESS_W - 1 : BYTEENABLE_ADDRESS_BITS ], temp_wire[BYTEENABLE_ADDRESS_BITS - 1 : 0 ] };
259
      end
260
      else begin
261
         real_uav_address = uav_address;
262
      end
263
 
264
      av_address = real_uav_address[ADDRESS_HIGH - 1  + ADDRESS_SHIFT_SELECTOR : ADDRESS_SHIFT_SELECTOR ];
265
 
266
      if( AV_CONSTANT_BURST_BEHAVIOR && !UAV_CONSTANT_BURST_BEHAVIOR && ~av_beginbursttransfer )
267
        av_address = address_reg;
268
   end
269
 
270
   always@* begin
271
      av_burstcount=uav_burstcount[BURSTCOUNT_HIGH - 1 + BURSTCOUNT_SHIFT_SELECTOR : BURSTCOUNT_SHIFT_SELECTOR ];
272
 
273
      if( AV_CONSTANT_BURST_BEHAVIOR && !UAV_CONSTANT_BURST_BEHAVIOR && ~av_beginbursttransfer )
274
        av_burstcount = burstcount_reg;
275
   end
276
 
277
   always@* begin
278
        av_lock = uav_lock;
279
   end
280
 
281
   // -------------------
282
   // Writebyteenable Assignment
283
   // -------------------
284
 
285
always@* begin
286
      av_writebyteenable = { (AV_BYTEENABLE_W){uav_write} } & uav_byteenable[AV_BYTEENABLE_W - 1 : 0];
287
end
288
 
289
   // -------------------
290
   // Waitrequest Assignment
291
   // -------------------
292
 
293
   reg       av_waitrequest_generated;
294
   reg       av_waitrequest_generated_read;
295
   reg       av_waitrequest_generated_write;
296
   reg       waitrequest_reset_override;
297
 
298
   reg [ ( LOG2_OF_LATENCY_SUM ? LOG2_OF_LATENCY_SUM - 1 : 0 ) : 0 ] wait_latency_counter;
299
 
300
   always@(posedge reset, posedge clk) begin
301
 
302
      if(reset) begin
303
         wait_latency_counter <= '0;
304
         waitrequest_reset_override <= 1'h1;
305
      end
306
      else begin
307
         waitrequest_reset_override <= 1'h0;
308
 
309
         wait_latency_counter <= '0;
310
 
311
         if( ~uav_waitrequest | waitrequest_reset_override )
312
           wait_latency_counter <= '0;
313
     else if( uav_read | uav_write )
314
       wait_latency_counter <= wait_latency_counter + 1'h1;
315
 
316
      end
317
 
318
   end
319
 
320
 
321
   always @* begin
322
 
323
      av_read    = uav_read;
324
      av_write   = uav_write;
325
 
326
      av_waitrequest_generated       = 1'h1;
327
      av_waitrequest_generated_read  = 1'h1;
328
      av_waitrequest_generated_write = 1'h1;
329
 
330
      if(LOG2_OF_LATENCY_SUM == 1)
331
        av_waitrequest_generated = 0;
332
 
333
      if(LOG2_OF_LATENCY_SUM > 1 && !USE_WAITREQUEST) begin
334
         av_read  = wait_latency_counter >= AV_SETUP_WAIT_CYCLES && uav_read;
335
         av_write = wait_latency_counter >= AV_SETUP_WAIT_CYCLES && uav_write && wait_latency_counter <= AV_WRITE_WAIT_INDEXED;
336
 
337
         av_waitrequest_generated_read  = wait_latency_counter != AV_READ_WAIT_INDEXED;
338
         av_waitrequest_generated_write  = wait_latency_counter != AV_DATA_HOLD_INDEXED;
339
 
340
         if(uav_write)
341
           av_waitrequest_generated = av_waitrequest_generated_write;
342
         else
343
           av_waitrequest_generated = av_waitrequest_generated_read;
344
 
345
      end
346
 
347
      if(USE_WAITREQUEST) begin
348
         uav_waitrequest = av_waitrequest;
349
      end
350
      else begin
351
         uav_waitrequest = av_waitrequest_generated | waitrequest_reset_override;
352
      end
353
 
354
   end
355
 
356
   // --------------
357
   // Readdata Assignment
358
   // --------------
359
 
360
   reg[(AV_DATA_W ? AV_DATA_W -1 : 0 ): 0]              av_readdata_pre;
361
 
362
   always@(posedge clk, posedge reset) begin
363
      if(reset)
364
        av_readdata_pre <= 'b0;
365
      else
366
        av_readdata_pre <= av_readdata;
367
   end
368
 
369
   always@* begin
370
      uav_readdata = {UAV_DATA_W{1'b0}};
371
 
372
      if( AV_READLATENCY != 0  || USE_READDATAVALID ) begin
373
        uav_readdata[AV_DATA_W-1:0] = av_readdata;
374
      end
375
      else begin
376
            uav_readdata[AV_DATA_W-1:0] = av_readdata_pre;
377
      end
378
   end
379
   // -------------------
380
   // Readdatavalid Assigment
381
   // -------------------
382
 
383
   reg[(AV_READLATENCY>0 ? AV_READLATENCY-1:0) :0]      read_latency_shift_reg;
384
   reg                                                  top_read_latency_shift_reg;
385
 
386
 
387
 
388
   always@* begin
389
 
390
      uav_readdatavalid=top_read_latency_shift_reg;
391
 
392
      if(USE_READDATAVALID) begin
393
         uav_readdatavalid = av_readdatavalid;
394
      end
395
 
396
   end
397
 
398
   always@* begin
399
 
400
      top_read_latency_shift_reg = uav_read & ~uav_waitrequest & ~waitrequest_reset_override;
401
 
402
      if(AV_READLATENCY == 1 || AV_READLATENCY == 0 ) begin
403
         top_read_latency_shift_reg=read_latency_shift_reg;
404
      end
405
 
406
      if (AV_READLATENCY > 1) begin
407
         top_read_latency_shift_reg = read_latency_shift_reg[(AV_READLATENCY ? AV_READLATENCY-1 : 0)];
408
      end
409
 
410
   end
411
 
412
   always@(posedge reset, posedge clk) begin
413
 
414
      if (reset) begin
415
         read_latency_shift_reg <= '0;
416
      end
417
      else if (av_clken) begin
418
 
419
         read_latency_shift_reg[0] <= uav_read && ~uav_waitrequest & ~waitrequest_reset_override;
420
 
421
         for (int i=0; i+1 < AV_READLATENCY ; i+=1 ) begin
422
            read_latency_shift_reg[i+1] <= read_latency_shift_reg[i];
423
         end
424
 
425
      end
426
 
427
   end
428
 
429
   // ------------
430
   // Chipselect and OutputEnable
431
   // ------------
432
 
433
   reg             av_chipselect_pre;
434
   wire            cs_extension;
435
   reg             av_outputenable_pre;
436
 
437
 
438
   assign          av_chipselect  = (uav_read | uav_write) ? 1'b1 : av_chipselect_pre;
439
   assign          cs_extension = ( (^ read_latency_shift_reg) & ~top_read_latency_shift_reg ) | ((| read_latency_shift_reg) & ~(^ read_latency_shift_reg));
440
 
441
   assign          av_outputenable = uav_read ? 1'b1 : av_outputenable_pre;
442
 
443
   always@(posedge reset, posedge clk) begin
444
      if(reset)
445
         av_outputenable_pre <= 1'b0;
446
      else if( AV_READLATENCY == 0  && AV_READ_WAIT_INDEXED != 0 )
447
         av_outputenable_pre <= 0;
448
      else
449
         av_outputenable_pre <= cs_extension | uav_read;
450
   end
451
 
452
   always@(posedge reset, posedge clk) begin
453
      if(reset) begin
454
         av_chipselect_pre  <= 1'b0;
455
      end
456
      else begin
457
         av_chipselect_pre  <= 1'b0;
458
 
459
         if(AV_READLATENCY != 0 && CHIPSELECT_THROUGH_READLATENCY == 1) begin
460
            //The AV_READLATENCY term is only here to prevent chipselect from remaining asserted while read and write fall.
461
            //There is no functional impact as 0 cycle transactions are treated as 1 cycle on the other side of the translator.
462
            if(uav_read) begin
463
               av_chipselect_pre <= 1'b1;
464
            end
465
            else if(cs_extension == 1) begin
466
               av_chipselect_pre <= 1'b1;
467
            end
468
 
469
         end
470
      end
471
   end
472
 
473
   // -------------------
474
   // Begintransfer Assigment
475
   // -------------------
476
 
477
   reg       end_begintransfer;
478
 
479
   always@* begin
480
         av_begintransfer = ( uav_write | uav_read ) & ~end_begintransfer;
481
   end
482
 
483
   always@ ( posedge clk or posedge reset ) begin
484
 
485
      if(reset) begin
486
         end_begintransfer <= 1'b0;
487
      end
488
      else begin
489
 
490
         if(av_begintransfer == 1 && uav_waitrequest && ~waitrequest_reset_override)
491
           end_begintransfer <= 1'b1;
492
         else if(uav_waitrequest)
493
           end_begintransfer <= end_begintransfer;
494
         else
495
           end_begintransfer <= 1'b0;
496
 
497
      end
498
 
499
   end
500
 
501
   // -------------------
502
   // Beginbursttransfer Assigment
503
   // -------------------
504
 
505
   reg                                                  end_beginbursttransfer;
506
   reg                                                  in_transfer;
507
 
508
 
509
 
510
   always@* begin
511
         av_beginbursttransfer = uav_read ? av_begintransfer : (av_begintransfer && ~end_beginbursttransfer && ~in_transfer);
512
   end
513
 
514
   always@ ( posedge clk or posedge reset ) begin
515
      if(reset) begin
516
         end_beginbursttransfer <= 1'b0;
517
         in_transfer <= 1'b0;
518
      end
519
      else begin
520
 
521
         end_beginbursttransfer <= uav_write & ( uav_burstcount != symbols_per_word );
522
 
523
         if(uav_write && uav_burstcount == symbols_per_word)
524
           in_transfer <=1'b0;
525
         else if(uav_write)
526
           in_transfer <=1'b1;
527
 
528
      end
529
 
530
   end
531
 
532
endmodule

powered by: WebSVN 2.1.0

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