Commit f1543888 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

more code entered

parent 902a78af
Loading
Loading
Loading
Loading
+93 −5
Original line number Original line Diff line number Diff line
@@ -23,23 +23,111 @@
`timescale 1ns/1ps
`timescale 1ns/1ps


module  ahci_dma_rd_fifo#(
module  ahci_dma_rd_fifo#(
    parameter WCNT_BITS = 21
    parameter WCNT_BITS    = 21,
    parameter ADDRESS_BITS = 3
)(
)(
    input                 mrst,
    input                 mrst,
    input                 hrst,
    input                 hrst,
    input                 mclk,
    input                 mclk,
    input                 hclk,
    input                 hclk,
    input [WCNT_BITS-1:0] wcnt,
    // hclk domain
    input [WCNT_BITS-1:0] wcnt,  // decrementing word counter, 0- based (0 need 1, 1 - need 2, ...) valid @ start
    input           [1:0] woffs, // 2 LSBs of the initial word address - valid @ start
    input                 start, // start transfer
    input          [63:0] din,
    input          [63:0] din,
    input                 din_av,
    input                 din_av,
    input                 din_av_many,
    input                 din_av_many,
    input                 flush, // last prd, flush partial dword if there were odd number of words transferred
    // Or maybe use "last_prd"?
    output                din_re,
    output                din_re,
    
    output                done,
    // mclk domain
    output         [31:0] dout,
    output         [31:0] dout,
    output                dout_av,
    output                dout_vld,
    output                dout_av_many,
    input                 dout_re
    input                 dout_re
);
);
    localparam ADDRESS_NUM = (1<<ADDRESS_BITS); // 8 for ADDRESS_BITS==3
    reg   [ADDRESS_BITS : 0] waddr; // 1 extra bit       
    reg   [ADDRESS_BITS+1:0] raddr; // 1 extra bit       
    reg              [63:16] din_prev; // only 48 bits are needed
    reg      [WCNT_BITS-3:0] qwcntr;
    reg                      some_offs;
    reg                      extra_in;
    reg                      busy;
    reg                      din_last_w = din_re && (qwcntr==0);
    wire               [2:0] end_offs = wcnt[1:0] + woffs;
    
    reg               [63:0] fifo_ram [0: ADDRESS_NUM - 1];
    reg                [3:0] vld_ram  [0: ADDRESS_NUM - 1];
    reg [(1<<ADDRESS_BITS)-1:0] fifo_full;  // set in write clock domain
    reg [(1<<ADDRESS_BITS)-1:0] fifo_nempty;// set in read clock domain
    wire                     fifo_wr;
    wire                     fifo_rd;
    reg                      hrst_mclk;
    wire [(1<<ADDRESS_BITS)-1:0] fifo_full2 =       {fifo_full[0],fifo_full[ADDRESS_NUM-1:1]};
//    wire [(1<<ADDRESS_BITS)-1:0] fifo_nempty_half = {fifo_nempty[(ADDRESS_NUM>>1)-1:0],fifo_full[ADDRESS_NUM-1: ADDRESS_NUM>>1]};
    reg                      fifo_dav;  // @mclk
    reg                      fifo_dav2; // @mclk
    reg                      fifo_half_hclk;
    reg                [1:0] woffs_r;
    
    wire              [63:0] fifo_di= woffs_r[1]?(woffs_r[0] ? {din[47:0],din_prev[63:48]} : {din[31:0],din_prev[63:32]}):
                                                 (woffs_r[0] ? {din[15:0],din_prev[63:16]} : din[63:0]);
    wire               [3:0] fifo_di_vld; // Assign                                             
    
    always @ (posedge hclk) begin
        if      (hrst)  busy <= 0;
        else if (start) busy <= 1;
        else if (done)  busy <= 0;
        
        if       (start) qwcntr <= wcnt[WCNT_BITS-1:2];
        else if (din_re) qwcntr <= qwcntr - 1;
        
        if (start) some_offs <= wcnt[1:0] != 0;
        
        if (start) extra_in <= end_offs[2];

        if (start) woffs_r <= woffs;
        
        if      (hrst)    fifo_full <= 0;
        else if (fifo_wr) fifo_full <= {fifo_full[ADDRESS_NUM-2:0],waddr[ADDRESS_BITS]};

        if      (hrst)    waddr <= 0;
        else if (fifo_wr) waddr <= waddr+1;
        
        fifo_half_hclk <= fifo_nempty [waddr[ADDRESS_BITS-1:0]] ^ waddr[ADDRESS_BITS];
        
        if (din_re) din_prev[63:16] <= din[63:16];
        
        if (fifo_wr) fifo_ram[waddr[ADDRESS_BITS-1:0]] <= fifo_di;
        if (fifo_wr) vld_ram [waddr[ADDRESS_BITS-1:0]] <= fifo_di_vld;
    end
    
    always @ (posedge hclk) begin
        hrst_mclk <= hrst;

        if      (hrst_mclk)           fifo_nempty <= {{(ADDRESS_NUM>>1){1'b0}},{(ADDRESS_NUM>>1){1'b1}}};// 8'b00001111
        else if (fifo_rd && raddr[0]) fifo_nempty <= {fifo_nempty[ADDRESS_NUM-2:0],raddr[ADDRESS_BITS+1] ^ raddr[ADDRESS_BITS]};
        
        fifo_dav <=  fifo_full [raddr[ADDRESS_BITS:1]] ^ raddr[ADDRESS_BITS+1];
        fifo_dav2 <= fifo_full2[raddr[ADDRESS_BITS:1]];
    end
    
    ahci_dma_rd_stuff ahci_dma_rd_stuff_i (
        .rst      (mrst), // input
        .clk      (mclk), // input
        .din_av   (), // input
        .din_avm  (), // input
        .flush    (), // input
        .din      (), // input[31:0] 
        .dm       (), // input[1:0] 
        .din_re   (), // output
        .dout     (dout),     // output[31:0] reg 
        .dout_vld (dout_vld), // output
        .dout_re  (dout_re)   // input
    );
    
    




endmodule
endmodule
+9 −8
Original line number Original line Diff line number Diff line
@@ -37,12 +37,15 @@ module ahci_dma_rd_stuff(
    reg         hr_full;
    reg         hr_full;
    reg         dout_vld_r;
    reg         dout_vld_r;
    reg         flushing;
    reg         flushing;
    wire        din_av_safe = din_av && (din_avm || !din_re);
    reg         din_av_safe_r;
    wire  [1:0] dav_in = {2{din_av_safe}} & dm;
    wire  [1:0] dav_in = {2{din_av_safe_r}} & dm;
    wire        two_words_avail = &dav_in || (|dav_in && hr_full);
    wire        two_words_avail = &dav_in || (|dav_in && hr_full);
    assign din_re = (din_av_safe && !(|dm)) || ((!dout_vld_r || dout_re) && (two_words_avail)) ; // flush
    assign din_re = (din_av_safe_r && !(|dm)) || ((!dout_vld_r || dout_re) && (two_words_avail)) ; // flush
    assign dout_vld = dout_vld_r;
    assign dout_vld = dout_vld_r;
    always @ (posedge clk) begin
    always @ (posedge clk) begin
        if (rst) din_av_safe_r <= 0;
        else     din_av_safe_r <= din_av && (din_avm || !din_re);
    
        if ((!dout_vld_r || dout_re) && (two_words_avail || flushing)) begin
        if ((!dout_vld_r || dout_re) && (two_words_avail || flushing)) begin
            if (hr_full)               dout[15: 0] <= hr;
            if (hr_full)               dout[15: 0] <= hr;
            else                       dout[15: 0] <= din[15: 0];
            else                       dout[15: 0] <= din[15: 0];
@@ -52,7 +55,8 @@ module ahci_dma_rd_stuff(
        end
        end


        // todo add reset/flush
        // todo add reset/flush
        if (!dout_vld_r || dout_re)
        if (rst) hr_full <= 0;
        else if (!dout_vld_r || dout_re)
            // 2 but not 3 sources available
            // 2 but not 3 sources available
            if (flushing || ((two_words_avail) && ! (&dav_in && hr_full))) hr_full <= 0;
            if (flushing || ((two_words_avail) && ! (&dav_in && hr_full))) hr_full <= 0;
        else if (dav_in[0] ^ dav_in[1]) hr_full <= 1;
        else if (dav_in[0] ^ dav_in[1]) hr_full <= 1;
@@ -68,10 +72,7 @@ module ahci_dma_rd_stuff(
        else if (flush)                                             flushing <= 1;
        else if (flush)                                             flushing <= 1;
        else if ((!dout_vld_r || dout_re) && !(&dav_in && hr_full)) flushing <= 0; 
        else if ((!dout_vld_r || dout_re) && !(&dav_in && hr_full)) flushing <= 0; 
        
        
        
    end
    end




endmodule
endmodule