aboutsummaryrefslogtreecommitdiffstats
path: root/projects/U50-HBM/verilog/cdc_HBM_to_rbe.v
blob: 05a2164a5c661a475d41794da3dc8063494a9f85 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// Since we are moving from a fast to slow clock domain, 
// We need to implement this circuitry that will essentially "stretch" the signals coming from the fast clock domain
// This will make sure that a pulse (in the worst case) will always be captured by the circuitry in the slow clock domain

module cdc_HBM_to_rbe(
        input dfi_clk,
        input dfi_rst_n,
        input fab_clk,
        
        // HBM TO DRAM BENDER INTERFACE
        //input dfi_0_init_complete,
        input [255 : 0] dfi_0_dw_rddata_p0,
        input [255 : 0] dfi_0_dw_rddata_p1,
        input [3:0] dfi_0_dw_rddata_valid,

        output [255 : 0] o_dfi_0_dw_rddata_p0,
        output [255 : 0] o_dfi_0_dw_rddata_p1,
        output o_dfi_0_dw_rddata_valid
        
    );
    
    reg [255 : 0] dfi_0_dw_rddata_p0_r;
    reg [255 : 0] dfi_0_dw_rddata_p1_r;
    reg wr_en_r;

    wire [255:0] w_dfi_0_dw_rddata_p0;
    wire [255:0] w_dfi_0_dw_rddata_p1;
    wire [511:0] w_dfi_0_dw_rddata;
    wire w_wr_en;
    
    wire fifo_full;
    wire fifo_empty;
    wire fifo_valid;
    
    always @ (posedge dfi_clk)
    begin
        if (~dfi_rst_n) begin
            dfi_0_dw_rddata_p0_r <= 0;
            dfi_0_dw_rddata_p1_r <= 0;
        end else begin
            // for now I am assuming if rdvalid = 1111 we ignore the read
            // But in this circuit, there will still be a chance a 1111 will be captured, fix this issue
            // the thing is i don't know what 1111 is. It should be reading from both PC at the same time.
            // But in the testbench I have seperated from DRAM Bender I cant replicate this
            if ((dfi_0_dw_rddata_valid[1:0] == 2'b11) ^ (dfi_0_dw_rddata_valid[3:2] == 2'b11)) begin
                if ((dfi_0_dw_rddata_valid == 4'b0011)) begin
                    dfi_0_dw_rddata_p0_r <= {dfi_0_dw_rddata_p1[191:128], dfi_0_dw_rddata_p1[63:0], dfi_0_dw_rddata_p0[191:128], dfi_0_dw_rddata_p0[63:0]};
                    dfi_0_dw_rddata_p1_r <= 0;
                end else if ((dfi_0_dw_rddata_valid == 4'b1100)) begin
                    dfi_0_dw_rddata_p0_r <= 0;
                    dfi_0_dw_rddata_p1_r <= {dfi_0_dw_rddata_p1[255:192], dfi_0_dw_rddata_p1[127:64], dfi_0_dw_rddata_p0[255:192], dfi_0_dw_rddata_p0[127:64]};
                end
                wr_en_r <= 1'b1;
            end else begin
                dfi_0_dw_rddata_p0_r <= dfi_0_dw_rddata_p0_r;
                dfi_0_dw_rddata_p1_r <= dfi_0_dw_rddata_p1_r;
                wr_en_r <= 0;
            end
        end
    end

    assign w_dfi_0_dw_rddata_p0     = dfi_0_dw_rddata_p0_r;
    assign w_dfi_0_dw_rddata_p1     = dfi_0_dw_rddata_p1_r;
    assign w_wr_en                  = wr_en_r;
    
    assign o_dfi_0_dw_rddata_p0     = w_dfi_0_dw_rddata[255:0];
    assign o_dfi_0_dw_rddata_p1     = w_dfi_0_dw_rddata[511:256];
    assign o_dfi_0_dw_rddata_valid  = fifo_valid;
    
    
    cdc_fifo cdc_fifo0 (
        .srst(~dfi_rst_n),
        .wr_clk(dfi_clk),
        .rd_clk(fab_clk),
        .din({w_dfi_0_dw_rddata_p1, w_dfi_0_dw_rddata_p0}),
        .wr_en(w_wr_en),
        .rd_en(1'b1), // not sure what to set this to
        .dout(w_dfi_0_dw_rddata), // this is sent to the readback engine
        .full(fifo_full),
        .empty(fifo_empty),
        .valid(fifo_valid)
        //.wr_rst_busy(), // not needed
        //.rd_rst_busy()
    );
    
       
        
endmodule