Commit c4e8308e authored by Tristan Gingold's avatar Tristan Gingold

vme_bus: improve direction driving.

parent 73230942
...@@ -146,6 +146,7 @@ architecture rtl of vme_bus is ...@@ -146,6 +146,7 @@ architecture rtl of vme_bus is
signal vme_odff_data : std_logic_vector(31 downto 0); signal vme_odff_data : std_logic_vector(31 downto 0);
signal vme_odff_lword_n : std_logic; signal vme_odff_lword_n : std_logic;
signal vme_odff_addr_dir : std_logic; signal vme_odff_addr_dir : std_logic;
signal vme_odff_data_dir : std_logic;
-- Register containing the address. Initialized from VME, adjusted -- Register containing the address. Initialized from VME, adjusted
-- by address decoder, and incremented during DMA. -- by address decoder, and incremented during DMA.
...@@ -324,7 +325,7 @@ begin ...@@ -324,7 +325,7 @@ begin
-- VME -- VME
vme_dtack_oe_o <= '0'; vme_dtack_oe_o <= '0';
vme_dtack_n_o <= '1'; vme_dtack_n_o <= '1';
vme_data_dir_o <= '0'; vme_odff_data_dir <= '0';
vme_odff_addr_dir <= '0'; vme_odff_addr_dir <= '0';
vme_odff_lword_n <= '0'; vme_odff_lword_n <= '0';
vme_berr_n_o <= '1'; vme_berr_n_o <= '1';
...@@ -339,7 +340,6 @@ begin ...@@ -339,7 +340,6 @@ begin
vme_idff_am <= (others => '0'); vme_idff_am <= (others => '0');
vme_odff_addr <= (others => '0'); vme_odff_addr <= (others => '0');
vme_odff_addr_dir <= '0';
load_addr_reg_phase1 <= '0'; load_addr_reg_phase1 <= '0';
...@@ -352,8 +352,6 @@ begin ...@@ -352,8 +352,6 @@ begin
decode_start_o <= '0'; decode_start_o <= '0';
vme_dtack_oe_o <= '0'; vme_dtack_oe_o <= '0';
vme_dtack_n_o <= '1'; vme_dtack_n_o <= '1';
vme_data_dir_o <= '0';
vme_odff_addr_dir <= '0';
vme_berr_n_o <= '1'; vme_berr_n_o <= '1';
vme_iackout_n_o <= '1'; vme_iackout_n_o <= '1';
irq_ack_o <= '0'; irq_ack_o <= '0';
...@@ -368,6 +366,10 @@ begin ...@@ -368,6 +366,10 @@ begin
-- cycle. -- cycle.
assert vme_as_n_i = '0'; assert vme_as_n_i = '0';
-- Data and address are inputs
vme_odff_data_dir <= '0';
vme_odff_addr_dir <= '0';
-- Store ADDR, AM and LWORD -- Store ADDR, AM and LWORD
vme_idff_addr <= vme_addr_i; vme_idff_addr <= vme_addr_i;
vme_idff_lword_n <= vme_lword_n_i; vme_idff_lword_n <= vme_lword_n_i;
...@@ -452,6 +454,8 @@ begin ...@@ -452,6 +454,8 @@ begin
when WAIT_FOR_DS => when WAIT_FOR_DS =>
-- wait until DS /= "11" -- wait until DS /= "11"
-- Note: before entering this state, s_DS_latch_count must be set. -- Note: before entering this state, s_DS_latch_count must be set.
vme_dtack_oe_o <= '1';
vme_dtack_n_o <= '1';
if vme_ds_n_i /= "11" then if vme_ds_n_i /= "11" then
-- ANSI/VITA 1-1994 Table 4-1 -- ANSI/VITA 1-1994 Table 4-1
...@@ -464,7 +468,18 @@ begin ...@@ -464,7 +468,18 @@ begin
s_DS_latch_count <= s_DS_latch_count - 1; s_DS_latch_count <= s_DS_latch_count - 1;
end if; end if;
s_mainFSMstate <= LATCH_DS; if s_transferType = MBLT
and s_MBLT_Data = '1'
and vme_idff_write_n = '1'
then
-- Next data read transfer.
-- Improve speed.
vme_odff_addr_dir <= '1';
vme_odff_data_dir <= '1';
s_mainFSMstate <= DATA_TO_BUS;
else
s_mainFSMstate <= LATCH_DS;
end if;
else else
s_mainFSMstate <= WAIT_FOR_DS; s_mainFSMstate <= WAIT_FOR_DS;
end if; end if;
...@@ -472,12 +487,13 @@ begin ...@@ -472,12 +487,13 @@ begin
when LATCH_DS => when LATCH_DS =>
-- This state is necessary indeed the VME master can assert the -- This state is necessary indeed the VME master can assert the
-- DS lines not at the same time. -- DS lines not at the same time.
vme_dtack_oe_o <= '1';
vme_dtack_n_o <= '1';
-- ANSI/VITA 1-1994 Rule 2.53a -- ANSI/VITA 1-1994 Rule 2.53a
-- During all read cycles [...], the responding slave MUST NOT -- During all read cycles [...], the responding slave MUST NOT
-- drive the D[] lines until DSA* goes low. -- drive the D[] lines until DSA* goes low.
vme_data_dir_o <= vme_idff_write_n; vme_odff_data_dir <= vme_idff_write_n;
vme_odff_addr_dir <= '0';
if s_DS_latch_count = 0 or s_transferType = MBLT then if s_DS_latch_count = 0 or s_transferType = MBLT then
-- Read DS (which is delayed to avoid metastability). -- Read DS (which is delayed to avoid metastability).
...@@ -512,7 +528,9 @@ begin ...@@ -512,7 +528,9 @@ begin
end if; end if;
when CHECK_TRANSFER_TYPE => when CHECK_TRANSFER_TYPE =>
vme_data_dir_o <= vme_idff_write_n; vme_dtack_oe_o <= '1';
vme_dtack_n_o <= '1';
vme_odff_data_dir <= vme_idff_write_n;
-- vme_addr is an output during MBLT *read* data transfer. -- vme_addr is an output during MBLT *read* data transfer.
if s_transferType = MBLT and vme_idff_write_n = '1' and g_VME32 then if s_transferType = MBLT and vme_idff_write_n = '1' and g_VME32 then
...@@ -535,9 +553,11 @@ begin ...@@ -535,9 +553,11 @@ begin
when DATA_TO_BUS => when DATA_TO_BUS =>
-- Update what WB FSM prepared -- Update what WB FSM prepared
vme_dtack_oe_o <= '1';
vme_dtack_n_o <= '1';
if s_conf_sel = '1' or s_wb_done = '1' or s_irq_sel = '1' then if s_conf_sel = '1' or s_wb_done = '1' or s_irq_sel = '1' then
vme_dtack_oe_o <= '1'; vme_odff_data_dir <= vme_idff_write_n;
vme_data_dir_o <= vme_idff_write_n;
if g_VME32 then if g_VME32 then
-- only for MBLT -- only for MBLT
...@@ -560,7 +580,8 @@ begin ...@@ -560,7 +580,8 @@ begin
when DTACK_LOW => when DTACK_LOW =>
-- Set /DTACK, wait until /DS[1:0] are released. -- Set /DTACK, wait until /DS[1:0] are released.
vme_dtack_oe_o <= '1'; vme_dtack_oe_o <= '1';
vme_data_dir_o <= vme_idff_write_n; vme_dtack_n_o <= '1';
vme_odff_data_dir <= vme_idff_write_n;
-- Set DTACK (or retry or berr) -- Set DTACK (or retry or berr)
if s_card_sel = '1' and s_err = '1' then if s_card_sel = '1' and s_err = '1' then
...@@ -574,7 +595,6 @@ begin ...@@ -574,7 +595,6 @@ begin
-- MUST NOT release them or drive DTACK* high until it detects -- MUST NOT release them or drive DTACK* high until it detects
-- both DS0* and DS1* high. -- both DS0* and DS1* high.
if vme_ds_n_i = "11" then if vme_ds_n_i = "11" then
vme_data_dir_o <= '0';
vme_berr_n_o <= '1'; vme_berr_n_o <= '1';
-- Rescind DTACK. -- Rescind DTACK.
...@@ -589,12 +609,18 @@ begin ...@@ -589,12 +609,18 @@ begin
-- Cycle should be finished, but allow another access at -- Cycle should be finished, but allow another access at
-- the same address (RMW). -- the same address (RMW).
s_mainFSMstate <= WAIT_FOR_DS; s_mainFSMstate <= WAIT_FOR_DS;
-- Data and address as input.
vme_odff_data_dir <= '0';
vme_odff_addr_dir <= '0';
else else
-- Any block transfer. -- Any block transfer.
if g_VME32 and s_transferType = MBLT and s_MBLT_Data = '0' then if g_VME32 and s_transferType = MBLT and s_MBLT_Data = '0' then
-- MBLT: end of address phase. -- MBLT: end of address phase.
s_MBLT_Data <= '1'; s_MBLT_Data <= '1';
end if; end if;
-- Keep same direction for data and address.
s_mainFSMstate <= WAIT_FOR_DS; s_mainFSMstate <= WAIT_FOR_DS;
end if; end if;
else else
...@@ -628,6 +654,10 @@ begin ...@@ -628,6 +654,10 @@ begin
when WAIT_END => when WAIT_END =>
-- Will stay here until AS is released. -- Will stay here until AS is released.
vme_odff_data_dir <= '0';
vme_odff_addr_dir <= '0';
s_mainFSMstate <= WAIT_END; s_mainFSMstate <= WAIT_END;
when others => when others =>
...@@ -887,6 +917,7 @@ begin ...@@ -887,6 +917,7 @@ begin
else '0'; else '0';
vme_addr_dir_o <= vme_odff_addr_dir; vme_addr_dir_o <= vme_odff_addr_dir;
vme_data_dir_o <= vme_odff_data_dir;
vme_addr_o <= vme_odff_addr; vme_addr_o <= vme_odff_addr;
vme_data_o <= vme_odff_data; vme_data_o <= vme_odff_data;
vme_lword_n_o <= vme_odff_lword_n; vme_lword_n_o <= vme_odff_lword_n;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment