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

Subversion Repositories openhmc

[/] [openhmc/] [trunk/] [openHMC/] [rtl/] [hmc_controller/] [rx/] [rx_crc_compare.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: rx_crc_compare
39
 *
40
 */
41
 
42
`default_nettype none
43
 
44
module rx_crc_compare #(
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 [FPW-1:0]      d_in_valid,
62
    input   wire [DWIDTH-1:0]   d_in_data,
63
    input   wire [(FPW*4)-1:0]  d_in_lng,
64
 
65
    //----------------------------------
66
    //----Outputs
67
    //----------------------------------
68
    output  wire [DWIDTH-1:0]   d_out_data,
69
    output  reg  [FPW-1:0]      d_out_hdr,
70
    output  reg  [FPW-1:0]      d_out_tail,
71
    output  reg  [FPW-1:0]      d_out_valid,
72
    output  reg  [FPW-1:0]      d_out_error,
73
    output  reg  [FPW-1:0]      d_out_poisoned,
74
    output  reg  [FPW-1:0]      d_out_rtc,
75
    output  reg  [FPW-1:0]      d_out_flow
76
 
77
);
78
 
79
//=====================================================================================================
80
//-----------------------------------------------------------------------------------------------------
81
//---------WIRING AND SIGNAL STUFF---------------------------------------------------------------------
82
//-----------------------------------------------------------------------------------------------------
83
//=====================================================================================================
84
 
85
`include "hmc_field_functions.h"
86
//------------------------------------------------------------------------------------General Assignments
87
integer i_f;    //counts to FPW
88
integer i_f2;   //counts to FPW inside another i_f loop
89
integer i_c;    //depth of the crc data pipeline
90
 
91
genvar f, f2;
92
 
93
localparam CMD_TRET = 6'b000010;
94
localparam CMD_PRET = 6'b000001;
95
 
96
//------------------------------------------------------------------------------------Split input data into FLITs
97
wire [127:0]    d_in_flit             [FPW-1:0];
98
wire [127:0]    d_in_flit_removed_crc [FPW-1:0];
99
generate
100
    for(f = 0; f < (FPW); f = f + 1) begin
101
        assign d_in_flit[f] = d_in_data[(f*128)+128-1:f*128];
102
        assign d_in_flit_removed_crc[f][95:0] = d_in_flit[f][95:0];
103
        assign d_in_flit_removed_crc[f][127:96] = d_in_tail[f] ? {32'h0} : d_in_flit[f][127:96];
104
    end
105
endgenerate
106
 
107
reg  [DWIDTH-1:0]       d_in_data_dly;
108
reg  [FPW-1:0]          d_in_hdr_dly;
109
reg  [FPW-1:0]          d_in_tail_dly;
110
reg  [FPW-1:0]          d_in_valid_dly;
111
reg  [LOG_FPW-1:0]      d_in_flit_target_crc  [FPW-1:0];
112
 
113
wire [3:0] d_in_lng_per_flit [FPW-1:0];
114
reg  [3:0] d_in_lng_per_flit_dly [FPW-1:0];
115
generate
116
    for(f = 0; f < (FPW); f = f + 1) begin  : retrieve_packet_lengths_for_crc_assignment
117
        assign d_in_lng_per_flit[f] = d_in_lng[(f*4)+4-1:f*4] ;
118
    end
119
endgenerate
120
 
121
//------------------------------------------------------------------------------------CRC Target Assignment
122
reg                     swap_crc;
123
 
124
//Retrieve the target crc from the header and assign to corresponding tail
125
reg  [LOG_FPW-1:0]      target_crc_per_tail     [FPW-1:0];
126
reg  [LOG_FPW-1:0]      target_crc_per_tail1    [FPW-1:0];
127
reg  [LOG_FPW-1:0]      target_crc_per_tail_comb[FPW-1:0];
128
reg  [LOG_FPW-1:0]      target_crc_comb;
129
reg  [LOG_FPW-1:0]      target_crc_temp;
130
 
131
//------------------------------------------------------------------------------------CRC Modules Input stage
132
wire [31:0]    crc_init_out      [FPW-1:0];
133
reg  [31:0]    crc_accu_in       [FPW-1:0];
134
reg  [FPW-1:0] crc_accu_in_valid [FPW-1:0];
135
reg  [FPW-1:0] crc_accu_in_tail  [FPW-1:0];
136
wire [31:0]    crc_per_flit      [FPW-1:0];
137
 
138
//------------------------------------------------------------------------------------Inter CRC stage
139
reg  [3:0]              payload_remain    [FPW-1:0];
140
 
141
wire [(FPW*32)-1:0] crc_accu_in_combined [FPW-1:0];
142
generate
143
    for(f=0;f<FPW;f=f+1) begin
144
        for(f2=0;f2<FPW;f2=f2+1) begin
145
            assign crc_accu_in_combined[f][(f2*32)+31:(f2*32)] = crc_accu_in_valid[f][f2] ? crc_accu_in[f2] : 32'h0;
146
        end
147
    end
148
endgenerate
149
 
150
 
151
//------------------------------------------------------------------------------------Data Pipeline signals
152
reg  [DWIDTH-1:0]       crc_data_pipe_in_data                               [1:0];
153
reg  [FPW-1:0]          crc_data_pipe_in_hdr                                [1:0];
154
reg  [FPW-1:0]          crc_data_pipe_in_tail                               [1:0];
155
reg  [FPW-1:0]          crc_data_pipe_in_valid                              [1:0];
156
wire [128-1:0]          crc_data_pipe_out_data_flit                         [FPW-1:0];
157
 
158
generate
159
    for(f = 0; f < (FPW); f = f + 1) begin : assign_data_pipe_output
160
        assign crc_data_pipe_out_data_flit[f]                        = crc_data_pipe_in_data[1][(f*128)+128-1:f*128];
161
    end
162
endgenerate
163
 
164
 
165
reg  [128-1:0]       data_rdy_flit   [FPW-1:0];
166
generate
167
        for(f = 0; f < (FPW); f = f + 1) begin : reorder_flits_to_word
168
            assign d_out_data[(f*128)+128-1:(f*128)] = data_rdy_flit[f];
169
        end
170
endgenerate
171
 
172
//==================================================================================
173
//---------------------------------Retrieve the lengths to invalide FLITs
174
//==================================================================================
175
always @(*)  begin
176
//Retrieve the length from the header and assign it to the tail. This information will be used in the
177
//invalidation stage to the correct number of FLITs
178
 
179
    target_crc_comb = target_crc_temp;
180
 
181
    for(i_f = 0; i_f < (FPW); i_f = i_f + 1) begin
182
 
183
        if(d_in_hdr_dly[i_f]) begin
184
            target_crc_comb = d_in_flit_target_crc[i_f];
185
        end
186
 
187
        if(d_in_tail_dly[i_f]) begin
188
            target_crc_per_tail_comb[i_f] = target_crc_comb;
189
        end else begin
190
            target_crc_per_tail_comb[i_f] = {4{1'b0}};
191
        end
192
 
193
    end
194
end
195
 
196
//Register combinational values
197
`ifdef ASYNC_RES
198
always @(posedge clk or negedge res_n)  begin `else
199
always @(posedge clk)  begin `endif
200
if(!res_n) begin
201
    for(i_f = 0; i_f < (FPW); i_f = i_f + 1) begin
202
        target_crc_per_tail[i_f] <= 0;
203
    end
204
    target_crc_temp    <= {4{1'b0}};
205
end else begin
206
    for(i_f = 0; i_f < (FPW); i_f = i_f + 1) begin
207
        target_crc_per_tail[i_f] <= target_crc_per_tail_comb[i_f];
208
    end
209
    target_crc_temp    <= target_crc_comb;
210
end
211
end
212
 
213
//=====================================================================================================
214
//-----------------------------------------------------------------------------------------------------
215
//---------LOGIC STARTS HERE---------------------------------------------------------------------------
216
//-----------------------------------------------------------------------------------------------------
217
//=====================================================================================================
218
//====================================================================
219
//---------------------------------Assign input data stream to target CRCs
220
//====================================================================
221
`ifdef ASYNC_RES
222
always @(posedge clk or negedge res_n)  begin `else
223
always @(posedge clk)  begin `endif
224
if(!res_n) begin
225
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
226
        d_in_flit_target_crc[i_f] <= {LOG_FPW{1'b0}};
227
    end
228
    swap_crc            <= 1'b0;
229
end else begin
230
 
231
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
232
        d_in_flit_target_crc[i_f] <= {LOG_FPW{1'b0}};
233
    end
234
 
235
    //Reset if seen a tail
236
    if(|d_in_tail) begin
237
        swap_crc        <= 1'b0;
238
    end
239
 
240
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
241
        if(d_in_hdr[i_f])begin
242
 
243
            if((i_f+d_in_lng_per_flit[i_f])>FPW) begin
244
            //If the current packet spreads over multiple cycles
245
 
246
                if(swap_crc) begin
247
                    //If the last packet was swapped and the current packet also spreads over the more than 1 cycle use crc 0 now
248
                    d_in_flit_target_crc[i_f]   <= 3'h0;
249
                end else begin
250
                    d_in_flit_target_crc[i_f]   <= FPW-1'b1;
251
                    swap_crc                    <= 1'b1;
252
                end
253
 
254
            end else begin
255
 
256
                d_in_flit_target_crc[i_f] <= i_f;
257
 
258
                //If the highest order CRC contains a data packet that ends in this cycle, dont use this crc
259
                //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)
260
                if(swap_crc && !(d_in_hdr > d_in_tail)) begin
261
                    d_in_flit_target_crc[i_f] <= i_f-1;
262
                end
263
 
264
            end
265
        end
266
    end
267
 
268
end
269
end
270
 
271
//Register input values to be used in CRC assignment logic after crc init stage
272
`ifdef ASYNC_RES
273
always @(posedge clk or negedge res_n)  begin `else
274
always @(posedge clk)  begin `endif
275
if(!res_n) begin
276
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
277
        d_in_lng_per_flit_dly[i_f]  <= 4'h0;
278
    end
279
    d_in_data_dly   <= {DWIDTH{1'b0}};
280
    d_in_hdr_dly    <= {FPW{1'b0}};
281
    d_in_tail_dly   <= {FPW{1'b0}};
282
    d_in_valid_dly  <= {FPW{1'b0}};
283
end else begin
284
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
285
        d_in_lng_per_flit_dly[i_f]  <= d_in_lng_per_flit[i_f];
286
    end
287
    d_in_data_dly   <= d_in_data;
288
    d_in_hdr_dly    <= d_in_hdr;
289
    d_in_tail_dly   <= d_in_tail;
290
    d_in_valid_dly  <= d_in_valid;
291
end
292
end
293
 
294
//====================================================================
295
//---------------------------------Inter CRC stage, CRC assignment Logic
296
//====================================================================
297
`ifdef ASYNC_RES
298
always @(posedge clk or negedge res_n)  begin `else
299
always @(posedge clk)  begin `endif
300
if(!res_n) begin
301
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
302
        crc_accu_in[i_f] <= {32{1'b0}};
303
        crc_accu_in_valid[i_f]  <= {FPW{1'b0}};
304
        crc_accu_in_tail[i_f]  <= {FPW{1'b0}};
305
        payload_remain[i_f]     <= 4'h0;
306
    end
307
end else begin
308
 
309
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
310
        crc_accu_in[i_f] <= crc_init_out[i_f];
311
        crc_accu_in_valid[i_f]  <= 4'h0;
312
        crc_accu_in_tail[i_f]  <= 4'h0;
313
    end
314
 
315
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
316
    //First go through accu crcs
317
 
318
        if(|payload_remain[i_f]) begin
319
 
320
            if(payload_remain[i_f] > FPW) begin
321
                crc_accu_in_valid[i_f]  <= {FPW{1'b1}};
322
                payload_remain[i_f]     <= payload_remain[i_f]-FPW;
323
            end else begin
324
                crc_accu_in_valid[i_f]  <= {FPW{1'b1}} >> (FPW-payload_remain[i_f]);
325
                crc_accu_in_tail[i_f]   <= 1'b1 << (payload_remain[i_f]-1);
326
                payload_remain[i_f]     <= 4'h0;
327
            end
328
        end
329
 
330
        for(i_f2=0;i_f2<FPW;i_f2=i_f2+1)begin
331
            if(i_f==d_in_flit_target_crc[i_f2] && d_in_hdr_dly[i_f2]) begin
332
            //Then go through all input crcs from the init crc and find the crc's that must be assigned to the currently selected crc
333
 
334
                if( (i_f2+d_in_lng_per_flit_dly[i_f2]) >FPW ) begin
335
                    payload_remain[i_f] <= (d_in_lng_per_flit_dly[i_f2]-FPW+i_f2);
336
                    crc_accu_in_valid[i_f]   <=  {FPW{1'b1}} >> i_f2 << i_f2;
337
                end else begin
338
                    crc_accu_in_tail[i_f] <= 1'b1 << d_in_lng_per_flit_dly[i_f2]+i_f2-1;
339
                    crc_accu_in_valid[i_f]   <=  ({FPW{1'b1}} >> (FPW-i_f2-d_in_lng_per_flit_dly[i_f2])) >> i_f2 << i_f2;
340
                end
341
            end
342
 
343
        end
344
    end
345
end
346
end
347
 
348
//====================================================================
349
//---------------------------------Constant propagation of the data pipeline
350
//====================================================================
351
`ifdef ASYNC_RES
352
always @(posedge clk or negedge res_n)  begin `else
353
always @(posedge clk)  begin `endif
354
if(!res_n) begin
355
    for(i_c=0;i_c<2;i_c=i_c+1)begin
356
        crc_data_pipe_in_data[i_c]       <= {DWIDTH{1'b0}};
357
        crc_data_pipe_in_hdr[i_c]        <= {FPW{1'b0}};
358
        crc_data_pipe_in_tail[i_c]       <= {FPW{1'b0}};
359
        crc_data_pipe_in_valid[i_c]      <= {FPW{1'b0}};
360
    end
361
 
362
    for(i_f = 0; i_f < (FPW); i_f = i_f + 1) begin
363
        target_crc_per_tail1[i_f] <= 3'h0;
364
    end
365
end else begin
366
 
367
    for(i_f = 0; i_f < (FPW); i_f = i_f + 1) begin
368
        target_crc_per_tail1[i_f] <= target_crc_per_tail[i_f];
369
    end
370
 
371
    //Set the first stage of the data pipeline
372
    crc_data_pipe_in_data[0]       <= d_in_data_dly;
373
    crc_data_pipe_in_hdr[0]        <= d_in_hdr_dly;
374
    crc_data_pipe_in_tail[0]       <= d_in_tail_dly;
375
    crc_data_pipe_in_valid[0]      <= d_in_valid_dly;
376
 
377
    //Data Pipeline propagation
378
    for(i_c=0;i_c<(1);i_c=i_c+1)begin
379
        crc_data_pipe_in_data[i_c+1]   <= crc_data_pipe_in_data[i_c];
380
        crc_data_pipe_in_tail[i_c+1]   <= crc_data_pipe_in_tail[i_c];
381
        crc_data_pipe_in_hdr[i_c+1]    <= crc_data_pipe_in_hdr[i_c];
382
        crc_data_pipe_in_tail[i_c+1]   <= crc_data_pipe_in_tail[i_c];
383
        crc_data_pipe_in_valid[i_c+1]  <= crc_data_pipe_in_valid[i_c];
384
    end
385
end
386
end
387
 
388
//====================================================================
389
//---------------------------------At the end of the data pipeline get and compare the CRCs
390
//====================================================================
391
`ifdef ASYNC_RES
392
always @(posedge clk or negedge res_n)  begin `else
393
always @(posedge clk)  begin `endif
394
if(!res_n) begin
395
 
396
    //Reset the outputs
397
    d_out_hdr             <= {FPW{1'b0}};
398
    d_out_tail            <= {FPW{1'b0}};
399
    d_out_valid           <= {FPW{1'b0}};
400
    d_out_error           <= {FPW{1'b0}};
401
    d_out_poisoned        <= {FPW{1'b0}};
402
    d_out_rtc             <= {FPW{1'b0}};
403
    d_out_flow            <= {FPW{1'b0}};
404
 
405
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
406
        data_rdy_flit[i_f]  <= {128{1'b0}};
407
    end
408
 
409
end else begin
410
 
411
    d_out_rtc               <= {FPW{1'b0}};
412
    d_out_error             <= {FPW{1'b0}};
413
    d_out_poisoned          <= {FPW{1'b0}};
414
    d_out_flow              <= {FPW{1'b0}};
415
 
416
    //Propagate
417
    d_out_hdr           <= crc_data_pipe_in_hdr[1];
418
    d_out_tail          <= crc_data_pipe_in_tail[1];
419
    d_out_valid         <= crc_data_pipe_in_valid[1];
420
 
421
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
422
 
423
        //Propagate data
424
        data_rdy_flit[i_f]  <= crc_data_pipe_out_data_flit[i_f];
425
 
426
        if(crc_data_pipe_in_tail[1][i_f])begin
427
        //Finally compare the CRC and add flow/rtc information if there is a tail
428
 
429
            if(crc(crc_data_pipe_out_data_flit[i_f]) == ~crc_per_flit[target_crc_per_tail1[i_f]]) begin
430
                //Poisoned
431
                d_out_poisoned[i_f]    <= 1'b1;
432
            end else if(crc(crc_data_pipe_out_data_flit[i_f]) != crc_per_flit[target_crc_per_tail1[i_f]]) begin
433
                //Error
434
                d_out_error[i_f]    <= 1'b1;
435
            end
436
 
437
            //Add the return token count indicator when the packet has rtc
438
            if(!crc_data_pipe_in_hdr[1][i_f]) begin
439
                //Multi-FLIT packets always have a valid RTC
440
                d_out_rtc[i_f] <= 1'b1;
441
            end else begin
442
 
443
                if((cmd(crc_data_pipe_out_data_flit[i_f]) == CMD_TRET) || !is_flow(crc_data_pipe_out_data_flit[i_f])) begin
444
                    //All non-flow packets have a valid RTC
445
                    d_out_rtc[i_f] <= 1'b1;
446
                end
447
                if(is_flow(crc_data_pipe_out_data_flit[i_f])) begin
448
                    //Set the flow packet indicator
449
                    d_out_flow[i_f] <= 1'b1;
450
 
451
                    //Check flow packets zero fields
452
                    if(|adrs(crc_data_pipe_out_data_flit[i_f]) || |tag(crc_data_pipe_out_data_flit[i_f])) begin
453
                        d_out_error[i_f]    <= 1'b1;
454
                    end
455
                    if( (cmd(crc_data_pipe_out_data_flit[i_f]) != CMD_TRET) &&
456
                        (|rtc(crc_data_pipe_out_data_flit[i_f]) || |seq(crc_data_pipe_out_data_flit[i_f]))) begin
457
                        d_out_error[i_f]    <= 1'b1;
458
                    end
459
                    if((cmd(crc_data_pipe_out_data_flit[i_f]) == CMD_PRET) && |frp(crc_data_pipe_out_data_flit[i_f])) begin
460
                        d_out_error[i_f] <= 1'b1;
461
                    end
462
                end
463
            end
464
 
465
        end
466
    end
467
end
468
end
469
 
470
//=====================================================================================================
471
//-----------------------------------------------------------------------------------------------------
472
//---------INSTANTIATIONS HERE-------------------------------------------------------------------------
473
//-----------------------------------------------------------------------------------------------------
474
//=====================================================================================================
475
//Init CRC: Calculate the remainders of each input FLIT individually
476
generate
477
    for(f=0;f<FPW;f=f+1) begin : crc_init_gen
478
        crc_128_init crc_init_I
479
        (
480
            .clk(clk),
481
            .res_n(res_n),
482
            .inData(d_in_flit_removed_crc[f]),
483
            .crc(crc_init_out[f])
484
        );
485
    end
486
endgenerate
487
 
488
//Calculate the actual CRC over all valid remainders
489
generate
490
    for(f=0;f<FPW;f=f+1) begin : crc_accu_gen
491
        crc_accu #(
492
        .FPW(FPW)
493
        )
494
        crc_accu_I
495
        (
496
            .clk(clk),
497
            .res_n(res_n),
498
            .tail(crc_accu_in_tail[f]),
499
            .d_in(crc_accu_in_combined[f]),
500
            .valid(crc_accu_in_valid[f]),
501
            .crc_out(crc_per_flit[f])
502
        );
503
    end
504
endgenerate
505
 
506
endmodule
507
`default_nettype wire

powered by: WebSVN 2.1.0

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