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_burst_adapter_13_1.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
// (C) 2001-2012 Altera Corporation. All rights reserved.
15
// Your use of Altera Corporation's design tools, logic functions and other
16
// software and tools, and its AMPP partner logic functions, and any output
17
// files any of the foregoing (including device programming or simulation
18
// files), and any associated documentation or information are expressly subject
19
// to the terms and conditions of the Altera Program License Subscription
20
// Agreement, Altera MegaCore Function License Agreement, or other applicable
21
// license agreement, including, without limitation, that your use is for the
22
// sole purpose of programming logic devices manufactured by Altera and sold by
23
// Altera or its authorized distributors.  Please refer to the applicable
24
// agreement for further details.
25
 
26
 
27
// $Id: //acds/main/ip/merlin/altera_merlin_burst_adapter/altera_merlin_burst_adapter.sv#68 $
28
// $Revision: #68 $
29
// $Date: 2014/01/23 $
30
// $Author: wkleong $
31
 
32
// -------------------------------------------------------
33
// Merlin Burst Adapter
34
// -------------------------------------------------------
35
 
36
`timescale 1 ns / 1 ns
37
 
38
//  + 1
39
// By definition, burstwrap values are of the form 2^n - 1; adding 1 is a non-ripple operation.
40
module altera_merlin_burst_adapter_burstwrap_increment #(parameter WIDTH = 8)
41
  (
42
    input [WIDTH - 1:0] mask,
43
    output [WIDTH - 1:0] inc
44
  );
45
    assign inc[0] = ~mask[0];
46
 
47
    genvar i;
48
    generate
49
        for (i = 1; i < WIDTH; i = i+1) begin : burstwrap_increment_loop
50
          assign inc[i] = mask[i - 1] & ~mask[i];
51
        end
52
    endgenerate
53
endmodule
54
 
55
module altera_merlin_burst_adapter_adder #(parameter WIDTH = 8) (
56
    input cin,
57
    input  [WIDTH-1 : 0] a,
58
    input  [WIDTH-1 : 0] b,
59
    output [WIDTH-1 : 0] sum
60
  );
61
 
62
  genvar i;
63
 
64
  wire [WIDTH-1:0] carry;
65
  assign sum[0] = a[0] ^ b[0] ^ cin;
66
  assign carry[0] = a[0] & b[0] | a[0] & cin | b[0] & cin;
67
 
68
  generate
69
      for (i = 1; i < WIDTH; i = i+1) begin : full_adder_loop
70
          assign sum[i] = a[i] ^ b[i] ^ carry[i-1];
71
          assign carry[i] = a[i] & b[i] | a[i] & carry[i-1] | b[i] & carry[i-1];
72
      end
73
  endgenerate
74
endmodule
75
 
76
// a - b = a + ~b + 1
77
module altera_merlin_burst_adapter_subtractor #(parameter WIDTH = 8) (
78
    input  [WIDTH-1 : 0] a,
79
    input  [WIDTH-1 : 0] b,
80
    output [WIDTH-1 : 0] diff
81
  );
82
 
83
  altera_merlin_burst_adapter_adder #(.WIDTH (WIDTH)) subtract (
84
    .cin (1'b1),
85
    .a (a),
86
    .b (~b),
87
    .sum (diff)
88
  );
89
endmodule
90
 
91
// Pipeline position:
92
//   0: register module inputs
93
//   1: register module output
94
// I would have expected that with register retiming/duplication turned on, the
95
// pipeline position parameter would have no effect.  Not so,
96
// PIPELINE_POSITION=1 is significantly better than PIPELINE_POSITION=0.
97
 
98
module altera_merlin_burst_adapter_min #(parameter PKT_BYTE_CNT_W=8, PKT_BURSTWRAP_W=8, PIPELINE_POSITION = 1)
99
  (
100
    input clk,
101
    input reset,
102
    input [PKT_BYTE_CNT_W - 1 : 0] a,
103
    input [PKT_BYTE_CNT_W - 1 : 0] b,
104
    input [PKT_BURSTWRAP_W - 1 : 0] c,
105
    input c_enable,
106
    input [PKT_BYTE_CNT_W - 1 : 0] d,
107
    output reg [PKT_BYTE_CNT_W - 1 : 0] result
108
  );
109
 
110
    wire [PKT_BYTE_CNT_W : 0] ab_diff;
111
    wire [PKT_BYTE_CNT_W : 0] ac_diff;
112
    wire [PKT_BYTE_CNT_W : 0] bc_diff;
113
    wire a_lt_b;
114
    wire a_lt_c;
115
    wire b_lt_c;
116
 
117
    reg [PKT_BYTE_CNT_W - 1 : 0] a_reg;
118
    reg [PKT_BYTE_CNT_W - 1 : 0] b_reg;
119
    reg [PKT_BURSTWRAP_W - 1 : 0] c_reg;
120
    reg c_enable_reg;
121
    reg [PKT_BYTE_CNT_W - 1 : 0] d_reg;
122
 
123
    generate
124
      if (PIPELINE_POSITION == 0) begin
125
        always_ff @(posedge clk or posedge reset) begin
126
          if (reset) begin
127
            a_reg <= '0;
128
            b_reg <= '0;
129
            c_reg <= '0;
130
            c_enable_reg <= '0;
131
            d_reg <= '0;
132
          end
133
          else begin
134
            a_reg <= a;
135
            b_reg <= b;
136
            c_reg <= c;
137
            c_enable_reg <= c_enable;
138
            d_reg <= d;
139
          end
140
        end
141
      end
142
      else begin
143
        always @* begin
144
            a_reg = a;
145
            b_reg = b;
146
            c_reg = c;
147
            c_enable_reg = c_enable;
148
            d_reg = d;
149
        end
150
      end
151
    endgenerate
152
 
153
    altera_merlin_burst_adapter_subtractor #(.WIDTH (PKT_BYTE_CNT_W + 1)) ab_sub (
154
      .a ({1'b0, a_reg}),
155
      .b ({1'b0, b_reg}),
156
      .diff (ab_diff)
157
    );
158
    assign a_lt_b = ab_diff[PKT_BYTE_CNT_W];
159
 
160
    altera_merlin_burst_adapter_subtractor #(.WIDTH (PKT_BYTE_CNT_W + 1)) ac_sub (
161
      .a ({1'b0, a_reg}),
162
      .b ({{(PKT_BYTE_CNT_W - PKT_BURSTWRAP_W + 1) {1'b0}}, c_reg}),
163
      .diff (ac_diff)
164
    );
165
    assign a_lt_c = ac_diff[PKT_BYTE_CNT_W];
166
 
167
    altera_merlin_burst_adapter_subtractor #(.WIDTH (PKT_BYTE_CNT_W + 1)) bc_sub (
168
      .a ({1'b0, b_reg}),
169
      .b ({ {(PKT_BYTE_CNT_W - PKT_BURSTWRAP_W + 1) {1'b0}}, c_reg}),
170
      .diff (bc_diff)
171
    );
172
    assign b_lt_c = bc_diff[PKT_BYTE_CNT_W];
173
 
174
    // If d is greater than any of the values, it'll be greater than the min,
175
    // certainly.  If d is greater than the min, use d.  Of course, ignore c if
176
    // !c_enable.
177
 
178
    // Note: d is "number-of-symbols", of width PKT_BYTE_CNT_W. So, a constant,
179
    // and a power of 2 (until we support non-power-of-2 symbols/interface
180
    // here).
181
    // wire use_d = (d > a) || (d > b) || ( (d > c) && c_enable);
182
    // I think there's something clever I can do with masks, but my head hurts,
183
    // so try something simpler.
184
    // wire use_d =
185
    //   (&(~a[PKT_BYTE_CNT_W - 1:LOG2_NUMSYMBOLS])) ||
186
    //   (&(~b[PKT_BYTE_CNT_W-1:LOG2_NUMSYMBOLS])) ||
187
    //   ((&(~c[PKT_BURSTWRAP_W-1:LOG2_NUMSYMBOLS])) && c_enable
188
    // );
189
    wire [PKT_BYTE_CNT_W : 0] da_diff;
190
    wire [PKT_BYTE_CNT_W : 0] db_diff;
191
    wire [PKT_BYTE_CNT_W : 0] dc_diff;
192
    wire d_gt_a;
193
    wire d_gt_b;
194
    wire d_gt_c;
195
 
196
    altera_merlin_burst_adapter_subtractor #(.WIDTH (PKT_BYTE_CNT_W + 1)) da_sub (
197
      .a ({1'b0, d_reg}),
198
      .b ({1'b0, a_reg}),
199
      .diff (da_diff)
200
    );
201
    assign d_gt_a = ~da_diff[PKT_BYTE_CNT_W];
202
 
203
    altera_merlin_burst_adapter_subtractor #(.WIDTH (PKT_BYTE_CNT_W + 1)) db_sub (
204
      .a ({1'b0, d_reg}),
205
      .b ({1'b0, b_reg}),
206
      .diff (db_diff)
207
    );
208
    assign d_gt_b = ~db_diff[PKT_BYTE_CNT_W];
209
 
210
    altera_merlin_burst_adapter_subtractor #(.WIDTH (PKT_BYTE_CNT_W + 1)) dc_sub (
211
      .a ({1'b0, d_reg}),
212
      .b ({ {(PKT_BYTE_CNT_W - PKT_BURSTWRAP_W + 1) {1'b0}}, c_reg}),
213
      .diff (dc_diff)
214
    );
215
    assign d_gt_c = ~(d_reg < c_reg); // kevtan mod ~dc_diff[PKT_BYTE_CNT_W];
216
 
217
    wire use_d = d_gt_a || d_gt_b || (d_gt_c && c_enable_reg);
218
 
219
    wire [4:0] cmp = {a_lt_b, a_lt_c, b_lt_c, c_enable_reg, use_d};
220
 
221
    reg [PKT_BYTE_CNT_W - 1 : 0] p1_result;
222
    always @(a_reg or b_reg or c_reg or d_reg or cmp) begin
223
      casex (cmp)
224
        5'b00010: p1_result = c_reg;
225
        5'b00110: p1_result = b_reg;
226
        5'b01110: p1_result = b_reg;
227
        5'b10010: p1_result = c_reg;
228
        5'b11010: p1_result = a_reg;
229
        5'b11110: p1_result = a_reg;
230
 
231
        5'b00000: p1_result = b_reg;
232
        5'b00100: p1_result = b_reg;
233
        5'b01100: p1_result = b_reg;
234
        5'b10000: p1_result = a_reg;
235
        5'b11000: p1_result = a_reg;
236
        5'b11100: p1_result = a_reg;
237
 
238
        5'b????1: p1_result = d_reg;
239
 
240
        default: p1_result = 'X; // don't-care
241
      endcase
242
    end
243
 
244
    generate
245
      if (PIPELINE_POSITION == 1) begin
246
        always_ff @(posedge clk or posedge reset) begin
247
          if (reset) begin
248
            result <= '0;
249
          end
250
          else begin
251
            result <= p1_result;
252
          end
253
        end
254
      end
255
      else begin
256
        always @* begin
257
          result = p1_result;
258
        end
259
      end
260
    endgenerate
261
endmodule
262
 
263
 
264
module altera_merlin_burst_adapter_13_1
265
#(
266
  parameter // Merlin packet parameters
267
    PKT_BEGIN_BURST             = 81,
268
    PKT_ADDR_H                  = 79,
269
    PKT_ADDR_L                  = 48,
270
    PKT_BYTE_CNT_H              = 5,
271
    PKT_BYTE_CNT_L              = 0,
272
    PKT_BURSTWRAP_H             = 11,
273
    PKT_BURSTWRAP_L             = 6,
274
    PKT_TRANS_COMPRESSED_READ   = 14,
275
    PKT_TRANS_WRITE             = 13,
276
    PKT_TRANS_READ              = 12,
277
    PKT_BYTEEN_H                = 83,
278
    PKT_BYTEEN_L                = 80,
279
    PKT_BURST_TYPE_H            = 88,
280
    PKT_BURST_TYPE_L            = 87,
281
    PKT_BURST_SIZE_H            = 86,
282
    PKT_BURST_SIZE_L            = 84,
283
    IN_NARROW_SIZE              = 0,
284
    OUT_NARROW_SIZE             = 0,
285
    OUT_FIXED                   = 0,
286
    OUT_COMPLETE_WRAP           = 0,
287
    ST_DATA_W                   = 89,
288
    ST_CHANNEL_W                = 8,
289
 
290
    // Component-specific parameters
291
    BYTEENABLE_SYNTHESIS        = 0,
292
    BURSTWRAP_CONST_MASK        = 0,
293
    PIPE_INPUTS                         = 0,
294
    NO_WRAP_SUPPORT                     = 0,
295
    BURSTWRAP_CONST_VALUE       = -1,
296
    OUT_BYTE_CNT_H              = 5,
297
    OUT_BURSTWRAP_H             = 11
298
)
299
(
300
 
301
    input clk,
302
    input reset,
303
 
304
    // -------------------
305
    // Command Sink (Input)
306
    // -------------------
307
    input                       sink0_valid,
308
    input  [ST_DATA_W-1 : 0]    sink0_data,
309
    input  [ST_CHANNEL_W-1 : 0] sink0_channel,
310
    input                       sink0_startofpacket,
311
    input                       sink0_endofpacket,
312
    output reg                  sink0_ready,
313
 
314
    // -------------------
315
    // Command Source (Output)
316
    // -------------------
317
    output reg                      source0_valid,
318
    output reg [ST_DATA_W-1    : 0] source0_data,
319
    output reg [ST_CHANNEL_W-1 : 0] source0_channel,
320
    output reg                      source0_startofpacket,
321
    output reg                      source0_endofpacket,
322
    input                           source0_ready
323
);
324
  localparam
325
    PKT_BYTE_CNT_W          = PKT_BYTE_CNT_H - PKT_BYTE_CNT_L + 1,
326
    PKT_ADDR_W              = PKT_ADDR_H - PKT_ADDR_L + 1,
327
    PKT_BYTEEN_W            = PKT_BYTEEN_H - PKT_BYTEEN_L + 1,
328
    OUT_BYTE_CNT_W          = OUT_BYTE_CNT_H - PKT_BYTE_CNT_L + 1,
329
    OUT_BURSTWRAP_W         = OUT_BURSTWRAP_H - PKT_BURSTWRAP_L + 1,
330
    PKT_BURSTWRAP_W         = PKT_BURSTWRAP_H - PKT_BURSTWRAP_L + 1,
331
    OUT_MAX_BYTE_CNT        = 1 << (OUT_BYTE_CNT_W - 1),
332
    OUT_MAX_BURSTWRAP       = (1 << OUT_BURSTWRAP_W) - 1,
333
    NUM_SYMBOLS             = PKT_BYTEEN_H - PKT_BYTEEN_L + 1,
334
    PKT_BURST_SIZE_W        = PKT_BURST_SIZE_H - PKT_BURST_SIZE_L + 1,
335
    PKT_BURST_TYPE_W        = PKT_BURST_TYPE_H - PKT_BURST_TYPE_L + 1,
336
    LOG2_NUM_SYMBOLS        = (NUM_SYMBOLS == 1) ? 1 :log2ceil(NUM_SYMBOLS);
337
 
338
  // "min" operation on burstwrap values is a bitwise AND.
339
  // Todo: one input is always set to constant OUT_MAX_BURSTWRAP; this is a
340
  // number of the form 2^n.  Does this fact yield an optimization?
341
  function [PKT_BURSTWRAP_W - 1 : 0] altera_merlin_burst_adapter_burstwrap_min(
342
    input [PKT_BURSTWRAP_W - 1 : 0] a, b
343
  );
344
    altera_merlin_burst_adapter_burstwrap_min = a & b;
345
  endfunction
346
 
347
    // --------------------------------------------------
348
    // Ceil(log2()) function
349
    // --------------------------------------------------
350
    function unsigned[63:0] log2ceil;
351
        input reg[63:0] val;
352
        reg [63:0] i;
353
 
354
        begin
355
            i = 1;
356
            log2ceil = 0;
357
 
358
            while (i < val) begin
359
                log2ceil = log2ceil + 1;
360
                i = i << 1;
361
            end
362
        end
363
    endfunction
364
 
365
  //----------------------------------------------------
366
  // AXSIZE encoding: run-time  size of the transaction.
367
  // ---------------------------------------------------
368
  function reg[511:0] set_byteenable_based_on_size;
369
      input [PKT_BURST_SIZE_W-1:0] axsize;
370
           begin
371
              case (axsize)
372
                  4'b0000: set_byteenable_based_on_size = 512'h00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001;
373
                  4'b0001: set_byteenable_based_on_size = 512'h00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003;
374
                  4'b0010: set_byteenable_based_on_size = 512'h0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F;
375
                  4'b0011: set_byteenable_based_on_size = 512'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF;
376
                  4'b0100: set_byteenable_based_on_size = 512'h0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFF;
377
                  4'b0101: set_byteenable_based_on_size = 512'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFF;
378
                  4'b0110: set_byteenable_based_on_size = 512'h0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFF;
379
                  4'b0111: set_byteenable_based_on_size = 512'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
380
                  4'b1000: set_byteenable_based_on_size = 512'h0000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
381
                  4'b1001: set_byteenable_based_on_size = 512'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
382
                  default: set_byteenable_based_on_size = 512'h00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001;
383
              endcase
384
          end
385
  endfunction
386
 
387
  // ---------------------------------------------------
388
  // STATE MACHINE DEFINITIONS
389
  // ---------------------------------------------------
390
  typedef enum bit [2:0] { // int unsigned {
391
    ST_IDLE         = 3'b000,
392
    ST_COMP_TRANS   = 3'b001,   // This state is used for compressed transactions
393
                                                // - Address and byte count needs to be calculated for every round internally
394
    ST_UNCOMP_TRANS = 3'b010,   // This state is used for uncompressed transaction where address is passthrough
395
                                                // and bytecount is decremented based on max
396
    ST_UNCOMP_WR_SUBBURST = 3'b100
397
  } t_state;
398
  t_state state, next_state;
399
 
400
  // ---------------------------------------------------
401
  // AXI Burst Type Encoding
402
  // ---------------------------------------------------
403
  typedef enum bit  [1:0]
404
    {
405
        FIXED       = 2'b00,
406
        INCR        = 2'b01,
407
        WRAP        = 2'b10,
408
        RESERVED    = 2'b11
409
    } AxiBurstType;
410
 
411
  // ------------------------------
412
  // Note on signal naming convention used
413
  // in_*               --> These signals are either coming directly from sink or a combi off the sink signals
414
  //                    --> Timing - zero cycle
415
  // d0_in_*    --> Signals that are to be used in this block. It is off a mux between in_* signals
416
  //                and the 'saved' version of the signals
417
  //                --> Timing - zero cycle (IF PIPE_INPUTS == 0)
418
  // d1_in_*    --> Signals that are output of initial flop stage.
419
  //            --> Timing - always delayed by 1 clock. (vs the input)
420
 
421
  // ------------------------------
422
  // CONSTANTS
423
  // ------------------------------
424
  wire [PKT_BYTE_CNT_W - 1 : 0] num_symbols_sig             = NUM_SYMBOLS               [PKT_BYTE_CNT_W - 1 : 0];
425
  wire [PKT_BYTE_CNT_W - 1 : 0] out_max_byte_cnt_sig    = OUT_MAX_BYTE_CNT      [PKT_BYTE_CNT_W - 1 : 0];
426
 
427
  // quartus integration failure
428
  wire [63:0]                       log2_numsymbols     = log2ceil(NUM_SYMBOLS);
429
  wire [PKT_BURST_SIZE_W - 1 : 0]   encoded_numsymbols  = log2_numsymbols[PKT_BURST_SIZE_W-1:0];
430
 
431
  // ---------------------------------------------------
432
  // INPUT STAGE SIGNALS CONDITIONING
433
  // ---------------------------------------------------
434
 
435
  // Internal wires
436
  reg [ST_DATA_W - 1 : 0 ]              d1_in_data;
437
  reg [ST_CHANNEL_W - 1 : 0 ]           d1_in_channel;
438
  reg [PKT_BURST_SIZE_W - 1 : 0]        d1_in_size;
439
  reg [PKT_BURST_TYPE_W - 1 : 0]        d1_in_bursttype;
440
  reg [PKT_BYTEEN_W - 1 : 0]            d1_in_byteen;
441
  reg [PKT_BURST_SIZE_W - 1 : 0]        d0_in_size;
442
  reg [PKT_BURSTWRAP_W - 1 : 0]         d0_in_burstwrap;
443
  reg [PKT_BURST_TYPE_W - 1 : 0]        d0_in_bursttype;
444
  reg [PKT_ADDR_W - 1 : 0]              d0_in_addr;
445
  reg [PKT_BYTE_CNT_W - 1 : 0]          d0_in_bytecount;
446
  reg   d0_in_narrow;
447
  reg   d0_in_passthru;
448
  reg   d0_in_valid;
449
  reg   d0_in_sop;
450
  reg   d0_in_compressed_read;
451
  reg   d0_in_write;
452
  reg   d0_in_uncompressed_read;
453
  reg   d1_in_eop;
454
  reg   d1_in_uncompressed_read;
455
  reg   d1_in_narrow;
456
  reg   d1_in_passthru;
457
  reg   in_ready_hold;
458
 
459
  reg [PKT_BYTE_CNT_W - 1 : 0] the_min_byte_cnt_or_num_sym;
460
 
461
  wire [PKT_BURSTWRAP_W - 1 : 0] wrap_mask;
462
  wire [PKT_BURSTWRAP_W - 1 : 0] incremented_wrap_mask;
463
  reg disable_wrap_dist_calc;
464
 
465
  // Input stage registers
466
  reg [ST_DATA_W - 1 : 0]        in_data_reg;
467
  reg [ST_CHANNEL_W-1 : 0]       in_channel_reg;
468
  reg [PKT_BYTEEN_W - 1 : 0]     in_byteen_reg;
469
  reg [PKT_BURST_SIZE_W - 1 : 0] in_size_reg;
470
  reg [PKT_BURSTWRAP_W - 1 : 0]  in_burstwrap_reg;
471
  reg [PKT_BURST_TYPE_W - 1 : 0] in_bursttype_reg;
472
  reg [PKT_ADDR_W - 1 : 0]           in_addr_reg;
473
  reg [PKT_BYTE_CNT_W - 1 : 0]   in_bytecount_reg;
474
  reg in_compressed_read_reg;
475
  reg in_uncompressed_read_reg;
476
  reg in_narrow_reg;            // Holds the flag until next burst command.
477
  reg in_passthru_reg;          // Holds flag until next start of packet command
478
  reg in_eop_reg;
479
  reg in_bytecount_reg_zero;
480
  reg in_write_reg;
481
  reg in_valid_reg;
482
  reg in_sop_reg;
483
 
484
 
485
  // Length coversion
486
  reg [PKT_ADDR_W - 1 : 0]       int_nxt_addr_reg;
487
  reg [PKT_ADDR_W - 1 : 0]       int_nxt_addr_reg_dly;
488
  reg [PKT_BYTE_CNT_W - 1 : 0]   int_bytes_remaining_reg;
489
  reg [PKT_BYTE_CNT_W - 1 : 0]   out_uncomp_byte_cnt_reg;
490
  reg [PKT_BURSTWRAP_W - 1 :0]   int_dist_reg;
491
  reg                            new_burst_reg;
492
  reg [PKT_BYTE_CNT_W -1:0]     int_byte_cnt_narrow_reg;
493
 
494
  reg [PKT_ADDR_W - 1 : 0 ]     nxt_addr;
495
  reg [PKT_ADDR_W - 1 : 0 ]     nxt_addr2;
496
  reg [PKT_BYTE_CNT_W - 1 : 0]  nxt_byte_cnt;
497
  reg [PKT_BYTE_CNT_W - 1 : 0]  nxt_uncomp_subburst_byte_cnt;
498
  reg [PKT_BYTE_CNT_W - 1 : 0]  nxt_byte_remaining;
499
  reg [PKT_BURSTWRAP_W - 1 : 0] nxt_dist;
500
  reg [PKT_ADDR_W - 1 : 0]      extended_burstwrap;
501
 
502
  reg  [PKT_BYTE_CNT_W -1 :0] d0_int_bytes_remaining;
503
  reg  [PKT_ADDR_W - 1 : 0 ]  d0_int_nxt_addr;
504
  reg  [PKT_BURSTWRAP_W - 1 : 0 ] d0_int_dist;
505
 
506
  // Output registers
507
  reg [PKT_ADDR_W - 1 : 0]      out_addr_reg;
508
  reg                           out_valid_reg;
509
  reg                           out_sop_reg;
510
  reg                           out_eop_reg;
511
  reg [PKT_BURSTWRAP_W - 1 : 0] out_burstwrap_reg;
512
  reg [PKT_BYTE_CNT_W - 1 : 0]  out_byte_cnt_reg;
513
  reg                           nxt_in_ready;
514
 
515
//  wire [PKT_ADDR_W - 1 : 0]      nxt_out_addr;
516
  wire                           nxt_out_valid;
517
  wire                           nxt_out_sop;
518
  wire                           nxt_out_eop;
519
  wire [PKT_BURSTWRAP_W - 1 : 0] nxt_out_burstwrap;
520
//  wire [PKT_BYTE_CNT_W - 1 : 0]  nxt_bytecount;
521
 
522
  // ----------------
523
  // ALIAS INPUT MAPPINGS
524
  // -----------------
525
  // cmd              PKT_TRANS_COMPRESSED_READ  PKT_TRANS_READ PKT_TRANS_WRITE
526
  // read                                     0               1               0
527
  // compressed read                          1               1               0
528
  // write                                    0               0               1
529
  // N.b. The fabric sets both PKT_TRANS_COMPRESSED_READ and PKT_TRANS_READ ???
530
  wire in_compressed_read       =       sink0_data [PKT_TRANS_COMPRESSED_READ];
531
  wire in_write                     =   sink0_data [PKT_TRANS_WRITE];
532
  wire in_read                      =   sink0_data [PKT_TRANS_READ];
533
  wire in_uncompressed_read     =       in_read & ~sink0_data [PKT_TRANS_COMPRESSED_READ];
534
 
535
  wire [ST_DATA_W - 1 : 0] in_data = sink0_data;
536
  wire in_valid = sink0_valid & in_ready_hold;  // Fbz143820 hold ready and internal valid to zero during reset
537
  wire in_sop   = sink0_startofpacket;
538
  wire in_eop   = sink0_endofpacket;
539
  wire [ST_CHANNEL_W - 1 : 0] in_channel = sink0_channel;
540
 
541
  wire [PKT_ADDR_W - 1 : 0 ]      in_addr      = sink0_data[PKT_ADDR_H : PKT_ADDR_L];
542
  wire [PKT_BYTEEN_W - 1 : 0]     in_byteen    = sink0_data[PKT_BYTEEN_H : PKT_BYTEEN_L];
543
  wire [PKT_BYTE_CNT_W - 1 : 0]   in_bytecount = sink0_data[PKT_BYTE_CNT_H : PKT_BYTE_CNT_L];
544
  wire [PKT_BURST_SIZE_W - 1 : 0] in_size      = IN_NARROW_SIZE ? sink0_data[PKT_BURST_SIZE_H : PKT_BURST_SIZE_L] : encoded_numsymbols;
545
 
546
  // Signals decoded based on inputs
547
  wire [PKT_BYTE_CNT_W - 1 : 0] in_burstcount   = in_bytecount >> log2_numsymbols[PKT_BYTE_CNT_W -1 :0];
548
  wire in_narrow        = in_size < log2_numsymbols[PKT_BYTE_CNT_W -1 :0];
549
  wire in_passthru      = in_burstcount <= 16;
550
 
551
  wire [PKT_BURST_TYPE_W - 1 : 0] in_bursttype = sink0_data[PKT_BURST_TYPE_H : PKT_BURST_TYPE_L];
552
  wire [PKT_BURSTWRAP_W - 1 : 0]  in_burstwrap;
553
 
554
  genvar i;
555
  generate
556
    for (i = 0; i < PKT_BURSTWRAP_W; i = i + 1) begin : assign_burstwrap_bit
557
      if (BURSTWRAP_CONST_MASK[i]) begin
558
        assign in_burstwrap[i] = BURSTWRAP_CONST_VALUE[i];
559
      end
560
      else begin
561
        assign in_burstwrap[i] = sink0_data[PKT_BURSTWRAP_L + i];
562
      end
563
    end
564
  endgenerate
565
 
566
  // ----------------------------------
567
  // Input Load control signals
568
  // ----------------------------------
569
 
570
generate if (PIPE_INPUTS == 0)
571
 begin : NON_PIPELINED_INPUTS
572
 
573
  // Used to capture sink signals as each incoming cycle is accepted.
574
  wire  load_next_cmd   = d0_in_valid & sink0_ready;
575
 
576
  // Used to capture sink signals as each incoming transaction (currently only used by passthru generation)
577
  wire  load_next_pkt   = d0_in_valid & sink0_ready & d0_in_sop;
578
 
579
  always_ff @(posedge clk or posedge reset) begin
580
        if (reset) begin
581
                        in_channel_reg          <= '0;
582
                        in_data_reg             <= '0;
583
                        in_burstwrap_reg        <= '0;
584
                        in_bursttype_reg        <= '0;
585
                        in_byteen_reg           <= '0;
586
                        in_narrow_reg           <= '0;
587
                        in_size_reg                 <= '0;
588
                        in_passthru_reg         <= '0;
589
                        in_eop_reg                  <= '0;
590
                        in_bytecount_reg_zero       <= '0;
591
                        in_uncompressed_read_reg    <= '0;
592
        end
593
        else begin
594
                if (load_next_cmd) begin
595
                        in_channel_reg          <= in_channel;
596
                        in_data_reg             <= in_data;
597
                        in_burstwrap_reg        <= in_burstwrap;
598
                        in_bursttype_reg        <= in_bursttype;
599
                        in_byteen_reg           <= in_byteen;
600
                        in_narrow_reg           <= in_narrow;
601
                        in_size_reg                 <= in_size;
602
                        in_bytecount_reg_zero     <= ~|in_bytecount;
603
                        in_uncompressed_read_reg  <= in_uncompressed_read;
604
            in_eop_reg                <= in_eop;
605
                end
606
 
607
                // Passthru is evaluated every transaction
608
                if (load_next_pkt) begin
609
                        in_passthru_reg         <= in_passthru;
610
                end
611
        end
612
  end
613
 
614
  assign d0_in_size             = new_burst_reg ? in_size       : in_size_reg;
615
  assign d0_in_addr             = in_addr;
616
  assign d0_in_bytecount        = in_bytecount;
617
  assign d0_in_burstwrap        = new_burst_reg ? in_burstwrap  : in_burstwrap_reg;
618
  assign d0_in_bursttype        = new_burst_reg ? in_bursttype  : in_bursttype_reg;
619
  assign d0_in_narrow           = new_burst_reg ? in_narrow     : in_narrow_reg;
620
  assign d0_in_passthru         = load_next_pkt ? in_passthru   : in_passthru_reg;
621
  assign d0_in_write             = in_write;
622
  assign d0_in_compressed_read   = in_compressed_read;
623
  assign d0_in_uncompressed_read = in_uncompressed_read;
624
  assign d0_in_valid             = in_valid;
625
  assign d0_in_sop               = in_sop;
626
  assign d1_in_eop               = in_eop_reg;
627
  assign d1_in_data              = in_data_reg;
628
  assign d1_in_channel           = in_channel_reg;
629
  assign d1_in_size              = in_size_reg;
630
  assign d1_in_bursttype         = in_bursttype_reg;
631
  assign d1_in_byteen            = in_byteen_reg;
632
  assign d1_in_uncompressed_read = in_uncompressed_read_reg;
633
  assign d1_in_narrow            = in_narrow_reg;
634
  assign d1_in_passthru          = in_passthru_reg;
635
 
636
 end : NON_PIPELINED_INPUTS
637
 
638
else
639
 begin : PIPELINED_INPUTS
640
 
641
  reg [PKT_BURST_SIZE_W - 1 : 0]        d0_int_size;
642
  reg [PKT_BURSTWRAP_W - 1 : 0]         d0_int_burstwrap;
643
  reg [PKT_BURST_TYPE_W - 1 : 0]        d0_int_bursttype;
644
  reg d0_int_narrow;
645
  reg d0_int_passthru;
646
 
647
  always_ff @(posedge clk or posedge reset) begin
648
        if (reset) begin
649
            in_channel_reg          <= '0;
650
            in_data_reg             <= '0;
651
            in_burstwrap_reg        <= '0;
652
            in_bursttype_reg        <= '0;
653
            in_byteen_reg           <= '0;
654
            in_narrow_reg           <= '0;
655
            in_size_reg             <= '0;
656
            in_addr_reg             <= '0;
657
            in_passthru_reg         <= '0;
658
            in_eop_reg              <= '0;
659
            in_bytecount_reg        <= '0;
660
            in_bytecount_reg_zero   <= '0;
661
            in_uncompressed_read_reg  <= '0;
662
                        in_write_reg            <= '0;
663
                        in_compressed_read_reg  <= '0;
664
                        in_uncompressed_read_reg <= '0;
665
                        in_sop_reg              <= '0;
666
                        in_valid_reg            <= '0;
667
            d1_in_eop               <= '0;
668
            d1_in_data              <= '0;
669
            d1_in_channel           <= '0;
670
            d1_in_size              <= '0;
671
            d1_in_bursttype         <= '0;
672
            d1_in_byteen            <= '0;
673
            d1_in_uncompressed_read <= '0;
674
            d1_in_narrow            <= '0;
675
            d1_in_passthru          <= '0;
676
                        d0_int_size           <= '0;
677
                        d0_int_burstwrap      <= '0;
678
                        d0_int_bursttype     <= '0;
679
                        d0_int_narrow       <= '0;
680
                        d0_int_passthru         <= '0;
681
        end
682
        else begin
683
                if (sink0_ready & in_valid) begin
684
                        in_channel_reg           <= in_channel;
685
                        in_data_reg              <= in_data;
686
                        in_burstwrap_reg         <= in_burstwrap;
687
                        in_bursttype_reg         <= in_bursttype;
688
                        in_byteen_reg            <= in_byteen;
689
                        in_narrow_reg            <= in_narrow;
690
                        in_size_reg              <= in_size;
691
                        in_addr_reg              <= in_addr;
692
                        in_bytecount_reg         <= in_bytecount;
693
                        in_bytecount_reg_zero    <= ~|in_bytecount;
694
                        in_uncompressed_read_reg  <= in_uncompressed_read;
695
                        in_eop_reg               <= in_eop;
696
                        in_write_reg             <= in_write;
697
                        in_compressed_read_reg   <= in_compressed_read;
698
                        in_uncompressed_read_reg <= in_uncompressed_read;
699
                        in_sop_reg               <= in_sop;
700
                end
701
                // Passthru is evaluated every transaction
702
                if (sink0_ready & in_sop & in_valid) begin
703
                        in_passthru_reg         <= in_passthru;
704
                end
705
 
706
                if (sink0_ready) in_valid_reg             <= in_valid;
707
 
708
                if (    ( (state != ST_COMP_TRANS) & (~source0_valid | source0_ready)) |
709
                        ( (state == ST_COMP_TRANS) & (~source0_valid | source0_ready & source0_endofpacket) ) ) begin
710
                        d1_in_eop               <= in_eop_reg;
711
                        d1_in_data              <= in_data_reg;
712
                        d1_in_channel           <= in_channel_reg;
713
                        d1_in_size              <= in_size_reg;
714
                        d1_in_bursttype         <= in_bursttype_reg;
715
                        d1_in_byteen            <= in_byteen_reg;
716
                        d1_in_uncompressed_read <= in_uncompressed_read_reg;
717
                        d1_in_narrow            <= in_narrow_reg;
718
                        d1_in_passthru          <= in_passthru_reg;
719
                end
720
 
721
                if (    ( (state != ST_COMP_TRANS) & (~source0_valid | source0_ready)) |
722
                        ( (state == ST_COMP_TRANS) & (~source0_valid | source0_ready & source0_endofpacket) ) ) begin
723
                  d0_int_size        <= in_size_reg;
724
                  d0_int_burstwrap   <= in_burstwrap_reg;
725
                  d0_int_bursttype   <= in_bursttype_reg;
726
                  d0_int_narrow      <= in_narrow_reg;
727
                  d0_int_passthru    <= in_passthru_reg;
728
                end
729
 
730
 
731
        end
732
  end
733
 
734
  assign d0_in_size             = new_burst_reg ? in_size_reg : d0_int_size;
735
  assign d0_in_addr             = in_addr_reg;
736
  assign d0_in_bytecount        = in_bytecount_reg;
737
  assign d0_in_burstwrap        = new_burst_reg ? in_burstwrap_reg : d0_int_burstwrap;
738
  assign d0_in_bursttype        = new_burst_reg ? in_bursttype_reg : d0_int_bursttype;
739
  assign d0_in_narrow           = new_burst_reg ? in_narrow_reg : d0_int_narrow;
740
  assign d0_in_passthru         = new_burst_reg ? in_passthru_reg : d0_int_passthru;
741
  assign d0_in_write             = in_write_reg;
742
  assign d0_in_compressed_read   = in_compressed_read_reg;
743
  assign d0_in_uncompressed_read = in_uncompressed_read_reg;
744
  assign d0_in_valid             = in_valid_reg;
745
  assign d0_in_sop               = in_sop_reg;
746
 
747
 end : PIPELINED_INPUTS
748
endgenerate
749
 
750
  // -------------------------------
751
  // Length Calculation Input Staging.
752
  // -------------------------------
753
 
754
  reg [PKT_ADDR_W -1 : 0]       int_nxt_addr_with_offset;
755
 
756
  reg [PKT_BURSTWRAP_W - 1 : 0] no_wrap_dist;
757
 
758
  // These 2 values are part of break up of calculation from pre-flop to post-flop for timing optimization
759
  assign int_nxt_addr_with_offset  = int_nxt_addr_reg | extended_burstwrap & (int_nxt_addr_reg_dly + int_byte_cnt_narrow_reg);
760
 
761
  // Unaligned address support
762
  //reg [PKT_ADDR_W + LOG2_NUM_SYMBOLS - 1 : 0 ] d0_in_addr_aligned_full;
763
  reg [PKT_ADDR_W + log2ceil(NUM_SYMBOLS) - 1 : 0 ] d0_in_addr_aligned_full;
764
  altera_merlin_address_alignment
765
    # (
766
        .ADDR_W             (PKT_ADDR_W),
767
        .BURSTWRAP_W        (1), // Not used in burst adapter calculation usage of this module
768
        .TYPE_W             (0), // Not used in burst adapter calculation usage of this module
769
        .SIZE_W             (PKT_BURST_SIZE_W),
770
        .INCREMENT_ADDRESS  (0),
771
        .NUMSYMBOLS        (NUM_SYMBOLS)
772
        ) align_address_to_size
773
        (
774
            .clk(1'b0), .reset(1'b0), .in_valid(1'b0), .in_sop(1'b0), .in_eop(1'b0), .out_ready(),  // Dummy. Not used in INCREMENT_ADDRESS=0 settings
775
                                                                                                    // This block is purely combi
776
            .in_data    ( { d0_in_addr , d0_in_size } ),
777
            .out_data   ( d0_in_addr_aligned_full )
778
        );
779
 
780
  // On start of every new burst, take in new input values for calculations
781
  assign d0_int_bytes_remaining = new_burst_reg ? d0_in_bytecount: int_bytes_remaining_reg - out_byte_cnt_reg;
782
  assign d0_int_nxt_addr        = new_burst_reg ? d0_in_addr_aligned_full[PKT_ADDR_W-1:0] : int_nxt_addr_with_offset;
783
  assign d0_int_dist            = NO_WRAP_SUPPORT ? no_wrap_dist : incremented_wrap_mask - ( d0_int_nxt_addr[PKT_BURSTWRAP_W-1:0] & wrap_mask);
784
  always_comb begin
785
 
786
    if (OUT_BURSTWRAP_W == 0) begin // Special case: 1-symbol, fixed-burst slave.
787
      no_wrap_dist = ~nxt_out_burstwrap[PKT_BURSTWRAP_W] ? num_symbols_sig : '1;
788
    end
789
    else if (OUT_BURSTWRAP_W == 1) begin
790
     no_wrap_dist =  ~nxt_out_burstwrap[PKT_BURSTWRAP_W - 1] ? num_symbols_sig : '1;
791
    end
792
    else if (LOG2_NUM_SYMBOLS <= OUT_BURSTWRAP_W) begin
793
 
794
     no_wrap_dist = (|nxt_out_burstwrap[PKT_BURSTWRAP_W - 1: 0] &  ~nxt_out_burstwrap[PKT_BURSTWRAP_W - 1]) ?
795
                    num_symbols_sig : '1;
796
    end
797
    else begin
798
     no_wrap_dist = num_symbols_sig;
799
    end
800
 
801
  end
802
 
803
  // -------------------------------
804
  // Output Load Control Signals
805
  // -------------------------------
806
 
807
  // Used by output flops to load in next state when:
808
  // 1. source has taken command (or ready to accept)
809
  // 2. if no command is pending (IDLE)
810
  wire  load_next_out_cmd       = source0_ready | ~source0_valid;
811
  //wire  load_next_out_pkt     = (source0_ready & source0_endofpacket) | ~source0_valid;
812
 
813
  // ---------------------------------------------------
814
  // INTERMEDIATE CONTROL FLAGS / HOLDING REGISTERS
815
  // ---------------------------------------------------
816
 
817
  always_comb begin
818
 
819
    // Default case : Always try to use the slaves max byte count. If a narrow transfer occurs, follow the masters num_symbols_sig
820
    the_min_byte_cnt_or_num_sym = d0_in_narrow ? num_symbols_sig : out_max_byte_cnt_sig;
821
 
822
 
823
    if (OUT_BURSTWRAP_W == 0) begin // Special case: 1-symbol, fixed-burst slave.
824
      disable_wrap_dist_calc = ~d0_in_burstwrap[OUT_BURSTWRAP_W];
825
    end
826
    else begin
827
      if (OUT_NARROW_SIZE || OUT_FIXED || OUT_COMPLETE_WRAP) begin  //AXI Slave
828
        // When burst type is "RESERVED" it means that a fix burst wide-to-narrow has occured
829
        // kevtan : added highest bit of wrap mask
830
        disable_wrap_dist_calc          = (d0_in_passthru && d0_in_bursttype != RESERVED) | nxt_out_burstwrap[PKT_BURSTWRAP_W - 1];
831
        the_min_byte_cnt_or_num_sym     = (d0_in_narrow   && ~d0_in_passthru && d0_in_bursttype==WRAP) ? num_symbols_sig : out_max_byte_cnt_sig;
832
                                              // kevtan : Fbz140322 : in case of narrow transfer, chop to smallest if it's not passthru
833
                                              //                      Calculation is messed up if narrow
834
                                              //                    : added term to only chop to smallest in case of wrapping transactions
835
      end
836
      else if (OUT_BURSTWRAP_W == PKT_BURSTWRAP_W) begin // Sequential slave
837
        disable_wrap_dist_calc = d0_in_burstwrap[PKT_BURSTWRAP_W - 1];
838
      end
839
      else begin
840
        // Dont really have a full story here to tell "Default?"
841
        // This assumes that OUT_BURSTWRAP_W < PKT_BURSTWRAP_W. Then looks at the slave's wrap boundary.
842
        // If d0_in_burstwrap[OUT_BURSTWRAP_W] is set, this is sequential?
843
        // If d0_in_burstwrap[OUT_BURSTWRAP_W - 1] is set, then it needs to be sequential to the slave?
844
        disable_wrap_dist_calc =  ~d0_in_burstwrap[OUT_BURSTWRAP_W] & d0_in_burstwrap[OUT_BURSTWRAP_W - 1];
845
      end
846
    end
847
  end
848
 
849
 
850
  // ----------------------------------------------------
851
  // FSM : Finite State Machine
852
  // For handling the control signals for burst adapter.
853
  // Note: Arcs in the SM will only take effect is there's no backpressurring from the source
854
  // ---------------------------------------------------
855
 
856
  always_comb begin : state_transition
857
    // default
858
    next_state = ST_IDLE;
859
 
860
    case (state)
861
        ST_IDLE : begin
862
                next_state = ST_IDLE;
863
 
864
                if (d0_in_valid) begin
865
                        if (d0_in_write | d0_in_uncompressed_read)      next_state = ST_UNCOMP_TRANS;
866
                        if (d0_in_compressed_read)                  next_state = ST_COMP_TRANS;
867
                end
868
        end
869
 
870
        ST_UNCOMP_TRANS : begin
871
                next_state = ST_UNCOMP_TRANS;
872
 
873
                if (source0_endofpacket) begin
874
                        if (~d0_in_valid) next_state = ST_IDLE;
875
                        else begin
876
                if (d0_in_write | d0_in_uncompressed_read)      next_state = ST_UNCOMP_TRANS;
877
                if (d0_in_compressed_read)                  next_state = ST_COMP_TRANS;
878
            end
879
                end
880
        else begin
881
            if (|nxt_uncomp_subburst_byte_cnt)   next_state = ST_UNCOMP_WR_SUBBURST;
882
        end
883
        end
884
 
885
        ST_UNCOMP_WR_SUBBURST : begin
886
        next_state = ST_UNCOMP_WR_SUBBURST;
887
 
888
        if (source0_endofpacket) begin
889
            if (~d0_in_valid) next_state = ST_IDLE;
890
            else begin
891
                if (d0_in_write | d0_in_uncompressed_read)  next_state = ST_UNCOMP_TRANS;
892
                if (d0_in_compressed_read)                  next_state = ST_COMP_TRANS;
893
            end
894
        end
895
        else begin
896
            if (~|nxt_uncomp_subburst_byte_cnt) next_state = ST_UNCOMP_TRANS;
897
        end
898
    end
899
 
900
        ST_COMP_TRANS : begin
901
        next_state = ST_COMP_TRANS;
902
 
903
        if (source0_endofpacket) begin
904
            if (~d0_in_valid) begin
905
                next_state = ST_IDLE;
906
            end
907
            else begin
908
                if (d0_in_write | d0_in_uncompressed_read)      next_state = ST_UNCOMP_TRANS;
909
                if (d0_in_compressed_read)                      next_state = ST_COMP_TRANS;
910
            end
911
        end
912
    end
913
 
914
  endcase
915
  end
916
 
917
  // ----------------------------------------------------
918
  // FSM : Controlled output control signals
919
  // ----------------------------------------------------
920
 
921
  // in_ready is asserted when:
922
  // 1. IDLE
923
  // 2. COMPRESSED TRANSACTION   : When not being back pressured by source and sending out last cmd.
924
  // 3. UNCOMPRESSED TRANSACTION : When not being back pressured by source
925
 
926
  assign nxt_in_ready = (state == ST_COMP_TRANS) ? source0_endofpacket & source0_ready | ~source0_valid :
927
                                    (state == ST_UNCOMP_TRANS | state == ST_UNCOMP_WR_SUBBURST) ? source0_ready | ~source0_valid :
928
                                    in_ready_hold; // Fbz143820 hold ready and internal valid to zero during reset
929
 
930
  // out_valid is asserted:
931
  // 1. Following sink_valid unless in ST_COMP_TRANS, where it's always one, unless it's endofpacket.
932
  assign nxt_out_valid = ((state == ST_COMP_TRANS) & ~source0_endofpacket ) ? 1'b1 : d0_in_valid;
933
 
934
  // out_startofpacket
935
  // 1. Following sink_startofpacket unless in ST_COMP_TRANS, where it's always one for first cycle before accepted.
936
  assign nxt_out_sop = ( (state == ST_COMP_TRANS) & source0_ready & !new_burst_reg) ? 1'b0 : d0_in_sop;
937
 
938
  // out_endofpacket ??
939
  // Follows sink_endofpacket unless in ST_COMP_TRANS, where it is a compare of whether this is the last cycle
940
  assign nxt_out_eop = (state == ST_COMP_TRANS) ? ( source0_ready? new_burst_reg : in_bytecount_reg_zero ) : d1_in_eop;
941
 
942
 
943
 
944
  always_ff @(posedge clk or posedge reset) begin
945
        if (reset)      begin
946
                state               <= ST_IDLE;
947
                out_valid_reg   <= '0;
948
                out_sop_reg     <= '0;
949
        in_ready_hold   <= '0;
950
        end
951
        else begin
952
        if (~source0_valid | source0_ready) begin
953
                state               <= next_state;
954
                out_valid_reg   <= nxt_out_valid;
955
                out_sop_reg     <= nxt_out_sop;
956
    end
957
        in_ready_hold <= 1'b1;
958
        end
959
  end
960
 
961
  assign sink0_ready = nxt_in_ready; // COMBI OUT??
962
 
963
  // ---------------------------------------------------
964
  // Converter
965
  // ---------------------------------------------------
966
 
967
  // ---------------------------------------------------
968
  // Wrap boundary distance calculation
969
  // ---------------------------------------------------
970
 
971
  // Wrap mask takes in nxt_out_burstwrap to handle cases where there's a wrapping Avalon slave with boundary < PKT_BURSTWRAP_W
972
  assign wrap_mask = disable_wrap_dist_calc ? '1 : nxt_out_burstwrap;
973
 
974
  // Must be valid in the cycle prior to each begin-subburst, for calculating begin_subburst_byte_cnt.
975
  altera_merlin_burst_adapter_burstwrap_increment #(.WIDTH (PKT_BURSTWRAP_W)) the_burstwrap_increment
976
  (
977
    .mask (wrap_mask),
978
    .inc (incremented_wrap_mask)
979
  );
980
 
981
  // ---------------------------------------------------
982
  // Length Converter
983
  // ---------------------------------------------------
984
 
985
  always_comb
986
   begin : EXT_BURSTWRAP
987
        extended_burstwrap  = { {(PKT_ADDR_W - PKT_BURSTWRAP_W) {d0_in_burstwrap[PKT_BURSTWRAP_W -1]}}, d0_in_burstwrap };
988
   end
989
 
990
  altera_merlin_burst_adapter_min #(
991
    .PKT_BYTE_CNT_W (PKT_BYTE_CNT_W),
992
    .PKT_BURSTWRAP_W (PKT_BURSTWRAP_W),
993
    .PIPELINE_POSITION (2) // NO PIPELINE (ALL COMBI)
994
    )
995
   the_min (
996
    .clk (clk),
997
    .reset (reset),
998
    .a (d0_int_bytes_remaining),
999
    .b (the_min_byte_cnt_or_num_sym),
1000
    .c (d0_int_dist),
1001
    .c_enable (~wrap_mask[PKT_BURSTWRAP_W - 1]),
1002
    .d (num_symbols_sig),
1003
    .result (nxt_byte_cnt)
1004
  );
1005
 
1006
// synthesis translate_off
1007
 
1008
// TEMP ASSERTION FOR OWN CHECKING
1009
//always @(posedge clk or posedge reset) begin
1010
//        if (~reset && in_bursttype==WRAP && sink0_valid && sink0_ready && NO_WRAP_SUPPORT==1) begin
1011
//              $display ("SELF_CHK: WRAP transaction seen in no wrap support settings");
1012
//      end
1013
//end
1014
 
1015
// synthesis translate_on
1016
 
1017
  // ---------------------------------------
1018
  // Next Address Calculation
1019
  // ---------------------------------------
1020
  always_comb
1021
   begin : NXT_ADDR_CALC
1022
 
1023
         nxt_addr  = d0_int_nxt_addr & ~extended_burstwrap;
1024
         // this part of calculation is moved to post flop (nxt_addr2 = (extended_burstwrap & (d0_int_nxt_addr + nxt_byte_cnt_narrow));
1025
 
1026
   end
1027
 
1028
  // ---------------------------------------
1029
  // Length Converter Registers
1030
  // ---------------------------------------
1031
  always_ff @(posedge clk or posedge reset) begin
1032
        if (reset) begin
1033
                out_byte_cnt_reg            <= '0;
1034
                int_byte_cnt_narrow_reg <= '0;
1035
                int_bytes_remaining_reg <= '0;
1036
                int_nxt_addr_reg            <= '0;
1037
        int_nxt_addr_reg_dly    <= '0;
1038
                new_burst_reg               <= '0;
1039
                out_addr_reg                <= '0;
1040
        end
1041
        else begin
1042
           if (load_next_out_cmd) begin
1043
        out_byte_cnt_reg        <= nxt_byte_cnt;
1044
        int_byte_cnt_narrow_reg <= (nxt_byte_cnt >> log2_numsymbols[PKT_BYTE_CNT_W -1 :0]) << d0_in_size;
1045
        int_bytes_remaining_reg <= d0_int_bytes_remaining;
1046
        int_nxt_addr_reg        <= nxt_addr;
1047
        int_nxt_addr_reg_dly    <= d0_int_nxt_addr;
1048
        // New burst is when next byte count is equal to bytes remaining. (Used only in COMPRESSED transaction)
1049
        new_burst_reg           <= (nxt_byte_cnt == d0_int_bytes_remaining) | next_state != ST_COMP_TRANS;
1050
        // Initial address and non-COMPRESSED transaction address does not use offset.
1051
        out_addr_reg                <= new_burst_reg ? d0_in_addr : int_nxt_addr_with_offset;
1052
           end
1053
        end
1054
  end
1055
 
1056
 // ----------------------------------------------------
1057
 // Uncompressed transaction calculations
1058
 // Address     : No changes, just pass through (handled in the flop in for out_addr_reg) // Make it to the output?
1059
 // Byte count  : For reads, this will be just the num_symbols_sig
1060
 //                 : For writes, it will need to decrement for subsequent reads unless it's 0,
1061
 //               in which the next calculated byte count is used.
1062
 // ----------------------------------------------------
1063
 
1064
  always_comb
1065
        begin : UNCOMPRESSED_SUBBURST_BYTE_CNT_CALC
1066
 
1067
        // During start of uncompressed transaction, load the nxt_uncomp_subburst_byte_cnt with the "current output byte count - num_symbols_sig"
1068
        // After that, on subsequent cycles, load in the 'saved' byte count value - num_symbols_sig
1069
        // This signal is used also for transition of the state machine to ensure we will reload the byte count with the results from
1070
        // length converter if we decremented to zero.
1071
        // In essence, the wrap boundary is still observed and maintained. [Hence the use of the current output byte count when in ST_UNCOMP_TRANS.
1072
 
1073
        nxt_uncomp_subburst_byte_cnt  =
1074
                (state == ST_UNCOMP_TRANS) ?
1075
                        ( (source0_valid & source0_ready) ? out_byte_cnt_reg - num_symbols_sig : out_uncomp_byte_cnt_reg ) :
1076
                        out_uncomp_byte_cnt_reg - ( (source0_valid & source0_ready)? num_symbols_sig : '0)  ;
1077
 
1078
   end
1079
 
1080
  always_ff @(posedge clk or posedge reset) begin
1081
    if (reset) begin
1082
                out_uncomp_byte_cnt_reg <= '0;
1083
    end
1084
    else begin
1085
        if (load_next_out_cmd) begin
1086
                out_uncomp_byte_cnt_reg <= nxt_uncomp_subburst_byte_cnt;
1087
        end
1088
    end
1089
  end
1090
 
1091
  // ---------------------------------------------------
1092
  // Burst Type Generation
1093
  // AXI/Avalon masters - Avalon slave  - This is pass through from packet to slave
1094
  // AXI/Avalon masters - AXI slave             - It will always be converted to INCR type
1095
  // ---------------------------------------------------
1096
  reg [PKT_BURST_TYPE_W - 1 : 0 ] out_bursttype;
1097
 
1098
  // bursttype will switch to INCR if repeated wraps detected (NOTE: ??)
1099
  assign out_bursttype = ((d1_in_bursttype == RESERVED)| (~d1_in_passthru & OUT_NARROW_SIZE)) ? INCR : d1_in_bursttype;
1100
 
1101
  // ---------------------------------------------------
1102
  // Burst Wrap Generation
1103
  // Burst wrap is taken to be just the MIN between OUT_MAX_BURSTWRAP and the input burstwrap
1104
  // This is to handle cases where the slave's wrapping boundary is different from the master's
1105
  // Essentially, the master transaction characteristics are honored, but the burst wrap is modified.
1106
  // (Arguably, this can be handled by the slave)
1107
  // NOTE: Internally, this is used to generate the wrap_mask, so to calculate the correct wrapping distance.
1108
  // ---------------------------------------------------
1109
 
1110
  assign nxt_out_burstwrap = altera_merlin_burst_adapter_burstwrap_min(OUT_MAX_BURSTWRAP, d0_in_burstwrap);
1111
 
1112
  always_ff @(posedge clk or posedge reset) begin
1113
        if (reset)      out_burstwrap_reg <= '0;
1114
        else
1115
                if (    ( (state != ST_COMP_TRANS) & (~source0_valid | source0_ready)) |
1116
                        ( (state == ST_COMP_TRANS) & (~source0_valid | source0_ready & source0_endofpacket) ) ) begin
1117
                out_burstwrap_reg <= nxt_out_burstwrap;
1118
                end
1119
  end
1120
 
1121
  // ---------------------------------------------------
1122
  // Byte enable generation
1123
  // Follow unless : in compressed transaction.
1124
  // ---------------------------------------------------
1125
  reg  [LOG2_NUM_SYMBOLS - 1 : 0 ] out_addr_masked;
1126
  wire [511:0 ] d1_initial_byteen = set_byteenable_based_on_size(d1_in_size);   // To fix quartus integration error.
1127
                                                                                // Unused bits are expected to be synthesized away
1128
  reg  [PKT_BYTEEN_W - 1 : 0 ] out_byteen;
1129
 
1130
  // Unaligned address changes.
1131
  // NOTE : Assumption : Byte enable is calculated for all cycles coming out from BA, and needs to be based on aligned address.
1132
  //                     Hence, it cannot take directly output address of BA (which sends out unaligned address for 1st cycle)
1133
    always_ff @(posedge clk or posedge reset) begin
1134
        if (reset)                  out_addr_masked <= '0;
1135
        else
1136
            if (load_next_out_cmd)  out_addr_masked <= new_burst_reg ? d0_in_addr_aligned_full[LOG2_NUM_SYMBOLS-1:0] : int_nxt_addr_with_offset[LOG2_NUM_SYMBOLS-1:0];
1137
    end
1138
 
1139
  always_comb begin
1140
        if (BYTEENABLE_SYNTHESIS == 1 && d1_in_narrow == 1 && (state == ST_COMP_TRANS) )
1141
                out_byteen      = d1_initial_byteen [NUM_SYMBOLS-1:0] << out_addr_masked;
1142
        else
1143
                out_byteen      = d1_in_byteen;
1144
  end
1145
 
1146
 
1147
  // ---------------------------------------------------
1148
  // Mapping of output signals. This will help to see what is comb out or flop out
1149
  // ---------------------------------------------------
1150
 
1151
  always_comb begin : source0_out_assignments
1152
 
1153
        source0_valid               = out_valid_reg;
1154
        source0_startofpacket   = out_sop_reg;
1155
        source0_endofpacket         = nxt_out_eop;      // COMBI
1156
 
1157
        // Generic assign to all data
1158
        source0_data    = d1_in_data;
1159
    source0_channel = d1_in_channel;
1160
 
1161
        // Override fields the component is aware of.
1162
        source0_data[PKT_BYTE_CNT_H : PKT_BYTE_CNT_L]           = d1_in_uncompressed_read ? num_symbols_sig :
1163
                                                              (state == ST_UNCOMP_WR_SUBBURST) ? out_uncomp_byte_cnt_reg :
1164
                                                              out_byte_cnt_reg; // COMBI
1165
        source0_data[PKT_ADDR_H : PKT_ADDR_L]               = out_addr_reg;
1166
        source0_data[PKT_BURSTWRAP_H : PKT_BURSTWRAP_L]     = out_burstwrap_reg;
1167
        source0_data[PKT_BURST_TYPE_H : PKT_BURST_TYPE_L]   = out_bursttype;    // COMBI
1168
        source0_data[PKT_BYTEEN_H: PKT_BYTEEN_L]            = out_byteen;               // COMBI
1169
  end
1170
 
1171
 
1172
endmodule
1173
 
1174
 

powered by: WebSVN 2.1.0

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