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 24 to Rev 25
    Reverse comparison

Rev 24 → Rev 25

/trunk/rtl/vhdl/ocidec1/atahost_pio_tctrl.vhd
0,0 → 1,285
---------------------------------------------------------------------
---- ----
---- 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. ----
---- ----
---------------------------------------------------------------------
 
-- rev.: 1.0 march 7th, 2001. Initial release
-- rev.: 1.1 July 11th, 2001. Changed 'igo' & 'hold_go' signal generation.
--
--
-- CVS Log
--
-- $Id: atahost_pio_tctrl.vhd,v 1.1 2002-02-18 14:29:38 rherveille Exp $
--
-- $Date: 2002-02-18 14:29:38 $
-- $Revision: 1.1 $
-- $Author: rherveille $
-- $Locker: $
-- $State: Exp $
--
-- Change History:
-- $Log: not supported by cvs2svn $
--
--
 
--
---------------------------
-- PIO Timing controller --
---------------------------
--
 
--
-- 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
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
 
entity atahost_pio_tctrl is
generic(
TWIDTH : natural := 8; -- counter width
 
-- PIO mode 0 settings (@100MHz clock)
PIO_mode0_T1 : natural := 6; -- 70ns
PIO_mode0_T2 : natural := 28; -- 290ns
PIO_mode0_T4 : natural := 2; -- 30ns
PIO_mode0_Teoc : natural := 23 -- 240ns ==> T0 - T1 - T2 = 600 - 70 - 290 = 240
);
port(
clk : in std_logic; -- master clock
nReset : in std_logic; -- asynchronous active low reset
rst : in std_logic; -- synchronous active high reset
 
-- timing/control register settings
IORDY_en : in std_logic; -- use IORDY (or not)
T1 : in unsigned(TWIDTH -1 downto 0); -- T1 time (in clk-ticks)
T2 : in unsigned(TWIDTH -1 downto 0); -- T2 time (in clk-ticks)
T4 : in unsigned(TWIDTH -1 downto 0); -- T4 time (in clk-ticks)
Teoc : in unsigned(TWIDTH -1 downto 0); -- end of cycle time
 
-- control signals
go : in std_logic; -- PIO controller selected (strobe signal)
we : in std_logic; -- write enable signal. '0'=read from device, '1'=write to device
 
-- return signals
oe : buffer std_logic; -- output enable signal
done : out std_logic; -- finished cycle
dstrb : out std_logic; -- data strobe, latch data (during read)
 
-- ATA signals
DIOR, -- IOread signal, active high
DIOW : buffer std_logic; -- IOwrite signal, active high
IORDY : in std_logic -- IORDY signal
);
end entity atahost_pio_tctrl;
 
architecture structural of atahost_pio_tctrl is
component ro_cnt is
generic(
SIZE : natural := 8;
UD : std_logic := '0'; -- default count down
ID : natural := 0 -- initial data after reset
);
port(
clk : in std_logic; -- master clock
nReset : in std_logic := '1'; -- asynchronous active low reset
rst : in std_logic := '0'; -- synchronous active high reset
 
cnt_en : in std_logic := '1'; -- count enable
go : in std_logic; -- load counter and start sequence
done : out std_logic; -- done counting
d : in unsigned(SIZE -1 downto 0); -- load counter value
q : out unsigned(SIZE -1 downto 0) -- current counter value
);
end component ro_cnt;
 
signal T1done, T2done, T4done, Teoc_done, IORDY_done : std_logic;
signal busy, hold_go, igo, hT2done : std_logic;
begin
-- generate internal go strobe
-- strecht go until ready for new cycle
process(clk, nReset)
begin
if (nReset = '0') then
busy <= '0';
hold_go <= '0';
elsif (clk'event and clk = '1') then
if (rst = '1') then
busy <= '0';
hold_go <= '0';
else
busy <= (igo or busy) and not Teoc_done;
hold_go <= (go or (hold_go and busy)) and not igo;
end if;
end if;
end process;
igo <= (go or hold_go) and not busy;
 
-- 1) hookup T1 counter
t1_cnt : ro_cnt
generic map (
SIZE => TWIDTH,
UD => '0',
ID => PIO_mode0_T1
)
port map (
clk => clk,
nReset => nReset,
rst => rst,
go => igo,
D => T1,
done => T1done
);
 
-- 2) set (and reset) DIOR-/DIOW-, set output-enable when writing to device
T2proc: process(clk, nReset)
begin
if (nReset = '0') then
DIOR <= '0';
DIOW <= '0';
oe <= '0';
elsif (clk'event and clk = '1') then
if (rst = '1') then
DIOR <= '0';
DIOW <= '0';
oe <= '0';
else
DIOR <= (not we and T1done) or (DIOR and not IORDY_done);
DIOW <= ( we and T1done) or (DIOW and not IORDY_done);
oe <= ( (we and igo) or oe) and not T4done; -- negate oe when t4-done
end if;
end if;
end process T2proc;
 
-- 3) hookup T2 counter
t2_cnt : ro_cnt
generic map (
SIZE => TWIDTH,
UD => '0',
ID => PIO_mode0_T2
)
port map (
clk => clk,
nReset => nReset,
rst => rst,
go => T1done,
D => T2,
done => T2done
);
 
-- 4) check IORDY (if used), generate release_DIOR-/DIOW- signal (ie negate DIOR-/DIOW-)
-- hold T2done
gen_hT2done: process(clk, nReset)
begin
if (nReset = '0') then
hT2done <= '0';
elsif (clk'event and clk = '1') then
if (rst = '1') then
hT2done <= '0';
else
hT2done <= (T2done or hT2done) and not IORDY_done;
end if;
end if;
end process gen_hT2done;
IORDY_done <= (T2done or hT2done) and (IORDY or not IORDY_en);
 
-- generate datastrobe, capture data at rising DIOR- edge
gen_dstrb: process(clk)
begin
if (clk'event and clk = '1') then
dstrb <= IORDY_done;
end if;
end process gen_dstrb;
 
-- hookup data hold counter
dhold_cnt : ro_cnt
generic map (
SIZE => TWIDTH,
UD => '0',
ID => PIO_mode0_T4
)
port map (
clk => clk,
nReset => nReset,
rst => rst,
go => IORDY_done,
D => T4,
done => T4done
);
done <= T4done; -- placing done here provides the fastest return possible,
-- while still guaranteeing data and address hold-times
 
-- 5) hookup end_of_cycle counter
eoc_cnt : ro_cnt
generic map (
SIZE => TWIDTH,
UD => '0',
ID => PIO_mode0_Teoc
)
port map (
clk => clk,
nReset => nReset,
rst => rst,
go => IORDY_done,
D => Teoc,
done => Teoc_done
);
 
end architecture structural;
/trunk/rtl/vhdl/ocidec1/atahost_top.vhd
0,0 → 1,426
---------------------------------------------------------------------
---- ----
---- OpenCores IDE Controller ATA/ATAPI-5 (OCIDEC-1) ----
---- 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. ----
---- ----
---------------------------------------------------------------------
 
-- rev.: 1.0 march 22nd, 2001. Initial release
-- rev.: 1.0a april 12th, 2001. Removed references to records.vhd to make it compatible with freely available VHDL to Verilog converter tools
-- rev.: 1.1 june 18th, 2001. Changed wishbone address-input from (A4..A0) to (A6..A2)
-- rev.: 1.1a june 19th, 2001. Missed a reference to ADR_I(4). Simplified DAT_O output multiplexor.
--
--
-- CVS Log
--
-- $Id: atahost_top.vhd,v 1.1 2002-02-18 14:29:38 rherveille Exp $
--
-- $Date: 2002-02-18 14:29:38 $
-- $Revision: 1.1 $
-- $Author: rherveille $
-- $Locker: $
-- $State: Exp $
--
-- Change History:
-- $Log: not supported by cvs2svn $
--
--
--
 
-- DeviceType: OCIDEC-1: OpenCores IDE Controller type1
-- Features: PIO Compatible Timing
-- DeviceID: 0x01
-- 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
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
 
entity atahost_top is
generic(
ARST_LVL : std_logic := '0'; -- asynchronous reset level
 
TWIDTH : natural := 8; -- counter width
 
-- PIO mode 0 settings (@100MHz clock)
PIO_mode0_T1 : natural := 6; -- 70ns
PIO_mode0_T2 : natural := 28; -- 290ns
PIO_mode0_T4 : natural := 2; -- 30ns
PIO_mode0_Teoc : natural := 23 -- 240ns ==> T0 - T1 - T2 = 600 - 70 - 290 = 240
);
port(
-- WISHBONE SYSCON signals
wb_clk_i : in std_logic; -- master clock in
arst_i : in std_logic := '1'; -- asynchronous active low reset
wb_rst_i : in std_logic := '0'; -- synchronous active high reset
 
-- WISHBONE SLAVE signals
wb_cyc_i : in std_logic; -- valid bus cycle input
wb_stb_i : in std_logic; -- strobe/core select input
wb_ack_o : out std_logic; -- strobe acknowledge output
wb_err_o : out std_logic; -- error output
wb_adr_i : in unsigned(6 downto 2); -- A6 = '1' ATA devices selected
-- A5 = '1' CS1- asserted, '0' CS0- asserted
-- A4..A2 ATA address lines
-- A6 = '0' ATA controller selected
wb_dat_i : in std_logic_vector(31 downto 0); -- Databus in
wb_dat_o : out std_logic_vector(31 downto 0); -- Databus out
wb_sel_i : in std_logic_vector(3 downto 0); -- Byte select signals
wb_we_i : in std_logic; -- Write enable input
wb_inta_o : out std_logic; -- interrupt request signal IDE0
 
-- ATA signals
resetn_pad_o : out std_logic;
dd_pad_i : in std_logic_vector(15 downto 0);
dd_pad_o : out std_logic_vector(15 downto 0);
dd_padoe_o : out std_logic;
da_pad_o : out unsigned(2 downto 0);
cs0n_pad_o : out std_logic;
cs1n_pad_o : out std_logic;
 
diorn_pad_o : out std_logic;
diown_pad_o : out std_logic;
iordy_pad_i : in std_logic;
intrq_pad_i : in std_logic
);
end entity atahost_top;
 
architecture structural of atahost_top is
--
-- constants
--
 
-- Device ID
constant DeviceId : unsigned(3 downto 0) := x"1";
constant RevisionNo : unsigned(3 downto 0) := x"0";
 
--
-- component declarations
--
component atahost_wb_slave is
generic(
DeviceID : unsigned(3 downto 0) := x"0";
RevisionNo : unsigned(3 downto 0) := x"0";
 
-- PIO mode 0 settings (@100MHz clock)
PIO_mode0_T1 : natural := 6; -- 70ns
PIO_mode0_T2 : natural := 28; -- 290ns
PIO_mode0_T4 : natural := 2; -- 30ns
PIO_mode0_Teoc : natural := 23; -- 240ns ==> T0 - T1 - T2 = 600 - 70 - 290 = 240
 
-- Multiword DMA mode 0 settings (@100MHz clock)
DMA_mode0_Tm : natural := 4; -- 50ns
DMA_mode0_Td : natural := 21; -- 215ns
DMA_mode0_Teoc : natural := 21 -- 215ns ==> T0 - Td - Tm = 480 - 50 - 215 = 215
);
port(
-- WISHBONE SYSCON signals
clk_i : in std_logic; -- master clock in
arst_i : in std_logic := '1'; -- asynchronous active low reset
rst_i : in std_logic := '0'; -- synchronous active high reset
 
-- WISHBONE SLAVE signals
cyc_i : in std_logic; -- valid bus cycle input
stb_i : in std_logic; -- strobe/core select input
ack_o : out std_logic; -- strobe acknowledge output
rty_o : out std_logic; -- retry output
err_o : out std_logic; -- error output
adr_i : in unsigned(6 downto 2); -- A6 = '1' ATA devices selected
-- A5 = '1' CS1- asserted, '0' CS0- asserted
-- A4..A2 ATA address lines
-- A6 = '0' ATA controller selected
dat_i : in std_logic_vector(31 downto 0); -- Databus in
dat_o : out std_logic_vector(31 downto 0); -- Databus out
sel_i : in std_logic_vector(3 downto 0); -- Byte select signals
we_i : in std_logic; -- Write enable input
inta_o : out std_logic; -- interrupt request signal IDE0
 
-- PIO control input
PIOsel : buffer std_logic;
PIOtip, -- PIO transfer in progress
PIOack : in std_logic; -- PIO acknowledge signal
PIOq : in std_logic_vector(15 downto 0); -- PIO data input
PIOpp_full : in std_logic; -- PIO write-ping-pong buffers full
irq : in std_logic; -- interrupt signal input
 
-- DMA control inputs
DMAsel : out std_logic;
DMAtip, -- DMA transfer in progress
DMAack, -- DMA transfer acknowledge
DMARxEmpty, -- DMA receive buffer empty
DMATxFull, -- DMA transmit buffer full
DMA_dmarq : in std_logic; -- wishbone DMA request
DMAq : in std_logic_vector(31 downto 0);
 
-- outputs
-- control register outputs
IDEctrl_rst,
IDEctrl_IDEen,
IDEctrl_FATR1,
IDEctrl_FATR0,
IDEctrl_ppen,
DMActrl_DMAen,
DMActrl_dir,
DMActrl_BeLeC0,
DMActrl_BeLeC1 : out std_logic;
 
-- CMD port timing registers
PIO_cmdport_T1,
PIO_cmdport_T2,
PIO_cmdport_T4,
PIO_cmdport_Teoc : buffer unsigned(7 downto 0);
PIO_cmdport_IORDYen : out std_logic;
 
-- data-port0 timing registers
PIO_dport0_T1,
PIO_dport0_T2,
PIO_dport0_T4,
PIO_dport0_Teoc : buffer unsigned(7 downto 0);
PIO_dport0_IORDYen : out std_logic;
 
-- data-port1 timing registers
PIO_dport1_T1,
PIO_dport1_T2,
PIO_dport1_T4,
PIO_dport1_Teoc : buffer unsigned(7 downto 0);
PIO_dport1_IORDYen : out std_logic;
 
-- DMA device0 timing registers
DMA_dev0_Tm,
DMA_dev0_Td,
DMA_dev0_Teoc : buffer unsigned(7 downto 0);
 
-- DMA device1 timing registers
DMA_dev1_Tm,
DMA_dev1_Td,
DMA_dev1_Teoc : buffer unsigned(7 downto 0)
);
end component atahost_wb_slave;
 
 
component atahost_controller is
generic(
TWIDTH : natural := 8; -- counter width
 
-- PIO mode 0 settings (@100MHz clock)
PIO_mode0_T1 : natural := 6; -- 70ns
PIO_mode0_T2 : natural := 28; -- 290ns
PIO_mode0_T4 : natural := 2; -- 30ns
PIO_mode0_Teoc : natural := 23 -- 240ns ==> T0 - T1 - T2 = 600 - 70 - 290 = 240
);
port(
clk : in std_logic; -- master clock in
nReset : in std_logic := '1'; -- asynchronous active low reset
rst : in std_logic := '0'; -- synchronous active high reset
irq : out std_logic; -- interrupt request signal
 
-- control / registers
IDEctrl_rst,
IDEctrl_IDEen : in std_logic;
 
-- PIO registers
PIO_cmdport_T1,
PIO_cmdport_T2,
PIO_cmdport_T4,
PIO_cmdport_Teoc : in unsigned(7 downto 0); -- PIO command timing
PIO_cmdport_IORDYen : in std_logic;
 
PIOreq : in std_logic; -- PIO transfer request
PIOack : buffer std_logic; -- PIO transfer ended
PIOa : in unsigned(3 downto 0); -- PIO address
PIOd : in std_logic_vector(15 downto 0); -- PIO data in
PIOq : out std_logic_vector(15 downto 0); -- PIO data out
PIOwe : in std_logic; -- PIO direction bit '1'=write, '0'=read
 
-- ATA signals
RESETn : out std_logic;
DDi : in std_logic_vector(15 downto 0);
DDo : out std_logic_vector(15 downto 0);
DDoe : out std_logic;
DA : out unsigned(2 downto 0);
CS0n : out std_logic;
CS1n : out std_logic;
 
DIORn : out std_logic;
DIOWn : out std_logic;
IORDY : in std_logic;
INTRQ : in std_logic
);
end component atahost_controller;
 
-- asynchronous reset signal
signal arst_signal : std_logic;
 
-- primary address decoder
signal PIOsel : std_logic; -- controller select, IDE devices select
-- registers
signal IDEctrl_IDEen, IDEctrl_rst: std_logic;
signal PIO_cmdport_T1, PIO_cmdport_T2, PIO_cmdport_T4, PIO_cmdport_Teoc : unsigned(7 downto 0);
signal PIO_cmdport_IORDYen : std_logic;
signal PIOack : std_logic;
signal PIOq : std_logic_vector(15 downto 0);
 
signal irq : std_logic; -- ATA bus IRQ signal
 
begin
-- generate asynchronous reset level
arst_signal <= arst_i xor ARST_LVL;
 
--
-- hookup wishbone slave
--
u0: atahost_wb_slave
generic map(
DeviceID => DeviceID,
RevisionNo => RevisionNo,
 
-- PIO mode 0 settings
PIO_mode0_T1 => PIO_mode0_T1,
PIO_mode0_T2 => PIO_mode0_T2,
PIO_mode0_T4 => PIO_mode0_T4,
PIO_mode0_Teoc => PIO_mode0_Teoc,
 
-- Multiword DMA mode 0 settings
-- OCIDEC-1 does not support DMA, set registers to zero
DMA_mode0_Tm => 0,
DMA_mode0_Td => 0,
DMA_mode0_Teoc => 0
)
port map(
-- 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,
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 input
-- 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 => '0',
PIOack => PIOack,
PIOq => PIOq,
PIOsel => PIOsel,
PIOpp_full => '0', -- OCIDEC-1 does not support PIO-write PingPong, negate signal
irq => irq,
 
-- DMA control inputs (negate all of them)
DMAtip => '0',
DMAack => '0',
DMARxEmpty => '0',
DMATxFull => '0',
DMA_dmarq => '0',
DMAq => x"00000000",
 
-- outputs
-- control register outputs
IDEctrl_rst => IDEctrl_rst,
IDEctrl_IDEen => IDEctrl_IDEen,
 
-- 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
);
 
--
-- hookup controller section
--
u1: atahost_controller
generic map(
TWIDTH => TWIDTH,
PIO_mode0_T1 => PIO_mode0_T1,
PIO_mode0_T2 => PIO_mode0_T2,
PIO_mode0_T4 => PIO_mode0_T4,
PIO_mode0_Teoc => PIO_mode0_Teoc
)
port map(
clk => wb_clk_i,
nReset => arst_signal,
rst => wb_rst_i,
irq => irq,
IDEctrl_rst => IDEctrl_rst,
IDEctrl_IDEen => IDEctrl_IDEen,
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,
PIOreq => PIOsel,
PIOack => PIOack,
PIOa => wb_adr_i(5 downto 2),
PIOd => wb_dat_i(15 downto 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
);
 
end architecture structural;
 
 
 
 
 
 
/trunk/rtl/vhdl/ocidec1/atahost_wb_slave.vhd
0,0 → 1,467
---------------------------------------------------------------------
---- ----
---- OpenCores IDE Controller ----
---- Wishbone Slave (common for all OCIDEC cores) ----
---- ----
---- Author: Richard Herveille ----
---- richard@asics.ws ----
---- www.asics.ws ----
---- ----
---------------------------------------------------------------------
---- ----
---- Copyright (C) 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.vhd,v 1.1 2002-02-18 14:29:38 rherveille Exp $
--
-- $Date: 2002-02-18 14:29:38 $
-- $Revision: 1.1 $
-- $Author: rherveille $
-- $Locker: $
-- $State: Exp $
--
-- Change History:
-- $Log: not supported by cvs2svn $
--
 
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
 
entity atahost_wb_slave is
generic(
DeviceID : unsigned(3 downto 0) := x"0";
RevisionNo : unsigned(3 downto 0) := x"0";
 
-- PIO mode 0 settings (@100MHz clock)
PIO_mode0_T1 : natural := 6; -- 70ns
PIO_mode0_T2 : natural := 28; -- 290ns
PIO_mode0_T4 : natural := 2; -- 30ns
PIO_mode0_Teoc : natural := 23; -- 240ns ==> T0 - T1 - T2 = 600 - 70 - 290 = 240
 
-- Multiword DMA mode 0 settings (@100MHz clock)
DMA_mode0_Tm : natural := 4; -- 50ns
DMA_mode0_Td : natural := 21; -- 215ns
DMA_mode0_Teoc : natural := 21 -- 215ns ==> T0 - Td - Tm = 480 - 50 - 215 = 215
);
port(
-- WISHBONE SYSCON signals
clk_i : in std_logic; -- master clock in
arst_i : in std_logic := '1'; -- asynchronous active low reset
rst_i : in std_logic := '0'; -- synchronous active high reset
 
-- WISHBONE SLAVE signals
cyc_i : in std_logic; -- valid bus cycle input
stb_i : in std_logic; -- strobe/core select input
ack_o : out std_logic; -- strobe acknowledge output
rty_o : out std_logic; -- retry output
err_o : out std_logic; -- error output
adr_i : in unsigned(6 downto 2); -- A6 = '1' ATA devices selected
-- A5 = '1' CS1- asserted, '0' CS0- asserted
-- A4..A2 ATA address lines
-- A6 = '0' ATA controller selected
dat_i : in std_logic_vector(31 downto 0); -- Databus in
dat_o : out std_logic_vector(31 downto 0); -- Databus out
sel_i : in std_logic_vector(3 downto 0); -- Byte select signals
we_i : in std_logic; -- Write enable input
inta_o : out std_logic; -- interrupt request signal IDE0
 
-- PIO control input
PIOsel : buffer std_logic;
PIOtip, -- PIO transfer in progress
PIOack : in std_logic; -- PIO acknowledge signal
PIOq : in std_logic_vector(15 downto 0); -- PIO data input
PIOpp_full : in std_logic; -- PIO write-ping-pong buffers full
irq : in std_logic; -- interrupt signal input
 
-- DMA control inputs
DMAsel : out std_logic;
DMAtip, -- DMA transfer in progress
DMAack, -- DMA transfer acknowledge
DMARxEmpty, -- DMA receive buffer empty
DMATxFull, -- DMA transmit buffer full
DMA_dmarq : in std_logic; -- wishbone DMA request
DMAq : in std_logic_vector(31 downto 0);
 
-- outputs
-- control register outputs
IDEctrl_rst,
IDEctrl_IDEen,
IDEctrl_FATR1,
IDEctrl_FATR0,
IDEctrl_ppen,
DMActrl_DMAen,
DMActrl_dir,
DMActrl_BeLeC0,
DMActrl_BeLeC1 : out std_logic;
 
-- CMD port timing registers
PIO_cmdport_T1,
PIO_cmdport_T2,
PIO_cmdport_T4,
PIO_cmdport_Teoc : buffer unsigned(7 downto 0);
PIO_cmdport_IORDYen : out std_logic;
 
-- data-port0 timing registers
PIO_dport0_T1,
PIO_dport0_T2,
PIO_dport0_T4,
PIO_dport0_Teoc : buffer unsigned(7 downto 0);
PIO_dport0_IORDYen : out std_logic;
 
-- data-port1 timing registers
PIO_dport1_T1,
PIO_dport1_T2,
PIO_dport1_T4,
PIO_dport1_Teoc : buffer unsigned(7 downto 0);
PIO_dport1_IORDYen : out std_logic;
 
-- DMA device0 timing registers
DMA_dev0_Tm,
DMA_dev0_Td,
DMA_dev0_Teoc : buffer unsigned(7 downto 0);
 
-- DMA device1 timing registers
DMA_dev1_Tm,
DMA_dev1_Td,
DMA_dev1_Teoc : buffer unsigned(7 downto 0)
);
end entity atahost_wb_slave;
 
architecture structural of atahost_wb_slave is
--
-- constants
--
 
-- addresses
alias ATA_DEV_ADR : std_logic is adr_i(6);
alias ATA_ADR : unsigned(3 downto 0) is adr_i(5 downto 2);
 
constant ATA_CTRL_REG : unsigned(3 downto 0) := "0000";
constant ATA_STAT_REG : unsigned(3 downto 0) := "0001";
constant ATA_PIO_CMD : unsigned(3 downto 0) := "0010";
constant ATA_PIO_DP0 : unsigned(3 downto 0) := "0011";
constant ATA_PIO_DP1 : unsigned(3 downto 0) := "0100";
constant ATA_DMA_DEV0 : unsigned(3 downto 0) := "0101";
constant ATA_DMA_DEV1 : unsigned(3 downto 0) := "0110";
-- reserved --
constant ATA_DMA_PORT : unsigned(3 downto 0) := "1111";
 
--
-- function declarations
--
-- overload '=' to compare two unsigned numbers
function "=" (a, b : unsigned) return std_logic is
alias la: unsigned(1 to a'length) is a;
alias lb: unsigned(1 to b'length) is b;
variable result : std_logic;
begin
-- check vector length
assert a'length = b'length
report "std_logic_vector comparison: operands of unequal lengths"
severity FAILURE;
 
result := '1';
for n in 1 to a'length loop
result := result and not (la(n) xor lb(n));
end loop;
 
return result;
end;
 
-- primary address decoder
signal CONsel : std_logic; -- controller select, IDE devices select
signal berr, brty : std_logic; -- bus error, bus retry
 
-- registers
signal CtrlReg, StatReg : std_logic_vector(31 downto 0); -- control and status registers
 
begin
--
-- generate bus cycle / address decoder
--
gen_bc_dec: block
signal w_acc, dw_acc : std_logic; -- word access, double word access
signal store_pp_full : std_logic;
begin
-- word / double word
w_acc <= sel_i(1) and sel_i(0);
dw_acc <= sel_i(3) and sel_i(2) and sel_i(1) and sel_i(0);
 
-- bus error
berr <= not w_acc when (ATA_DEV_ADR = '1') else not dw_acc;
 
-- PIO accesses at least 16bit wide, no PIO access during DMAtip or pingpong full
PIOsel <= cyc_i and stb_i and ATA_DEV_ADR and w_acc and not (DMAtip or store_pp_full);
 
-- CON accesses only 32bit wide
CONsel <= cyc_i and stb_i and not ATA_DEV_ADR and dw_acc;
DMAsel <= CONsel and (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
process(clk_i)
begin
if (clk_i'event and clk_i = '1') then
if (PIOsel = '0') then
store_pp_full <= PIOpp_full;
end if;
end if;
end process;
brty <= (ATA_DEV_ADR and w_acc) and (DMAtip or store_pp_full);
end block gen_bc_dec;
 
--
-- generate registers
--
register_block : block
signal sel_PIO_cmdport, sel_PIO_dport0, sel_PIO_dport1 : std_logic; -- PIO timing registers
signal sel_DMA_dev0, sel_DMA_dev1 : std_logic; -- DMA timing registers
signal sel_ctrl, sel_stat : std_logic; -- control / status register
begin
-- generate register select signals
sel_ctrl <= CONsel and we_i and (ATA_ADR = ATA_CTRL_REG);
sel_stat <= CONsel and we_i and (ATA_ADR = ATA_STAT_REG);
sel_PIO_cmdport <= CONsel and we_i and (ATA_ADR = ATA_PIO_CMD);
sel_PIO_dport0 <= CONsel and we_i and (ATA_ADR = ATA_PIO_DP0);
sel_PIO_dport1 <= CONsel and we_i and (ATA_ADR = ATA_PIO_DP1);
sel_DMA_dev0 <= CONsel and we_i and (ATA_ADR = ATA_DMA_DEV0);
sel_DMA_dev1 <= CONsel and we_i and (ATA_ADR = ATA_DMA_DEV1);
-- reserved 0x1C-0x38 --
-- reserved 0x3C : DMA port --
 
-- generate control register
gen_ctrl_reg: process(clk_i, arst_i)
begin
if (arst_i = '0') then
CtrlReg(31 downto 1) <= (others => '0');
CtrlReg(0) <= '1'; -- set reset bit
elsif (clk_i'event and clk_i = '1') then
if (rst_i = '1') then
CtrlReg(31 downto 1) <= (others => '0');
CtrlReg(0) <= '1'; -- set reset bit
elsif (sel_ctrl = '1') then
CtrlReg <= dat_i;
end if;
end if;
end process gen_ctrl_reg;
-- assign bits
DMActrl_DMAen <= CtrlReg(15);
DMActrl_dir <= CtrlReg(13);
DMActrl_BeLeC1 <= CtrlReg(9);
DMActrl_BeLeC0 <= CtrlReg(8);
IDEctrl_IDEen <= CtrlReg(7);
IDEctrl_FATR1 <= CtrlReg(6);
IDEctrl_FATR0 <= CtrlReg(5);
IDEctrl_ppen <= CtrlReg(4);
PIO_dport1_IORDYen <= CtrlReg(3);
PIO_dport0_IORDYen <= CtrlReg(2);
PIO_cmdport_IORDYen <= CtrlReg(1);
IDEctrl_rst <= CtrlReg(0);
 
-- generate status register clearable bits
gen_stat_reg: block
signal dirq, int : std_logic;
begin
gen_irq: process(clk_i, arst_i)
begin
if (arst_i = '0') then
int <= '0';
dirq <= '0';
elsif (clk_i'event and clk_i = '1') then
if (rst_i = '1') then
int <= '0';
dirq <= '0';
else
int <= (int or (irq and not dirq)) and not (sel_stat and not dat_i(0));
dirq <= irq;
end if;
end if;
end process gen_irq;
 
gen_stat: process(DMAtip, DMARxEmpty, DMATxFull, DMA_dmarq, PIOtip, int, PIOpp_full)
begin
StatReg(31 downto 0) <= (others => '0'); -- clear all bits (read unused bits as '0')
 
StatReg(31 downto 28) <= std_logic_vector(DeviceId); -- set Device ID
StatReg(27 downto 24) <= std_logic_vector(RevisionNo); -- set revision number
StatReg(15) <= DMAtip;
StatReg(10) <= DMARxEmpty;
StatReg(9) <= DMATxFull;
StatReg(8) <= DMA_dmarq;
StatReg(7) <= PIOtip;
StatReg(6) <= PIOpp_full;
StatReg(0) <= int;
end process;
end block gen_stat_reg;
 
-- generate PIO compatible / command-port timing register
gen_PIO_cmdport_reg: process(clk_i, arst_i)
begin
if (arst_i = '0') then
PIO_cmdport_T1 <= conv_unsigned(PIO_mode0_T1, 8);
PIO_cmdport_T2 <= conv_unsigned(PIO_mode0_T2, 8);
PIO_cmdport_T4 <= conv_unsigned(PIO_mode0_T4, 8);
PIO_cmdport_Teoc <= conv_unsigned(PIO_mode0_Teoc, 8);
elsif (clk_i'event and clk_i = '1') then
if (rst_i = '1') then
PIO_cmdport_T1 <= conv_unsigned(PIO_mode0_T1, 8);
PIO_cmdport_T2 <= conv_unsigned(PIO_mode0_T2, 8);
PIO_cmdport_T4 <= conv_unsigned(PIO_mode0_T4, 8);
PIO_cmdport_Teoc <= conv_unsigned(PIO_mode0_Teoc, 8);
elsif (sel_PIO_cmdport = '1') then
PIO_cmdport_T1 <= unsigned(dat_i( 7 downto 0));
PIO_cmdport_T2 <= unsigned(dat_i(15 downto 8));
PIO_cmdport_T4 <= unsigned(dat_i(23 downto 16));
PIO_cmdport_Teoc <= unsigned(dat_i(31 downto 24));
end if;
end if;
end process gen_PIO_cmdport_reg;
 
-- generate PIO device0 timing register
gen_PIO_dport0_reg: process(clk_i, arst_i)
begin
if (arst_i = '0') then
PIO_dport0_T1 <= conv_unsigned(PIO_mode0_T1, 8);
PIO_dport0_T2 <= conv_unsigned(PIO_mode0_T2, 8);
PIO_dport0_T4 <= conv_unsigned(PIO_mode0_T4, 8);
PIO_dport0_Teoc <= conv_unsigned(PIO_mode0_Teoc, 8);
elsif (clk_i'event and clk_i = '1') then
if (rst_i = '1') then
PIO_dport0_T1 <= conv_unsigned(PIO_mode0_T1, 8);
PIO_dport0_T2 <= conv_unsigned(PIO_mode0_T2, 8);
PIO_dport0_T4 <= conv_unsigned(PIO_mode0_T4, 8);
PIO_dport0_Teoc <= conv_unsigned(PIO_mode0_Teoc, 8);
elsif (sel_PIO_dport0 = '1') then
PIO_dport0_T1 <= unsigned(dat_i( 7 downto 0));
PIO_dport0_T2 <= unsigned(dat_i(15 downto 8));
PIO_dport0_T4 <= unsigned(dat_i(23 downto 16));
PIO_dport0_Teoc <= unsigned(dat_i(31 downto 24));
end if;
end if;
end process gen_PIO_dport0_reg;
 
-- generate PIO device1 timing register
gen_PIO_dport1_reg: process(clk_i, arst_i)
begin
if (arst_i = '0') then
PIO_dport1_T1 <= conv_unsigned(PIO_mode0_T1, 8);
PIO_dport1_T2 <= conv_unsigned(PIO_mode0_T2, 8);
PIO_dport1_T4 <= conv_unsigned(PIO_mode0_T4, 8);
PIO_dport1_Teoc <= conv_unsigned(PIO_mode0_Teoc, 8);
elsif (clk_i'event and clk_i = '1') then
if (rst_i = '1') then
PIO_dport1_T1 <= conv_unsigned(PIO_mode0_T1, 8);
PIO_dport1_T2 <= conv_unsigned(PIO_mode0_T2, 8);
PIO_dport1_T4 <= conv_unsigned(PIO_mode0_T4, 8);
PIO_dport1_Teoc <= conv_unsigned(PIO_mode0_Teoc, 8);
elsif (sel_PIO_dport1 = '1') then
PIO_dport1_T1 <= unsigned(dat_i( 7 downto 0));
PIO_dport1_T2 <= unsigned(dat_i(15 downto 8));
PIO_dport1_T4 <= unsigned(dat_i(23 downto 16));
PIO_dport1_Teoc <= unsigned(dat_i(31 downto 24));
end if;
end if;
end process gen_PIO_dport1_reg;
 
-- generate DMA device0 timing register
gen_DMA_dev0_reg: process(clk_i, arst_i)
begin
if (arst_i = '0') then
DMA_dev0_Tm <= conv_unsigned(DMA_mode0_Tm, 8);
DMA_dev0_Td <= conv_unsigned(DMA_mode0_Td, 8);
DMA_dev0_Teoc <= conv_unsigned(DMA_mode0_Teoc, 8);
elsif (clk_i'event and clk_i = '1') then
if (rst_i = '1') then
DMA_dev0_Tm <= conv_unsigned(DMA_mode0_Tm, 8);
DMA_dev0_Td <= conv_unsigned(DMA_mode0_Td, 8);
DMA_dev0_Teoc <= conv_unsigned(DMA_mode0_Teoc, 8);
elsif (sel_DMA_dev0 = '1') then
DMA_dev0_Tm <= unsigned(dat_i( 7 downto 0));
DMA_dev0_Td <= unsigned(dat_i(15 downto 8));
DMA_dev0_Teoc <= unsigned(dat_i(31 downto 24));
end if;
end if;
end process gen_DMA_dev0_reg;
 
-- generate DMA device1 timing register
gen_DMA_dev1_reg: process(clk_i, arst_i)
begin
if (arst_i = '0') then
DMA_dev1_Tm <= conv_unsigned(DMA_mode0_Tm, 8);
DMA_dev1_Td <= conv_unsigned(DMA_mode0_Td, 8);
DMA_dev1_Teoc <= conv_unsigned(DMA_mode0_Teoc, 8);
elsif (clk_i'event and clk_i = '1') then
if (rst_i = '1') then
DMA_dev1_Tm <= conv_unsigned(DMA_mode0_Tm, 8);
DMA_dev1_Td <= conv_unsigned(DMA_mode0_Td, 8);
DMA_dev1_Teoc <= conv_unsigned(DMA_mode0_Teoc, 8);
elsif (sel_DMA_dev1 = '1') then
DMA_dev1_Tm <= unsigned(dat_i( 7 downto 0));
DMA_dev1_Td <= unsigned(dat_i(15 downto 8));
DMA_dev1_Teoc <= unsigned(dat_i(31 downto 24));
end if;
end if;
end process gen_DMA_dev1_reg;
 
end block register_block;
 
--
-- generate WISHBONE interconnect signals
--
gen_WB_sigs: block
signal Q : std_logic_vector(31 downto 0);
begin
-- generate acknowledge signal
ack_o <= PIOack or CONsel; -- or DMAack; -- since DMAack is derived from CONsel this is OK
 
-- generate error signal
err_o <= cyc_i and stb_i and berr;
 
-- generate retry signal
rty_o <= cyc_i and stb_i and brty;
 
-- assign interrupt signal
inta_o <= StatReg(0);
-- generate output multiplexor
with ATA_ADR select
Q <= CtrlReg when ATA_CTRL_REG, -- control register
StatReg when ATA_STAT_REG, -- status register
std_logic_vector(PIO_cmdport_Teoc & PIO_cmdport_T4 & PIO_cmdport_T2 & PIO_cmdport_T1) when ATA_PIO_CMD, -- PIO compatible / cmd-port timing register
std_logic_vector(PIO_dport0_Teoc & PIO_dport0_T4 & PIO_dport0_T2 & PIO_dport0_T1) when ATA_PIO_DP0, -- PIO fast timing register device0
std_logic_vector(PIO_dport1_Teoc & PIO_dport1_T4 & PIO_dport1_T2 & PIO_dport1_T1) when ATA_PIO_DP1, -- PIO fast timing register device1
std_logic_vector(DMA_dev0_Teoc & x"00" & DMA_dev0_Td & DMA_dev0_Tm) when ATA_DMA_DEV0, -- DMA timing register device0
std_logic_vector(DMA_dev1_Teoc & x"00" & DMA_dev1_Td & DMA_dev1_Tm) when ATA_DMA_DEV1, -- DMA timing register device1
DMAq when ATA_DMA_PORT, -- DMA port, DMA receive register
(others => '0') when others;
 
dat_o <= (x"0000" & PIOq) when (ATA_DEV_ADR = '1') else Q;
end block gen_WB_sigs;
 
end architecture structural;
/trunk/rtl/vhdl/ocidec1/atahost_controller.vhd
0,0 → 1,310
---------------------------------------------------------------------
---- ----
---- OpenCores IDE Controller (OCIDEC-1) ----
---- PIO Contoller ----
---- ----
---- 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. ----
---- ----
---------------------------------------------------------------------
 
-- rev.: 1.0 march 18th, 2001
-- rev.: 1.0a april 12th, 2001. Removed references to records.vhd to make it compatible with freely available VHDL to Verilog converter tools
-- rev.: 1.1 june 18th, 2001. Changed PIOack generation. Avoid asserting PIOack continuously when IDEen = '0'
-- rev.: 1.2 june 26th, 2001. Changed dPIOreq generation. Core did not support wishbone burst accesses to ATA-device.
-- rev.: 1.3 july 11th, 2001. Changed PIOreq & PIOack generation (made them synchronous).
--
--
-- CVS Log
--
-- $Id: atahost_controller.vhd,v 1.1 2002-02-18 14:29:39 rherveille Exp $
--
-- $Date: 2002-02-18 14:29:39 $
-- $Revision: 1.1 $
-- $Author: rherveille $
-- $Locker: $
-- $State: Exp $
--
-- Change History:
-- $Log: not supported by cvs2svn $
--
 
 
-- OCIDEC1 supports:
-- -Common Compatible timing access to all connected devices
--
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
 
entity atahost_controller is
generic(
TWIDTH : natural := 8; -- counter width
 
-- PIO mode 0 settings (@100MHz clock)
PIO_mode0_T1 : natural := 6; -- 70ns
PIO_mode0_T2 : natural := 28; -- 290ns
PIO_mode0_T4 : natural := 2; -- 30ns
PIO_mode0_Teoc : natural := 23 -- 240ns ==> T0 - T1 - T2 = 600 - 70 - 290 = 240
);
port(
clk : in std_logic; -- master clock in
nReset : in std_logic := '1'; -- asynchronous active low reset
rst : in std_logic := '0'; -- synchronous active high reset
irq : out std_logic; -- interrupt request signal
 
-- control / registers
IDEctrl_rst,
IDEctrl_IDEen : in std_logic;
 
-- PIO registers
PIO_cmdport_T1,
PIO_cmdport_T2,
PIO_cmdport_T4,
PIO_cmdport_Teoc : in unsigned(7 downto 0); -- PIO command timing
PIO_cmdport_IORDYen : in std_logic;
 
PIOreq : in std_logic; -- PIO transfer request
PIOack : buffer std_logic; -- PIO transfer ended
PIOa : in unsigned(3 downto 0); -- PIO address
PIOd : in std_logic_vector(15 downto 0); -- PIO data in
PIOq : out std_logic_vector(15 downto 0); -- PIO data out
PIOwe : in std_logic; -- PIO direction bit '1'=write, '0'=read
 
-- ATA signals
RESETn : out std_logic;
DDi : in std_logic_vector(15 downto 0);
DDo : out std_logic_vector(15 downto 0);
DDoe : out std_logic;
DA : out unsigned(2 downto 0);
CS0n : out std_logic;
CS1n : out std_logic;
 
DIORn : out std_logic;
DIOWn : out std_logic;
IORDY : in std_logic;
INTRQ : in std_logic
);
end entity atahost_controller;
 
architecture structural of atahost_controller is
--
-- Component declarations
--
component atahost_pio_tctrl is
generic(
TWIDTH : natural := 8; -- counter width
 
-- PIO mode 0 settings (@100MHz clock)
PIO_mode0_T1 : natural := 6; -- 70ns
PIO_mode0_T2 : natural := 28; -- 290ns
PIO_mode0_T4 : natural := 2; -- 30ns
PIO_mode0_Teoc : natural := 23 -- 240ns ==> T0 - T1 - T2 = 600 - 70 - 290 = 240
);
port(
clk : in std_logic; -- master clock
nReset : in std_logic; -- asynchronous active low reset
rst : in std_logic; -- synchronous active high reset
 
-- timing/control register settings
IORDY_en : in std_logic; -- use IORDY (or not)
T1 : in unsigned(TWIDTH -1 downto 0); -- T1 time (in clk-ticks)
T2 : in unsigned(TWIDTH -1 downto 0); -- T2 time (in clk-ticks)
T4 : in unsigned(TWIDTH -1 downto 0); -- T4 time (in clk-ticks)
Teoc : in unsigned(TWIDTH -1 downto 0); -- end of cycle time
 
-- control signals
go : in std_logic; -- PIO controller selected (strobe signal)
we : in std_logic; -- write enable signal. '0'=read from device, '1'=write to device
 
-- return signals
oe : buffer std_logic; -- output enable signal
done : out std_logic; -- finished cycle
dstrb : out std_logic; -- data strobe, latch data (during read)
 
-- ATA signals
DIOR, -- IOread signal, active high
DIOW : buffer std_logic; -- IOwrite signal, active high
IORDY : in std_logic -- IORDY signal
);
end component atahost_pio_tctrl;
 
--
-- signals
--
signal dPIOreq, PIOgo : std_logic; -- start PIO timing controller
signal PIOdone : std_logic; -- PIO timing controller done
 
-- PIO signals
signal PIOdior, PIOdiow : std_logic;
signal PIOoe : std_logic;
 
-- Timing settings
signal dstrb : std_logic;
signal T1, T2, T4, Teoc : unsigned(TWIDTH -1 downto 0);
signal IORDYen : std_logic;
 
-- synchronized ATA inputs
signal sIORDY : std_logic;
 
begin
 
--
-- synchronize incoming signals
--
synch_incoming: block
signal cIORDY : std_logic; -- capture IORDY
signal cINTRQ : std_logic; -- capture INTRQ
begin
process(clk)
begin
if (clk'event and clk = '1') then
cIORDY <= IORDY;
cINTRQ <= INTRQ;
 
sIORDY <= cIORDY;
irq <= cINTRQ;
end if;
end process;
end block synch_incoming;
 
--
-- generate ATA signals
--
gen_ata_sigs: block
begin
-- generate registers for ATA signals
gen_regs: process(clk, nReset)
begin
if (nReset = '0') then
RESETn <= '0';
DIORn <= '1';
DIOWn <= '1';
DA <= (others => '0');
CS0n <= '1';
CS1n <= '1';
DDo <= (others => '0');
DDoe <= '0';
elsif (clk'event and clk = '1') then
if (rst = '1') then
RESETn <= '0';
DIORn <= '1';
DIOWn <= '1';
DA <= (others => '0');
CS0n <= '1';
CS1n <= '1';
DDo <= (others => '0');
DDoe <= '0';
else
RESETn <= not IDEctrl_rst;
DA <= PIOa(2 downto 0);
CS0n <= not (not PIOa(3) and PIOreq); -- CS0 asserted when A(3) = '0'
CS1n <= not ( PIOa(3) and PIOreq); -- CS1 asserted when A(3) = '1'
 
DDo <= PIOd;
DDoe <= PIOoe;
DIORn <= not PIOdior;
DIOWn <= not PIOdiow;
end if;
end if;
end process gen_regs;
end block gen_ata_sigs;
 
 
--
--------------------------
-- PIO transfer control --
--------------------------
--
-- capture ATA data for PIO access
gen_PIOq: process(clk)
begin
if (clk'event and clk = '1') then
if (dstrb = '1') then
PIOq <= DDi;
end if;
end if;
end process gen_PIOq;
 
-- generate PIOgo signal
gen_PIOgo: process(clk)
begin
if (clk'event and clk = '1') then
dPIOreq <= PIOreq and not PIOack;
PIOgo <= (PIOreq and not dPIOreq) and IDEctrl_IDEen;
end if;
end process gen_PIOgo;
 
-- set Timing signals
T1 <= PIO_cmdport_T1;
T2 <= PIO_cmdport_T2;
T4 <= PIO_cmdport_T4;
Teoc <= PIO_cmdport_Teoc;
IORDYen <= PIO_cmdport_IORDYen;
 
--
-- hookup timing controller
--
PIO_timing_controller: atahost_pio_tctrl
generic map (
TWIDTH => TWIDTH,
PIO_mode0_T1 => PIO_mode0_T1,
PIO_mode0_T2 => PIO_mode0_T2,
PIO_mode0_T4 => PIO_mode0_T4,
PIO_mode0_Teoc => PIO_mode0_Teoc
)
port map (
clk => clk,
nReset => nReset,
rst => rst,
IORDY_en => IORDYen,
T1 => T1,
T2 => T2,
T4 => T4,
Teoc => Teoc,
go => PIOgo,
we => PIOwe,
oe => PIOoe,
done => PIOdone,
dstrb => dstrb,
DIOR => PIOdior,
DIOW => PIOdiow,
IORDY => sIORDY
);
 
-- generate acknowledge
gen_ack: process(clk)
begin
if (clk'event and clk = '1') then
PIOack <= PIOdone or (PIOreq and not IDEctrl_IDEen); -- acknowledge when done or when IDE not enabled (discard request)
end if;
end process gen_ack;
end architecture structural;
 
/trunk/rtl/vhdl/ocidec1/revision_history.txt
46,3 → 46,22
- Changed PIOreq & PIOack generation (controller.vhd); made them synchronous
- Changed 'go' & 'igo' generation (pio_tctrl.vhdl).
-----------------------------
 
-----------------------------
Revision: 1.4
Date: Februar 17th, 2002
Author: Richard Herveille
- renamed 'atahost.vhd' to 'atahost_top.vhd'
- renamed 'controller.vhd' to 'atahost_controller.vhd'
- renamed 'pio_tctrl.vhd' to 'atahost_pio_tctrl.vhd'
- broke-up 'counter.vhd' into 'ud_cnt.vhd' and 'ro_cnt.vhd'
- changed resD input to generic RESD in ud_cnt.vhd
- changed ID input to generic ID in ro_cnt.vhd
- changed core to reflect changes in ro_cnt.vhd
- removed references to 'count' library
- changed IO names
- added disclaimer
- added CVS log
- moved registers and wishbone signals into 'atahost_wb_slave.vhd'
- core is now equivalent to verilog version
-----------------------------

powered by: WebSVN 2.1.0

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