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 11

Go to most recent revision | 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
reg  [3:0]              d_in_flit_lng_dly     [FPW-1:0];
93
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
endgenerate
127
 
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
        assign crc_data_pipe_out_data_flit[f]                        = crc_data_pipe_in_data[1][(f*128)+128-1:f*128];
136
    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
 
218
            if(i_f+lng(d_in_flit[i_f])>FPW) begin
219
            //If the current packet spreads over multiple cycles
220
 
221
                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
 
239
            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
if(!res_n) begin
251
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
252
        d_in_flit_lng_dly[i_f]  <= 4'h0;
253
    end
254
    d_in_data_dly <= {DWIDTH{1'b0}};
255
    d_in_tail_dly <= {FPW{1'b0}};
256
    d_in_hdr_dly  <= {FPW{1'b0}};
257
end else begin
258
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
259
        d_in_flit_lng_dly[i_f]  <= lng(d_in_flit[i_f]);
260
    end
261
    d_in_data_dly <= d_in_data;
262
    d_in_tail_dly <= d_in_tail;
263
    d_in_hdr_dly  <= d_in_hdr;
264
end
265
end
266
 
267
//====================================================================
268
//---------------------------------Inter CRC stage, CRC assignment Logic
269
//====================================================================
270
`ifdef ASYNC_RES
271
always @(posedge clk or negedge res_n)  begin `else
272
always @(posedge clk)  begin `endif
273
if(!res_n) begin
274
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
275
        crc_accu_in[i_f] <= {32{1'b0}};
276
        crc_accu_in_valid[i_f]  <= {FPW{1'b0}};
277
        crc_accu_in_tail[i_f]  <= {FPW{1'b0}};
278
        payload_remain[i_f]     <= 4'h0;
279
    end
280
end else begin
281
 
282
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
283
        crc_accu_in[i_f] <= crc_init_out[i_f];
284
        crc_accu_in_valid[i_f]  <= 4'h0;
285
        crc_accu_in_tail[i_f]  <= 4'h0;
286
    end
287
 
288
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
289
    //First go through accu crcs
290
 
291
        if(|payload_remain[i_f]) begin
292
 
293
            if(payload_remain[i_f] > FPW) begin
294
                crc_accu_in_valid[i_f]  <= {FPW{1'b1}};
295
                payload_remain[i_f]     <= payload_remain[i_f]-FPW;
296
            end else begin
297
                crc_accu_in_valid[i_f]  <= {FPW{1'b1}} >> (FPW-payload_remain[i_f]);
298
                crc_accu_in_tail[i_f]   <= 1'b1 << (payload_remain[i_f]-1);
299
                payload_remain[i_f]     <= 4'h0;
300
            end
301
        end
302
 
303
        for(i_f2=0;i_f2<FPW;i_f2=i_f2+1)begin
304
            if(i_f==d_in_flit_target_crc[i_f2] && d_in_hdr_dly[i_f2]) begin
305
            //Then go through all input crcs from the init crc and find the crc's that must be assigned to the currently selected crc
306
 
307
                if( (i_f2+d_in_flit_lng_dly[i_f2]) >FPW ) begin
308
                    payload_remain[i_f] <= (d_in_flit_lng_dly[i_f2]-FPW+i_f2);
309
                    crc_accu_in_valid[i_f]   <=  {FPW{1'b1}} >> i_f2 << i_f2;
310
                end else begin
311
                    crc_accu_in_tail[i_f] <= 1'b1 << d_in_flit_lng_dly[i_f2]+i_f2-1;
312
                    crc_accu_in_valid[i_f]   <=  ({FPW{1'b1}} >> (FPW-i_f2-d_in_flit_lng_dly[i_f2])) >> i_f2 << i_f2;
313
                end
314
            end
315
 
316
        end
317
    end
318
end
319
end
320
 
321
//====================================================================
322
//---------------------------------Constant propagation of the data pipeline
323
//====================================================================
324
`ifdef ASYNC_RES
325
always @(posedge clk or negedge res_n)  begin `else
326
always @(posedge clk)  begin `endif
327
if(!res_n) begin
328
    for(i_c=0;i_c<2;i_c=i_c+1)begin
329
        crc_data_pipe_in_data[i_c]       <= {DWIDTH{1'b0}};
330
        crc_data_pipe_in_tail[i_c]       <= {FPW{1'b0}};
331
    end
332
 
333
    for(i_f = 0; i_f < (FPW); i_f = i_f + 1) begin
334
        target_crc_per_tail1[i_f] <= 3'h0;
335
    end
336
end else begin
337
 
338
    //We keep the tails per FLIT so they are not part of the data pipe
339
    for(i_f = 0; i_f < (FPW); i_f = i_f + 1) begin
340
        target_crc_per_tail1[i_f] <= target_crc_per_tail[i_f];
341
    end
342
 
343
    //Set the first stage of the data pipeline
344
    crc_data_pipe_in_data[0]       <= d_in_data_dly;
345
    crc_data_pipe_in_tail[0]       <= d_in_tail_dly;
346
 
347
    //Data Pipeline propagation
348
    for(i_c=0;i_c<(1);i_c=i_c+1)begin
349
        crc_data_pipe_in_data[i_c+1]       <= crc_data_pipe_in_data[i_c];
350
        crc_data_pipe_in_tail[i_c+1]       <= crc_data_pipe_in_tail[i_c];
351
    end
352
end
353
end
354
 
355
//====================================================================
356
//---------------------------------At the end of the data pipeline get and add CRCs
357
//====================================================================
358
//Data Pipeline output stage to final FLIT reg
359
`ifdef ASYNC_RES
360
always @(posedge clk or negedge res_n)  begin `else
361
always @(posedge clk)  begin `endif
362
if(!res_n) begin
363
 
364
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
365
        data_rdy_flit[i_f]  <= {128{1'b0}};
366
    end
367
 
368
end else begin
369
 
370
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
371
 
372
        data_rdy_flit[i_f]  <= crc_data_pipe_out_data_flit[i_f];
373
 
374
        if(crc_data_pipe_in_tail[1][i_f])begin    //Finally add the crc
375
            data_rdy_flit[i_f][128-1:128-32] <= crc_per_flit[target_crc_per_tail1[i_f]];
376
        end
377
    end
378
end
379
end
380
 
381
//=====================================================================================================
382
//-----------------------------------------------------------------------------------------------------
383
//---------INSTANTIATIONS HERE-------------------------------------------------------------------------
384
//-----------------------------------------------------------------------------------------------------
385
//=====================================================================================================
386
//Init CRC: Calculate the remainders of each input FLIT individually
387
generate
388
    for(f=0;f<FPW;f=f+1) begin : crc_init_gen
389
        crc_128_init crc_init_I
390
        (
391
            .clk(clk),
392
            .res_n(res_n),
393
            .inData(d_in_flit[f]),
394
            .crc(crc_init_out[f])
395
        );
396
    end
397
endgenerate
398
 
399
//Calculate the actual CRC over all valid remainders
400
generate
401
    for(f=0;f<FPW;f=f+1) begin : crc_accu_gen
402
        crc_accu #(
403
        .FPW(FPW)
404
        )
405
        crc_accu_I
406
        (
407
            .clk(clk),
408
            .res_n(res_n),
409
            .tail(crc_accu_in_tail[f]),
410
            .d_in(crc_accu_in_combined[f]),
411
            .valid(crc_accu_in_valid[f]),
412
            .crc_out(crc_per_flit[f])
413
        );
414
    end
415
endgenerate
416
 
417
endmodule
418
`default_nettype wire

powered by: WebSVN 2.1.0

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