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

Subversion Repositories openmsp430

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 221 olivier.gi
// (C) 2001-2014 Altera Corporation. All rights reserved.
2
// Your use of Altera Corporation's design tools, logic functions and other
3
// software and tools, and its AMPP partner logic functions, and any output
4
// files any of the foregoing (including device programming or simulation
5
// files), and any associated documentation or information are expressly subject
6
// to the terms and conditions of the Altera Program License Subscription
7
// Agreement, Altera MegaCore Function License Agreement, or other applicable
8
// license agreement, including, without limitation, that your use is for the
9
// sole purpose of programming logic devices manufactured by Altera and sold by
10
// Altera or its authorized distributors.  Please refer to the applicable
11
// agreement for further details.
12
 
13
 
14
// (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
// $Id: //acds/rel/14.0/ip/merlin/altera_merlin_slave_agent/altera_merlin_slave_agent.sv#2 $
28
// $Revision: #2 $
29
// $Date: 2014/02/20 $
30
// $Author: ccching $
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
(
89
 
90
    input                         clk,
91
    input                         reset,
92
 
93
    // Universal-Avalon anti-slave
94
    output [ADDR_W-1:0]           m0_address,
95
    output [AVS_BURSTCOUNT_W-1:0] m0_burstcount,
96
    output [AVS_BE_W-1:0]         m0_byteenable,
97
    output                        m0_read,
98
    input [AVS_DATA_W-1:0]        m0_readdata,
99
    input                         m0_waitrequest,
100
    output                        m0_write,
101
    output [AVS_DATA_W-1:0]       m0_writedata,
102
    input                         m0_readdatavalid,
103
    output                        m0_debugaccess,
104
    output                        m0_lock,
105
    input [1:0]                   m0_response,
106
    output                        m0_writeresponserequest,
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
 
138
    // Av-st sink command packet interface
139
    output                        cp_ready,
140
    input                         cp_valid,
141
    input [ST_DATA_W-1:0]         cp_data,
142
    input [ST_CHANNEL_W-1:0]      cp_channel,
143
    input                         cp_startofpacket,
144
    input                         cp_endofpacket,
145
 
146
    // Av-st source response packet interface
147
    input                         rp_ready,
148
    output reg                    rp_valid,
149
    output reg [ST_DATA_W-1:0]    rp_data,
150
    output                        rp_startofpacket,
151
    output                        rp_endofpacket
152
);
153
 
154
    // --------------------------------------------------
155
    // Ceil(log2()) function log2ceil of 4 = 2
156
    // --------------------------------------------------
157
    function integer log2ceil;
158
        input reg[63:0] val;
159
        reg [63:0] i;
160
 
161
        begin
162
            i = 1;
163
            log2ceil = 0;
164
 
165
            while (i < val) begin
166
                log2ceil = log2ceil + 1;
167
                i = i << 1;
168
            end
169
        end
170
    endfunction
171
 
172
    // ------------------------------------------------
173
    // Local Parameters
174
    // ------------------------------------------------
175
    localparam DATA_W       = PKT_DATA_H - PKT_DATA_L + 1;
176
    localparam BE_W         = PKT_BYTEEN_H - PKT_BYTEEN_L + 1;
177
    localparam MID_W        = PKT_SRC_ID_H - PKT_SRC_ID_L + 1;
178
    localparam SID_W        = PKT_DEST_ID_H - PKT_DEST_ID_L + 1;
179
    localparam BYTE_CNT_W   = PKT_BYTE_CNT_H - PKT_BYTE_CNT_L + 1;
180
    localparam BURSTWRAP_W  = PKT_BURSTWRAP_H - PKT_BURSTWRAP_L + 1;
181
    localparam BURSTSIZE_W  = PKT_BURST_SIZE_H - PKT_BURST_SIZE_L + 1;
182
    localparam BITS_TO_MASK = log2ceil(PKT_SYMBOLS);
183
    localparam MAX_BURST    = 1 << (AVS_BURSTCOUNT_W - 1);
184
    localparam BURSTING     = (MAX_BURST > PKT_SYMBOLS);
185
 
186
    // ------------------------------------------------
187
    // Signals
188
    // ------------------------------------------------
189
    wire [DATA_W-1:0]      cmd_data;
190
    wire [BE_W-1:0]        cmd_byteen;
191
    wire [ADDR_W-1:0]      cmd_addr;
192
    wire [MID_W-1:0]       cmd_mid;
193
    wire [SID_W-1:0]       cmd_sid;
194
    wire                   cmd_read;
195
    wire                   cmd_write;
196
    wire                   cmd_compressed;
197
    wire                   cmd_posted;
198
    wire [BYTE_CNT_W-1:0]  cmd_byte_cnt;
199
    wire [BURSTWRAP_W-1:0] cmd_burstwrap;
200
    wire [BURSTSIZE_W-1:0] cmd_burstsize;
201
    wire                   cmd_debugaccess;
202
 
203
    wire                   suppress_cmd;
204
    wire                   byteen_asserted;
205
    wire                   suppress_read;
206
    wire                   suppress_write;
207
    wire                   needs_response_synthesis;
208
    wire                   generate_response;
209
 
210
    // Assign command fields
211
    assign cmd_data         = cp_data[PKT_DATA_H  :PKT_DATA_L  ];
212
    assign cmd_byteen       = cp_data[PKT_BYTEEN_H:PKT_BYTEEN_L];
213
    assign cmd_addr         = cp_data[PKT_ADDR_H  :PKT_ADDR_L  ];
214
    assign cmd_compressed   = cp_data[PKT_TRANS_COMPRESSED_READ];
215
    assign cmd_posted       = cp_data[PKT_TRANS_POSTED];
216
    assign cmd_write        = cp_data[PKT_TRANS_WRITE];
217
    assign cmd_read         = cp_data[PKT_TRANS_READ];
218
    assign cmd_mid          = cp_data[PKT_SRC_ID_H :PKT_SRC_ID_L];
219
    assign cmd_sid          = cp_data[PKT_DEST_ID_H:PKT_DEST_ID_L];
220
    assign cmd_byte_cnt     = cp_data[PKT_BYTE_CNT_H:PKT_BYTE_CNT_L];
221
    assign cmd_burstwrap    = cp_data[PKT_BURSTWRAP_H:PKT_BURSTWRAP_L];
222
    assign cmd_burstsize    = cp_data[PKT_BURST_SIZE_H:PKT_BURST_SIZE_L];
223
    assign cmd_debugaccess  = cp_data[PKT_PROTECTION_L];
224
 
225
    // Local "ready_for_command" signal: deasserted when the agent is unable to accept
226
    // another command, e.g. rdv FIFO is full, (local readdata storage is full &&
227
    // ~rp_ready), ...
228
    // Say, this could depend on the type of command, for example, even if the
229
    // rdv FIFO is full, a write request can be accepted.  For later.
230
    wire ready_for_command;
231
 
232
    wire local_lock  = cp_valid & cp_data[PKT_TRANS_LOCK];
233
    wire local_write = cp_valid & cp_data[PKT_TRANS_WRITE];
234
    wire local_read  = cp_valid & cp_data[PKT_TRANS_READ];
235
    wire local_compressed_read = cp_valid & cp_data[PKT_TRANS_COMPRESSED_READ];
236
    wire nonposted_write_endofpacket = ~cp_data[PKT_TRANS_POSTED] & local_write & cp_endofpacket;
237
 
238
    // num_symbols is PKT_SYMBOLS, appropriately sized.
239
    wire [31:0] int_num_symbols = PKT_SYMBOLS;
240
    wire [BYTE_CNT_W-1:0] num_symbols = int_num_symbols[BYTE_CNT_W-1:0];
241
 
242
    generate
243
        if (PREVENT_FIFO_OVERFLOW) begin : prevent_fifo_overflow
244
            // ---------------------------------------------------
245
            // Backpressure if the slave says to, or if FIFO overflow may occur.
246
            //
247
            // All commands are backpressured once the FIFO is full
248
            // even if they don't need storage. This breaks a long
249
            // combinatorial path from the master read/write through
250
            // this logic and back to the master via the backpressure
251
            // path.
252
            //
253
            // To avoid a loss of throughput the FIFO will be parameterized
254
            // one slot deeper. The extra slot should never be used in normal
255
            // operation, but should a slave misbehave and accept one more
256
            // read than it should then backpressure will kick in.
257
            //
258
            // An example: assume a slave with MPRT = 2. It can accept a
259
            // command sequence RRWW without backpressuring. If the FIFO is
260
            // only 2 deep, we'd backpressure the writes leading to loss of
261
            // throughput. If the FIFO is 3 deep, we'll only backpressure when
262
            // RRR... which is an illegal condition anyway.
263
            // ---------------------------------------------------
264
 
265
            assign ready_for_command = rf_source_ready;
266
            assign cp_ready = (~m0_waitrequest | suppress_cmd) && ready_for_command;
267
 
268
        end else begin : no_prevent_fifo_overflow
269
 
270
            // Do not suppress the command or the slave will
271
            // not be able to waitrequest
272
            assign ready_for_command = 1'b1;
273
            // Backpressure only if the slave says to.
274
            assign cp_ready = ~m0_waitrequest | suppress_cmd;
275
 
276
        end
277
    endgenerate
278
 
279
    generate if (SUPPRESS_0_BYTEEN_CMD && !BURSTING) begin : suppress_0_byteen_cmd_non_bursting
280
        assign byteen_asserted  = |cmd_byteen;
281
        assign suppress_read    = ~byteen_asserted;
282
        assign suppress_write   = ~byteen_asserted;
283
        assign suppress_cmd     = ~byteen_asserted;
284
    end else if (SUPPRESS_0_BYTEEN_CMD && BURSTING) begin: suppress_0_byteen_cmd_bursting
285
        assign byteen_asserted  = |cmd_byteen;
286
        assign suppress_read    = ~byteen_asserted;
287
        assign suppress_write   = 1'b0;
288
        assign suppress_cmd     = ~byteen_asserted && cmd_read;
289
    end else begin : no_suppress_0_byteen_cmd
290
        assign suppress_read    = 1'b0;
291
        assign suppress_write   = 1'b0;
292
        assign suppress_cmd     = 1'b0;
293
    end
294
    endgenerate
295
 
296
    // -------------------------------------------------------------------
297
    // Extract avalon signals from command packet.
298
    // -------------------------------------------------------------------
299
    // Mask off the lower bits of address.
300
    // The burst adapter before this component will break narrow sized packets
301
    // into sub-bursts of length 1. However, the packet addresses are preserved,
302
    // which means this component may see size-aligned addresses.
303
    //
304
    // Masking ensures that the addresses seen by an Avalon slave are aligned to
305
    // the full data width instead of the size.
306
    //
307
    // Example:
308
    // output from burst adapter (datawidth=4, size=2 bytes):
309
    // subburst1 addr=0, subburst2 addr=2, subburst3 addr=4, subburst4 addr=6
310
    // expected output from slave agent:
311
    // subburst1 addr=0, subburst2 addr=0, subburst3 addr=4, subburst4 addr=4
312
    generate
313
        if (BITS_TO_MASK > 0) begin : mask_address
314
 
315
            assign m0_address = { cmd_addr[ADDR_W-1:BITS_TO_MASK], {BITS_TO_MASK{1'b0}} };
316
 
317
        end else begin : no_mask_address
318
 
319
            assign m0_address = cmd_addr;
320
 
321
        end
322
    endgenerate
323
 
324
    assign m0_byteenable = cmd_byteen;
325
    assign m0_writedata  = cmd_data;
326
 
327
    // Note: no Avalon-MM slave in existence accepts uncompressed read bursts -
328
    // this sort of burst exists only in merlin fabric ST packets. What to do
329
    // if we see such a burst? All beats in that burst need to be transmitted
330
    // to the slave so we have enough space-time for byteenable expression.
331
    //
332
    // There can be multiple bursts in a packet, but only one beat per burst
333
    // in  cases. The exception is when we've decided not to insert a
334
    // burst adapter for efficiency reasons, in which case this agent is also
335
    // responsible for driving burstcount to 1 on each beat of an uncompressed
336
    // read burst.
337
 
338
    assign m0_read = ready_for_command & !suppress_read &
339
      (local_compressed_read | local_read);
340
 
341
    generate
342
        begin : m0_burstcount_zero_pad
343
            // AVS_BURSTCOUNT_W and BYTE_CNT_W may not be equal.  Assign m0_burstcount
344
            // from a sub-range, or 0-pad, as appropriate.
345
            if (AVS_BURSTCOUNT_W > BYTE_CNT_W) begin
346
                wire [AVS_BURSTCOUNT_W - BYTE_CNT_W - 1 : 0] zero_pad =
347
                  {(AVS_BURSTCOUNT_W - BYTE_CNT_W) {1'b0}};
348
                assign m0_burstcount = (local_read & ~local_compressed_read) ?
349
                  {zero_pad, num_symbols} :
350
                  {zero_pad, cmd_byte_cnt};
351
            end
352
            else begin : m0_burstcount_no_pad
353
                assign m0_burstcount = (local_read & ~local_compressed_read) ?
354
                  num_symbols[AVS_BURSTCOUNT_W-1:0] :
355
                  cmd_byte_cnt[AVS_BURSTCOUNT_W-1:0];
356
            end
357
        end
358
    endgenerate
359
 
360
    assign m0_write = ready_for_command & local_write & !suppress_write;
361
    assign m0_lock  = ready_for_command & local_lock & (m0_read | m0_write);
362
        assign m0_debugaccess  = cmd_debugaccess;
363
        // For now, to support write response
364
        assign m0_writeresponserequest  = ready_for_command & local_write & !suppress_write & !cmd_posted;
365
 
366
    // -------------------------------------------------------------------
367
    // Indirection layer for response packet values.  Some may always wire
368
    // directly from the slave translator; others will no doubt emerge from
369
    // various FIFOs.
370
    // What to put in resp_data when a write occured? Answer: it does not
371
    // matter, because only response status is needed for non-posted writes,
372
    // and the packet already has a field for that.
373
 
374
    // tgngo:Use the rdata_fifo to store write response as well
375
        // So that we wont lost response if master can back-pressured
376
        // as well as it needs for write response merging
377
    assign rdata_fifo_src_valid = m0_readdatavalid | m0_writeresponsevalid;
378
        //assign rdata_fifo_src_valid = m0_readdatavalid;
379
    assign rdata_fifo_src_data  = {m0_response,m0_readdata};
380
 
381
    // ------------------------------------------------------------------
382
    // Generate a token when read commands are suppressed. The token
383
    // is stored in the response FIFO, and will be used to synthesize
384
    // a read response. The same token is used for non-posted write
385
    // response synthesis.
386
    //
387
    // Note: this token is not generated for suppressed uncompressed read cycles;
388
    // the burst uncompression logic at the read side of the response FIFO
389
    // generates the correct number of responses.
390
    // ------------------------------------------------------------------
391
        // When the slave can return the response, let it does its works. Dont generate sysnthesis response
392
    assign needs_response_synthesis = ((local_read | local_compressed_read) & suppress_read) | (nonposted_write_endofpacket && !USE_WRITERESPONSE);
393
 
394
    // Avalon-ST interfaces to external response fifo:
395
        // tgngo:Currently, with "generate response synthesis", only one write command is allowed to write in at eop of non-posted write
396
        // To support response from slave, we need to store each sub-burst of write command into fifo.
397
        // Each sub-burst will return a response and these two command and response are popped out together
398
        // Resposne merging will happen and at end_of_packet of the command - the last sub-burst write
399
        // the slave agent will send out the final merged response
400
 
401
        wire internal_cp_endofburst;
402
        wire [31:0] minimum_bytecount_wire = PKT_SYMBOLS; // to solve qis warning
403
        wire [AVS_BURSTCOUNT_W-1:0]     minimum_bytecount;
404
        assign minimum_bytecount                = minimum_bytecount_wire[AVS_BURSTCOUNT_W-1:0];
405
        assign internal_cp_endofburst   = (cmd_byte_cnt == minimum_bytecount);
406
        wire local_nonposted_write              = ~cp_data[PKT_TRANS_POSTED] & local_write;
407
        wire nonposted_end_of_subburst  = local_nonposted_write & internal_cp_endofburst;
408
 
409
    assign rf_source_valid = (local_read | local_compressed_read | (nonposted_write_endofpacket && !USE_WRITERESPONSE) | (USE_WRITERESPONSE && nonposted_end_of_subburst))
410
                                                                & ready_for_command & cp_ready;
411
    assign rf_source_startofpacket = cp_startofpacket;
412
    assign rf_source_endofpacket   = cp_endofpacket;
413
    always @* begin
414
        // default: assign every command packet field to the response FIFO...
415
        rf_source_data                                  = {1'b0, cp_data};
416
 
417
        // ... and override select fields as needed.
418
        rf_source_data[FIFO_DATA_W-1]                   = needs_response_synthesis;
419
        rf_source_data[PKT_DATA_H   :PKT_DATA_L]        = {DATA_W {1'b0}};
420
        rf_source_data[PKT_BYTEEN_H :PKT_BYTEEN_L]      = cmd_byteen;
421
        rf_source_data[PKT_ADDR_H   :PKT_ADDR_L]        = cmd_addr;
422
        //rf_source_data[PKT_ADDR_H   :PKT_ADDR_L]        = m0_address;
423
        rf_source_data[PKT_TRANS_COMPRESSED_READ]       = cmd_compressed;
424
        rf_source_data[PKT_TRANS_POSTED]                = cmd_posted;
425
        rf_source_data[PKT_TRANS_WRITE]                 = cmd_write;
426
        rf_source_data[PKT_TRANS_READ]                  = cmd_read;
427
        rf_source_data[PKT_SRC_ID_H :PKT_SRC_ID_L]      = cmd_mid;
428
        rf_source_data[PKT_DEST_ID_H:PKT_DEST_ID_L]     = cmd_sid;
429
        rf_source_data[PKT_BYTE_CNT_H:PKT_BYTE_CNT_L]   = cmd_byte_cnt;
430
        rf_source_data[PKT_BURSTWRAP_H:PKT_BURSTWRAP_L] = cmd_burstwrap;
431
        rf_source_data[PKT_BURST_SIZE_H:PKT_BURST_SIZE_L] = cmd_burstsize;
432
        rf_source_data[PKT_PROTECTION_H:PKT_PROTECTION_L] = '0;
433
        rf_source_data[PKT_PROTECTION_L]                = cmd_debugaccess;
434
    end
435
 
436
    wire uncompressor_source_valid;
437
    wire [BURSTSIZE_W-1:0]     uncompressor_burstsize;
438
 
439
        //assign rp_valid = rdata_fifo_sink_valid | uncompressor_source_valid;
440
        // tgngo: last_write_response indicates the last response of the burst (incase need sub-burst)
441
        // at this time, the final response merged will send out, and rp_valid is only asserted
442
        // for one response for whole burst
443
        generate
444
        if (USE_WRITERESPONSE) begin
445
                wire last_write_response = rf_sink_data[PKT_TRANS_WRITE] & !rf_sink_data[PKT_TRANS_POSTED] & rf_sink_endofpacket;
446
                always @* begin
447
                        if (rf_sink_data[PKT_TRANS_WRITE] == 1)
448
                                rp_valid = rdata_fifo_sink_valid & last_write_response;
449
                        else
450
                                rp_valid = rdata_fifo_sink_valid | uncompressor_source_valid;
451
                end
452
        end else begin
453
        always @* begin
454
                    rp_valid = rdata_fifo_sink_valid | uncompressor_source_valid;
455
        end
456
        end
457
        endgenerate
458
        // ------------------------------------------------------------------
459
    // Response merging
460
    // ------------------------------------------------------------------
461
 
462
    reg [1:0] current_response;
463
        reg [1:0] response_merged;
464
        generate
465
        begin: response_merging
466
        if (USE_WRITERESPONSE) begin
467
                reg first_write_response;
468
                reg reset_merged_output;
469
                reg [1:0] previous_response_in;
470
                reg [1:0]  previous_response;
471
 
472
                always_ff @(posedge clk, posedge reset) begin
473
                        if (reset) begin
474
                                first_write_response  <= 1'b1;
475
                        end
476
                        else begin // Merging work for write response, for read: previous_response_in = current_response
477
                                if (rf_sink_valid & rdata_fifo_sink_valid & rf_sink_data[PKT_TRANS_WRITE]) begin
478
                                        first_write_response <= 1'b0;
479
                                        if (rf_sink_endofpacket)
480
                                                first_write_response <= 1'b1;
481
                                end
482
                        end
483
                end
484
 
485
                always_comb begin
486
            current_response = rdata_fifo_sink_data[AVS_DATA_W+1:AVS_DATA_W];
487
                        reset_merged_output = first_write_response && rdata_fifo_sink_valid;
488
                        previous_response_in = reset_merged_output ? current_response : previous_response;
489
                        response_merged = current_response >= previous_response ? current_response: previous_response_in;
490
                end
491
 
492
                always_ff @(posedge clk or posedge reset) begin
493
                        if (reset) begin
494
                                previous_response <= 2'b00;
495
                        end
496
                        else begin
497
                                if (rf_sink_valid & rdata_fifo_sink_valid) begin
498
                                        previous_response <= response_merged;
499
                                end
500
                        end
501
                end
502
        end else begin
503
        always @* begin
504
            current_response = generate_response ? 2'b00: rdata_fifo_sink_data[AVS_DATA_W+1:AVS_DATA_W];
505
                    response_merged = current_response;
506
        end
507
        end
508
        end
509
        endgenerate
510
 
511
        assign generate_response = rf_sink_data[FIFO_DATA_W-1];
512
 
513
    wire [BYTE_CNT_W-1:0]  rf_sink_byte_cnt   = rf_sink_data[PKT_BYTE_CNT_H:PKT_BYTE_CNT_L];
514
    wire                   rf_sink_compressed = rf_sink_data[PKT_TRANS_COMPRESSED_READ];
515
    wire [BURSTWRAP_W-1:0] rf_sink_burstwrap  = rf_sink_data[PKT_BURSTWRAP_H:PKT_BURSTWRAP_L];
516
    wire [BURSTSIZE_W-1:0] rf_sink_burstsize  = rf_sink_data[PKT_BURST_SIZE_H:PKT_BURST_SIZE_L];
517
    wire [ADDR_W-1:0]      rf_sink_addr       = rf_sink_data[PKT_ADDR_H:PKT_ADDR_L];
518
    // 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
519
    wire rf_sink_startofpacket_wire = rf_sink_data[PKT_TRANS_WRITE] ? 1'b1 : rf_sink_startofpacket;
520
 
521
    wire [BYTE_CNT_W-1:0]       burst_byte_cnt;
522
    wire [BURSTWRAP_W-1:0]      rp_burstwrap;
523
    wire [ADDR_W-1:0]           rp_address;
524
    wire                        rp_is_compressed;
525
 
526
    // ------------------------------------------------------------------
527
    // Backpressure the readdata fifo if we're supposed to synthesize a response.
528
    // This may be a read response (for suppressed reads) or a write response
529
    // (for non-posted writes).
530
    // ------------------------------------------------------------------
531
    assign rdata_fifo_sink_ready = rdata_fifo_sink_valid & rp_ready & ~(rf_sink_valid & generate_response);
532
 
533
    always @* begin
534
        // By default, return all fields...
535
        rp_data                                               = rf_sink_data[ST_DATA_W - 1 : 0];
536
 
537
        // ... and override specific fields.
538
        rp_data[PKT_DATA_H   :PKT_DATA_L]                     = rdata_fifo_sink_data[AVS_DATA_W-1:0];
539
        // Assignments directly from the response fifo.
540
        rp_data[PKT_TRANS_POSTED]                             = rf_sink_data[PKT_TRANS_POSTED];
541
        rp_data[PKT_TRANS_WRITE]                              = rf_sink_data[PKT_TRANS_WRITE];
542
        rp_data[PKT_SRC_ID_H :PKT_SRC_ID_L]                   = rf_sink_data[PKT_DEST_ID_H : PKT_DEST_ID_L];
543
        rp_data[PKT_DEST_ID_H:PKT_DEST_ID_L]                  = rf_sink_data[PKT_SRC_ID_H : PKT_SRC_ID_L];
544
        rp_data[PKT_BYTEEN_H :PKT_BYTEEN_L]                   = rf_sink_data[PKT_BYTEEN_H : PKT_BYTEEN_L];
545
        rp_data[PKT_PROTECTION_H:PKT_PROTECTION_L]            = rf_sink_data[PKT_PROTECTION_H:PKT_PROTECTION_L];
546
 
547
        // Burst uncompressor assignments
548
        rp_data[PKT_ADDR_H   :PKT_ADDR_L]                     = rp_address;
549
        rp_data[PKT_BURSTWRAP_H:PKT_BURSTWRAP_L]              = rp_burstwrap;
550
        rp_data[PKT_BYTE_CNT_H:PKT_BYTE_CNT_L]                = burst_byte_cnt;
551
        rp_data[PKT_TRANS_READ]                               = rf_sink_data[PKT_TRANS_READ] | rf_sink_data[PKT_TRANS_COMPRESSED_READ];
552
        rp_data[PKT_TRANS_COMPRESSED_READ]                    = rp_is_compressed;
553
 
554
        // avalon slaves always respond with "okay" -> not true for now
555
        //rp_data[PKT_RESPONSE_STATUS_H:PKT_RESPONSE_STATUS_L]  = {RESPONSE_W{ 1'b0 }};
556
                rp_data[PKT_RESPONSE_STATUS_H:PKT_RESPONSE_STATUS_L]  = response_merged;
557
                rp_data[PKT_BURST_SIZE_H:PKT_BURST_SIZE_L]            = uncompressor_burstsize;
558
                // bounce the original size back to the master untouch
559
                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];
560
    end
561
 
562
    // ------------------------------------------------------------------
563
    // Note: the burst uncompressor may be asked to generate responses for
564
    // write packets; these are treated the same as single-cycle uncompressed
565
    // reads.
566
    // ------------------------------------------------------------------
567
    altera_merlin_burst_uncompressor #(
568
        .ADDR_W               (ADDR_W),
569
        .BURSTWRAP_W          (BURSTWRAP_W),
570
        .BYTE_CNT_W           (BYTE_CNT_W),
571
        .PKT_SYMBOLS          (PKT_SYMBOLS),
572
        .BURST_SIZE_W         (BURSTSIZE_W)
573
    ) uncompressor
574
    (
575
        .clk                  (clk),
576
        .reset                (reset),
577
        .sink_startofpacket   (rf_sink_startofpacket_wire),
578
        .sink_endofpacket     (rf_sink_endofpacket),
579
        .sink_valid           (rf_sink_valid & (rdata_fifo_sink_valid | generate_response)),
580
        .sink_ready           (rf_sink_ready),
581
        .sink_addr            (rf_sink_addr),
582
        .sink_burstwrap       (rf_sink_burstwrap),
583
        .sink_byte_cnt        (rf_sink_byte_cnt),
584
        .sink_is_compressed   (rf_sink_compressed),
585
        .sink_burstsize       (rf_sink_burstsize),
586
 
587
        .source_startofpacket (rp_startofpacket),
588
        .source_endofpacket   (rp_endofpacket),
589
        .source_valid         (uncompressor_source_valid),
590
        .source_ready         (rp_ready),
591
        .source_addr          (rp_address),
592
        .source_burstwrap     (rp_burstwrap),
593
        .source_byte_cnt      (burst_byte_cnt),
594
        .source_is_compressed (rp_is_compressed),
595
        .source_burstsize     (uncompressor_burstsize)
596
    );
597
 
598
//--------------------------------------
599
// Assertion: In case slave support response. Yhe slave needs return response in order
600
// Ex: non-posted write followed by a read: write response must complete before read data
601
//--------------------------------------
602
// synthesis translate_off
603
ERROR_write_response_and_read_response_cannot_happen_same_time:
604
        assert property ( @(posedge clk)
605
                disable iff (reset) !(m0_writeresponsevalid  && m0_readdatavalid)
606
        );
607
 
608
// synthesis translate_on
609
endmodule
610
 

powered by: WebSVN 2.1.0

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