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_agent.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-2011 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 40 redbear
// $Id: //acds/rel/17.1std/ip/merlin/altera_merlin_slave_agent/altera_merlin_slave_agent.sv#1 $
28 32 redbear
// $Revision: #1 $
29 40 redbear
// $Date: 2017/07/30 $
30 32 redbear
// $Author: swbranch $
31
 
32
`timescale 1 ns / 1 ns
33
 
34
module altera_merlin_slave_agent
35
#(
36
   // Packet parameters
37
   parameter PKT_BEGIN_BURST           = 81,
38
   parameter PKT_DATA_H                = 31,
39
   parameter PKT_DATA_L                = 0,
40
   parameter PKT_SYMBOL_W              = 8,
41
   parameter PKT_BYTEEN_H              = 71,
42
   parameter PKT_BYTEEN_L              = 68,
43
   parameter PKT_ADDR_H                = 63,
44
   parameter PKT_ADDR_L                = 32,
45
   parameter PKT_TRANS_LOCK            = 87,
46
   parameter PKT_TRANS_COMPRESSED_READ = 67,
47
   parameter PKT_TRANS_POSTED          = 66,
48
   parameter PKT_TRANS_WRITE           = 65,
49
   parameter PKT_TRANS_READ            = 64,
50
   parameter PKT_SRC_ID_H              = 74,
51
   parameter PKT_SRC_ID_L              = 72,
52
   parameter PKT_DEST_ID_H             = 77,
53
   parameter PKT_DEST_ID_L             = 75,
54
   parameter PKT_BURSTWRAP_H           = 85,
55
   parameter PKT_BURSTWRAP_L           = 82,
56
   parameter PKT_BYTE_CNT_H            = 81,
57
   parameter PKT_BYTE_CNT_L            = 78,
58
   parameter PKT_PROTECTION_H          = 86,
59
   parameter PKT_PROTECTION_L          = 86,
60
   parameter PKT_RESPONSE_STATUS_H     = 89,
61
   parameter PKT_RESPONSE_STATUS_L     = 88,
62
   parameter PKT_BURST_SIZE_H          = 92,
63
   parameter PKT_BURST_SIZE_L          = 90,
64
   parameter PKT_ORI_BURST_SIZE_L      = 93,
65
   parameter PKT_ORI_BURST_SIZE_H      = 95,
66
   parameter ST_DATA_W                 = 96,
67
   parameter ST_CHANNEL_W              = 32,
68
 
69
   // Slave parameters
70
   parameter ADDR_W           = PKT_ADDR_H - PKT_ADDR_L + 1,
71
   parameter AVS_DATA_W       = PKT_DATA_H - PKT_DATA_L + 1,
72
   parameter AVS_BURSTCOUNT_W = 4,
73
   parameter PKT_SYMBOLS      = AVS_DATA_W / PKT_SYMBOL_W,
74
 
75
   // Slave agent parameters
76
   parameter PREVENT_FIFO_OVERFLOW = 0,
77
   parameter SUPPRESS_0_BYTEEN_CMD = 1,
78
   parameter USE_READRESPONSE      = 0,
79
   parameter USE_WRITERESPONSE     = 0,
80
 
81
   // Derived slave parameters
82
   parameter AVS_BE_W = PKT_BYTEEN_H - PKT_BYTEEN_L + 1,
83
   parameter BURST_SIZE_W = 3,
84
 
85
   // Derived FIFO width
86
   parameter FIFO_DATA_W = ST_DATA_W + 1,
87
 
88
   // ECC parameter
89
   parameter ECC_ENABLE = 0
90
) (
91
   input                         clk,
92
   input                         reset,
93
 
94
   // Universal-Avalon anti-slave
95
   output [ADDR_W-1:0]           m0_address,
96
   output [AVS_BURSTCOUNT_W-1:0] m0_burstcount,
97
   output [AVS_BE_W-1:0]         m0_byteenable,
98
   output                        m0_read,
99
   input [AVS_DATA_W-1:0]        m0_readdata,
100
   input                         m0_waitrequest,
101
   output                        m0_write,
102
   output [AVS_DATA_W-1:0]       m0_writedata,
103
   input                         m0_readdatavalid,
104
   output                        m0_debugaccess,
105
   output                        m0_lock,
106
   input [1:0]                   m0_response,
107
   input                         m0_writeresponsevalid,
108
 
109
   // Avalon-ST FIFO interfaces.
110
   // Note: there's no need to include the "data" field here, at least for
111
   // reads, since readdata is filled in from slave info.  To keep life
112
   // simple, have a data field, but fill it with 0s.
113
   // Av-st response fifo source interface
114
   output reg [FIFO_DATA_W-1:0]  rf_source_data,
115
   output                        rf_source_valid,
116
   output                        rf_source_startofpacket,
117
   output                        rf_source_endofpacket,
118
   input                         rf_source_ready,
119
 
120
   // Av-st response fifo sink interface
121
   input [FIFO_DATA_W-1:0]       rf_sink_data,
122
   input                         rf_sink_valid,
123
   input                         rf_sink_startofpacket,
124
   input                         rf_sink_endofpacket,
125
   output                        rf_sink_ready,
126
 
127
   // Av-st readdata fifo src interface, data and response
128
   // extra 2 bits for storing RESPONSE STATUS
129
   output [AVS_DATA_W+1:0]       rdata_fifo_src_data,
130
   output                        rdata_fifo_src_valid,
131
   input                         rdata_fifo_src_ready,
132
 
133
   // Av-st readdata fifo sink interface
134
   input [AVS_DATA_W+1:0]        rdata_fifo_sink_data,
135
   input                         rdata_fifo_sink_valid,
136
   output                        rdata_fifo_sink_ready,
137
   input                         rdata_fifo_sink_error,
138
 
139
   // Av-st sink command packet interface
140
   output                        cp_ready,
141
   input                         cp_valid,
142
   input [ST_DATA_W-1:0]         cp_data,
143
   input [ST_CHANNEL_W-1:0]      cp_channel,
144
   input                         cp_startofpacket,
145
   input                         cp_endofpacket,
146
 
147
   // Av-st source response packet interface
148
   input                         rp_ready,
149
   output reg                    rp_valid,
150
   output reg [ST_DATA_W-1:0]    rp_data,
151
   output                        rp_startofpacket,
152
   output                        rp_endofpacket
153
);
154
 
155
   // --------------------------------------------------
156
   // Ceil(log2()) function log2ceil of 4 = 2
157
   // --------------------------------------------------
158
   function integer log2ceil;
159
      input reg[63:0] val;
160
      reg [63:0] i;
161
 
162
      begin
163
         i = 1;
164
         log2ceil = 0;
165
 
166
         while (i < val) begin
167
            log2ceil = log2ceil + 1;
168
            i = i << 1;
169
         end
170
      end
171
   endfunction
172
 
173
   // ------------------------------------------------
174
   // Local Parameters
175
   // ------------------------------------------------
176
   localparam DATA_W       = PKT_DATA_H - PKT_DATA_L + 1;
177
   localparam BE_W         = PKT_BYTEEN_H - PKT_BYTEEN_L + 1;
178
   localparam MID_W        = PKT_SRC_ID_H - PKT_SRC_ID_L + 1;
179
   localparam SID_W        = PKT_DEST_ID_H - PKT_DEST_ID_L + 1;
180
   localparam BYTE_CNT_W   = PKT_BYTE_CNT_H - PKT_BYTE_CNT_L + 1;
181
   localparam BURSTWRAP_W  = PKT_BURSTWRAP_H - PKT_BURSTWRAP_L + 1;
182
   localparam BURSTSIZE_W  = PKT_BURST_SIZE_H - PKT_BURST_SIZE_L + 1;
183
   localparam BITS_TO_MASK = log2ceil(PKT_SYMBOLS);
184
   localparam MAX_BURST    = 1 << (AVS_BURSTCOUNT_W - 1);
185
   localparam BURSTING     = (MAX_BURST > PKT_SYMBOLS);
186
 
187
   // ------------------------------------------------
188
   // Signals
189
   // ------------------------------------------------
190
   wire [DATA_W-1:0]      cmd_data;
191
   wire [BE_W-1:0]        cmd_byteen;
192
   wire [ADDR_W-1:0]      cmd_addr;
193
   wire [MID_W-1:0]       cmd_mid;
194
   wire [SID_W-1:0]       cmd_sid;
195
   wire                   cmd_read;
196
   wire                   cmd_write;
197
   wire                   cmd_compressed;
198
   wire                   cmd_posted;
199
   wire [BYTE_CNT_W-1:0]  cmd_byte_cnt;
200
   wire [BURSTWRAP_W-1:0] cmd_burstwrap;
201
   wire [BURSTSIZE_W-1:0] cmd_burstsize;
202
   wire                   cmd_debugaccess;
203
 
204
   wire                   suppress_cmd;
205
   wire                   byteen_asserted;
206
   wire                   suppress_read;
207
   wire                   suppress_write;
208
   wire                   needs_response_synthesis;
209
   wire                   generate_response;
210
 
211
   // Assign command fields
212
   assign cmd_data         = cp_data[PKT_DATA_H  :PKT_DATA_L  ];
213
   assign cmd_byteen       = cp_data[PKT_BYTEEN_H:PKT_BYTEEN_L];
214
   assign cmd_addr         = cp_data[PKT_ADDR_H  :PKT_ADDR_L  ];
215
   assign cmd_compressed   = cp_data[PKT_TRANS_COMPRESSED_READ];
216
   assign cmd_posted       = cp_data[PKT_TRANS_POSTED];
217
   assign cmd_write        = cp_data[PKT_TRANS_WRITE];
218
   assign cmd_read         = cp_data[PKT_TRANS_READ];
219
   assign cmd_mid          = cp_data[PKT_SRC_ID_H :PKT_SRC_ID_L];
220
   assign cmd_sid          = cp_data[PKT_DEST_ID_H:PKT_DEST_ID_L];
221
   assign cmd_byte_cnt     = cp_data[PKT_BYTE_CNT_H:PKT_BYTE_CNT_L];
222
   assign cmd_burstwrap    = cp_data[PKT_BURSTWRAP_H:PKT_BURSTWRAP_L];
223
   assign cmd_burstsize    = cp_data[PKT_BURST_SIZE_H:PKT_BURST_SIZE_L];
224
   assign cmd_debugaccess  = cp_data[PKT_PROTECTION_L];
225
 
226
   // Local "ready_for_command" signal: deasserted when the agent is unable to accept
227
   // another command, e.g. rdv FIFO is full, (local readdata storage is full &&
228
   // ~rp_ready), ...
229
   // Say, this could depend on the type of command, for example, even if the
230
   // rdv FIFO is full, a write request can be accepted.  For later.
231
   wire ready_for_command;
232
 
233
   wire local_lock  = cp_valid & cp_data[PKT_TRANS_LOCK];
234
   wire local_write = cp_valid & cp_data[PKT_TRANS_WRITE];
235
   wire local_read  = cp_valid & cp_data[PKT_TRANS_READ];
236
   wire local_compressed_read = cp_valid & cp_data[PKT_TRANS_COMPRESSED_READ];
237
   wire nonposted_write_endofpacket = ~cp_data[PKT_TRANS_POSTED] & local_write & cp_endofpacket;
238
 
239
   // num_symbols is PKT_SYMBOLS, appropriately sized.
240
   wire [31:0] int_num_symbols = PKT_SYMBOLS;
241
   wire [BYTE_CNT_W-1:0] num_symbols = int_num_symbols[BYTE_CNT_W-1:0];
242
 
243
   generate
244
      if (PREVENT_FIFO_OVERFLOW) begin : prevent_fifo_overflow_block
245
         // ---------------------------------------------------
246
         // Backpressure if the slave says to, or if FIFO overflow may occur.
247
         //
248
         // All commands are backpressured once the FIFO is full
249
         // even if they don't need storage. This breaks a long
250
         // combinatorial path from the master read/write through
251
         // this logic and back to the master via the backpressure
252
         // path.
253
         //
254
         // To avoid a loss of throughput the FIFO will be parameterized
255
         // one slot deeper. The extra slot should never be used in normal
256
         // operation, but should a slave misbehave and accept one more
257
         // read than it should then backpressure will kick in.
258
         //
259
         // An example: assume a slave with MPRT = 2. It can accept a
260
         // command sequence RRWW without backpressuring. If the FIFO is
261
         // only 2 deep, we'd backpressure the writes leading to loss of
262
         // throughput. If the FIFO is 3 deep, we'll only backpressure when
263
         // RRR... which is an illegal condition anyway.
264
         // ---------------------------------------------------
265
 
266
         assign ready_for_command = rf_source_ready;
267
         assign cp_ready = (~m0_waitrequest | suppress_cmd) && ready_for_command;
268
 
269
      end else begin : no_prevent_fifo_overflow_block
270
 
271
         // Do not suppress the command or the slave will
272
         // not be able to waitrequest
273
         assign ready_for_command = 1'b1;
274
         // Backpressure only if the slave says to.
275
         assign cp_ready = ~m0_waitrequest | suppress_cmd;
276
 
277
      end
278
   endgenerate
279
 
280
   generate if (SUPPRESS_0_BYTEEN_CMD && !BURSTING) begin : suppress_0_byteen_cmd_non_bursting
281
      assign byteen_asserted  = |cmd_byteen;
282
      assign suppress_read    = ~byteen_asserted;
283
      assign suppress_write   = ~byteen_asserted;
284
      assign suppress_cmd     = ~byteen_asserted;
285
   end else if (SUPPRESS_0_BYTEEN_CMD && BURSTING) begin: suppress_0_byteen_cmd_bursting
286
      assign byteen_asserted  = |cmd_byteen;
287
      assign suppress_read    = ~byteen_asserted;
288
      assign suppress_write   = 1'b0;
289
      assign suppress_cmd     = ~byteen_asserted && cmd_read;
290
   end else begin : no_suppress_0_byteen_cmd
291
      assign suppress_read    = 1'b0;
292
      assign suppress_write   = 1'b0;
293
      assign suppress_cmd     = 1'b0;
294
   end
295
   endgenerate
296
 
297
   // -------------------------------------------------------------------
298
   // Extract avalon signals from command packet.
299
   // -------------------------------------------------------------------
300
   // Mask off the lower bits of address.
301
   // The burst adapter before this component will break narrow sized packets
302
   // into sub-bursts of length 1. However, the packet addresses are preserved,
303
   // which means this component may see size-aligned addresses.
304
   //
305
   // Masking ensures that the addresses seen by an Avalon slave are aligned to
306
   // the full data width instead of the size.
307
   //
308
   // Example:
309
   // output from burst adapter (datawidth=4, size=2 bytes):
310
   // subburst1 addr=0, subburst2 addr=2, subburst3 addr=4, subburst4 addr=6
311
   // expected output from slave agent:
312
   // subburst1 addr=0, subburst2 addr=0, subburst3 addr=4, subburst4 addr=4
313
   generate
314
      if (BITS_TO_MASK > 0) begin : mask_address
315
 
316
         assign m0_address = { cmd_addr[ADDR_W-1:BITS_TO_MASK], {BITS_TO_MASK{1'b0}} };
317
 
318
      end else begin : no_mask_address
319
 
320
         assign m0_address = cmd_addr;
321
 
322
      end
323
   endgenerate
324
 
325
   assign m0_byteenable = cmd_byteen;
326
   assign m0_writedata  = cmd_data;
327
 
328
   // Note: no Avalon-MM slave in existence accepts uncompressed read bursts -
329
   // this sort of burst exists only in merlin fabric ST packets. What to do
330
   // if we see such a burst? All beats in that burst need to be transmitted
331
   // to the slave so we have enough space-time for byteenable expression.
332
   //
333
   // There can be multiple bursts in a packet, but only one beat per burst
334
   // in  cases. The exception is when we've decided not to insert a
335
   // burst adapter for efficiency reasons, in which case this agent is also
336
   // responsible for driving burstcount to 1 on each beat of an uncompressed
337
   // read burst.
338
 
339
   assign m0_read = ready_for_command & !suppress_read & (local_compressed_read | local_read);
340
 
341
   generate
342
       // AVS_BURSTCOUNT_W and BYTE_CNT_W may not be equal.  Assign m0_burstcount
343
       // from a sub-range, or 0-pad, as appropriate.
344
       if (AVS_BURSTCOUNT_W > BYTE_CNT_W) begin : m0_burstcount_zero_pad
345
          wire [AVS_BURSTCOUNT_W - BYTE_CNT_W - 1 : 0] zero_pad = {(AVS_BURSTCOUNT_W - BYTE_CNT_W) {1'b0}};
346
          assign m0_burstcount = (local_read & ~local_compressed_read) ?
347
             {zero_pad, num_symbols} :
348
             {zero_pad, cmd_byte_cnt};
349
       end
350
       else begin : m0_burstcount_no_pad
351
          assign m0_burstcount = (local_read & ~local_compressed_read) ?
352
          num_symbols[AVS_BURSTCOUNT_W-1:0] :
353
          cmd_byte_cnt[AVS_BURSTCOUNT_W-1:0];
354
       end
355
   endgenerate
356
 
357
   assign m0_write = ready_for_command & local_write & !suppress_write;
358
   assign m0_lock  = ready_for_command & local_lock & (m0_read | m0_write);
359
   assign m0_debugaccess  = cmd_debugaccess;
360
 
361
   // -------------------------------------------------------------------
362
   // Indirection layer for response packet values.  Some may always wire
363
   // directly from the slave translator; others will no doubt emerge from
364
   // various FIFOs.
365
   // What to put in resp_data when a write occured? Answer: it does not
366
   // matter, because only response status is needed for non-posted writes,
367
   // and the packet already has a field for that.
368
   //
369
   // We use the rdata_fifo to store write responses as well. This allows us
370
   // to handle backpressure on the response path, and allows write response
371
   // merging.
372
   assign rdata_fifo_src_valid = m0_readdatavalid | m0_writeresponsevalid;
373
   assign rdata_fifo_src_data  = {m0_response, m0_readdata};
374
 
375
   // ------------------------------------------------------------------
376
   // Generate a token when read commands are suppressed. The token
377
   // is stored in the response FIFO, and will be used to synthesize
378
   // a read response. The same token is used for non-posted write
379
   // response synthesis.
380
   //
381
   // Note: this token is not generated for suppressed uncompressed read cycles;
382
   // the burst uncompression logic at the read side of the response FIFO
383
   // generates the correct number of responses.
384
   //
385
   // When the slave can return the response, let it do its job. Don't
386
   // synthesize a response in that case, unless we've suppressed the
387
   // the last transfer in a write sub-burst.
388
   // ------------------------------------------------------------------
389
   wire write_end_of_subburst;
390
   assign needs_response_synthesis = ((local_read | local_compressed_read) & suppress_read) ||
391
                                        (!USE_WRITERESPONSE && nonposted_write_endofpacket) ||
392
                                        (USE_WRITERESPONSE && write_end_of_subburst && suppress_write);
393
 
394
   // Avalon-ST interfaces to external response FIFO.
395
   //
396
   // For efficiency, when synthesizing a write response we only store a non-posted write
397
   // transaction at its endofpacket, even if it was split into multiple sub-bursts.
398
   //
399
   // When not synthesizing write responses, we store each sub-burst in the FIFO.
400
   // Each sub-burst to the slave will return a response, which corresponds to one
401
   // entry in the FIFO. We merge all the sub-burst responses on the final
402
   // sub-burst and send it on the response channel.
403
 
404
   wire internal_cp_endofburst;
405
   wire [31:0] minimum_bytecount_wire = PKT_SYMBOLS; // to solve qis warning
406
   wire [AVS_BURSTCOUNT_W-1:0] minimum_bytecount;
407
 
408
   assign minimum_bytecount = minimum_bytecount_wire[AVS_BURSTCOUNT_W-1:0];
409
   assign internal_cp_endofburst = (cmd_byte_cnt == minimum_bytecount);
410
   assign write_end_of_subburst = local_write & internal_cp_endofburst;
411
 
412
   assign rf_source_valid = (local_read | local_compressed_read | (nonposted_write_endofpacket && !USE_WRITERESPONSE) | (USE_WRITERESPONSE && internal_cp_endofburst && local_write))
413
                             & ready_for_command & cp_ready;
414
   assign rf_source_startofpacket = cp_startofpacket;
415
   assign rf_source_endofpacket   = cp_endofpacket;
416
   always @* begin
417
      // default: assign every command packet field to the response FIFO...
418
      rf_source_data                                  = {1'b0, cp_data};
419
 
420
      // ... and override select fields as needed.
421
      rf_source_data[FIFO_DATA_W-1]                      = needs_response_synthesis;
422
      rf_source_data[PKT_DATA_H   :PKT_DATA_L]           = {DATA_W {1'b0}};
423
      rf_source_data[PKT_BYTEEN_H :PKT_BYTEEN_L]         = cmd_byteen;
424
      rf_source_data[PKT_ADDR_H   :PKT_ADDR_L]           = cmd_addr;
425
      rf_source_data[PKT_TRANS_COMPRESSED_READ]          = cmd_compressed;
426
      rf_source_data[PKT_TRANS_POSTED]                   = cmd_posted;
427
      rf_source_data[PKT_TRANS_WRITE]                    = cmd_write;
428
      rf_source_data[PKT_TRANS_READ]                     = cmd_read;
429
      rf_source_data[PKT_SRC_ID_H :PKT_SRC_ID_L]         = cmd_mid;
430
      rf_source_data[PKT_DEST_ID_H:PKT_DEST_ID_L]        = cmd_sid;
431
      rf_source_data[PKT_BYTE_CNT_H:PKT_BYTE_CNT_L]      = cmd_byte_cnt;
432
      rf_source_data[PKT_BURSTWRAP_H:PKT_BURSTWRAP_L]    = cmd_burstwrap;
433
      rf_source_data[PKT_BURST_SIZE_H:PKT_BURST_SIZE_L]  = cmd_burstsize;
434
      rf_source_data[PKT_PROTECTION_H:PKT_PROTECTION_L]  = '0;
435
      rf_source_data[PKT_PROTECTION_L]                   = cmd_debugaccess;
436
   end
437
 
438
   wire uncompressor_source_valid;
439
   wire [BURSTSIZE_W-1:0] uncompressor_burstsize;
440
   wire last_write_response;
441
 
442
   // last_write_response indicates the last response of the broken-up write burst (sub-bursts).
443
   // At this time, the final merged response is sent, and rp_valid is only asserted
444
   // once for the whole burst.
445
   generate
446
      if (USE_WRITERESPONSE) begin
447
         assign last_write_response = rf_sink_data[PKT_TRANS_WRITE] & rf_sink_endofpacket;
448
         always @* begin
449
            if (rf_sink_data[PKT_TRANS_WRITE] == 1)
450
               rp_valid = (rdata_fifo_sink_valid | generate_response) & last_write_response & !rf_sink_data[PKT_TRANS_POSTED];
451
            else
452
               rp_valid = rdata_fifo_sink_valid | uncompressor_source_valid;
453
         end
454
      end else begin
455
         assign last_write_response = 1'b0;
456
         always @* begin
457
            rp_valid = rdata_fifo_sink_valid | uncompressor_source_valid;
458
         end
459
      end
460
   endgenerate
461
 
462
   // ------------------------------------------------------------------
463
   // Response merging
464
   // ------------------------------------------------------------------
465
   reg [1:0] current_response;
466
   reg [1:0] response_merged;
467
   generate
468
     if (USE_WRITERESPONSE) begin : response_merging_all
469
        reg first_write_response;
470
        reg reset_merged_output;
471
        reg [1:0] previous_response_in;
472
        reg [1:0]  previous_response;
473
 
474
        always_ff @(posedge clk, posedge reset) begin
475
           if (reset) begin
476
              first_write_response  <= 1'b1;
477
           end
478
           else begin // Merging work for write response, for read: previous_response_in = current_response
479
              if (rf_sink_valid & (rdata_fifo_sink_valid | generate_response) & rf_sink_data[PKT_TRANS_WRITE]) begin
480
                 first_write_response <= 1'b0;
481
                 if (rf_sink_endofpacket)
482
                    first_write_response <= 1'b1;
483
              end
484
           end
485
        end
486
 
487
        always_comb begin
488
           current_response = generate_response ? 2'b00 : rdata_fifo_sink_data[AVS_DATA_W+1:AVS_DATA_W] | {2{rdata_fifo_sink_error}};
489
           reset_merged_output = first_write_response && (rdata_fifo_sink_valid || generate_response);
490
           previous_response_in = reset_merged_output ? current_response : previous_response;
491
           response_merged = current_response >= previous_response ? current_response: previous_response_in;
492
        end
493
 
494
        always_ff @(posedge clk or posedge reset) begin
495
           if (reset) begin
496
              previous_response <= 2'b00;
497
           end
498
           else begin
499
              if (rf_sink_valid & (rdata_fifo_sink_valid || generate_response)) begin
500
                 previous_response <= response_merged;
501
              end
502
           end
503
        end
504
     end else begin : response_merging_read_only
505
        always @* begin
506
           current_response = generate_response ? 2'b00: rdata_fifo_sink_data[AVS_DATA_W+1:AVS_DATA_W] |
507
                                                         {2{rdata_fifo_sink_error}};
508
           response_merged = current_response;
509
        end
510
     end
511
   endgenerate
512
 
513
   assign generate_response = rf_sink_data[FIFO_DATA_W-1];
514
 
515
   wire [BYTE_CNT_W-1:0]  rf_sink_byte_cnt   = rf_sink_data[PKT_BYTE_CNT_H:PKT_BYTE_CNT_L];
516
   wire                   rf_sink_compressed = rf_sink_data[PKT_TRANS_COMPRESSED_READ];
517
   wire [BURSTWRAP_W-1:0] rf_sink_burstwrap  = rf_sink_data[PKT_BURSTWRAP_H:PKT_BURSTWRAP_L];
518
   wire [BURSTSIZE_W-1:0] rf_sink_burstsize  = rf_sink_data[PKT_BURST_SIZE_H:PKT_BURST_SIZE_L];
519
   wire [ADDR_W-1:0]      rf_sink_addr       = rf_sink_data[PKT_ADDR_H:PKT_ADDR_L];
520
   // a non posted write response is always completed in 1 cycle. Modify the startofpacket signal to 1'b1 instead of taking whatever is in the rf_fifo
521
   wire rf_sink_startofpacket_wire = rf_sink_data[PKT_TRANS_WRITE] ? 1'b1 : rf_sink_startofpacket;
522
 
523
   wire [BYTE_CNT_W-1:0]   burst_byte_cnt;
524
   wire [BURSTWRAP_W-1:0]  rp_burstwrap;
525
   wire [ADDR_W-1:0]       rp_address;
526
   wire                    rp_is_compressed;
527
   wire                    ready_for_response;
528
 
529
   // ------------------------------------------------------------------
530
   // We're typically ready for a response if the network is ready. There
531
   // is one exception:
532
   //
533
   // If the slave issues write responses, we only issue a merged response on
534
   // the final sub-burst. As a result, we only care about response channel
535
   // availability on the final burst when we send out the merged response.
536
   // ------------------------------------------------------------------
537
   assign ready_for_response = (USE_WRITERESPONSE) ?
538
                            rp_ready || (rf_sink_data[PKT_TRANS_WRITE] && !last_write_response) || rf_sink_data[PKT_TRANS_POSTED]:
539
                            rp_ready;
540
 
541
   // ------------------------------------------------------------------
542
   // Backpressure the readdata fifo if we're supposed to synthesize a response.
543
   // This may be a read response (for suppressed reads) or a write response
544
   // (for non-posted writes).
545
   // ------------------------------------------------------------------
546
   assign rdata_fifo_sink_ready = rdata_fifo_sink_valid & ready_for_response & ~(rf_sink_valid & generate_response);
547
 
548
   always @* begin
549
      // By default, return all fields...
550
      rp_data                                               = rf_sink_data[ST_DATA_W - 1 : 0];
551
 
552
      // ... and override specific fields.
553
      rp_data[PKT_DATA_H   :PKT_DATA_L]                     = rdata_fifo_sink_data[AVS_DATA_W-1:0];
554
      // Assignments directly from the response fifo.
555
      rp_data[PKT_TRANS_POSTED]                             = rf_sink_data[PKT_TRANS_POSTED];
556
      rp_data[PKT_TRANS_WRITE]                              = rf_sink_data[PKT_TRANS_WRITE];
557
      rp_data[PKT_SRC_ID_H :PKT_SRC_ID_L]                   = rf_sink_data[PKT_DEST_ID_H : PKT_DEST_ID_L];
558
      rp_data[PKT_DEST_ID_H:PKT_DEST_ID_L]                  = rf_sink_data[PKT_SRC_ID_H : PKT_SRC_ID_L];
559
      rp_data[PKT_BYTEEN_H :PKT_BYTEEN_L]                   = rf_sink_data[PKT_BYTEEN_H : PKT_BYTEEN_L];
560
      rp_data[PKT_PROTECTION_H:PKT_PROTECTION_L]            = rf_sink_data[PKT_PROTECTION_H:PKT_PROTECTION_L];
561
 
562
      // Burst uncompressor assignments
563
      rp_data[PKT_ADDR_H   :PKT_ADDR_L]                     = rp_address;
564
      rp_data[PKT_BURSTWRAP_H:PKT_BURSTWRAP_L]              = rp_burstwrap;
565
      rp_data[PKT_BYTE_CNT_H:PKT_BYTE_CNT_L]                = burst_byte_cnt;
566
      rp_data[PKT_TRANS_READ]                               = rf_sink_data[PKT_TRANS_READ] | rf_sink_data[PKT_TRANS_COMPRESSED_READ];
567
      rp_data[PKT_TRANS_COMPRESSED_READ]                    = rp_is_compressed;
568
 
569
      rp_data[PKT_RESPONSE_STATUS_H:PKT_RESPONSE_STATUS_L]  = response_merged;
570
      rp_data[PKT_BURST_SIZE_H:PKT_BURST_SIZE_L]            = uncompressor_burstsize;
571
      // bounce the original size back to the master untouched
572
      rp_data[PKT_ORI_BURST_SIZE_H:PKT_ORI_BURST_SIZE_L]    = rf_sink_data[PKT_ORI_BURST_SIZE_H:PKT_ORI_BURST_SIZE_L];
573
   end
574
 
575
   // ------------------------------------------------------------------
576
   // Note: the burst uncompressor may be asked to generate responses for
577
   // write packets; these are treated the same as single-cycle uncompressed
578
   // reads.
579
   // ------------------------------------------------------------------
580
   altera_merlin_burst_uncompressor #(
581
      .ADDR_W               (ADDR_W),
582
      .BURSTWRAP_W          (BURSTWRAP_W),
583
      .BYTE_CNT_W           (BYTE_CNT_W),
584
      .PKT_SYMBOLS          (PKT_SYMBOLS),
585
      .BURST_SIZE_W         (BURSTSIZE_W)
586
   ) uncompressor (
587
      .clk                  (clk),
588
      .reset                (reset),
589
      .sink_startofpacket   (rf_sink_startofpacket_wire),
590
      .sink_endofpacket     (rf_sink_endofpacket),
591
      .sink_valid           (rf_sink_valid & (rdata_fifo_sink_valid | generate_response)),
592
      .sink_ready           (rf_sink_ready),
593
      .sink_addr            (rf_sink_addr),
594
      .sink_burstwrap       (rf_sink_burstwrap),
595
      .sink_byte_cnt        (rf_sink_byte_cnt),
596
      .sink_is_compressed   (rf_sink_compressed),
597
      .sink_burstsize       (rf_sink_burstsize),
598
 
599
      .source_startofpacket (rp_startofpacket),
600
      .source_endofpacket   (rp_endofpacket),
601
      .source_valid         (uncompressor_source_valid),
602
      .source_ready         (ready_for_response),
603
      .source_addr          (rp_address),
604
      .source_burstwrap     (rp_burstwrap),
605
      .source_byte_cnt      (burst_byte_cnt),
606
      .source_is_compressed (rp_is_compressed),
607
      .source_burstsize     (uncompressor_burstsize)
608
   );
609
 
610
   //--------------------------------------
611
   // Assertion: In case slave support response. The slave needs return response in order
612
   // Ex: non-posted write followed by a read: write response must complete before read data
613
   //--------------------------------------
614
   // synthesis translate_off
615
   ERROR_write_response_and_read_response_cannot_happen_same_time:
616
   assert property ( @(posedge clk)
617
      disable iff (reset) !(m0_writeresponsevalid  && m0_readdatavalid)
618
   );
619
 
620
   // synthesis translate_on
621
endmodule
622
 

powered by: WebSVN 2.1.0

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