OpenCores
URL https://opencores.org/ocsvn/ata/ata/trunk

Subversion Repositories ata

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 23 to Rev 24
    Reverse comparison

Rev 23 → Rev 24

/trunk/rtl/verilog/ocidec-2/ud_cnt.v
0,0 → 1,105
/////////////////////////////////////////////////////////////////////
//// ////
//// Generic Up/Down counter ////
//// ////
//// Author: Richard Herveille ////
//// richard@asics.ws ////
//// www.asics.ws ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2001, 2002 Richard Herveille ////
//// richard@asics.ws ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
//// POSSIBILITY OF SUCH DAMAGE. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
// CVS Log
//
// $Id: ud_cnt.v,v 1.1 2002-02-18 14:26:46 rherveille Exp $
//
// $Date: 2002-02-18 14:26:46 $
// $Revision: 1.1 $
// $Author: rherveille $
// $Locker: $
// $State: Exp $
//
// Change History:
// $Log: not supported by cvs2svn $
// Revision 1.2 2002/02/16 10:42:17 rherveille
// Added disclaimer
// Added CVS information
// Changed core for new internal counter libraries (synthesis fixes).
//
//
 
 
/////////////////////////////
// general purpose counter //
/////////////////////////////
 
`include "timescale.v"
 
module ud_cnt (clk, nReset, rst, cnt_en, ud, nld, d, q, rci, rco);
// parameter declaration
parameter SIZE = 8;
parameter RESD = {SIZE{1'b0}}; // data after reset
 
// inputs & outputs
input clk; // master clock
input nReset; // asynchronous active low reset
input rst; // synchronous active high reset
input cnt_en; // count enable
input ud; // up/not down
input nld; // synchronous active low load
input [SIZE-1:0] d; // load counter value
output [SIZE-1:0] q; // current counter value
input rci; // carry input
output rco; // carry output
 
// variable declarations
reg [SIZE-1:0] Qi; // intermediate value
wire [SIZE:0] val; // carry+result
 
//
// Module body
//
 
assign val = ud ? ( {1'b0, Qi} + rci) : ( {1'b0, Qi} - rci);
 
always@(posedge clk or negedge nReset)
begin
if (~nReset)
Qi <= #1 RESD;
else if (rst)
Qi <= #1 RESD;
else if (~nld)
Qi <= #1 d;
else if (cnt_en)
Qi <= #1 val[SIZE-1:0];
end
 
// assign outputs
assign q = Qi;
assign rco = val[SIZE];
endmodule
 
 
/trunk/rtl/verilog/ocidec-2/atahost_pio_actrl.v
0,0 → 1,197
/////////////////////////////////////////////////////////////////////
//// ////
//// OpenCores ATA/ATAPI-5 Host Controller ////
//// PIO Access Controller (common for OCIDEC 2 and above) ////
//// ////
//// Author: Richard Herveille ////
//// richard@asics.ws ////
//// www.asics.ws ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2001, 2002 Richard Herveille ////
//// richard@asics.ws ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
//// POSSIBILITY OF SUCH DAMAGE. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
//
// CVS Log
//
// $Id: atahost_pio_actrl.v,v 1.1 2002-02-18 14:26:46 rherveille Exp $
//
// $Date: 2002-02-18 14:26:46 $
// $Revision: 1.1 $
// $Author: rherveille $
// $Locker: $
// $State: Exp $
//
// Change History:
// $Log: not supported by cvs2svn $
 
`include "timescale.v"
 
module atahost_pio_actrl (
clk, nReset, rst, IDEctrl_FATR0, IDEctrl_FATR1,
cmdport_T1, cmdport_T2, cmdport_T4, cmdport_Teoc, cmdport_IORDYen,
dport0_T1, dport0_T2, dport0_T4, dport0_Teoc, dport0_IORDYen,
dport1_T1, dport1_T2, dport1_T4, dport1_Teoc, dport1_IORDYen,
SelDev, go, done, dir, a, q, DDi, oe, DIOR, DIOW, IORDY
);
 
//
// parameters
//
parameter TWIDTH = 8;
parameter PIO_mode0_T1 = 6; // 70ns
parameter PIO_mode0_T2 = 28; // 290ns
parameter PIO_mode0_T4 = 2; // 30ns
parameter PIO_mode0_Teoc = 23; // 240ns
 
//
// inputs & outputs
//
input clk; // master clock
input nReset; // asynchronous active low reset
input rst; // synchronous active high reset
 
input IDEctrl_FATR0;
input IDEctrl_FATR1;
 
input [7:0] cmdport_T1,
cmdport_T2,
cmdport_T4,
cmdport_Teoc;
input cmdport_IORDYen; // PIO command port / non-fast timing
 
input [7:0] dport0_T1,
dport0_T2,
dport0_T4,
dport0_Teoc;
input dport0_IORDYen; // PIO mode data-port / fast timing device 0
 
input [7:0] dport1_T1,
dport1_T2,
dport1_T4,
dport1_Teoc;
input dport1_IORDYen; // PIO mode data-port / fast timing device 1
 
input SelDev; // Selected device
 
input go; // Start transfer sequence
output done; // Transfer sequence done
input dir; // Transfer direction '1'=write, '0'=read
input [ 3:0] a; // PIO transfer address
output [15:0] q; // Data read from ATA devices
reg [15:0] q;
 
input [15:0] DDi; // Data from ATA DD bus
output oe; // DDbus output-enable signal
 
output DIOR;
output DIOW;
input IORDY;
 
//
// signals & variables
//
wire dstrb;
reg [7:0] T1, T2, T4, Teoc;
reg IORDYen;
 
 
//
// Module body
//
 
// PIO transfer control
//
// capture ATA data for PIO access
always@(posedge clk)
if (dstrb)
q <= DDi;
 
 
// PIO timing controllers
//
// select timing settings for the addressed port
always@(posedge clk)
if (|a) // command ports accessed ?
begin
T1 <= #1 cmdport_T1;
T2 <= #1 cmdport_T2;
T4 <= #1 cmdport_T4;
Teoc <= #1 cmdport_Teoc;
IORDYen <= #1 cmdport_IORDYen;
end
else // data ports accessed
begin
if (SelDev & IDEctrl_FATR1)
begin
T1 <= #1 dport1_T1;
T2 <= #1 dport1_T2;
T4 <= #1 dport1_T4;
Teoc <= #1 dport1_Teoc;
IORDYen <= #1 dport1_IORDYen;
end
else if (!SelDev & IDEctrl_FATR0)
begin
T1 <= #1 dport0_T1;
T2 <= #1 dport0_T2;
T4 <= #1 dport0_T4;
Teoc <= #1 dport0_Teoc;
IORDYen <= #1 dport0_IORDYen;
end
else
begin
T1 <= #1 cmdport_T1;
T2 <= #1 cmdport_T2;
T4 <= #1 cmdport_T4;
Teoc <= #1 cmdport_Teoc;
IORDYen <= #1 cmdport_IORDYen;
end
end
 
//
// hookup timing controller
//
atahost_pio_tctrl #(TWIDTH, PIO_mode0_T1, PIO_mode0_T2, PIO_mode0_T4, PIO_mode0_Teoc)
PIO_timing_controller (
.clk(clk),
.nReset(nReset),
.rst(rst),
.IORDY_en(IORDYen),
.T1(T1),
.T2(T2),
.T4(T4),
.Teoc(Teoc),
.go(go),
.we(dir),
.oe(oe),
.done(done),
.dstrb(dstrb),
.DIOR(DIOR),
.DIOW(DIOW),
.IORDY(IORDY)
);
 
endmodule
 
/trunk/rtl/verilog/ocidec-2/atahost_pio_tctrl.v
0,0 → 1,265
/////////////////////////////////////////////////////////////////////
//// ////
//// OpenCores ATA/ATAPI-5 Host Controller ////
//// PIO Timing Controller (common for all OCIDEC cores) ////
//// ////
//// Author: Richard Herveille ////
//// richard@asics.ws ////
//// www.asics.ws ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2001, 2002 Richard Herveille ////
//// richard@asics.ws ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
//// POSSIBILITY OF SUCH DAMAGE. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
// CVS Log
//
// $Id: atahost_pio_tctrl.v,v 1.1 2002-02-18 14:26:46 rherveille Exp $
//
// $Date: 2002-02-18 14:26:46 $
// $Revision: 1.1 $
// $Author: rherveille $
// $Locker: $
// $State: Exp $
//
// Change History:
// Rev. 1.0 June 27th, 2001. Initial Verilog release
// Rev. 1.1 July 2nd, 2001. Fixed incomplete port list and some Verilog related issues.
// Rev. 1.2 July 11th, 2001. Changed 'igo' & 'hold_go' generation.
//
// $Log: not supported by cvs2svn $
// Revision 1.2 2002/02/16 10:42:17 rherveille
// Added disclaimer
// Added CVS information
// Changed core for new internal counter libraries (synthesis fixes).
//
//
 
 
//
// Timing PIO mode transfers
//--------------------------------------------
// T0: cycle time
// T1: address valid to DIOR-/DIOW-
// T2: DIOR-/DIOW- pulse width
// T2i: DIOR-/DIOW- recovery time
// T3: DIOW- data setup
// T4: DIOW- data hold
// T5: DIOR- data setup
// T6: DIOR- data hold
// T9: address hold from DIOR-/DIOW- negated
// Trd: Read data valid to IORDY asserted
// Ta: IORDY setup time
// Tb: IORDY pulse width
//
// Transfer sequence
//--------------------------------
// 1) set address (DA, CS0-, CS1-)
// 2) wait for T1
// 3) assert DIOR-/DIOW-
// when write action present Data (timing spec. T3 always honored), enable output enable-signal
// 4) wait for T2
// 5) check IORDY
// when not IORDY goto 5
// when IORDY negate DIOW-/DIOR-, latch data (if read action)
// when write, hold data for T4, disable output-enable signal
// 6) wait end_of_cycle_time. This is T2i or T9 or (T0-T1-T2) whichever takes the longest
// 7) start new cycle
 
`include "timescale.v"
 
module atahost_pio_tctrl(clk, nReset, rst, IORDY_en, T1, T2, T4, Teoc, go, we, oe, done, dstrb, DIOR, DIOW, IORDY);
// parameter declarations
parameter TWIDTH = 8;
parameter PIO_MODE0_T1 = 6; // 70ns
parameter PIO_MODE0_T2 = 28; // 290ns
parameter PIO_MODE0_T4 = 2; // 30ns
parameter PIO_MODE0_Teoc = 23; // 240ns
// inputs & outputs
input clk; // master clock
input nReset; // asynchronous active low reset
input rst; // synchronous active high reset
// timing & control register settings
input IORDY_en; // use IORDY (or not)
input [TWIDTH-1:0] T1; // T1 time (in clk-ticks)
input [TWIDTH-1:0] T2; // T1 time (in clk-ticks)
input [TWIDTH-1:0] T4; // T1 time (in clk-ticks)
input [TWIDTH-1:0] Teoc; // T1 time (in clk-ticks)
 
// control signals
input go; // PIO controller selected (strobe signal)
input we; // write enable signal. 1'b0 == read, 1'b1 == write
 
// return signals
output oe; // output enable signal
reg oe;
output done; // finished cycle
output dstrb; // data strobe, latch data (during read)
reg dstrb;
 
// ata signals
output DIOR; // IOread signal, active high
reg DIOR;
output DIOW; // IOwrite signal, active high
reg DIOW;
input IORDY; // IOrDY signal
 
 
//
// constant declarations
//
// PIO mode 0 settings (@100MHz clock)
wire [TWIDTH-1:0] T1_m0 = PIO_MODE0_T1;
wire [TWIDTH-1:0] T2_m0 = PIO_MODE0_T2;
wire [TWIDTH-1:0] T4_m0 = PIO_MODE0_T4;
wire [TWIDTH-1:0] Teoc_m0 = PIO_MODE0_Teoc;
 
//
// variable declaration
//
reg busy, hold_go;
wire igo;
wire T1done, T2done, T4done, Teoc_done, IORDY_done;
reg hT2done;
 
//
// module body
//
 
// generate internal go strobe
// strecht go until ready for new cycle
always@(posedge clk or negedge nReset)
if (~nReset)
begin
busy <= #1 1'b0;
hold_go <= #1 1'b0;
end
else if (rst)
begin
busy <= #1 1'b0;
hold_go <= #1 1'b0;
end
else
begin
busy <= #1 (igo | busy) & !Teoc_done;
hold_go <= #1 (go | (hold_go & busy)) & !igo;
end
 
assign igo = (go | hold_go) & !busy;
 
// 1) hookup T1 counter
ro_cnt #(TWIDTH, 1'b0, PIO_MODE0_T1)
t1_cnt(
.clk(clk),
.rst(rst),
.nReset(nReset),
.cnt_en(1'b1),
.go(igo),
.d(T1),
.q(),
.done(T1done)
);
 
// 2) set (and reset) DIOR-/DIOW-, set output-enable when writing to device
always@(posedge clk or negedge nReset)
if (~nReset)
begin
DIOR <= #1 1'b0;
DIOW <= #1 1'b0;
oe <= #1 1'b0;
end
else if (rst)
begin
DIOR <= #1 1'b0;
DIOW <= #1 1'b0;
oe <= #1 1'b0;
end
else
begin
DIOR <= #1 (!we & T1done) | (DIOR & !IORDY_done);
DIOW <= #1 ( we & T1done) | (DIOW & !IORDY_done);
oe <= #1 ( (we & igo) | oe) & !T4done; // negate oe when t4-done
end
 
// 3) hookup T2 counter
ro_cnt #(TWIDTH, 1'b0, PIO_MODE0_T2)
t2_cnt(
.clk(clk),
.rst(rst),
.nReset(nReset),
.cnt_en(1'b1),
.go(T1done),
.d(T2),
.q(),
.done(T2done)
);
 
// 4) check IORDY (if used), generate release_DIOR-/DIOW- signal (ie negate DIOR-/DIOW-)
// hold T2done
always@(posedge clk or negedge nReset)
if (~nReset)
hT2done <= #1 1'b0;
else if (rst)
hT2done <= #1 1'b0;
else
hT2done <= #1 (T2done | hT2done) & !IORDY_done;
 
assign IORDY_done = (T2done | hT2done) & (IORDY | !IORDY_en);
 
// generate datastrobe, capture data at rising DIOR- edge
always@(posedge clk)
dstrb <= #1 IORDY_done;
 
// hookup data hold counter
ro_cnt #(TWIDTH, 1'b0, PIO_MODE0_T4)
dhold_cnt(
.clk(clk),
.rst(rst),
.nReset(nReset),
.cnt_en(1'b1),
.go(IORDY_done),
.d(T4),
.q(),
.done(T4done)
);
 
assign done = T4done; // placing done here provides the fastest return possible,
// while still guaranteeing data and address hold-times
 
// 5) hookup end_of_cycle counter
ro_cnt #(TWIDTH, 1'b0, PIO_MODE0_Teoc)
eoc_cnt(
.clk(clk),
.rst(rst),
.nReset(nReset),
.cnt_en(1'b1),
.go(IORDY_done),
.d(Teoc),
.q(),
.done(Teoc_done)
);
 
endmodule
/trunk/rtl/verilog/ocidec-2/ro_cnt.v
0,0 → 1,111
/////////////////////////////////////////////////////////////////////
//// ////
//// Run-Once counter ////
//// ////
//// Author: Richard Herveille ////
//// richard@asics.ws ////
//// www.asics.ws ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2001, 2002 Richard Herveille ////
//// richard@asics.ws ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
//// POSSIBILITY OF SUCH DAMAGE. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
// CVS Log
//
// $Id: ro_cnt.v,v 1.1 2002-02-18 14:26:46 rherveille Exp $
//
// $Date: 2002-02-18 14:26:46 $
// $Revision: 1.1 $
// $Author: rherveille $
// $Locker: $
// $State: Exp $
//
// Change History:
// $Log: not supported by cvs2svn $
// Revision 1.2 2002/02/16 10:42:17 rherveille
// Added disclaimer
// Added CVS information
// Changed core for new internal counter libraries (synthesis fixes).
//
//
 
 
///////////////////////////
// run-once down-counter //
///////////////////////////
 
// counts D+1 cycles before generating 'DONE'
 
`include "timescale.v"
 
module ro_cnt (clk, nReset, rst, cnt_en, go, done, d, q);
 
// parameter declaration
parameter SIZE = 8;
 
parameter UD = 1'b0; // default count down
parameter ID = {SIZE{1'b0}}; // initial data after reset
 
// inputs & outputs
input clk; // master clock
input nReset; // asynchronous active low reset
input rst; // synchronous active high reset
input cnt_en; // count enable
input go; // load counter and start sequence
output done; // done counting
input [SIZE-1:0] d; // load counter value
output [SIZE-1:0] q; // current counter value
 
// variable declarations
reg rci;
wire nld, rco;
 
//
// module body
//
 
always@(posedge clk or negedge nReset)
if (~nReset)
rci <= #1 1'b0;
else if (rst)
rci <= #1 1'b0;
else //if (cnt_en)
rci <= #1 go | (rci & !rco);
 
assign nld = !go;
 
// hookup counter
ud_cnt #(SIZE, ID) cnt (.clk(clk), .nReset(nReset), .rst(rst), .cnt_en(cnt_en),
.ud(UD), .nld(nld), .d(d), .q(q), .rci(rci), .rco(rco));
 
 
// assign outputs
 
assign done = rco;
 
endmodule
 
 
 
/trunk/rtl/verilog/ocidec-2/atahost_top.v
0,0 → 1,296
/////////////////////////////////////////////////////////////////////
//// ////
//// OpenCores ATA/ATAPI-5 Host Controller ////
//// ATA/ATAPI-5 PIO Controller (OCIDEC-2) Top Level ////
//// ////
//// Author: Richard Herveille ////
//// richard@asics.ws ////
//// www.asics.ws ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2001, 2002 Richard Herveille ////
//// richard@asics.ws ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
//// POSSIBILITY OF SUCH DAMAGE. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
//
// CVS Log
//
// $Id: atahost_top.v,v 1.1 2002-02-18 14:26:46 rherveille Exp $
//
// $Date: 2002-02-18 14:26:46 $
// $Revision: 1.1 $
// $Author: rherveille $
// $Locker: $
// $State: Exp $
//
// Change History:
// $Log: not supported by cvs2svn $
//
 
//
// DeviceType: OCIDEC-2: OpenCores IDE Controller type2
// Features: PIO Compatible Timing, PIO Fast Timing 0/1
// DeviceID: 0x02
// RevNo : 0x00
//
 
//
// Host signals:
// Reset
// DIOR- read strobe. The falling edge enables data from device onto DD. The rising edge latches data at the host.
// DIOW- write strobe. The rising edge latches data from DD into the device.
// DA(2:0) 3bit binary coded adress
// CS0- select command block registers
// CS1- select control block registers
//
 
`include "timescale.v"
 
module atahost_top (wb_clk_i, arst_i, wb_rst_i, wb_cyc_i, wb_stb_i, wb_ack_o, wb_err_o,
wb_adr_i, wb_dat_i, wb_dat_o, wb_sel_i, wb_we_i, wb_inta_o,
resetn_pad_o, dd_pad_i, dd_pad_o, dd_padoe_o, da_pad_o, cs0n_pad_o,
cs1n_pad_o, diorn_pad_o, diown_pad_o, iordy_pad_i, intrq_pad_i);
//
// Parameter declarations
//
parameter ARST_LVL = 1'b0; // asynchronous reset level
 
parameter TWIDTH = 8; // counter width
// PIO mode 0 settings (@100MHz clock)
parameter PIO_mode0_T1 = 6; // 70ns
parameter PIO_mode0_T2 = 28; // 290ns
parameter PIO_mode0_T4 = 2; // 30ns
parameter PIO_mode0_Teoc = 23; // 240ns ==> T0 - T1 - T2 = 600 - 70 - 290 = 240
 
//
// inputs & outputs
//
 
// WISHBONE SYSCON signals
input wb_clk_i; // master clock in
input arst_i; // asynchronous reset
input wb_rst_i; // synchronous reset
 
// WISHBONE SLAVE signals
input wb_cyc_i; // valid bus cycle input
input wb_stb_i; // strobe/core select input
output wb_ack_o; // strobe acknowledge output
output wb_err_o; // error output
input [6:2] wb_adr_i; // A6 = '1' ATA devices selected
// A5 = '1' CS1- asserted, '0' CS0- asserted
// A4..A2 ATA address lines
// A6 = '0' ATA controller selected
input [31:0] wb_dat_i; // Databus in
output [31:0] wb_dat_o; // Databus out
input [ 3:0] wb_sel_i; // Byte select signals
input wb_we_i; // Write enable input
output wb_inta_o; // interrupt request signal
 
// ATA signals
output resetn_pad_o;
input [15:0] dd_pad_i;
output [15:0] dd_pad_o;
output dd_padoe_o;
output [ 2:0] da_pad_o;
output cs0n_pad_o;
output cs1n_pad_o;
 
output diorn_pad_o;
output diown_pad_o;
input iordy_pad_i;
input intrq_pad_i;
 
//
// constant declarations
//
parameter [3:0] DeviceId = 4'h2;
parameter [3:0] RevisionNo = 4'h0;
 
//
// Variable declarations
//
 
// registers
wire IDEctrl_IDEen, IDEctrl_rst;
wire IDEctrl_FATR0, IDEctrl_FATR1;
wire [ 7:0] PIO_cmdport_T1, PIO_cmdport_T2, PIO_cmdport_T4, PIO_cmdport_Teoc;
wire PIO_cmdport_IORDYen;
wire [ 7:0] PIO_dport0_T1, PIO_dport0_T2, PIO_dport0_T4, PIO_dport0_Teoc;
wire PIO_dport0_IORDYen;
wire [ 7:0] PIO_dport1_T1, PIO_dport1_T2, PIO_dport1_T4, PIO_dport1_Teoc;
wire PIO_dport1_IORDYen;
 
wire PIOack;
wire [15:0] PIOq;
 
wire irq; // ATA bus IRQ signal
 
 
/////////////////
// Module body //
/////////////////
 
// generate asynchronous reset level
// arst_signal is either a wire or a NOT-gate
wire arst_signal = arst_i ^ ARST_LVL;
 
//
// hookup wishbone slave
//
atahost_wb_slave #(DeviceId, RevisionNo, PIO_mode0_T1,
PIO_mode0_T2, PIO_mode0_T4, PIO_mode0_Teoc, 0, 0, 0)
u0 (
// WISHBONE SYSCON signals
.clk_i(wb_clk_i),
.arst_i(arst_signal),
.rst_i(wb_rst_i),
 
// WISHBONE SLAVE signals
.cyc_i(wb_cyc_i),
.stb_i(wb_stb_i),
.ack_o(wb_ack_o),
.rty_o(),
.err_o(wb_err_o),
.adr_i(wb_adr_i),
.dat_i(wb_dat_i),
.dat_o(wb_dat_o),
.sel_i(wb_sel_i),
.we_i(wb_we_i),
.inta_o(wb_inta_o),
 
// PIO control inputs
.PIOsel(PIOsel),
// PIOtip is only asserted during a PIO transfer (No shit! ;)
// Since it is impossible to read the status register and access the PIO registers at the same time
// this bit is useless (besides using-up resources)
.PIOtip(1'b0),
.PIOack(PIOack),
.PIOq(PIOq),
.PIOpp_full(1'b0), // OCIDEC-2 does not support PIO-write pingpong, negate signal
.irq(irq),
 
// DMA control inputs (negate all of them, OCIDEC-2 does not support DMA)
.DMAsel(),
.DMAtip(1'b0),
.DMAack(1'b0),
.DMARxEmpty(1'b0),
.DMATxFull(1'b0),
.DMA_dmarq(1'b0),
.DMAq(32'h0),
 
// outputs
// control register outputs
.IDEctrl_rst(IDEctrl_rst),
.IDEctrl_IDEen(IDEctrl_IDEen),
.IDEctrl_FATR0(IDEctrl_FATR0),
.IDEctrl_FATR1(IDEctrl_FATR1),
.IDEctrl_ppen(),
 
.DMActrl_DMAen(),
.DMActrl_dir(),
.DMActrl_BeLeC0(),
.DMActrl_BeLeC1(),
 
// CMD port timing registers
.PIO_cmdport_T1(PIO_cmdport_T1),
.PIO_cmdport_T2(PIO_cmdport_T2),
.PIO_cmdport_T4(PIO_cmdport_T4),
.PIO_cmdport_Teoc(PIO_cmdport_Teoc),
.PIO_cmdport_IORDYen(PIO_cmdport_IORDYen),
 
// data-port0 timing registers
.PIO_dport0_T1(PIO_dport0_T1),
.PIO_dport0_T2(PIO_dport0_T2),
.PIO_dport0_T4(PIO_dport0_T4),
.PIO_dport0_Teoc(PIO_dport0_Teoc),
.PIO_dport0_IORDYen(PIO_dport0_IORDYen),
 
// data-port1 timing registers
.PIO_dport1_T1(PIO_dport1_T1),
.PIO_dport1_T2(PIO_dport1_T2),
.PIO_dport1_T4(PIO_dport1_T4),
.PIO_dport1_Teoc(PIO_dport1_Teoc),
.PIO_dport1_IORDYen(PIO_dport1_IORDYen),
 
// DMA device0 timing registers
.DMA_dev0_Tm(),
.DMA_dev0_Td(),
.DMA_dev0_Teoc(),
 
// DMA device1 timing registers
.DMA_dev1_Tm(),
.DMA_dev1_Td(),
.DMA_dev1_Teoc()
);
 
 
//
// hookup controller section
//
atahost_controller #(TWIDTH, PIO_mode0_T1, PIO_mode0_T2, PIO_mode0_T4, PIO_mode0_Teoc)
u1 (
.clk(wb_clk_i),
.nReset(arst_signal),
.rst(wb_rst_i),
.irq(irq),
.IDEctrl_rst(IDEctrl_rst),
.IDEctrl_IDEen(IDEctrl_IDEen),
.IDEctrl_FATR0(IDEctrl_FATR0),
.IDEctrl_FATR1(IDEctrl_FATR1),
.cmdport_T1(PIO_cmdport_T1),
.cmdport_T2(PIO_cmdport_T2),
.cmdport_T4(PIO_cmdport_T4),
.cmdport_Teoc(PIO_cmdport_Teoc),
.cmdport_IORDYen(PIO_cmdport_IORDYen),
.dport0_T1(PIO_dport0_T1),
.dport0_T2(PIO_dport0_T2),
.dport0_T4(PIO_dport0_T4),
.dport0_Teoc(PIO_dport0_Teoc),
.dport0_IORDYen(PIO_dport0_IORDYen),
.dport1_T1(PIO_dport1_T1),
.dport1_T2(PIO_dport1_T2),
.dport1_T4(PIO_dport1_T4),
.dport1_Teoc(PIO_dport1_Teoc),
.dport1_IORDYen(PIO_dport1_IORDYen),
.PIOreq(PIOsel),
.PIOack(PIOack),
.PIOa(wb_adr_i[5:2]),
.PIOd(wb_dat_i[15:0]),
.PIOq(PIOq),
.PIOwe(wb_we_i),
.RESETn(resetn_pad_o),
.DDi(dd_pad_i),
.DDo(dd_pad_o),
.DDoe(dd_padoe_o),
.DA(da_pad_o),
.CS0n(cs0n_pad_o),
.CS1n(cs1n_pad_o),
.DIORn(diorn_pad_o),
.DIOWn(diown_pad_o),
.IORDY(iordy_pad_i),
.INTRQ(intrq_pad_i)
);
 
endmodule
 
/trunk/rtl/verilog/ocidec-2/atahost_wb_slave.v
0,0 → 1,484
/////////////////////////////////////////////////////////////////////
//// ////
//// OCIDEC-1 ATA/ATAPI-5 Controller ////
//// Wishbone Slave interface (common for all OCIDEC cores) ////
//// ////
//// Author: Richard Herveille ////
//// richard@asics.ws ////
//// www.asics.ws ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2001, 2002 Richard Herveille ////
//// richard@asics.ws ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
//// POSSIBILITY OF SUCH DAMAGE. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
//
// CVS Log
//
// $Id: atahost_wb_slave.v,v 1.1 2002-02-18 14:26:46 rherveille Exp $
//
// $Date: 2002-02-18 14:26:46 $
// $Revision: 1.1 $
// $Author: rherveille $
// $Locker: $
// $State: Exp $
//
// Change History:
// $Log: not supported by cvs2svn $
//
 
`include "timescale.v"
 
module atahost_wb_slave (
clk_i, arst_i, rst_i, cyc_i, stb_i, ack_o, rty_o, err_o, adr_i, dat_i, dat_o, sel_i, we_i, inta_o,
PIOsel, PIOtip, PIOack, PIOq, PIOpp_full, irq,
DMAsel, DMAtip, DMAack, DMARxEmpty, DMATxFull, DMA_dmarq, DMAq,
IDEctrl_rst, IDEctrl_IDEen, IDEctrl_FATR1, IDEctrl_FATR0, IDEctrl_ppen,
DMActrl_DMAen, DMActrl_dir, DMActrl_BeLeC0, DMActrl_BeLeC1,
PIO_cmdport_T1, PIO_cmdport_T2, PIO_cmdport_T4, PIO_cmdport_Teoc, PIO_cmdport_IORDYen,
PIO_dport0_T1, PIO_dport0_T2, PIO_dport0_T4, PIO_dport0_Teoc, PIO_dport0_IORDYen,
PIO_dport1_T1, PIO_dport1_T2, PIO_dport1_T4, PIO_dport1_Teoc, PIO_dport1_IORDYen,
DMA_dev0_Tm, DMA_dev0_Td, DMA_dev0_Teoc, DMA_dev1_Tm, DMA_dev1_Td, DMA_dev1_Teoc
);
 
//
// Parameters
//
parameter DeviceId = 4'h0;
parameter RevisionNo = 4'h0;
 
// PIO mode 0 settings (@100MHz clock)
parameter PIO_mode0_T1 = 6; // 70ns
parameter PIO_mode0_T2 = 28; // 290ns
parameter PIO_mode0_T4 = 2; // 30ns
parameter PIO_mode0_Teoc = 23; // 240ns ==> T0 - T1 - T2 = 600 - 70 - 290 = 240
 
// Multiword DMA mode 0 settings (@100MHz clock)
parameter DMA_mode0_Tm = 6; // 50ns
parameter DMA_mode0_Td = 21; // 215ns
parameter DMA_mode0_Teoc = 21; // 215ns ==> T0 - Td - Tm = 480 - 50 - 215 = 215
 
//
// inputs & outputs
//
// WISHBONE SYSCON signals
input clk_i; // master clock in
input arst_i; // asynchronous active low reset
input rst_i; // synchronous active high reset
 
// WISHBONE SLAVE signals
input cyc_i; // valid bus cycle input
input stb_i; // strobe/core select input
output ack_o; // strobe acknowledge output
output rty_o; // retry output
output err_o; // error output
input [6:2] adr_i; // A6 = '1' ATA devices selected
// A5 = '1' CS1- asserted, '0' CS0- asserted
// A4..A2 ATA address lines
// A6 = '0' ATA controller selected
input [31:0] dat_i; // Databus in
output [31:0] dat_o; // Databus out
input [ 3:0] sel_i; // Byte select signals
input we_i; // Write enable input
output inta_o; // interrupt request signal IDE0
 
// PIO control input
output PIOsel;
input PIOtip; // PIO transfer in progress
input PIOack; // PIO acknowledge signal
input [15:0] PIOq; // PIO data input
input PIOpp_full; // PIO write-ping-pong buffers full
input irq; // interrupt signal input
 
// DMA control inputs
output DMAsel;
input DMAtip; // DMA transfer in progress
input DMAack; // DMA transfer acknowledge
input DMARxEmpty; // DMA receive buffer empty
input DMATxFull; // DMA transmit buffer full
input DMA_dmarq; // wishbone DMA request
input [31:0] DMAq;
 
// outputs
// control register outputs
output IDEctrl_rst;
output IDEctrl_IDEen;
output IDEctrl_FATR1;
output IDEctrl_FATR0;
output IDEctrl_ppen;
output DMActrl_DMAen;
output DMActrl_dir;
output DMActrl_BeLeC0;
output DMActrl_BeLeC1;
 
// CMD port timing registers
output [7:0] PIO_cmdport_T1,
PIO_cmdport_T2,
PIO_cmdport_T4,
PIO_cmdport_Teoc;
output PIO_cmdport_IORDYen;
 
reg [7:0] PIO_cmdport_T1,
PIO_cmdport_T2,
PIO_cmdport_T4,
PIO_cmdport_Teoc;
 
// data-port0 timing registers
output [7:0] PIO_dport0_T1,
PIO_dport0_T2,
PIO_dport0_T4,
PIO_dport0_Teoc;
output PIO_dport0_IORDYen;
 
reg [7:0] PIO_dport0_T1,
PIO_dport0_T2,
PIO_dport0_T4,
PIO_dport0_Teoc;
 
// data-port1 timing registers
output [7:0] PIO_dport1_T1,
PIO_dport1_T2,
PIO_dport1_T4,
PIO_dport1_Teoc;
output PIO_dport1_IORDYen;
 
reg [7:0] PIO_dport1_T1,
PIO_dport1_T2,
PIO_dport1_T4,
PIO_dport1_Teoc;
 
// DMA device0 timing registers
output [7:0] DMA_dev0_Tm,
DMA_dev0_Td,
DMA_dev0_Teoc;
 
reg [7:0] DMA_dev0_Tm,
DMA_dev0_Td,
DMA_dev0_Teoc;
 
// DMA device1 timing registers
output [7:0] DMA_dev1_Tm,
DMA_dev1_Td,
DMA_dev1_Teoc;
 
reg [7:0] DMA_dev1_Tm,
DMA_dev1_Td,
DMA_dev1_Teoc;
 
 
//
// constants
//
 
// addresses
`define ATA_DEV_ADR adr_i[6]
`define ATA_ADR adr_i[5:2]
 
`define ATA_CTRL_REG 4'b0000
`define ATA_STAT_REG 4'b0001
`define ATA_PIO_CMD 4'b0010
`define ATA_PIO_DP0 4'b0011
`define ATA_PIO_DP1 4'b0100
`define ATA_DMA_DEV0 4'b0101
`define ATA_DMA_DEV1 4'b0110
// reserved //
`define ATA_DMA_PORT 4'b1111
 
 
//
// signals
//
 
// registers
reg [31:0] CtrlReg; // control register
wire [31:0] StatReg; // status register
 
// store ping-pong-full signal
reg store_pp_full;
 
 
//
// generate bus cycle / address decoder
//
wire w_acc = &sel_i[1:0]; // word access
wire dw_acc = &sel_i; // double word access
 
// bus error
wire berr = `ATA_DEV_ADR ? !w_acc : !dw_acc;
 
// PIO accesses at least 16bit wide, no PIO access during DMAtip or pingpong-full
wire PIOsel = cyc_i & stb_i & `ATA_DEV_ADR & w_acc & !(DMAtip | store_pp_full);
 
// CON accesses only 32bit wide
wire CONsel = cyc_i & stb_i & !(`ATA_DEV_ADR) & dw_acc;
wire DMAsel = CONsel & (`ATA_ADR == `ATA_DMA_PORT);
 
// bus retry (OCIDEC-3 and above)
// store PIOpp_full, we don't want a PPfull based retry initiated by the current bus-cycle
always@(posedge clk_i)
if (!PIOsel)
store_pp_full <= #1 PIOpp_full;
 
wire brty = (`ATA_DEV_ADR & w_acc) & (DMAtip | store_pp_full);
 
//
// generate registers
//
 
// generate register select signals
wire sel_ctrl = CONsel & we_i & (`ATA_ADR == `ATA_CTRL_REG);
wire sel_stat = CONsel & we_i & (`ATA_ADR == `ATA_STAT_REG);
wire sel_PIO_cmdport = CONsel & we_i & (`ATA_ADR == `ATA_PIO_CMD);
wire sel_PIO_dport0 = CONsel & we_i & (`ATA_ADR == `ATA_PIO_DP0);
wire sel_PIO_dport1 = CONsel & we_i & (`ATA_ADR == `ATA_PIO_DP1);
wire sel_DMA_dev0 = CONsel & we_i & (`ATA_ADR == `ATA_DMA_DEV0);
wire sel_DMA_dev1 = CONsel & we_i & (`ATA_ADR == `ATA_DMA_DEV1);
// reserved 0x1c-0x38
// reserved 0x3c : DMA-port
 
 
// generate control register
always@(posedge clk_i or negedge arst_i)
if (~arst_i)
begin
CtrlReg[31:1] <= #1 0;
CtrlReg[0] <= #1 1'b1; // set reset bit (ATA-RESETn line)
end
else if (rst_i)
begin
CtrlReg[31:1] <= #1 0;
CtrlReg[0] <= #1 1'b1; // set reset bit (ATA-RESETn line)
end
else if (sel_ctrl)
CtrlReg <= #1 dat_i;
 
// assign bits
assign DMActrl_DMAen = CtrlReg[15];
assign DMActrl_dir = CtrlReg[13];
assign DMActrl_BeLeC1 = CtrlReg[9];
assign DMActrl_BeLeC0 = CtrlReg[8];
assign IDEctrl_IDEen = CtrlReg[7];
assign IDEctrl_FATR1 = CtrlReg[6];
assign IDEctrl_FATR0 = CtrlReg[5];
assign IDEctrl_ppen = CtrlReg[4];
assign PIO_dport1_IORDYen = CtrlReg[3];
assign PIO_dport0_IORDYen = CtrlReg[2];
assign PIO_cmdport_IORDYen = CtrlReg[1];
assign IDEctrl_rst = CtrlReg[0];
 
 
// generate status register clearable bits
reg dirq, int;
always@(posedge clk_i or negedge arst_i)
if (~arst_i)
begin
int <= #1 1'b0;
dirq <= #1 1'b0;
end
else if (rst_i)
begin
int <= #1 1'b0;
dirq <= #1 1'b0;
end
else
begin
int <= #1 (int | (irq & !dirq)) & !(sel_stat & !dat_i[0]);
dirq <= #1 irq;
end
 
// assign status bits
assign StatReg[31:28] = DeviceId; // set Device ID
assign StatReg[27:24] = RevisionNo; // set revision number
assign StatReg[23:16] = 0; // reserved
assign StatReg[15] = DMAtip;
assign StatReg[14:11] = 0;
assign StatReg[10] = DMARxEmpty;
assign StatReg[9] = DMATxFull;
assign StatReg[8] = DMA_dmarq;
assign StatReg[7] = PIOtip;
assign StatReg[6] = PIOpp_full;
assign StatReg[5:1] = 0; // reserved
assign StatReg[0] = int;
 
 
// generate PIO compatible / command-port timing register
always@(posedge clk_i or negedge arst_i)
if (~arst_i)
begin
PIO_cmdport_T1 <= #1 PIO_mode0_T1;
PIO_cmdport_T2 <= #1 PIO_mode0_T2;
PIO_cmdport_T4 <= #1 PIO_mode0_T4;
PIO_cmdport_Teoc <= #1 PIO_mode0_Teoc;
end
else if (rst_i)
begin
PIO_cmdport_T1 <= #1 PIO_mode0_T1;
PIO_cmdport_T2 <= #1 PIO_mode0_T2;
PIO_cmdport_T4 <= #1 PIO_mode0_T4;
PIO_cmdport_Teoc <= #1 PIO_mode0_Teoc;
end
else if(sel_PIO_cmdport)
begin
PIO_cmdport_T1 <= #1 dat_i[ 7: 0];
PIO_cmdport_T2 <= #1 dat_i[15: 8];
PIO_cmdport_T4 <= #1 dat_i[23:16];
PIO_cmdport_Teoc <= #1 dat_i[31:24];
end
 
// generate PIO device0 timing register
always@(posedge clk_i or negedge arst_i)
if (~arst_i)
begin
PIO_dport0_T1 <= #1 PIO_mode0_T1;
PIO_dport0_T2 <= #1 PIO_mode0_T2;
PIO_dport0_T4 <= #1 PIO_mode0_T4;
PIO_dport0_Teoc <= #1 PIO_mode0_Teoc;
end
else if (rst_i)
begin
PIO_dport0_T1 <= #1 PIO_mode0_T1;
PIO_dport0_T2 <= #1 PIO_mode0_T2;
PIO_dport0_T4 <= #1 PIO_mode0_T4;
PIO_dport0_Teoc <= #1 PIO_mode0_Teoc;
end
else if(sel_PIO_dport0)
begin
PIO_dport0_T1 <= #1 dat_i[ 7: 0];
PIO_dport0_T2 <= #1 dat_i[15: 8];
PIO_dport0_T4 <= #1 dat_i[23:16];
PIO_dport0_Teoc <= #1 dat_i[31:24];
end
 
// generate PIO device1 timing register
always@(posedge clk_i or negedge arst_i)
if (~arst_i)
begin
PIO_dport1_T1 <= #1 PIO_mode0_T1;
PIO_dport1_T2 <= #1 PIO_mode0_T2;
PIO_dport1_T4 <= #1 PIO_mode0_T4;
PIO_dport1_Teoc <= #1 PIO_mode0_Teoc;
end
else if (rst_i)
begin
PIO_dport1_T1 <= #1 PIO_mode0_T1;
PIO_dport1_T2 <= #1 PIO_mode0_T2;
PIO_dport1_T4 <= #1 PIO_mode0_T4;
PIO_dport1_Teoc <= #1 PIO_mode0_Teoc;
end
else if(sel_PIO_dport1)
begin
PIO_dport1_T1 <= #1 dat_i[ 7: 0];
PIO_dport1_T2 <= #1 dat_i[15: 8];
PIO_dport1_T4 <= #1 dat_i[23:16];
PIO_dport1_Teoc <= #1 dat_i[31:24];
end
 
// generate DMA device0 timing register
always@(posedge clk_i or negedge arst_i)
if (~arst_i)
begin
DMA_dev0_Tm <= #1 DMA_mode0_Tm;
DMA_dev0_Td <= #1 DMA_mode0_Td;
DMA_dev0_Teoc <= #1 DMA_mode0_Teoc;
end
else if (rst_i)
begin
DMA_dev0_Tm <= #1 DMA_mode0_Tm;
DMA_dev0_Td <= #1 DMA_mode0_Td;
DMA_dev0_Teoc <= #1 DMA_mode0_Teoc;
end
else if(sel_DMA_dev0)
begin
DMA_dev0_Tm <= #1 dat_i[ 7: 0];
DMA_dev0_Td <= #1 dat_i[15: 8];
DMA_dev0_Teoc <= #1 dat_i[31:24];
end
 
// generate DMA device1 timing register
always@(posedge clk_i or negedge arst_i)
if (~arst_i)
begin
DMA_dev1_Tm <= #1 DMA_mode0_Tm;
DMA_dev1_Td <= #1 DMA_mode0_Td;
DMA_dev1_Teoc <= #1 DMA_mode0_Teoc;
end
else if (rst_i)
begin
DMA_dev1_Tm <= #1 DMA_mode0_Tm;
DMA_dev1_Td <= #1 DMA_mode0_Td;
DMA_dev1_Teoc <= #1 DMA_mode0_Teoc;
end
else if(sel_DMA_dev1)
begin
DMA_dev1_Tm <= #1 dat_i[ 7: 0];
DMA_dev1_Td <= #1 dat_i[15: 8];
DMA_dev1_Teoc <= #1 dat_i[31:24];
end
 
//
// generate WISHBONE interconnect signals
//
reg [31:0] Q;
 
// generate acknowledge signal
assign ack_o = PIOack | CONsel; // | DMAack; // since DMAack is derived from CONsel this is OK
 
// generate error signal
assign err_o = cyc_i & stb_i & berr;
 
// generate retry signal (for OCIDEC-3 and above only)
assign rty_o = cyc_i & stb_i & brty;
 
// generate interrupt signal
assign inta_o = StatReg[0];
// generate output multiplexor
always@(`ATA_ADR or CtrlReg or StatReg or
PIO_cmdport_T1 or PIO_cmdport_T2 or PIO_cmdport_T4 or PIO_cmdport_Teoc or
PIO_dport0_T1 or PIO_dport0_T2 or PIO_dport0_T4 or PIO_dport0_Teoc or
PIO_dport1_T1 or PIO_dport1_T2 or PIO_dport1_T4 or PIO_dport1_Teoc or
DMA_dev0_Tm or DMA_dev0_Td or DMA_dev0_Teoc or
DMA_dev1_Tm or DMA_dev1_Td or DMA_dev1_Teoc or
DMAq
)
case (`ATA_ADR) // synopsis full_case parallel_case
`ATA_CTRL_REG: Q = CtrlReg;
`ATA_STAT_REG: Q = StatReg;
`ATA_PIO_CMD : Q = {PIO_cmdport_Teoc, PIO_cmdport_T4, PIO_cmdport_T2, PIO_cmdport_T1};
`ATA_PIO_DP0 : Q = {PIO_dport0_Teoc, PIO_dport0_T4, PIO_dport0_T2, PIO_dport0_T1};
`ATA_PIO_DP1 : Q = {PIO_dport1_Teoc, PIO_dport1_T4, PIO_dport1_T2, PIO_dport1_T1};
`ATA_DMA_DEV0: Q = {DMA_dev0_Teoc, 8'h0, DMA_dev0_Td, DMA_dev0_Tm};
`ATA_DMA_DEV1: Q = {DMA_dev1_Teoc, 8'h0, DMA_dev1_Td, DMA_dev1_Tm};
`ATA_DMA_PORT: Q = DMAq;
default: Q = 0;
endcase
 
// assign DAT_O output
assign dat_o = `ATA_DEV_ADR ? {16'h0, PIOq} : Q;
 
endmodule
 
 
/trunk/rtl/verilog/ocidec-2/atahost_controller.v
0,0 → 1,265
/////////////////////////////////////////////////////////////////////
//// ////
//// OpenCores ATA/ATAPI-5 Host Controller ////
//// ATA/ATAPI-5 PIO Controller (OCIDEC-2) ////
//// ////
//// Author: Richard Herveille ////
//// richard@asics.ws ////
//// www.asics.ws ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2001, 2002 Richard Herveille ////
//// richard@asics.ws ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
//// POSSIBILITY OF SUCH DAMAGE. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
//
// CVS Log
//
// $Id: atahost_controller.v,v 1.1 2002-02-18 14:26:46 rherveille Exp $
//
// $Date: 2002-02-18 14:26:46 $
// $Revision: 1.1 $
// $Author: rherveille $
// $Locker: $
// $State: Exp $
//
// Change History:
// $Log: not supported by cvs2svn $
 
//
// OCIDEC2 supports:
// -Common Compatible timing access to all connected devices
// -Separate timing accesses to data port
// -No DMA support
//
 
`include "timescale.v"
 
module atahost_controller (
clk, nReset, rst, irq, IDEctrl_rst, IDEctrl_IDEen, IDEctrl_FATR0, IDEctrl_FATR1,
cmdport_T1, cmdport_T2, cmdport_T4, cmdport_Teoc, cmdport_IORDYen,
dport0_T1, dport0_T2, dport0_T4, dport0_Teoc, dport0_IORDYen,
dport1_T1, dport1_T2, dport1_T4, dport1_Teoc, dport1_IORDYen,
PIOreq, PIOack, PIOa, PIOd, PIOq, PIOwe,
RESETn, DDi, DDo, DDoe, DA, CS0n, CS1n, DIORn, DIOWn, IORDY, INTRQ
);
 
//
// parameters
//
parameter TWIDTH = 8;
parameter PIO_mode0_T1 = 6; // 70ns
parameter PIO_mode0_T2 = 28; // 290ns
parameter PIO_mode0_T4 = 2; // 30ns
parameter PIO_mode0_Teoc = 23; // 240ns
 
//
// inputs & outputs
//
input clk; // master clock
input nReset; // asynchronous active low reset
input rst; // synchronous active high reset
output irq; // interrupt request signal
reg irq;
 
// control / registers
input IDEctrl_rst;
input IDEctrl_IDEen;
input IDEctrl_FATR0;
input IDEctrl_FATR1;
 
input [7:0] cmdport_T1,
cmdport_T2,
cmdport_T4,
cmdport_Teoc;
input cmdport_IORDYen; // PIO command port / non-fast timing
 
input [7:0] dport0_T1,
dport0_T2,
dport0_T4,
dport0_Teoc;
input dport0_IORDYen; // PIO mode data-port / fast timing device 0
 
input [7:0] dport1_T1,
dport1_T2,
dport1_T4,
dport1_Teoc;
input dport1_IORDYen; // PIO mode data-port / fast timing device 1
 
input PIOreq; // PIO transfer request
output PIOack; // PIO transfer ended
input [ 3:0] PIOa; // PIO address
input [15:0] PIOd; // PIO data in
output [15:0] PIOq; // PIO data out
input PIOwe; // PIO direction bit '1'=write, '0'=read
 
reg PIOack;
 
// ATA signals
output RESETn;
input [15:0] DDi;
output [15:0] DDo;
output DDoe;
output [ 2:0] DA;
output CS0n;
output CS1n;
output DIORn;
output DIOWn;
input IORDY;
input INTRQ;
 
reg RESETn;
reg [15:0] DDo;
reg DDoe;
reg [ 2:0] DA;
reg CS0n;
reg CS1n;
reg DIORn;
reg DIOWn;
 
 
//
// signals & variables
//
wire PIOdone; // PIO timing controller done
 
// PIO signals
wire PIOdior, PIOdiow, PIOoe;
 
// synchronized ATA inputs
reg sIORDY;
 
//
// module body
//
 
 
// synchronize incoming signals
reg cIORDY; // capture IORDY
reg cINTRQ; // capture INTRQ
 
always@(posedge clk)
begin : synch_incoming
 
cIORDY <= #1 IORDY;
cINTRQ <= #1 INTRQ;
 
sIORDY <= #1 cIORDY;
irq <= #1 cINTRQ;
end
 
// generate ATA signals
always@(posedge clk or negedge nReset)
if (~nReset)
begin
RESETn <= #1 1'b0;
DIORn <= #1 1'b1;
DIOWn <= #1 1'b1;
DA <= #1 0;
CS0n <= #1 1'b1;
CS1n <= #1 1'b1;
DDo <= #1 0;
DDoe <= #1 1'b0;
end
else if (rst)
begin
RESETn <= #1 1'b0;
DIORn <= #1 1'b1;
DIOWn <= #1 1'b1;
DA <= #1 0;
CS0n <= #1 1'b1;
CS1n <= #1 1'b1;
DDo <= #1 0;
DDoe <= #1 1'b0;
end
else
begin
RESETn <= #1 !IDEctrl_rst;
DA <= #1 PIOa[2:0];
CS0n <= #1 !( !PIOa[3] & PIOreq); // CS0 asserted when A(3) = '0'
CS1n <= #1 !( PIOa[3] & PIOreq); // CS1 asserted when A(3) = '1'
 
DDo <= #1 PIOd;
DDoe <= #1 PIOoe;
DIORn <= #1 !PIOdior;
DIOWn <= #1 !PIOdiow;
end
 
// generate selected device
reg SelDev;
always@(posedge clk)
if (PIOdone & (PIOa == 4'b0110) & PIOwe)
SelDev <= #1 PIOd[4];
 
// generate PIOgo signal
reg dPIOreq, PIOgo;
always@(posedge clk)
begin
dPIOreq <= #1 PIOreq & !PIOack;
PIOgo <= #1 PIOreq & !dPIOreq & IDEctrl_IDEen;
end
 
//
// Hookup PIO access controller
//
atahost_pio_actrl #(TWIDTH, PIO_mode0_T1, PIO_mode0_T2, PIO_mode0_T4, PIO_mode0_Teoc)
PIO_access_control (
.clk(clk),
.nReset(nReset),
.rst(rst),
.IDEctrl_FATR0(IDEctrl_FATR0),
.IDEctrl_FATR1(IDEctrl_FATR1),
.cmdport_T1(cmdport_T1),
.cmdport_T2(cmdport_T2),
.cmdport_T4(cmdport_T4),
.cmdport_Teoc(cmdport_Teoc),
.cmdport_IORDYen(cmdport_IORDYen),
.dport0_T1(dport0_T1),
.dport0_T2(dport0_T2),
.dport0_T4(dport0_T4),
.dport0_Teoc(dport0_Teoc),
.dport0_IORDYen(dport0_IORDYen),
.dport1_T1(dport1_T1),
.dport1_T2(dport1_T2),
.dport1_T4(dport1_T4),
.dport1_Teoc(dport1_Teoc),
.dport1_IORDYen(dport1_IORDYen),
.SelDev(SelDev),
.go(PIOgo),
.done(PIOdone),
.dir(PIOwe),
.a(PIOa),
.q(PIOq),
.DDi(DDi),
.oe(PIOoe),
.DIOR(PIOdior),
.DIOW(PIOdiow),
.IORDY(sIORDY)
);
 
always@(posedge clk)
PIOack <= #1 PIOdone | (PIOreq & !IDEctrl_IDEen); // acknowledge when done or when IDE not enabled (discard request)
 
endmodule
/trunk/rtl/verilog/ocidec-2/timescale.v
0,0 → 1,2
`timescale 1ns / 10ps
 
/trunk/rtl/verilog/ocidec-2/revision_history.txt
0,0 → 1,6
-----------------------------
Revision: 1.0
Date: februar 18th, 2002
Author: Richard Herveille
- initial Verilog release
-----------------------------

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.