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 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: 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 15 juko
    `ifdef RESET_ALL
276
        if(!res_n) d_in_data_dly   <= {DWIDTH{1'b0}};
277
        else
278
    `endif
279
    begin
280
        d_in_data_dly   <= d_in_data;
281 11 juko
    end
282 15 juko
 
283
    `ifdef RESET_ALL
284
        if(!res_n) begin
285
            for(i_f=0;i_f<FPW;i_f=i_f+1)begin
286
                d_in_lng_per_flit_dly[i_f]  <= 4'h0;
287
            end
288
 
289
            d_in_hdr_dly    <= {FPW{1'b0}};
290
            d_in_tail_dly   <= {FPW{1'b0}};
291
            d_in_valid_dly  <= {FPW{1'b0}};
292
        end else
293
    `endif
294
    begin
295 11 juko
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
296
        d_in_lng_per_flit_dly[i_f]  <= d_in_lng_per_flit[i_f];
297
    end
298 15 juko
    d_in_hdr_dly    <= d_in_hdr & d_in_valid;
299
    d_in_tail_dly   <= d_in_tail & d_in_valid;
300 11 juko
    d_in_valid_dly  <= d_in_valid;
301 15 juko
    end
302 11 juko
end
303
 
304
//====================================================================
305
//---------------------------------Inter CRC stage, CRC assignment Logic
306
//====================================================================
307
`ifdef ASYNC_RES
308
always @(posedge clk or negedge res_n)  begin `else
309
always @(posedge clk)  begin `endif
310 15 juko
 
311
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
312
        `ifdef RESET_ALL
313
            if (!res_n) crc_accu_in[i_f] <= {32{1'b0}};
314
            else
315
        `endif
316
        begin
317
            crc_accu_in[i_f]        <= crc_init_out[i_f];
318
        end
319
    end
320
 
321 11 juko
if(!res_n) begin
322
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
323 15 juko
 
324 11 juko
        crc_accu_in_valid[i_f]  <= {FPW{1'b0}};
325
        crc_accu_in_tail[i_f]  <= {FPW{1'b0}};
326
        payload_remain[i_f]     <= 4'h0;
327
    end
328
end else begin
329
 
330
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
331
        crc_accu_in_valid[i_f]  <= 4'h0;
332 15 juko
        crc_accu_in_tail[i_f]   <= 4'h0;
333 11 juko
    end
334
 
335
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
336
    //First go through accu crcs
337
        if(|payload_remain[i_f]) begin
338
 
339
            if(payload_remain[i_f] > FPW) begin
340
                crc_accu_in_valid[i_f]  <= {FPW{1'b1}};
341
                payload_remain[i_f]     <= payload_remain[i_f]-FPW;
342
            end else begin
343
                crc_accu_in_valid[i_f]  <= {FPW{1'b1}} >> (FPW-payload_remain[i_f]);
344
                crc_accu_in_tail[i_f]   <= 1'b1 << (payload_remain[i_f]-1);
345
                payload_remain[i_f]     <= 4'h0;
346
            end
347
        end
348
 
349
        for(i_f2=0;i_f2<FPW;i_f2=i_f2+1)begin
350
            if(i_f==d_in_flit_target_crc[i_f2] && d_in_hdr_dly[i_f2]) begin
351
            //Then go through all input crcs from the init crc and find the crc's that must be assigned to the currently selected crc
352
 
353
                if( (i_f2+d_in_lng_per_flit_dly[i_f2]) >FPW ) begin
354 15 juko
                    payload_remain[i_f]      <= (d_in_lng_per_flit_dly[i_f2]-FPW+i_f2);
355 11 juko
                    crc_accu_in_valid[i_f]   <=  {FPW{1'b1}} >> i_f2 << i_f2;
356
                end else begin
357 15 juko
                    crc_accu_in_tail[i_f]    <= 1'b1 << d_in_lng_per_flit_dly[i_f2]+i_f2-1;
358 11 juko
                    crc_accu_in_valid[i_f]   <=  ({FPW{1'b1}} >> (FPW-i_f2-d_in_lng_per_flit_dly[i_f2])) >> i_f2 << i_f2;
359
                end
360
            end
361
 
362
        end
363
    end
364
end
365
end
366
 
367
//====================================================================
368
//---------------------------------Constant propagation of the data pipeline
369
//====================================================================
370
`ifdef ASYNC_RES
371
always @(posedge clk or negedge res_n)  begin `else
372
always @(posedge clk)  begin `endif
373 15 juko
 
374
    `ifdef ASYNC_RES
375
        if (!res_n) begin
376
            for(i_c=0;i_c<2;i_c=i_c+1)begin
377
                crc_data_pipe_in_data[i_c]       <= {DWIDTH{1'b0}};
378
            end
379
        end else
380
    `endif
381
    begin
382
        //Data forward
383
        crc_data_pipe_in_data[0]   <= d_in_data_dly;
384
        crc_data_pipe_in_data[1]   <= crc_data_pipe_in_data[0];
385 11 juko
    end
386
 
387 15 juko
    `ifdef RESET_ALL
388
    if(!res_n) begin
389
        for(i_c=0;i_c<2;i_c=i_c+1)begin
390
            crc_data_pipe_in_hdr[i_c]        <= {FPW{1'b0}};
391
            crc_data_pipe_in_tail[i_c]       <= {FPW{1'b0}};
392
            crc_data_pipe_in_valid[i_c]      <= {FPW{1'b0}};
393
        end
394 11 juko
 
395 15 juko
        for(i_f = 0; i_f < (FPW); i_f = i_f + 1) begin
396
            target_crc_per_tail1[i_f] <= 3'h0;
397
        end
398
    end else
399
    `endif
400
    begin
401
        for(i_f = 0; i_f < (FPW); i_f = i_f + 1) begin
402
            target_crc_per_tail1[i_f] <= target_crc_per_tail[i_f];
403
        end
404 11 juko
 
405 15 juko
        //Set the first stage of the data pipeline
406
        crc_data_pipe_in_hdr[0]    <= d_in_hdr_dly;
407
        crc_data_pipe_in_tail[0]   <= d_in_tail_dly;
408
        crc_data_pipe_in_valid[0]  <= d_in_valid_dly;
409 11 juko
 
410 15 juko
        //Second Stage
411
        crc_data_pipe_in_tail[1]   <= crc_data_pipe_in_tail[0];
412
        crc_data_pipe_in_hdr[1]    <= crc_data_pipe_in_hdr[0];
413
        crc_data_pipe_in_tail[1]   <= crc_data_pipe_in_tail[0];
414
        crc_data_pipe_in_valid[1]  <= crc_data_pipe_in_valid[0];
415 11 juko
    end
416
end
417
 
418
//====================================================================
419
//---------------------------------At the end of the data pipeline get and compare the CRCs
420
//====================================================================
421
`ifdef ASYNC_RES
422
always @(posedge clk or negedge res_n)  begin `else
423
always @(posedge clk)  begin `endif
424 15 juko
 
425
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
426
        `ifdef ASYNC_RES
427
            if(!res_n)data_rdy_flit[i_f]  <= {128{1'b0}};
428
            else
429
        `endif
430
        begin // Datapath
431
            data_rdy_flit[i_f]  <= crc_data_pipe_out_data_flit[i_f];
432
        end
433
    end
434
    //Propagate
435
    d_out_hdr           <= crc_data_pipe_in_hdr[1];
436
    d_out_tail          <= crc_data_pipe_in_tail[1];
437
    d_out_valid         <= crc_data_pipe_in_valid[1];
438
 
439 11 juko
if(!res_n) begin
440
 
441
    //Reset the outputs
442
    d_out_error           <= {FPW{1'b0}};
443
    d_out_poisoned        <= {FPW{1'b0}};
444
    d_out_rtc             <= {FPW{1'b0}};
445
    d_out_flow            <= {FPW{1'b0}};
446
 
447
end else begin
448
 
449
    d_out_rtc               <= {FPW{1'b0}};
450
    d_out_error             <= {FPW{1'b0}};
451
    d_out_poisoned          <= {FPW{1'b0}};
452
    d_out_flow              <= {FPW{1'b0}};
453
 
454
 
455 15 juko
 
456 11 juko
    for(i_f=0;i_f<FPW;i_f=i_f+1)begin
457 15 juko
        d_out_error[i_f] <=  crc_data_pipe_in_hdr[1][i_f] && (  ~|lng(crc_data_pipe_out_data_flit[i_f])
458
                                                                || lng(crc_data_pipe_out_data_flit[i_f])>9
459
                                                                || !lng_dln_equal(crc_data_pipe_out_data_flit[i_f]));
460 11 juko
 
461
        if(crc_data_pipe_in_tail[1][i_f])begin
462
        //Finally compare the CRC and add flow/rtc information if there is a tail
463
 
464
            if(crc(crc_data_pipe_out_data_flit[i_f]) == ~crc_per_flit[target_crc_per_tail1[i_f]]) begin
465
                //Poisoned
466
                d_out_poisoned[i_f]    <= 1'b1;
467
            end else if(crc(crc_data_pipe_out_data_flit[i_f]) != crc_per_flit[target_crc_per_tail1[i_f]]) begin
468
                //Error
469
                d_out_error[i_f]    <= 1'b1;
470
            end
471
 
472
            //Add the return token count indicator when the packet has rtc
473
            if(!crc_data_pipe_in_hdr[1][i_f]) begin
474
                //Multi-FLIT packets always have a valid RTC
475
                d_out_rtc[i_f] <= 1'b1;
476
            end else begin
477
 
478 15 juko
                if((cmd(crc_data_pipe_out_data_flit[i_f]) == CMD_TRET) || !is_rsp_flow(crc_data_pipe_out_data_flit[i_f])) begin
479
                    //All non-flow packets have a valid RTC, except TRET
480 11 juko
                    d_out_rtc[i_f] <= 1'b1;
481
                end
482 15 juko
                if(is_rsp_flow(crc_data_pipe_out_data_flit[i_f])) begin
483
                    d_out_flow[i_f] <= 1'b1;
484 11 juko
                end
485
            end
486
 
487
        end
488
    end
489
end
490
end
491
 
492
//=====================================================================================================
493
//-----------------------------------------------------------------------------------------------------
494
//---------INSTANTIATIONS HERE-------------------------------------------------------------------------
495
//-----------------------------------------------------------------------------------------------------
496
//=====================================================================================================
497
//Init CRC: Calculate the remainders of each input FLIT individually
498
generate
499
    for(f=0;f<FPW;f=f+1) begin : crc_init_gen
500
        crc_128_init crc_init_I
501
        (
502
            .clk(clk),
503 15 juko
            `ifdef ASYNC_RES
504
                .res_n(res_n),
505
            `endif
506 11 juko
            .inData(d_in_flit_removed_crc[f]),
507
            .crc(crc_init_out[f])
508
        );
509
    end
510
endgenerate
511
 
512
//Calculate the actual CRC over all valid remainders
513
generate
514
    for(f=0;f<FPW;f=f+1) begin : crc_accu_gen
515
        crc_accu #(
516
        .FPW(FPW)
517
        )
518
        crc_accu_I
519
        (
520
            .clk(clk),
521
            .res_n(res_n),
522
            .tail(crc_accu_in_tail[f]),
523
            .d_in(crc_accu_in_combined[f]),
524
            .crc_out(crc_per_flit[f])
525
        );
526
    end
527
endgenerate
528
 
529
endmodule
530 15 juko
`default_nettype wire

powered by: WebSVN 2.1.0

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