Commit f1543888 authored by Andrey Filippov's avatar Andrey Filippov

more code entered

parent 902a78af
...@@ -23,23 +23,111 @@ ...@@ -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
......
...@@ -37,13 +37,16 @@ module ahci_dma_rd_stuff( ...@@ -37,13 +37,16 @@ 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 ((!dout_vld_r || dout_re) && (two_words_avail || flushing) ) 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 (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( ...@@ -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( ...@@ -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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment