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

Subversion Repositories spacewiresystemc

[/] [spacewiresystemc/] [trunk/] [altera_work/] [spw_fifo_ulight/] [ulight_fifo/] [synthesis/] [submodules/] [altera_merlin_slave_translator.sv] - Blame information for rev 40

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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