Commit 902a78af authored by Andrey Filippov's avatar Andrey Filippov

Started implementation of the DMA for AHCI

parent 6fdd001b
/*******************************************************************************
* Module: ahci_dma
* Date:2016-01-01
* Author: andrey
* Description: DMA R/W over 64-AXI channel for AHCI implementation
*
* Copyright (c) 2016 Elphel, Inc .
* ahci_dma.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ahci_dma.v is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
`timescale 1ns/1ps
module ahci_dma (
// input rst,
input mrst, // @posedge mclk - sync reset
input hrst, // @posedge hclk - sync reset
input mclk, // for command/status
input hclk, // global clock to run axi_hp @ 150MHz
// Control interface (@mclk)
input [31:7] ctba, // command table base address
input ctba_ld, // load command table base address
input [15:0] prdtl, // number of entries in PRD table (valid at cmd_start)
input cmd_start, // start processing command table, reset prdbc
// Some data from the command table will be used internally, data will be available on the general
// sys_out[31:0] port and should be consumed
output ct_busy, // cleared after 0x20 DWORDs are read out
// After the first 0x80 bytes of the Command Table are read out, this module will read/process PRDs,
// not forwarding them to the output
output prd_done, // prd done (regardless of the interrupt)
output prd_irq, // prd interrupt, if enabled
output cmd_busy, // all command
output cmd_done,
// Data System memory -> HBA interface @ mclk
output [31:0] sys_out, // 32-bit data from the system memory to HBA - command table, dma data
output sys_dav, // at least one dword is ready to be read
output sys_dav_many, // several DWORDs are in the FIFO (TODO: decide how many)
input sys_re, // sys_out data read, advance internal FIFO
// Data HBA -> System memory interface @ mclk
output [31:0] sys_out, // 32-bit data from the system memory to HBA - command table, dma data
output sys_nfull, // internal FIFO has room for more data (will decide - how big reserved space to keep)
input sys_we,
// axi_hp signals write channel
// write address
output [31:0] afi_awaddr,
output afi_awvalid,
input afi_awready, // @SuppressThisWarning VEditor unused - used FIF0 level
output [ 5:0] afi_awid,
output [ 1:0] afi_awlock,
output [ 3:0] afi_awcache,
output [ 2:0] afi_awprot,
output [ 3:0] afi_awlen,
output [ 1:0] afi_awsize,
output [ 1:0] afi_awburst,
output [ 3:0] afi_awqos,
// write data
output [63:0] afi_wdata,
output afi_wvalid,
input afi_wready, // @SuppressThisWarning VEditor unused - used FIF0 level
output [ 5:0] afi_wid,
output afi_wlast,
output [ 7:0] afi_wstrb,
// write response
input afi_bvalid,
output afi_bready,
input [ 5:0] afi_bid, // @SuppressThisWarning VEditor unused
input [ 1:0] afi_bresp, // @SuppressThisWarning VEditor unused
// PL extra (non-AXI) signals
input [ 7:0] afi_wcount,
input [ 5:0] afi_wacount,
output afi_wrissuecap1en,
// AXI_HP signals - read channel
// read address
output [31:0] afi_araddr,
output afi_arvalid,
input afi_arready, // @SuppressThisWarning VEditor unused - used FIF0 level
output [ 5:0] afi_arid,
output [ 1:0] afi_arlock,
output [ 3:0] afi_arcache,
output [ 2:0] afi_arprot,
output [ 3:0] afi_arlen,
output [ 1:0] afi_arsize,
output [ 1:0] afi_arburst,
output [ 3:0] afi_arqos,
// read data
input [63:0] afi_rdata,
input afi_rvalid,
output afi_rready,
input [ 5:0] afi_rid, // @SuppressThisWarning VEditor unused
input afi_rlast, // @SuppressThisWarning VEditor unused
input [ 1:0] afi_rresp, // @SuppressThisWarning VEditor unused
// PL extra (non-AXI) signals
input [ 7:0] afi_rcount,
input [ 2:0] afi_racount,
output afi_rdissuecap1en
);
endmodule
/*******************************************************************************
* Module: ahci_dma_rd_fifo
* Date:2016-01-01
* Author: andrey
* Description: cross clocks, word-realign, 64->32
* Convertion from x64 QWORD-aligned AXI data @hclk to
* 32-bit word-aligned data at mclk
*
* Copyright (c) 2016 Elphel, Inc .
* ahci_dma_rd_fifo.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ahci_dma_rd_fifo.v is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
`timescale 1ns/1ps
module ahci_dma_rd_fifo#(
parameter WCNT_BITS = 21
)(
input mrst,
input hrst,
input mclk,
input hclk,
input [WCNT_BITS-1:0] wcnt,
input [63:0] din,
input din_av,
input din_av_many,
output din_re,
output [31:0] dout,
output dout_av,
output dout_av_many,
input dout_re
);
endmodule
/*******************************************************************************
* Module: ahci_dma_rd_stuff
* Date:2016-01-01
* Author: andrey
* Description: Stuff DWORD data with missing words into continuous 32-bit data
*
* Copyright (c) 2016 Elphel, Inc .
* ahci_dma_rd_stuff.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ahci_dma_rd_stuff.v is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
`timescale 1ns/1ps
module ahci_dma_rd_stuff(
input rst, // sync reset
input clk, // single clock
input din_av, // input data available
input din_avm, // >1 word of data available
input flush, // output partial dword if available (should be ? cycles after last _re/ with data?)
input [31:0] din, // 32-bit input dfata
input [1:0] dm, // data mask showing which (if any) words in input dword are valid
output din_re, // read input data
output reg [31:0] dout, // output 32-bit data
output dout_vld, // output data valid
input dout_re // consumer reads output data (should be anded with dout_vld)
);
reg [15:0] hr; // holds 16-bit data from previous din_re if not consumed
reg hr_full;
reg dout_vld_r;
reg flushing;
wire din_av_safe = din_av && (din_avm || !din_re);
wire [1:0] dav_in = {2{din_av_safe}} & dm;
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 dout_vld = dout_vld_r;
always @ (posedge clk) begin
if ((!dout_vld_r || dout_re) && (two_words_avail || flushing) ) begin
if (hr_full) dout[15: 0] <= hr;
else dout[15: 0] <= din[15: 0];
if (hr_full && dav_in[0]) dout[31:16] <= din[15: 0];
else dout[31:16] <= din[31:16];
end
// todo add reset/flush
if (!dout_vld_r || dout_re)
// 2 but not 3 sources available
if (flushing || ((two_words_avail) && ! (&dav_in && hr_full))) hr_full <= 0;
else if (dav_in[0] ^ dav_in[1]) hr_full <= 1;
if ((!dout_vld_r || dout_re) && (&dav_in && hr_full)) hr <= din[31:16];
else if ((dav_in[0] ^ dav_in[1]) && !hr_full) hr <= dav_in[0]? din[15:0] : din[31:16];
if (rst) dout_vld_r <= 0;
else if ((!dout_vld_r || dout_re) && (two_words_avail || (flushing && hr_full))) dout_vld_r <= 1;
else if (dout_re) dout_vld_r <= 0;
if (rst) flushing <= 0;
else if (flush) flushing <= 1;
else if ((!dout_vld_r || dout_re) && !(&dav_in && hr_full)) flushing <= 0;
end
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