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

Subversion Repositories spacewiresystemc

[/] [spacewiresystemc/] [trunk/] [altera_work/] [spw_fifo_ulight/] [ulight_fifo/] [synthesis/] [submodules/] [altera_wrap_burst_converter.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 40 redbear
// $Id: //acds/rel/17.1std/ip/merlin/altera_merlin_burst_adapter/new_source/altera_wrap_burst_converter.sv#1 $
15 32 redbear
// $Revision: #1 $
16 40 redbear
// $Date: 2017/07/30 $
17 32 redbear
// $Author: swbranch $
18
 
19
// ------------------------------------------------------
20
// This component is specially for Wrapping Avalon slave.
21
// It converts burst length of input packet
22
// to match slave burst.
23
// ------------------------------------------------------
24
 
25
`timescale 1 ns / 1 ns
26
 
27
module altera_wrap_burst_converter
28
#(
29
  parameter
30
    // ----------------------------------------
31
    // Burst length Parameters
32
    // (real burst length value, not bytecount)
33
    // ----------------------------------------
34
    MAX_IN_LEN              = 16,
35
    MAX_OUT_LEN             = 4,
36
    ADDR_WIDTH              = 12,
37
    BNDRY_WIDTH             = 12,
38
    NUM_SYMBOLS             = 4,
39
    AXI_SLAVE               = 0,
40
    OPTIMIZE_WRITE_BURST    = 0,
41
    // ------------------
42
    // Derived Parameters
43
    // ------------------
44
    LEN_WIDTH       = log2ceil(MAX_IN_LEN) + 1,
45
    OUT_LEN_WIDTH   = log2ceil(MAX_OUT_LEN) + 1,
46
    LOG2_NUMSYMBOLS = log2ceil(NUM_SYMBOLS)
47
)
48
(
49
    input                           clk,
50
    input                           reset,
51
    input                           enable_write,
52
    input                           enable_read,
53
 
54
    input [LEN_WIDTH   - 1 : 0]     in_len,
55
    input [LEN_WIDTH   - 1 : 0]     first_len,
56
    input                           in_sop,
57
 
58
    input [ADDR_WIDTH  - 1 : 0]     in_addr,
59
    input [ADDR_WIDTH  - 1 : 0]     in_addr_reg,
60
    input [BNDRY_WIDTH - 1 : 0]     in_boundary,
61
    input [BNDRY_WIDTH - 1 : 0]     in_burstwrap,
62
    input [BNDRY_WIDTH - 1 : 0]     in_burstwrap_reg,
63
 
64
    // converted output length
65
    // out_len         : compressed burst, read
66
    // uncompressed_len: uncompressed, write
67
    output reg [LEN_WIDTH - 1 : 0]  out_len,
68
    output reg [LEN_WIDTH - 1 : 0]  uncompr_out_len,
69
 
70
    // Compressed address output
71
    output reg [ADDR_WIDTH - 1 : 0] out_addr,
72
    output reg                      new_burst_export
73
);
74
 
75
    // ------------------------------
76
    // Local parameters
77
    // ------------------------------
78
    localparam
79
        OUT_BOUNDARY        = MAX_OUT_LEN * NUM_SYMBOLS,
80
        ADDR_SEL            = log2ceil(OUT_BOUNDARY);
81
 
82
    // ----------------------------------------
83
    // Signals for wrapping support
84
    // ----------------------------------------
85
    reg [LEN_WIDTH - 1 : 0]        remaining_len;
86
    reg [LEN_WIDTH - 1 : 0]        next_out_len;
87
    reg [LEN_WIDTH - 1 : 0]        next_rem_len;
88
    reg [LEN_WIDTH - 1 : 0]        uncompr_remaining_len;
89
    reg                            new_burst;
90
    reg                            uncompr_sub_burst;
91
    reg [LEN_WIDTH - 1 : 0]        next_uncompr_out_len;
92
    reg [LEN_WIDTH - 1 : 0]        next_uncompr_sub_len;
93
 
94
    // Avoid QIS warning
95
    wire [OUT_LEN_WIDTH - 1 : 0]   max_out_length;
96
    assign max_out_length  = MAX_OUT_LEN[OUT_LEN_WIDTH - 1 : 0];
97
 
98
    // ----------------------------------------
99
    // Calculate aligned length for WRAP burst
100
    // ----------------------------------------
101
    reg [ADDR_WIDTH - 1 : 0]       extended_burstwrap;
102
    reg [ADDR_WIDTH - 1 : 0]       extended_burstwrap_reg;
103
 
104
    always_comb begin
105
        extended_burstwrap      = {{(ADDR_WIDTH - BNDRY_WIDTH) {in_burstwrap[BNDRY_WIDTH - 1]}}, in_burstwrap};
106
        extended_burstwrap_reg  = {{(ADDR_WIDTH - BNDRY_WIDTH) {in_burstwrap_reg[BNDRY_WIDTH - 1]}}, in_burstwrap_reg};
107
        new_burst_export        = new_burst;
108
    end
109
 
110
    // -------------------------------------------
111
    // length calculation
112
    // -------------------------------------------
113
    reg [LEN_WIDTH -1 : 0] next_uncompr_remaining_len;
114
    always_comb begin
115
        // Signals name
116
        // *_uncompr_* --> uncompressed transaction
117
        // -------------------------------------------
118
        // Always use max_out_length as possible.
119
        // Else use the remaining length.
120
        // If in length smaller and not cross bndry or same, pass thru.
121
 
122
        if (in_sop) begin
123
            uncompr_remaining_len = in_len;
124
        end
125
        else begin
126
            uncompr_remaining_len = next_uncompr_remaining_len;
127
        end
128
    end // always_comb
129
 
130
    // compressed transactions
131
    always_comb begin : proc_compressed_read
132
        remaining_len  = in_len;
133
        if (!new_burst)
134
            remaining_len = next_rem_len;
135
    end
136
 
137
    always_comb begin
138
        next_uncompr_out_len = first_len;
139
        if (in_sop) begin
140
            next_uncompr_out_len = first_len;
141
        end
142
        else begin
143
            if (uncompr_sub_burst)
144
                next_uncompr_out_len = next_uncompr_sub_len;
145
            else begin
146
                if (uncompr_remaining_len < max_out_length)
147
                    next_uncompr_out_len = uncompr_remaining_len;
148
                else
149
                    next_uncompr_out_len = max_out_length;
150
            end
151
        end
152
    end
153
 
154
    // Compressed transaction: Always try to send MAX out_len then remaining length.
155
    // Seperate it as the main difference is the first out len.
156
    // For a WRAP burst, the first beat is the aligned length, then similar to INCR.
157
    always_comb begin
158
        if (new_burst) begin
159
            next_out_len = first_len;
160
        end
161
        else begin
162
            next_out_len = max_out_length;
163
            if (remaining_len < max_out_length) begin
164
                next_out_len = remaining_len;
165
            end
166
        end
167
    end // always_comb
168
 
169
    // --------------------------------------------------
170
    // Length remaining calculation : Compressed
171
    // --------------------------------------------------
172
    // length remaining for compressed transaction
173
    // for wrap, need special handling for first out length
174
 
175
    always_ff @(posedge clk, posedge reset) begin
176
        if (reset)
177
            next_rem_len  <= 0;
178
        else if (enable_read) begin
179
            if (new_burst)
180
                next_rem_len <= in_len - first_len;
181
            else
182
                next_rem_len <= next_rem_len - max_out_length;
183
        end
184
    end // always_ff @
185
 
186
    // --------------------------------------------------
187
    // Length remaining calculation : Uncompressed
188
    // --------------------------------------------------
189
    always_ff @(posedge clk, posedge reset) begin
190
        if (reset) begin
191
            next_uncompr_remaining_len  <= 0;
192
        end
193
        else if (enable_write) begin
194
            if (in_sop)
195
                next_uncompr_remaining_len  <= in_len - first_len;
196
            else if (!uncompr_sub_burst)
197
                next_uncompr_remaining_len  <= next_uncompr_remaining_len - max_out_length;
198
        end
199
    end // always_ff @
200
 
201
    // length for each sub-burst if it needs to chop the burst
202
    always_ff @(posedge clk, posedge reset) begin
203
        if (reset) begin
204
            next_uncompr_sub_len  <= 0;
205
        end
206
        else if (enable_write) begin
207
            next_uncompr_sub_len  <= next_uncompr_out_len - 1'b1; // in term of length, it just reduces 1
208
        end
209
    end
210
 
211
    // the sub-burst still active
212
    always_ff @(posedge clk, posedge reset) begin
213
        if (reset) begin
214
            uncompr_sub_burst <= 0;
215
        end
216
        else if (enable_write) begin
217
            uncompr_sub_burst <= (next_uncompr_out_len > 1'b1);
218
        end
219
    end
220
 
221
    // --------------------------------------------------
222
    // Control signals
223
    // --------------------------------------------------
224
    wire end_compressed_sub_burst;
225
    assign end_compressed_sub_burst  = (remaining_len == next_out_len);
226
 
227
    // new_burst:
228
    //  the converter takes in_len for new caculation
229
    always_ff @(posedge clk, posedge reset) begin
230
        if (reset) begin
231
            new_burst   <= 1;
232
        end
233
        else if (enable_read) begin
234
            new_burst   <= end_compressed_sub_burst;
235
        end
236
    end
237
 
238
    // --------------------------------------------------
239
    // Output length
240
    // --------------------------------------------------
241
    // register out_len for compressed trans
242
    always_ff @(posedge clk, posedge reset) begin
243
        if (reset) begin
244
            out_len <= 0;
245
        end
246
        else if (enable_read) begin
247
            out_len <= next_out_len;
248
        end
249
    end
250
 
251
    // register uncompr_out_len for uncompressed trans
252
    generate
253
        if (OPTIMIZE_WRITE_BURST) begin : optimized_write_burst_len
254
            always_ff @(posedge clk, posedge reset) begin
255
                if (reset) begin
256
                    uncompr_out_len <= '0;
257
                end
258
                //else if (enable_write) begin
259
                else if (enable_read) begin
260
                    uncompr_out_len <= first_len;
261
                end
262
            end
263
        end
264
        else begin : unoptimized_write_burst_len
265
            always_ff @(posedge clk, posedge reset) begin
266
                if (reset) begin
267
                    uncompr_out_len <= '0;
268
                end
269
                else if (enable_write) begin
270
                    uncompr_out_len <= next_uncompr_out_len;
271
                end
272
            end
273
        end
274
    endgenerate
275
 
276
    // --------------------------------------------------
277
    // Address calculation
278
    // --------------------------------------------------
279
    reg [ADDR_WIDTH - 1 : 0]        addr_incr;
280
    localparam [ADDR_WIDTH - 1 : 0] ADDR_INCR = MAX_OUT_LEN << LOG2_NUMSYMBOLS;
281
    assign addr_incr  = ADDR_INCR[ADDR_WIDTH - 1 : 0];
282
 
283
    reg [ADDR_WIDTH - 1 : 0]    next_out_addr;
284
    reg [ADDR_WIDTH - 1 : 0]    incremented_addr;
285
 
286
    always_ff @(posedge clk, posedge reset) begin
287
        if (reset) begin
288
            out_addr <= '0;
289
        end
290
        else begin
291
            if (enable_read) begin
292
                out_addr <=  (next_out_addr);
293
            end
294
        end
295
    end // always_ff @
296
 
297
    // use burstwrap/burstwrap_reg to calculate address incrementing
298
    always_ff @(posedge clk, posedge reset) begin
299
        if (reset) begin
300
            incremented_addr <= '0;
301
        end
302
        else if (enable_read) begin
303
            incremented_addr <= ((next_out_addr + addr_incr) & extended_burstwrap_reg);
304
            if (new_burst) begin
305
                incremented_addr <= ((next_out_addr + (first_len << LOG2_NUMSYMBOLS)) & extended_burstwrap); //byte address
306
            end
307
        end
308
    end // always_ff @
309
 
310
    always_comb begin
311
        next_out_addr  = in_addr;
312
        if (!new_burst) begin
313
            next_out_addr = in_addr_reg & ~extended_burstwrap_reg | incremented_addr;
314
        end
315
    end
316
 
317
    // --------------------------------------------------
318
    // Calculates the log2ceil of the input value
319
    // --------------------------------------------------
320
    function integer log2ceil;
321
        input integer val;
322
        reg[31:0] i;
323
 
324
        begin
325
            i = 1;
326
            log2ceil = 0;
327
 
328
            while (i < val) begin
329
                log2ceil = log2ceil + 1;
330
                i = i[30:0] << 1;
331
            end
332
        end
333
    endfunction
334
 
335
endmodule

powered by: WebSVN 2.1.0

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