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/pio_tctrl.vhd
File deleted
/trunk/rtl/vhdl/ocidec1/controller.vhd
File deleted
/trunk/rtl/vhdl/ocidec1/atahost.vhd
File deleted
/trunk/rtl/vhdl/ocidec1/counter.vhd
File deleted
/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 |
----------------------------- |