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_uncompressor.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 40 redbear
// $Id: //acds/rel/17.1std/ip/merlin/altera_merlin_slave_agent/altera_merlin_burst_uncompressor.sv#1 $
28 32 redbear
// $Revision: #1 $
29 40 redbear
// $Date: 2017/07/30 $
30 32 redbear
// $Author: swbranch $
31
 
32
// ------------------------------------------
33
// Merlin Burst Uncompressor
34
//
35
// Compressed read bursts -> uncompressed
36
// ------------------------------------------
37
 
38
`timescale 1 ns / 1 ns
39
 
40
module altera_merlin_burst_uncompressor
41
#(
42
    parameter ADDR_W      = 16,
43
    parameter BURSTWRAP_W = 3,
44
    parameter BYTE_CNT_W  = 4,
45
    parameter PKT_SYMBOLS = 4,
46
    parameter BURST_SIZE_W = 3
47
)
48
(
49
    input clk,
50
    input reset,
51
 
52
    // sink ST signals
53
    input sink_startofpacket,
54
    input sink_endofpacket,
55
    input sink_valid,
56
    output sink_ready,
57
 
58
    // sink ST "data"
59
    input [ADDR_W - 1: 0] sink_addr,
60
    input [BURSTWRAP_W - 1 : 0] sink_burstwrap,
61
    input [BYTE_CNT_W - 1 : 0] sink_byte_cnt,
62
    input sink_is_compressed,
63
    input [BURST_SIZE_W-1 : 0] sink_burstsize,
64
 
65
    // source ST signals
66
    output source_startofpacket,
67
    output source_endofpacket,
68
    output source_valid,
69
    input source_ready,
70
 
71
    // source ST "data"
72
    output [ADDR_W - 1: 0] source_addr,
73
    output [BURSTWRAP_W - 1 : 0] source_burstwrap,
74
    output [BYTE_CNT_W - 1 : 0] source_byte_cnt,
75
 
76
    // Note: in the slave agent, the output should always be uncompressed.  In
77
    // other applications, it may be required to leave-compressed or not. How to
78
    // control?  Seems like a simple mux - pass-through if no uncompression is
79
    // required.
80
    output source_is_compressed,
81
    output [BURST_SIZE_W-1 : 0] source_burstsize
82
);
83
 
84
//----------------------------------------------------
85
// AXSIZE decoding
86
//
87
// Turns the axsize value into the actual number of bytes
88
// being transferred.
89
// ---------------------------------------------------
90
function reg[63:0] bytes_in_transfer;
91
    input [BURST_SIZE_W-1:0] axsize;
92
    case (axsize)
93
        4'b0000: bytes_in_transfer = 64'b0000000000000000000000000000000000000000000000000000000000000001;
94
        4'b0001: bytes_in_transfer = 64'b0000000000000000000000000000000000000000000000000000000000000010;
95
        4'b0010: bytes_in_transfer = 64'b0000000000000000000000000000000000000000000000000000000000000100;
96
        4'b0011: bytes_in_transfer = 64'b0000000000000000000000000000000000000000000000000000000000001000;
97
        4'b0100: bytes_in_transfer = 64'b0000000000000000000000000000000000000000000000000000000000010000;
98
        4'b0101: bytes_in_transfer = 64'b0000000000000000000000000000000000000000000000000000000000100000;
99
        4'b0110: bytes_in_transfer = 64'b0000000000000000000000000000000000000000000000000000000001000000;
100
        4'b0111: bytes_in_transfer = 64'b0000000000000000000000000000000000000000000000000000000010000000;
101
        4'b1000: bytes_in_transfer = 64'b0000000000000000000000000000000000000000000000000000000100000000;
102
        4'b1001: bytes_in_transfer = 64'b0000000000000000000000000000000000000000000000000000001000000000;
103
        default:bytes_in_transfer = 64'b0000000000000000000000000000000000000000000000000000000000000001;
104
    endcase
105
 
106
endfunction
107
 
108
   // num_symbols is PKT_SYMBOLS, appropriately sized.
109
   wire [31:0] int_num_symbols = PKT_SYMBOLS;
110
   wire [BYTE_CNT_W-1:0] num_symbols = int_num_symbols[BYTE_CNT_W-1:0];
111
 
112
   // def: Burst Compression.  In a merlin network, a compressed burst is one
113
   // which is transmitted in a single beat.  Example: read burst.  In
114
   // constrast, an uncompressed burst (example: write burst) is transmitted in
115
   // one beat per writedata item.
116
   //
117
   // For compressed bursts which require response packets, burst
118
   // uncompression is required.  Concrete example: a read burst of size 8
119
   // occupies one response-fifo position.  When that fifo position reaches the
120
   // front of the FIFO, the slave starts providing the required 8 readdatavalid
121
   // pulses.  The 8 return response beats must be provided in a single packet,
122
   // with incrementing address and decrementing byte_cnt fields.  Upon receipt
123
   // of the final readdata item of the burst, the response FIFO item is
124
   // retired.
125
   // Burst uncompression logic provides:
126
   //   a) 2-state FSM (idle, busy)
127
   //     reset to idle state
128
   //     transition to busy state for 2nd and subsequent rdv pulses
129
   //     - a single-cycle burst (aka non-burst read) causes no transition to
130
   //     busy state.
131
   //   b) response startofpacket/endofpacket logic.  The response FIFO item
132
   //   will have sop asserted, and may have eop asserted. (In the case of
133
   //   multiple read bursts transmit in the command fabric in a single packet,
134
   //   the eop assertion will come in a later FIFO item.)  To support packet
135
   //   conservation, and emit a well-formed packet on the response fabric,
136
   //     i) response fabric startofpacket is asserted only for the first resp.
137
   //     beat;
138
   //     ii) response fabric endofpacket is asserted only for the last resp.
139
   //     beat.
140
   //   c) response address field.  The response address field contains an
141
   //   incrementing sequence, such that each readdata item is associated with
142
   //   its slave-map location.  N.b. a) computing the address correctly requires
143
   //   knowledge of burstwrap behavior b) there may be no clients of the address
144
   //   field, which makes this field a good target for optimization.  See
145
   //   burst_uncompress_address_counter below.
146
   //   d) response byte_cnt field.  The response byte_cnt field contains a
147
   //   decrementing sequence, such that each beat of the response contains the
148
   //   count of bytes to follow.  In the case of sub-bursts in a single packet,
149
   //   the byte_cnt field may decrement down to num_symbols, then back up to
150
   //   some value, multiple times in the packet.
151
 
152
   reg burst_uncompress_busy;
153
   reg [BYTE_CNT_W:0] burst_uncompress_byte_counter;
154
   wire [BYTE_CNT_W-1:0] burst_uncompress_byte_counter_lint;
155
   wire first_packet_beat;
156
   wire last_packet_beat;
157
 
158
   assign first_packet_beat = sink_valid & ~burst_uncompress_busy;
159
   assign burst_uncompress_byte_counter_lint = burst_uncompress_byte_counter[BYTE_CNT_W-1:0];
160
 
161
   // First cycle: burst_uncompress_byte_counter isn't ready yet, mux the input to
162
   // the output.
163
   assign source_byte_cnt =
164
     first_packet_beat ? sink_byte_cnt : burst_uncompress_byte_counter_lint;
165
   assign source_valid = sink_valid;
166
 
167
   // Last packet beat is set throughout receipt of an uncompressed read burst
168
   // from the response FIFO - this forces all the burst uncompression machinery
169
   // idle.
170
   assign last_packet_beat = ~sink_is_compressed |
171
     (
172
     burst_uncompress_busy ?
173
       (sink_valid & (burst_uncompress_byte_counter_lint == num_symbols)) :
174
         sink_valid & (sink_byte_cnt == num_symbols)
175
     );
176
 
177
   always @(posedge clk or posedge reset) begin
178
     if (reset) begin
179
       burst_uncompress_busy <= '0;
180
       burst_uncompress_byte_counter <= '0;
181
     end
182
     else begin
183
       if (source_valid & source_ready & sink_valid) begin
184
         // No matter what the current state, last_packet_beat leads to
185
         // idle.
186
         if (last_packet_beat) begin
187
           burst_uncompress_busy <= '0;
188
           burst_uncompress_byte_counter <= '0;
189
         end
190
         else begin
191
           if (burst_uncompress_busy) begin
192
             burst_uncompress_byte_counter <= (burst_uncompress_byte_counter > 0) ?
193
               (burst_uncompress_byte_counter_lint - num_symbols) :
194
               (sink_byte_cnt - num_symbols);
195
           end
196
           else begin // not busy, at least one more beat to go
197
             burst_uncompress_byte_counter <= sink_byte_cnt - num_symbols;
198
             // To do: should busy go true for numsymbols-size compressed
199
             // bursts?
200
             burst_uncompress_busy <= 1'b1;
201
           end
202
         end
203
       end
204
     end
205
   end
206
 
207
   reg [ADDR_W - 1 : 0 ] burst_uncompress_address_base;
208
   reg [ADDR_W - 1 : 0] burst_uncompress_address_offset;
209
 
210
   wire [63:0] decoded_burstsize_wire;
211
   wire [ADDR_W-1:0] decoded_burstsize;
212
 
213
 
214
   localparam ADD_BURSTWRAP_W = (ADDR_W > BURSTWRAP_W) ? ADDR_W : BURSTWRAP_W;
215
   wire [ADD_BURSTWRAP_W-1:0] addr_width_burstwrap;
216
   // The input burstwrap value can be used as a mask against address values,
217
   // but with one caveat: the address width may be (probably is) wider than
218
   // the burstwrap width.  The spec says: extend the msb of the burstwrap
219
   // value out over the entire address width (but only if the address width
220
   // actually is wider than the burstwrap width; otherwise it's a 0-width or
221
   // negative range and concatenation multiplier).
222
   generate
223
      if (ADDR_W > BURSTWRAP_W) begin : addr_sign_extend
224
         // Sign-extend, just wires:
225
            assign addr_width_burstwrap[ADDR_W - 1 : BURSTWRAP_W] =
226
                {(ADDR_W - BURSTWRAP_W) {sink_burstwrap[BURSTWRAP_W - 1]}};
227
            assign addr_width_burstwrap[BURSTWRAP_W-1:0] = sink_burstwrap [BURSTWRAP_W-1:0];
228
      end
229
      else begin
230
            assign addr_width_burstwrap[BURSTWRAP_W-1 : 0] = sink_burstwrap;
231
      end
232
   endgenerate
233
 
234
   always @(posedge clk or posedge reset) begin
235
     if (reset) begin
236
       burst_uncompress_address_base <= '0;
237
     end
238
     else if (first_packet_beat & source_ready) begin
239
       burst_uncompress_address_base <= sink_addr & ~addr_width_burstwrap[ADDR_W-1:0];
240
     end
241
   end
242
 
243
   assign decoded_burstsize_wire = bytes_in_transfer(sink_burstsize);  //expand it to 64 bits
244
   assign decoded_burstsize = decoded_burstsize_wire[ADDR_W-1:0];      //then take the width that is needed
245
 
246
   wire [ADDR_W : 0] p1_burst_uncompress_address_offset =
247
   (
248
     (first_packet_beat ?
249
       sink_addr :
250
       burst_uncompress_address_offset) + decoded_burstsize
251
    ) &
252
    addr_width_burstwrap[ADDR_W-1:0];
253
    wire [ADDR_W-1:0] p1_burst_uncompress_address_offset_lint = p1_burst_uncompress_address_offset [ADDR_W-1:0];
254
 
255
   always @(posedge clk or posedge reset) begin
256
     if (reset) begin
257
       burst_uncompress_address_offset <= '0;
258
     end
259
     else begin
260
       if (source_ready & source_valid) begin
261
         burst_uncompress_address_offset <= p1_burst_uncompress_address_offset_lint;
262
         // if (first_packet_beat) begin
263
         //   burst_uncompress_address_offset <=
264
         //     (sink_addr + num_symbols) & addr_width_burstwrap;
265
         // end
266
         // else begin
267
         //   burst_uncompress_address_offset <=
268
         //     (burst_uncompress_address_offset + num_symbols) & addr_width_burstwrap;
269
         // end
270
       end
271
     end
272
   end
273
 
274
   // On the first packet beat, send the input address out unchanged,
275
   // while values are computed/registered for 2nd and subsequent beats.
276
   assign source_addr = first_packet_beat ? sink_addr :
277
       burst_uncompress_address_base | burst_uncompress_address_offset;
278
   assign source_burstwrap = sink_burstwrap;
279
   assign source_burstsize = sink_burstsize;
280
 
281
   //-------------------------------------------------------------------
282
   // A single (compressed) read burst will have sop/eop in the same beat.
283
   // A sequence of read sub-bursts emitted by a burst adapter in response to a
284
   // single read burst will have sop on the first sub-burst, eop on the last.
285
   // Assert eop only upon (sink_endofpacket & last_packet_beat) to preserve
286
   // packet conservation.
287
   assign source_startofpacket = sink_startofpacket & ~burst_uncompress_busy;
288
   assign source_endofpacket   = sink_endofpacket & last_packet_beat;
289
   assign sink_ready = source_valid & source_ready & last_packet_beat;
290
 
291
   // This is correct for the slave agent usage, but won't always be true in the
292
   // width adapter.  To do: add an "please uncompress" input, and use it to
293
   // pass-through or modify, and set source_is_compressed accordingly.
294
   assign source_is_compressed = 1'b0;
295
endmodule
296
 

powered by: WebSVN 2.1.0

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