Commit c810475b authored by Tristan Gingold's avatar Tristan Gingold

vme_bus: prevent boundary crossing while prefetching.

parent ffb421dd
...@@ -262,6 +262,10 @@ architecture rtl of vme_bus is ...@@ -262,6 +262,10 @@ architecture rtl of vme_bus is
signal s_wb_done : std_logic; signal s_wb_done : std_logic;
signal s_wb_start : std_logic; signal s_wb_start : std_logic;
-- Set if the next WB access will cross boundary for BLT/MBLT
-- transfer. It will prevent from doing the next transfer.
signal s_cross_boundary : std_logic;
signal s_wb_dataphase : std_logic; signal s_wb_dataphase : std_logic;
begin begin
-- These output signals are connected to the buffers on the board -- These output signals are connected to the buffers on the board
...@@ -481,7 +485,7 @@ begin ...@@ -481,7 +485,7 @@ begin
and s_wb_done = '1' and s_wb_done = '1'
then then
-- Next data read transfer. -- Next data read transfer.
-- Improve speed. -- Improve speed by putting data on the VME bus.
vme_odff_addr_dir <= '1'; vme_odff_addr_dir <= '1';
vme_odff_data_dir <= '1'; vme_odff_data_dir <= '1';
...@@ -887,6 +891,7 @@ begin ...@@ -887,6 +891,7 @@ begin
s_err <= '0'; s_err <= '0';
s_wb_done <= '0'; s_wb_done <= '0';
s_cross_boundary <= '0';
else else
case s_WBFSMstate is case s_WBFSMstate is
when IDLE => when IDLE =>
...@@ -895,9 +900,12 @@ begin ...@@ -895,9 +900,12 @@ begin
assert vme_as_n_i = '0'; assert vme_as_n_i = '0';
if load_addr_reg_phase1 = '1' then if load_addr_reg_phase1 = '1' then
-- VME address phase 1.
addr_reg (31 downto 1) <= vme_idff_addr; addr_reg (31 downto 1) <= vme_idff_addr;
addr_reg (0) <= vme_idff_lword_n; addr_reg (0) <= vme_idff_lword_n;
s_cross_boundary <= '0';
-- Reformat address according to the mode (A16, A24, A32) -- Reformat address according to the mode (A16, A24, A32)
-- FIXME: not needed if ADEM are correctly reduced to not compare -- FIXME: not needed if ADEM are correctly reduced to not compare
-- MSBs of A16 or A24 addresses. -- MSBs of A16 or A24 addresses.
...@@ -920,6 +928,7 @@ begin ...@@ -920,6 +928,7 @@ begin
end if; end if;
if load_addr_reg_phase2 = '1' then if load_addr_reg_phase2 = '1' then
-- VME address phase 2 (for 2eVME oand 2eSST)
addr_reg(7 downto 0) <= vme_idff_addr (7 downto 1) & vme_idff_lword_n; addr_reg(7 downto 0) <= vme_idff_addr (7 downto 1) & vme_idff_lword_n;
end if; end if;
...@@ -929,13 +938,16 @@ begin ...@@ -929,13 +938,16 @@ begin
end if; end if;
if s_wb_start = '1' then if s_wb_start = '1' then
-- Even if no WB cycle is started, clear s_wb_done.
s_wb_done <= '0';
end if;
if s_wb_start = '1' and s_cross_boundary = '0' then
-- Start WB cycle. -- Start WB cycle.
wb_cyc_o <= s_card_sel; wb_cyc_o <= s_card_sel;
wb_stb_o <= s_card_sel; wb_stb_o <= s_card_sel;
wb_we_o <= not vme_idff_write_n; wb_we_o <= not vme_idff_write_n;
s_wb_done <= '0';
if vme_idff_write_n = '0' then if vme_idff_write_n = '0' then
-- Get the data to write (in case of write!). -- Get the data to write (in case of write!).
if g_VME32 and s_transferType = MBLT then if g_VME32 and s_transferType = MBLT then
...@@ -944,9 +956,10 @@ begin ...@@ -944,9 +956,10 @@ begin
data_reg (63 downto 32) <= vme_idff_data; data_reg (63 downto 32) <= vme_idff_data;
else else
if addr_reg(0) = '0' then if addr_reg(0) = '0' then
-- 32bit access -- 32bit access (lword is set)
data_reg (31 downto 0) <= vme_idff_data; data_reg (31 downto 0) <= vme_idff_data;
else else
-- 16bit access (lword is not set)
data_reg (15 downto 0) <= vme_idff_data (15 downto 0); data_reg (15 downto 0) <= vme_idff_data (15 downto 0);
data_reg (31 downto 16) <= vme_idff_data (15 downto 0); data_reg (31 downto 16) <= vme_idff_data (15 downto 0);
end if; end if;
...@@ -1023,8 +1036,19 @@ begin ...@@ -1023,8 +1036,19 @@ begin
if s_transferType /= SINGLE then if s_transferType /= SINGLE then
-- Next word for any block transfer. -- Next word for any block transfer.
addr_reg (11 downto 2) <= -- VITA 1-1994 RULE 2.12a:
std_logic_vector (unsigned(addr_reg (11 downto 2)) + 1); -- BLT must not cross any 256 byte boundary.
-- VITA 1-1994 RULE 2.78
-- MBLT cycles MUST not cross any 2048 byte boundary.
addr_reg (10 downto 2) <=
std_logic_vector (unsigned(addr_reg (10 downto 2)) + 1);
if addr_reg(7 downto 2) = b"1111_11" then
if s_transferType = MBLT and addr_reg (10 downto 8) = "111" then
s_cross_boundary <= '1';
elsif s_transferType = BLT then
s_cross_boundary <= '1';
end if;
end if;
end if; end if;
if (s_card_sel and wb_err_i) = '1' then if (s_card_sel and wb_err_i) = '1' then
......
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