/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// OpenCores ATA/ATAPI-5 Host Controller ////
|
//// OpenCores ATA/ATAPI-5 Host Controller ////
|
//// ATA/ATAPI-5 PIO Controller (OCIDEC-2) ////
|
//// ATA/ATAPI-5 PIO Controller (OCIDEC-2) ////
|
//// ////
|
//// ////
|
//// Author: Richard Herveille ////
|
//// Author: Richard Herveille ////
|
//// richard@asics.ws ////
|
//// richard@asics.ws ////
|
//// www.asics.ws ////
|
//// www.asics.ws ////
|
//// ////
|
//// ////
|
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Copyright (C) 2001, 2002 Richard Herveille ////
|
//// Copyright (C) 2001, 2002 Richard Herveille ////
|
//// richard@asics.ws ////
|
//// richard@asics.ws ////
|
//// ////
|
//// ////
|
//// This source file may be used and distributed without ////
|
//// This source file may be used and distributed without ////
|
//// restriction provided that this copyright statement is not ////
|
//// restriction provided that this copyright statement is not ////
|
//// removed from the file and that any derivative work contains ////
|
//// removed from the file and that any derivative work contains ////
|
//// the original copyright notice and the associated disclaimer.////
|
//// the original copyright notice and the associated disclaimer.////
|
//// ////
|
//// ////
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
//// ////
|
//// ////
|
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
|
|
//
|
//
|
// CVS Log
|
// CVS Log
|
//
|
//
|
// $Id: atahost_controller.v,v 1.2 2002-05-19 06:05:28 rherveille Exp $
|
// $Id: atahost_controller.v,v 1.2 2002-05-19 06:05:28 rherveille Exp $
|
//
|
//
|
// $Date: 2002-05-19 06:05:28 $
|
// $Date: 2002-05-19 06:05:28 $
|
// $Revision: 1.2 $
|
// $Revision: 1.2 $
|
// $Author: rherveille $
|
// $Author: rherveille $
|
// $Locker: $
|
// $Locker: $
|
// $State: Exp $
|
// $State: Exp $
|
//
|
//
|
// Change History:
|
// Change History:
|
// $Log: not supported by cvs2svn $
|
// $Log: not supported by cvs2svn $
|
|
|
//
|
//
|
// OCIDEC2 supports:
|
// OCIDEC2 supports:
|
// -Common Compatible timing access to all connected devices
|
// -Common Compatible timing access to all connected devices
|
// -Separate timing accesses to data port
|
// -Separate timing accesses to data port
|
// -No DMA support
|
// -No DMA support
|
//
|
//
|
|
|
`include "timescale.v"
|
`include "timescale.v"
|
|
|
module atahost_controller (
|
module atahost_controller (
|
clk, nReset, rst, irq, IDEctrl_rst, IDEctrl_IDEen, IDEctrl_FATR0, IDEctrl_FATR1,
|
clk, nReset, rst, irq, IDEctrl_rst, IDEctrl_IDEen, IDEctrl_FATR0, IDEctrl_FATR1,
|
cmdport_T1, cmdport_T2, cmdport_T4, cmdport_Teoc, cmdport_IORDYen,
|
cmdport_T1, cmdport_T2, cmdport_T4, cmdport_Teoc, cmdport_IORDYen,
|
dport0_T1, dport0_T2, dport0_T4, dport0_Teoc, dport0_IORDYen,
|
dport0_T1, dport0_T2, dport0_T4, dport0_Teoc, dport0_IORDYen,
|
dport1_T1, dport1_T2, dport1_T4, dport1_Teoc, dport1_IORDYen,
|
dport1_T1, dport1_T2, dport1_T4, dport1_Teoc, dport1_IORDYen,
|
PIOreq, PIOack, PIOa, PIOd, PIOq, PIOwe,
|
PIOreq, PIOack, PIOa, PIOd, PIOq, PIOwe,
|
RESETn, DDi, DDo, DDoe, DA, CS0n, CS1n, DIORn, DIOWn, IORDY, INTRQ
|
RESETn, DDi, DDo, DDoe, DA, CS0n, CS1n, DIORn, DIOWn, IORDY, INTRQ
|
);
|
);
|
|
|
//
|
//
|
// parameters
|
// parameters
|
//
|
//
|
parameter TWIDTH = 8;
|
parameter TWIDTH = 8;
|
parameter PIO_mode0_T1 = 6; // 70ns
|
parameter PIO_mode0_T1 = 6; // 70ns
|
parameter PIO_mode0_T2 = 28; // 290ns
|
parameter PIO_mode0_T2 = 28; // 290ns
|
parameter PIO_mode0_T4 = 2; // 30ns
|
parameter PIO_mode0_T4 = 2; // 30ns
|
parameter PIO_mode0_Teoc = 23; // 240ns
|
parameter PIO_mode0_Teoc = 23; // 240ns
|
|
|
//
|
//
|
// inputs & outputs
|
// inputs & outputs
|
//
|
//
|
input clk; // master clock
|
input clk; // master clock
|
input nReset; // asynchronous active low reset
|
input nReset; // asynchronous active low reset
|
input rst; // synchronous active high reset
|
input rst; // synchronous active high reset
|
|
|
output irq; // interrupt request signal
|
output irq; // interrupt request signal
|
reg irq;
|
reg irq;
|
|
|
// control / registers
|
// control / registers
|
input IDEctrl_rst;
|
input IDEctrl_rst;
|
input IDEctrl_IDEen;
|
input IDEctrl_IDEen;
|
input IDEctrl_FATR0;
|
input IDEctrl_FATR0;
|
input IDEctrl_FATR1;
|
input IDEctrl_FATR1;
|
|
|
input [7:0] cmdport_T1,
|
input [7:0] cmdport_T1,
|
cmdport_T2,
|
cmdport_T2,
|
cmdport_T4,
|
cmdport_T4,
|
cmdport_Teoc;
|
cmdport_Teoc;
|
input cmdport_IORDYen; // PIO command port / non-fast timing
|
input cmdport_IORDYen; // PIO command port / non-fast timing
|
|
|
input [7:0] dport0_T1,
|
input [7:0] dport0_T1,
|
dport0_T2,
|
dport0_T2,
|
dport0_T4,
|
dport0_T4,
|
dport0_Teoc;
|
dport0_Teoc;
|
input dport0_IORDYen; // PIO mode data-port / fast timing device 0
|
input dport0_IORDYen; // PIO mode data-port / fast timing device 0
|
|
|
input [7:0] dport1_T1,
|
input [7:0] dport1_T1,
|
dport1_T2,
|
dport1_T2,
|
dport1_T4,
|
dport1_T4,
|
dport1_Teoc;
|
dport1_Teoc;
|
input dport1_IORDYen; // PIO mode data-port / fast timing device 1
|
input dport1_IORDYen; // PIO mode data-port / fast timing device 1
|
|
|
input PIOreq; // PIO transfer request
|
input PIOreq; // PIO transfer request
|
output PIOack; // PIO transfer ended
|
output PIOack; // PIO transfer ended
|
input [ 3:0] PIOa; // PIO address
|
input [ 3:0] PIOa; // PIO address
|
input [15:0] PIOd; // PIO data in
|
input [15:0] PIOd; // PIO data in
|
output [15:0] PIOq; // PIO data out
|
output [15:0] PIOq; // PIO data out
|
input PIOwe; // PIO direction bit '1'=write, '0'=read
|
input PIOwe; // PIO direction bit '1'=write, '0'=read
|
|
|
reg PIOack;
|
reg PIOack;
|
|
|
// ATA signals
|
// ATA signals
|
output RESETn;
|
output RESETn;
|
input [15:0] DDi;
|
input [15:0] DDi;
|
output [15:0] DDo;
|
output [15:0] DDo;
|
output DDoe;
|
output DDoe;
|
output [ 2:0] DA;
|
output [ 2:0] DA;
|
output CS0n;
|
output CS0n;
|
output CS1n;
|
output CS1n;
|
output DIORn;
|
output DIORn;
|
output DIOWn;
|
output DIOWn;
|
input IORDY;
|
input IORDY;
|
input INTRQ;
|
input INTRQ;
|
|
|
reg RESETn;
|
reg RESETn;
|
reg [15:0] DDo;
|
reg [15:0] DDo;
|
reg DDoe;
|
reg DDoe;
|
reg [ 2:0] DA;
|
reg [ 2:0] DA;
|
reg CS0n;
|
reg CS0n;
|
reg CS1n;
|
reg CS1n;
|
reg DIORn;
|
reg DIORn;
|
reg DIOWn;
|
reg DIOWn;
|
|
|
|
|
//
|
//
|
// signals & variables
|
// signals & variables
|
//
|
//
|
wire PIOdone; // PIO timing controller done
|
wire PIOdone; // PIO timing controller done
|
|
|
// PIO signals
|
// PIO signals
|
wire PIOdior, PIOdiow, PIOoe;
|
wire PIOdior, PIOdiow, PIOoe;
|
|
|
// synchronized ATA inputs
|
// synchronized ATA inputs
|
reg sIORDY;
|
reg sIORDY;
|
|
|
//
|
//
|
// module body
|
// module body
|
//
|
//
|
|
|
|
|
// synchronize incoming signals
|
// synchronize incoming signals
|
reg cIORDY; // capture IORDY
|
reg cIORDY; // capture IORDY
|
reg cINTRQ; // capture INTRQ
|
reg cINTRQ; // capture INTRQ
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
begin : synch_incoming
|
begin : synch_incoming
|
|
|
cIORDY <= #1 IORDY;
|
cIORDY <= #1 IORDY;
|
cINTRQ <= #1 INTRQ;
|
cINTRQ <= #1 INTRQ;
|
|
|
sIORDY <= #1 cIORDY;
|
sIORDY <= #1 cIORDY;
|
irq <= #1 cINTRQ;
|
irq <= #1 cINTRQ;
|
end
|
end
|
|
|
// generate ATA signals
|
// generate ATA signals
|
always @(posedge clk or negedge nReset)
|
always @(posedge clk or negedge nReset)
|
if (~nReset)
|
if (~nReset)
|
begin
|
begin
|
RESETn <= #1 1'b0;
|
RESETn <= #1 1'b0;
|
DIORn <= #1 1'b1;
|
DIORn <= #1 1'b1;
|
DIOWn <= #1 1'b1;
|
DIOWn <= #1 1'b1;
|
DA <= #1 0;
|
DA <= #1 0;
|
CS0n <= #1 1'b1;
|
CS0n <= #1 1'b1;
|
CS1n <= #1 1'b1;
|
CS1n <= #1 1'b1;
|
DDo <= #1 0;
|
DDo <= #1 0;
|
DDoe <= #1 1'b0;
|
DDoe <= #1 1'b0;
|
end
|
end
|
else if (rst)
|
else if (rst)
|
begin
|
begin
|
RESETn <= #1 1'b0;
|
RESETn <= #1 1'b0;
|
DIORn <= #1 1'b1;
|
DIORn <= #1 1'b1;
|
DIOWn <= #1 1'b1;
|
DIOWn <= #1 1'b1;
|
DA <= #1 0;
|
DA <= #1 0;
|
CS0n <= #1 1'b1;
|
CS0n <= #1 1'b1;
|
CS1n <= #1 1'b1;
|
CS1n <= #1 1'b1;
|
DDo <= #1 0;
|
DDo <= #1 0;
|
DDoe <= #1 1'b0;
|
DDoe <= #1 1'b0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
RESETn <= #1 !IDEctrl_rst;
|
RESETn <= #1 !IDEctrl_rst;
|
DA <= #1 PIOa[2:0];
|
DA <= #1 PIOa[2:0];
|
CS0n <= #1 !( !PIOa[3] & PIOreq); // CS0 asserted when A(3) = '0'
|
CS0n <= #1 !( !PIOa[3] & PIOreq); // CS0 asserted when A(3) = '0'
|
CS1n <= #1 !( PIOa[3] & PIOreq); // CS1 asserted when A(3) = '1'
|
CS1n <= #1 !( PIOa[3] & PIOreq); // CS1 asserted when A(3) = '1'
|
|
|
DDo <= #1 PIOd;
|
DDo <= #1 PIOd;
|
DDoe <= #1 PIOoe;
|
DDoe <= #1 PIOoe;
|
DIORn <= #1 !PIOdior;
|
DIORn <= #1 !PIOdior;
|
DIOWn <= #1 !PIOdiow;
|
DIOWn <= #1 !PIOdiow;
|
end
|
end
|
|
|
// generate selected device
|
// generate selected device
|
reg SelDev;
|
reg SelDev;
|
always @(posedge clk)
|
always @(posedge clk)
|
if (PIOdone & (PIOa == 4'b0110) & PIOwe)
|
if (PIOdone & (PIOa == 4'b0110) & PIOwe)
|
SelDev <= #1 PIOd[4];
|
SelDev <= #1 PIOd[4];
|
|
|
// generate PIOgo signal
|
// generate PIOgo signal
|
always @(posedge clk or negedge nReset)
|
always @(posedge clk or negedge nReset)
|
if (~nReset)
|
if (~nReset)
|
begin
|
begin
|
dPIOreq <= #1 1'b0;
|
dPIOreq <= #1 1'b0;
|
PIOgo <= #1 1'b0;
|
PIOgo <= #1 1'b0;
|
end
|
end
|
else if (rst)
|
else if (rst)
|
begin
|
begin
|
dPIOreq <= #1 1'b0;
|
dPIOreq <= #1 1'b0;
|
PIOgo <= #1 1'b0;
|
PIOgo <= #1 1'b0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
dPIOreq <= #1 PIOreq & !PIOack;
|
dPIOreq <= #1 PIOreq & !PIOack;
|
PIOgo <= #1 (PIOreq & !dPIOreq) & IDEctrl_IDEen;
|
PIOgo <= #1 (PIOreq & !dPIOreq) & IDEctrl_IDEen;
|
end
|
end
|
|
|
//
|
//
|
// Hookup PIO access controller
|
// Hookup PIO access controller
|
//
|
//
|
atahost_pio_actrl #(TWIDTH, PIO_mode0_T1, PIO_mode0_T2, PIO_mode0_T4, PIO_mode0_Teoc)
|
atahost_pio_actrl #(TWIDTH, PIO_mode0_T1, PIO_mode0_T2, PIO_mode0_T4, PIO_mode0_Teoc)
|
PIO_access_control (
|
PIO_access_control (
|
.clk(clk),
|
.clk(clk),
|
.nReset(nReset),
|
.nReset(nReset),
|
.rst(rst),
|
.rst(rst),
|
.IDEctrl_FATR0(IDEctrl_FATR0),
|
.IDEctrl_FATR0(IDEctrl_FATR0),
|
.IDEctrl_FATR1(IDEctrl_FATR1),
|
.IDEctrl_FATR1(IDEctrl_FATR1),
|
.cmdport_T1(cmdport_T1),
|
.cmdport_T1(cmdport_T1),
|
.cmdport_T2(cmdport_T2),
|
.cmdport_T2(cmdport_T2),
|
.cmdport_T4(cmdport_T4),
|
.cmdport_T4(cmdport_T4),
|
.cmdport_Teoc(cmdport_Teoc),
|
.cmdport_Teoc(cmdport_Teoc),
|
.cmdport_IORDYen(cmdport_IORDYen),
|
.cmdport_IORDYen(cmdport_IORDYen),
|
.dport0_T1(dport0_T1),
|
.dport0_T1(dport0_T1),
|
.dport0_T2(dport0_T2),
|
.dport0_T2(dport0_T2),
|
.dport0_T4(dport0_T4),
|
.dport0_T4(dport0_T4),
|
.dport0_Teoc(dport0_Teoc),
|
.dport0_Teoc(dport0_Teoc),
|
.dport0_IORDYen(dport0_IORDYen),
|
.dport0_IORDYen(dport0_IORDYen),
|
.dport1_T1(dport1_T1),
|
.dport1_T1(dport1_T1),
|
.dport1_T2(dport1_T2),
|
.dport1_T2(dport1_T2),
|
.dport1_T4(dport1_T4),
|
.dport1_T4(dport1_T4),
|
.dport1_Teoc(dport1_Teoc),
|
.dport1_Teoc(dport1_Teoc),
|
.dport1_IORDYen(dport1_IORDYen),
|
.dport1_IORDYen(dport1_IORDYen),
|
.SelDev(SelDev),
|
.SelDev(SelDev),
|
.go(PIOgo),
|
.go(PIOgo),
|
.done(PIOdone),
|
.done(PIOdone),
|
.dir(PIOwe),
|
.dir(PIOwe),
|
.a(PIOa),
|
.a(PIOa),
|
.q(PIOq),
|
.q(PIOq),
|
.DDi(DDi),
|
.DDi(DDi),
|
.oe(PIOoe),
|
.oe(PIOoe),
|
.DIOR(PIOdior),
|
.DIOR(PIOdior),
|
.DIOW(PIOdiow),
|
.DIOW(PIOdiow),
|
.IORDY(sIORDY)
|
.IORDY(sIORDY)
|
);
|
);
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
PIOack <= #1 PIOdone | (PIOreq & !IDEctrl_IDEen); // acknowledge when done or when IDE not enabled (discard request)
|
PIOack <= #1 PIOdone | (PIOreq & !IDEctrl_IDEen); // acknowledge when done or when IDE not enabled (discard request)
|
|
|
endmodule
|
endmodule
|
|
|