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

Subversion Repositories openhmc

[/] [openhmc/] [trunk/] [openHMC/] [rtl/] [hmc_controller/] [tx/] [tx_crc_combine.v] - Blame information for rev 15

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 11 juko
/*
2
 *                              .--------------. .----------------. .------------.
3
 *                             | .------------. | .--------------. | .----------. |
4
 *                             | | ____  ____ | | | ____    ____ | | |   ______ | |
5
 *                             | ||_   ||   _|| | ||_   \  /   _|| | | .' ___  || |
6
 *       ___  _ __   ___ _ __  | |  | |__| |  | | |  |   \/   |  | | |/ .'   \_|| |
7
 *      / _ \| '_ \ / _ \ '_ \ | |  |  __  |  | | |  | |\  /| |  | | || |       | |
8
 *       (_) | |_) |  __/ | | || | _| |  | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
9
 *      \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
10
 *           | |               | |            | | |              | | |          | |
11
 *           |_|               | '------------' | '--------------' | '----------' |
12
 *                              '--------------' '----------------' '------------'
13
 *
14
 *  openHMC - An Open Source Hybrid Memory Cube Controller
15
 *  (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
16
 *  www.ziti.uni-heidelberg.de
17
 *  B6, 26
18
 *  68159 Mannheim
19
 *  Germany
20
 *
21
 *  Contact: openhmc@ziti.uni-heidelberg.de
22
 *  http://ra.ziti.uni-heidelberg.de/openhmc
23
 *
24
 *   This source file is free software: you can redistribute it and/or modify
25
 *   it under the terms of the GNU Lesser General Public License as published by
26
 *   the Free Software Foundation, either version 3 of the License, or
27
 *   (at your option) any later version.
28
 *
29
 *   This source file is distributed in the hope that it will be useful,
30
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
31
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
32
 *   GNU Lesser General Public License for more details.
33
 *
34
 *   You should have received a copy of the GNU Lesser General Public License
35
 *   along with this source file.  If not, see <http://www.gnu.org/licenses/>.
36
 *
37
 *
38
 *  Module name: tx_crc_combine
39
 *
40
 */
41
 
42
 `default_nettype none
43
 
44
module tx_crc_combine #(
45
    parameter LOG_FPW       = 2,
46
    parameter FPW           = 4,
47
    parameter DWIDTH        = 512
48
) (
49
 
50
    //----------------------------------
51
    //----SYSTEM INTERFACE
52
    //----------------------------------
53
    input   wire                clk,
54
    input   wire                res_n,
55
 
56
    //----------------------------------
57
    //----Input data
58
    //----------------------------------
59
    input   wire [FPW-1:0]      d_in_hdr,
60
    input   wire [FPW-1:0]      d_in_tail,
61
    input   wire [DWIDTH-1:0]   d_in_data,
62
 
63
    //----------------------------------
64
    //----Outputs
65
    //----------------------------------
66
    output  wire [DWIDTH-1:0]   d_out_data
67
 
68
);
69
 
70
//=====================================================================================================
71
//-----------------------------------------------------------------------------------------------------
72
//---------WIRING AND SIGNAL STUFF---------------------------------------------------------------------
73
//-----------------------------------------------------------------------------------------------------
74
//=====================================================================================================
75
 
76
`include "hmc_field_functions.h"
77
//------------------------------------------------------------------------------------General Assignments
78
integer i_f;    //counts to FPW
79
integer i_f2;   //counts to FPW inside another i_f loop
80
integer i_c;    //depth of the crc data pipeline
81
 
82
genvar f, f2;
83
 
84
//------------------------------------------------------------------------------------Split input data into FLITs
85
wire  [128-1:0]       d_in_flit   [FPW-1:0];
86
generate
87
    for(f = 0; f < (FPW); f = f + 1) begin
88
        assign d_in_flit[f] = d_in_data[(f*128)+128-1:f*128];
89
    end
90
endgenerate
91
 
92 15 juko
reg  [3:0]              d_in_flit_lng_dly     [FPW-1:0];
93 11 juko
reg  [DWIDTH-1:0]       d_in_data_dly;
94
reg  [FPW-1:0]          d_in_tail_dly;
95
reg  [FPW-1:0]          d_in_hdr_dly;
96
reg  [LOG_FPW-1:0]      d_in_flit_target_crc  [FPW-1:0];
97
 
98
//------------------------------------------------------------------------------------CRC Target Assignment
99
reg                     swap_crc;
100
 
101
//Retrieve the target crc from the header and assign to corresponding tail
102
reg  [LOG_FPW-1:0]      target_crc_per_tail         [FPW-1:0];
103
reg  [LOG_FPW-1:0]      target_crc_per_tail1        [FPW-1:0];
104
reg  [LOG_FPW-1:0]      target_crc_per_tail_comb    [FPW-1:0];
105
reg  [LOG_FPW-1:0]      target_crc_comb;
106
reg  [LOG_FPW-1:0]      target_crc_temp;
107
 
108
//------------------------------------------------------------------------------------CRC Modules Input stage
109
wire [31:0]    crc_init_out      [FPW-1:0];
110
reg  [31:0]    crc_accu_in       [FPW-1:0];
111
reg  [FPW-1:0] crc_accu_in_valid [FPW-1:0];
112
reg  [FPW-1:0] crc_accu_in_tail  [FPW-1:0];
113
wire [31:0]    crc_per_flit      [FPW-1:0];
114
 
115
 
116
//------------------------------------------------------------------------------------Inter CRC stage
117
reg  [3:0]                  payload_remain [FPW-1:0];
118
 
119
wire [(FPW*32)-1:0] crc_accu_in_combined [FPW-1:0];
120
generate
121
    for(f=0;f<FPW;f=f+1) begin
122
        for(f2=0;f2<FPW;f2=f2+1) begin
123
            assign crc_accu_in_combined[f][(f2*32)+31:(f2*32)] = crc_accu_in_valid[f][f2] ? crc_accu_in[f2] : 32'h0;
124
        end
125
    end
126 15 juko
endgenerate
127 11 juko
 
128
//------------------------------------------------------------------------------------Data Pipeline signals
129
reg  [DWIDTH-1:0]       crc_data_pipe_in_data                               [1:0];
130
reg  [FPW-1:0]          crc_data_pipe_in_tail                               [1:0];
131
wire [128-1:0]          crc_data_pipe_out_data_flit                         [FPW-1:0];
132
 
133
generate
134
    for(f = 0; f < (FPW); f = f + 1) begin : assign_data_pipe_output
135 15 juko
        assign crc_data_pipe_out_data_flit[f]                        = crc_data_pipe_in_data[1][(f*128)+127:f*128];
136 11 juko
    end
137
endgenerate
138
 
139
 
140
reg  [128-1:0]       data_rdy_flit   [FPW-1:0];
141
generate
142
        for(f = 0; f < (FPW); f = f + 1) begin : reorder_flits_to_word
143
            assign d_out_data[(f*128)+128-1:(f*128)] = data_rdy_flit[f];
144
        end
145
endgenerate
146
 
147
//==================================================================================
148
//---------------------------------Retrieve the lengths to invalide FLITs
149
//==================================================================================
150
always @(*)  begin
151
//Retrieve the length from the header and assign it to the tail. This information will be used in the
152
//invalidation stage to the correct number of FLITs
153
 
154
    target_crc_comb = target_crc_temp;
155
 
156
    for(i_f = 0; i_f < (FPW); i_f = i_f + 1) begin
157
 
158
        if(d_in_hdr_dly[i_f]) begin
159
            target_crc_comb = d_in_flit_target_crc[i_f];
160
        end
161
 
162
        if(d_in_tail_dly[i_f]) begin
163
            target_crc_per_tail_comb[i_f] = target_crc_comb;
164
        end else begin
165
            target_crc_per_tail_comb[i_f] = {4{1'b0}};
166
        end
167
 
168
    end
169
end
170
 
171
//Register combinational values
172
`ifdef ASYNC_RES
173
always @(posedge clk or negedge res_n)  begin `else
174
always @(posedge clk)  begin `endif
175
if(!res_n) begin
176
    for(i_f = 0; i_f < (FPW); i_f = i_f + 1) begin
177
        target_crc_per_tail[i_f] <= 0;
178
    end
179
    target_crc_temp    <= {4{1'b0}};
180
end else begin
181
    for(i_f = 0; i_f < (FPW); i_f = i_f + 1) begin
182
        target_crc_per_tail[i_f] <= target_crc_per_tail_comb[i_f];
183
    end
184
    target_crc_temp    <= target_crc_comb;
185
end
186
end
187
 
188
//=====================================================================================================
189
//-----------------------------------------------------------------------------------------------------
190
//---------LOGIC STARTS HERE---------------------------------------------------------------------------
191
//-----------------------------------------------------------------------------------------------------
192
//=====================================================================================================
193
//====================================================================
194
//---------------------------------Assign input data stream to target CRCs
195
//====================================================================
196
`ifdef ASYNC_RES
197
always @(posedge clk or negedge res_n)  begin `else
198
always @(posedge clk)  begin `endif
199
if(!res_n) begin
200
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
201
        d_in_flit_target_crc[i_f] <= {LOG_FPW{1'b0}};
202
    end
203
    swap_crc            <= 1'b0;
204
end else begin
205
 
206
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
207
        d_in_flit_target_crc[i_f] <= {LOG_FPW{1'b0}};
208
    end
209
 
210
    //Reset if seen a tail
211
    if(|d_in_tail) begin
212
        swap_crc        <= 1'b0;
213
    end
214
 
215
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
216
        if(d_in_hdr[i_f])begin
217 15 juko
 
218 11 juko
            if(i_f+lng(d_in_flit[i_f])>FPW) begin
219
            //If the current packet spreads over multiple cycles
220 15 juko
 
221 11 juko
                if(swap_crc) begin
222
                    //If the last packet was swapped and the current packet also spreads over the more than 1 cycle use crc 0 now
223
                    d_in_flit_target_crc[i_f]   <= 3'h0;
224
                end else begin
225
                    d_in_flit_target_crc[i_f]   <= FPW-1'b1;
226
                    swap_crc                    <= 1'b1;
227
                end
228
 
229
            end else begin
230
 
231
                d_in_flit_target_crc[i_f] <= i_f;
232
 
233
                //If the highest order CRC contains a data packet that ends in this cycle, dont use this crc
234
                //It's ok always to decrement by 1 since we know the lowest order CRC would not be used (at least FLIT0 goes to highest order CRC)
235
                if(swap_crc && !(d_in_hdr > d_in_tail)) begin
236
                    d_in_flit_target_crc[i_f] <= i_f-1;
237
                end
238 15 juko
 
239 11 juko
            end
240
        end
241
    end
242
 
243
end
244
end
245
 
246
//Register input values to be used in CRC assignment logic after crc init stage
247
`ifdef ASYNC_RES
248
always @(posedge clk or negedge res_n)  begin `else
249
always @(posedge clk)  begin `endif
250 15 juko
 
251
    //------------Data Propagation
252
    `ifdef RESET_ALL
253
        if(!res_n) d_in_data_dly <= {DWIDTH{1'b0}};
254
        else
255
    `endif
256
    d_in_data_dly <= d_in_data;
257
    //----------------------------
258
 
259
    `ifdef RESET_ALL
260
    if(!res_n) begin
261
        for(i_f=0;i_f<FPW;i_f=i_f+1)begin
262
            d_in_flit_lng_dly[i_f]  <= 4'h0;
263
        end
264
        d_in_tail_dly <= {FPW{1'b0}};
265
        d_in_hdr_dly  <= {FPW{1'b0}};
266
    end else
267
    `endif
268
    begin
269
        for(i_f=0;i_f<FPW;i_f=i_f+1)begin
270
            d_in_flit_lng_dly[i_f]  <= lng(d_in_flit[i_f]);
271
        end
272
        d_in_tail_dly <= d_in_tail;
273
        d_in_hdr_dly  <= d_in_hdr;
274 11 juko
    end
275
end
276
 
277
//====================================================================
278
//---------------------------------Inter CRC stage, CRC assignment Logic
279
//====================================================================
280
`ifdef ASYNC_RES
281
always @(posedge clk or negedge res_n)  begin `else
282
always @(posedge clk)  begin `endif
283 15 juko
 
284
    //------------Data Propagation
285
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
286
    `ifdef RESET_ALL
287
        if(!res_n) crc_accu_in[i_f] <= {32{1'b0}};
288
        else
289
    `endif
290
        crc_accu_in[i_f] <= crc_init_out[i_f];
291
    end
292
    //----------------------------
293
 
294 11 juko
if(!res_n) begin
295
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
296
        crc_accu_in_valid[i_f]  <= {FPW{1'b0}};
297
        crc_accu_in_tail[i_f]  <= {FPW{1'b0}};
298
        payload_remain[i_f]     <= 4'h0;
299
    end
300
end else begin
301
 
302
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
303 15 juko
 
304 11 juko
        crc_accu_in_valid[i_f]  <= 4'h0;
305
        crc_accu_in_tail[i_f]  <= 4'h0;
306
    end
307
 
308
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
309
    //First go through accu crcs
310
 
311 15 juko
        if(|payload_remain[i_f]) begin
312 11 juko
 
313
            if(payload_remain[i_f] > FPW) begin
314
                crc_accu_in_valid[i_f]  <= {FPW{1'b1}};
315
                payload_remain[i_f]     <= payload_remain[i_f]-FPW;
316
            end else begin
317
                crc_accu_in_valid[i_f]  <= {FPW{1'b1}} >> (FPW-payload_remain[i_f]);
318
                crc_accu_in_tail[i_f]   <= 1'b1 << (payload_remain[i_f]-1);
319 15 juko
                payload_remain[i_f]     <= 4'h0;
320 11 juko
            end
321
        end
322
 
323 15 juko
        for(i_f2=0;i_f2<FPW;i_f2=i_f2+1)begin
324 11 juko
            if(i_f==d_in_flit_target_crc[i_f2] && d_in_hdr_dly[i_f2]) begin
325
            //Then go through all input crcs from the init crc and find the crc's that must be assigned to the currently selected crc
326
 
327 15 juko
                if( (i_f2+d_in_flit_lng_dly[i_f2]) >FPW ) begin
328 11 juko
                    payload_remain[i_f] <= (d_in_flit_lng_dly[i_f2]-FPW+i_f2);
329
                    crc_accu_in_valid[i_f]   <=  {FPW{1'b1}} >> i_f2 << i_f2;
330
                end else begin
331
                    crc_accu_in_tail[i_f] <= 1'b1 << d_in_flit_lng_dly[i_f2]+i_f2-1;
332
                    crc_accu_in_valid[i_f]   <=  ({FPW{1'b1}} >> (FPW-i_f2-d_in_flit_lng_dly[i_f2])) >> i_f2 << i_f2;
333
                end
334
            end
335
 
336
        end
337
    end
338
end
339
end
340
 
341
//====================================================================
342
//---------------------------------Constant propagation of the data pipeline
343
//====================================================================
344
`ifdef ASYNC_RES
345
always @(posedge clk or negedge res_n)  begin `else
346
always @(posedge clk)  begin `endif
347 15 juko
 
348
    //------------Data Propagation
349
    `ifdef RESET_ALL
350
        if (!res_n) begin
351
            for(i_c=0;i_c<2;i_c=i_c+1)begin
352
                crc_data_pipe_in_data[i_c]       <= {DWIDTH{1'b0}};
353
            end
354
        end else
355
    `endif
356
    begin
357
        crc_data_pipe_in_data[0]   <= d_in_data_dly;
358
        crc_data_pipe_in_data[1]   <= crc_data_pipe_in_data[0];
359 11 juko
    end
360 15 juko
    //----------------------------
361 11 juko
 
362 15 juko
    `ifdef RESET_ALL
363
    if(!res_n) begin
364
        for(i_c=0;i_c<2;i_c=i_c+1)begin
365
            crc_data_pipe_in_tail[i_c]       <= {FPW{1'b0}};
366
        end
367 11 juko
 
368 15 juko
        for(i_f=0;i_f<(FPW);i_f=i_f+ 1) begin
369
            target_crc_per_tail1[i_f] <= {LOG_FPW{1'b0}};
370
        end
371
    end else
372
    `endif
373
    begin
374
 
375 11 juko
    //We keep the tails per FLIT so they are not part of the data pipe
376 15 juko
    for(i_f=0;i_f<(FPW);i_f=i_f+ 1) begin
377 11 juko
        target_crc_per_tail1[i_f] <= target_crc_per_tail[i_f];
378
    end
379
 
380
    //Set the first stage of the data pipeline
381
    crc_data_pipe_in_tail[0]       <= d_in_tail_dly;
382
 
383
    //Data Pipeline propagation
384 15 juko
    crc_data_pipe_in_tail[1]       <= crc_data_pipe_in_tail[0];
385 11 juko
    end
386
end
387
 
388
//====================================================================
389
//---------------------------------At the end of the data pipeline get and add CRCs
390
//====================================================================
391
//Data Pipeline output stage to final FLIT reg
392
`ifdef ASYNC_RES
393
always @(posedge clk or negedge res_n)  begin `else
394
always @(posedge clk)  begin `endif
395
 
396
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
397 15 juko
    `ifdef RESET_ALL
398
    if(!res_n) begin
399
        data_rdy_flit[i_f]  <= {128{1'b0}};
400
    end else
401
    `endif
402
    begin
403 11 juko
        data_rdy_flit[i_f]  <= crc_data_pipe_out_data_flit[i_f];
404
 
405
        if(crc_data_pipe_in_tail[1][i_f])begin    //Finally add the crc
406
            data_rdy_flit[i_f][128-1:128-32] <= crc_per_flit[target_crc_per_tail1[i_f]];
407
        end
408
    end
409 15 juko
    end
410 11 juko
end
411
 
412
//=====================================================================================================
413
//-----------------------------------------------------------------------------------------------------
414
//---------INSTANTIATIONS HERE-------------------------------------------------------------------------
415
//-----------------------------------------------------------------------------------------------------
416
//=====================================================================================================
417
//Init CRC: Calculate the remainders of each input FLIT individually
418
generate
419
    for(f=0;f<FPW;f=f+1) begin : crc_init_gen
420
        crc_128_init crc_init_I
421
        (
422
            .clk(clk),
423 15 juko
            `ifdef RESET_ALL
424
                .res_n(res_n),
425
            `endif
426 11 juko
            .inData(d_in_flit[f]),
427
            .crc(crc_init_out[f])
428
        );
429
    end
430
endgenerate
431
 
432
//Calculate the actual CRC over all valid remainders
433
generate
434
    for(f=0;f<FPW;f=f+1) begin : crc_accu_gen
435
        crc_accu #(
436
        .FPW(FPW)
437
        )
438
        crc_accu_I
439
        (
440
            .clk(clk),
441
            .res_n(res_n),
442
            .tail(crc_accu_in_tail[f]),
443
            .d_in(crc_accu_in_combined[f]),
444
            .crc_out(crc_per_flit[f])
445
        );
446
    end
447
endgenerate
448
 
449
endmodule
450
`default_nettype wire

powered by: WebSVN 2.1.0

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