Commit c6b3a685 authored by Tristan Gingold's avatar Tristan Gingold

Support MBLT.

parent 4c5c2f7a
......@@ -154,12 +154,12 @@ entity VME64xCore_Top is
-- Function 0
g_F0_ADEM : std_logic_vector( 31 downto 0) := x"ff000000";
g_F0_AMCAP : std_logic_vector( 63 downto 0) := x"00000000_0000ee00";
g_F0_AMCAP : std_logic_vector( 63 downto 0) := x"00000000_0000ff00";
g_F0_DAWPR : std_logic_vector( 7 downto 0) := x"84";
-- Function 1
g_F1_ADEM : std_logic_vector( 31 downto 0) := x"fff80000";
g_F1_AMCAP : std_logic_vector( 63 downto 0) := x"ee000000_00000000";
g_F1_AMCAP : std_logic_vector( 63 downto 0) := x"ff000000_00000000";
g_F1_DAWPR : std_logic_vector( 7 downto 0) := x"84";
-- Function 2
......@@ -340,11 +340,11 @@ architecture RTL of VME64xCore_Top is
-- List of supported AM.
constant c_AMCAP_ALLOWED : std_logic_vector(63 downto 0) :=
(16#3d# to 16#3f# => '1', -- A24
16#39# to 16#3b# => '1',
(16#3c# to 16#3f# => '1', -- A24
16#38# to 16#3b# => '1',
16#2d# | 16#29# => '1', -- A16
16#0d# to 16#0f# => '1', -- A32
16#09# to 16#0b# => '1',
16#0c# to 16#0f# => '1', -- A32
16#08# to 16#0b# => '1',
others => '0');
begin
-- Check for invalid bits in ADEM/AMCAP
......
......@@ -204,6 +204,7 @@ architecture RTL of VME_bus is
signal s_mainFSMstate : t_mainFSMstates;
signal s_conf_req : std_logic; -- Global memory request
signal s_dataPhase : std_logic; -- for MBLT
signal s_MBLT_Data : std_logic; -- for MBLT: '1' in Addr
-- Access decode signals
signal s_conf_sel : std_logic; -- CR or CSR is addressed
......@@ -240,15 +241,7 @@ begin
------------------------------------------------------------------------------
-- Type of data transfer decoder
-- VME64 ANSI/VITA 1-1994...Table 2-2 "Signal levels during data transfers"
-- A2 is used to select the D64 type (D64 --> MBLT and 2edge cycles)
-- VME DATA --> BIG ENDIAN
-- These 5 bits are not sufficient to descriminate the D32 and D64 data
-- transfer type; indeed the D32 access with A2 = '0' (eg 0x010)
-- fall within D64 access --> The data transfer type have to be evaluated
-- jointly with the address type.
--
-- Bytes position on VMEbus:
--
-- A24-31 | A16-23 | A08-15 | A00-07 | D24-31 | D16-23 | D08-15 | D00-07
......@@ -262,7 +255,7 @@ begin
-- BYTE 0 | BYTE 1 | BYTE 2 | BYTE 3 | BYTE 4 | BYTE 5 | BYTE 6 | BYTE 7
-- Address modifier decoder
-- Either the supervisor or user access modes are supported
-- Both the supervisor and the user access modes are supported
with s_AMlatched select s_addressingType <=
A24 when c_AM_A24_S_SUP | c_AM_A24_S,
A24_BLT when c_AM_A24_BLT | c_AM_A24_BLT_SUP,
......@@ -310,6 +303,7 @@ begin
VME_DATA_o <= (others => '0');
s_dataPhase <= '0';
s_MBLT_Data <= '0';
s_mainFSMstate <= IDLE;
-- WB
......@@ -331,7 +325,6 @@ begin
VME_DTACK_n_o <= '1';
VME_DATA_DIR_o <= '0';
VME_ADDR_DIR_o <= '0';
s_dataPhase <= '0';
VME_BERR_n_o <= '1';
s_DS_latch_count <= "000";
......@@ -372,14 +365,15 @@ begin
null; -- A32
end case;
-- Address is not yet decoded.
s_card_sel <= '0';
s_conf_sel <= '0';
-- VITA-1 Rule 2.6
-- A Slave MUST NOT respond with a falling edge on DTACK* during
-- an unaligned transfer cycle, if it does not have UAT
-- capability.
if ((s_transferType = SINGLE or s_transferType = BLT)
and s_LWORDlatched_n = '0' and s_ADDRlatched(1) = '1')
or (s_transferType = MBLT and s_ADDRlatched(2 downto 1) /= "00")
then
if s_LWORDlatched_n = '0' and s_ADDRlatched(1) = '1' then
-- unaligned.
s_mainFSMstate <= WAIT_END;
else
......@@ -431,13 +425,28 @@ begin
-- DS lines not at the same time
-- VITA-1 Rule 2.53a
-- During all read cycles [...], the responding slave MUST OT
-- During all read cycles [...], the responding slave MUST NOT
-- drive the D[] lines until DSA* goes low.
VME_DATA_DIR_o <= s_WRITElatched_n;
VME_ADDR_DIR_o <= (s_is_d64) and s_WRITElatched_n;
s_dataPhase <= s_dataPhase;
if s_transferType = MBLT then
s_dataPhase <= '1';
-- Start with D[31..0] when writing, but D[63..32] when reading.
s_ADDRlatched(2) <= not s_WRITElatched_n;
else
s_dataPhase <= '0';
end if;
if s_DS_latch_count = 0 then
s_mainFSMstate <= CHECK_TRANSFER_TYPE;
if s_transferType = MBLT and s_MBLT_Data = '0' then
-- MBLT: ack address.
-- (Data are also read but discarded).
s_mainFSMstate <= DTACK_LOW;
else
s_mainFSMstate <= CHECK_TRANSFER_TYPE;
end if;
-- Read DS (which is delayed to avoid metastability).
s_DSlatched_n <= VME_DS_n_i;
......@@ -445,6 +454,7 @@ begin
-- Read DATA (which are stable)
s_locDataIn(63 downto 33) <= VME_ADDR_i;
s_locDataIn(32) <= VME_LWORD_n_i;
if s_LWORDlatched_n = '1' and s_ADDRlatched(1) = '0' then
-- Word/byte access with A1=0
s_locDataIn(31 downto 16) <= VME_DATA_i(15 downto 0);
......@@ -458,7 +468,6 @@ begin
end if;
when CHECK_TRANSFER_TYPE =>
VME_DTACK_OE_o <= '1';
VME_DATA_DIR_o <= s_WRITElatched_n;
VME_ADDR_DIR_o <= (s_is_d64) and s_WRITElatched_n;
s_dataPhase <= s_dataPhase;
......@@ -478,11 +487,20 @@ begin
end case;
end if;
s_mainFSMstate <= MEMORY_REQ;
s_conf_req <= s_conf_sel;
cyc_o <= s_card_sel;
stb_o <= s_card_sel;
s_err <= '0';
-- VITA-1 Rule 2.6
-- A Slave MUST NOT respond with a falling edge on DTACK* during
-- an unaligned transfer cycle, if it does not have UAT
-- capability.
if s_LWORDlatched_n = '0' and s_DSlatched_n /= "00" then
-- unaligned.
s_mainFSMstate <= WAIT_END;
else
s_mainFSMstate <= MEMORY_REQ;
s_conf_req <= s_conf_sel;
cyc_o <= s_card_sel;
stb_o <= s_card_sel;
s_err <= '0';
end if;
when MEMORY_REQ =>
-- To request the memory CR/CSR or WB memory it is sufficient to
......@@ -490,7 +508,6 @@ begin
VME_DTACK_OE_o <= '1';
VME_DATA_DIR_o <= s_WRITElatched_n;
VME_ADDR_DIR_o <= (s_is_d64) and s_WRITElatched_n;
s_dataPhase <= s_dataPhase;
-- Assert STB if stall was asserted.
stb_o <= s_card_sel and stall_i;
......@@ -501,14 +518,28 @@ begin
-- WB ack
stb_o <= '0';
s_err <= s_card_sel and err_i;
if s_WRITElatched_n = '0' or (s_card_sel and err_i) = '1' then
-- Write cycle (or BERR)
if (s_card_sel and err_i) = '1' then
-- Error
s_mainFSMstate <= DTACK_LOW;
elsif s_WRITElatched_n = '0' then
-- Write cycle.
if s_dataPhase = '1' then
-- MBLT
s_dataPhase <= '0';
s_ADDRlatched(2) <= '0';
s_locDataIn(31 downto 0) <= s_locDataIn(63 downto 32);
s_mainFSMstate <= CHECK_TRANSFER_TYPE;
else
s_mainFSMstate <= DTACK_LOW;
end if;
else
-- Read cycle
-- Mux (CS-CSR or WB)
s_locDataOut <= (others => '0');
s_locDataOut(63 downto 32) <= s_locDataOut(31 downto 0);
s_locDataOut(31 downto 0) <= (others => '0');
if s_card_sel = '1' then
if s_LWORDlatched_n = '1' and s_ADDRlatched(1) = '0' then
-- Word/byte access with A1 = 0
......@@ -516,11 +547,19 @@ begin
else
s_locDataOut(31 downto 0) <= dat_i;
end if;
elsif s_conf_sel = '1' then
else
s_locDataOut(7 downto 0) <= cr_csr_data_i;
end if;
s_mainFSMstate <= DATA_TO_BUS;
if s_dataPhase = '1' then
-- MBLT
s_dataPhase <= '0';
s_ADDRlatched(2) <= '1';
s_mainFSMstate <= CHECK_TRANSFER_TYPE;
else
s_mainFSMstate <= DATA_TO_BUS;
end if;
end if;
else
s_mainFSMstate <= MEMORY_REQ;
......@@ -530,24 +569,20 @@ begin
VME_DTACK_OE_o <= '1';
VME_DATA_DIR_o <= s_WRITElatched_n;
VME_ADDR_DIR_o <= (s_is_d64) and s_WRITElatched_n;
s_dataPhase <= s_dataPhase;
s_mainFSMstate <= DTACK_LOW;
VME_ADDR_o <= s_locDataOut(63 downto 33);
VME_LWORD_n_o <= s_locDataOut(32);
VME_DATA_o <= s_locDataOut(31 downto 0);
-- VITA-1 Rule 2.54a
-- During all read cycles, the responding Slave MUST NOT drive
-- DTACK* low before it drives D[].
if s_transferType = MBLT then
VME_ADDR_o <= s_locDataOut(63 downto 33);
VME_LWORD_n_o <= s_locDataOut(32);
end if;
VME_DATA_o <= s_locDataOut(31 downto 0);
s_mainFSMstate <= DTACK_LOW;
when DTACK_LOW =>
VME_DTACK_OE_o <= '1';
VME_DATA_DIR_o <= s_WRITElatched_n;
VME_ADDR_DIR_o <= (s_is_d64) and s_WRITElatched_n;
s_dataPhase <= s_dataPhase;
-- Set DTACK (or retry or berr)
if s_err = '1' then
......@@ -566,25 +601,21 @@ begin
-- Rescind DTACK.
VME_DTACK_n_o <= '1';
case s_transferType is
when SINGLE =>
-- Cycle should be finished, but allow another access at
-- the same address (RMW).
if s_transferType = SINGLE then
-- Cycle should be finished, but allow another access at
-- the same address (RMW).
s_mainFSMstate <= WAIT_FOR_DS;
else
if s_transferType = MBLT and s_MBLT_Data = '0' then
-- MBLT: end of address phase.
s_mainFSMstate <= WAIT_FOR_DS;
when BLT =>
s_MBLT_Data <= '1';
else
-- Block
s_mainFSMstate <= INCREMENT_ADDR;
when MBLT =>
if s_dataPhase = '1' then
s_mainFSMstate <= INCREMENT_ADDR;
else
-- Address was got, now transfer data
s_dataPhase <= '1';
s_mainFSMstate <= WAIT_FOR_DS;
end if;
when error =>
null;
end case;
end if;
end if;
else
s_mainFSMstate <= DTACK_LOW;
end if;
......@@ -592,12 +623,13 @@ begin
when INCREMENT_ADDR =>
VME_DTACK_OE_o <= '1';
VME_ADDR_DIR_o <= (s_is_d64) and s_WRITElatched_n;
s_dataPhase <= s_dataPhase;
if s_LWORDlatched_n = '0' then
if s_transferType = MBLT then
-- 64 bit
addr_word_incr := 4;
else
-- 32 bit
addr_word_incr := 2;
end if;
else
......
......@@ -136,10 +136,10 @@ package vme64x_pack is
g_BEG_SN : std_logic_vector(23 downto 0) := x"000000";
g_END_SN : std_logic_vector(23 downto 0) := x"000000";
g_F0_ADEM : std_logic_vector( 31 downto 0) := x"ff000000";
g_F0_AMCAP : std_logic_vector( 63 downto 0) := x"00000000_0000ee00";
g_F0_AMCAP : std_logic_vector( 63 downto 0) := x"00000000_0000ff00";
g_F0_DAWPR : std_logic_vector( 7 downto 0) := x"84";
g_F1_ADEM : std_logic_vector( 31 downto 0) := x"fff80000";
g_F1_AMCAP : std_logic_vector( 63 downto 0) := x"ee000000_00000000";
g_F1_AMCAP : std_logic_vector( 63 downto 0) := x"ff000000_00000000";
g_F1_DAWPR : std_logic_vector( 7 downto 0) := x"84";
g_F2_ADEM : std_logic_vector( 31 downto 0) := x"00000000";
g_F2_AMCAP : std_logic_vector( 63 downto 0) := x"00000000_00000000";
......
entity top_tb is
generic (scenario : natural range 0 to 5 := 1);
generic (scenario : natural range 0 to 6 := 6);
end;
library ieee;
......@@ -14,10 +14,12 @@ architecture behaviour of top_tb is
subtype byte_t is std_logic_vector (7 downto 0);
subtype word_t is std_logic_vector (15 downto 0);
subtype lword_t is std_logic_vector (31 downto 0);
subtype qword_t is std_logic_vector (63 downto 0);
type byte_array_t is array (natural range <>) of byte_t;
type word_array_t is array (natural range <>) of word_t;
type lword_array_t is array (natural range <>) of lword_t;
type qword_array_t is array (natural range <>) of qword_t;
subtype vme_am_t is std_logic_vector (5 downto 0);
......@@ -657,6 +659,38 @@ begin
read_release;
end read16_blt;
procedure read64_mblt (addr : std_logic_vector (31 downto 0);
am : vme_am_t;
variable data : out qword_array_t)
is
variable res : lword_t;
begin
VME_LWORD_n_i <= '0';
read_setup_addr (addr, am);
VME_DS_n_i <= "00";
read_wait_dtack;
read_blt_end_cycle;
assert addr (2 downto 0) = "000"
report "unaligned read64_mblt" severity error;
for i in data'range loop
VME_DS_n_i <= "00";
read_wait_dtack;
if bus_timer = '0' then
data (i) := VME_ADDR_o & VME_LWORD_n_o & VME_DATA_o;
else
data (i) := (others => 'X');
VME_DS_n_i <= "11";
exit;
end if;
if i /= data'right then
read_blt_end_cycle;
end if;
end loop;
read_release;
end read64_mblt;
procedure write_setup_addr (addr : std_logic_vector (31 downto 0);
lword_n : std_logic;
am : vme_am_t) is
......@@ -739,7 +773,7 @@ begin
data : lword_array_t) is
begin
assert addr(1 downto 0) = "00"
report "unaligned write16" severity error;
report "unaligned write32" severity error;
write_setup_addr (addr, '0', am);
......@@ -753,6 +787,29 @@ begin
VME_AS_n_i <= '1';
end write32_blt;
procedure write64_mblt (addr : std_logic_vector (31 downto 0);
am : vme_am_t;
data : qword_array_t) is
begin
assert addr(2 downto 0) = "000"
report "unaligned write64" severity error;
write_setup_addr (addr, '0', am);
VME_DS_n_i <= "00";
write_wait_dtack_pulse;
for i in data'range loop
VME_DS_n_i <= "00";
VME_DATA_i (31 downto 0) <= data (i)(31 downto 0);
VME_LWORD_n_i <= data (i)(32);
VME_ADDR_i <= data(i)(63 downto 33);
write_wait_dtack_pulse;
end loop;
VME_AS_n_i <= '1';
end write64_mblt;
procedure write8_conf (addr : cfg_addr_t;
data : byte_t)
is
......@@ -939,8 +996,9 @@ begin
variable d16 : word_t;
variable d32 : lword_t;
variable v32 : lword_array_t (0 to 64);
variable v16 : word_array_t (0 to 64);
variable v64 : qword_array_t (0 to 16);
variable v32 : lword_array_t (0 to 16);
variable v16 : word_array_t (0 to 16);
begin
-- Each scenario starts with a reset.
-- VME reset
......@@ -1146,7 +1204,32 @@ begin
assert d32 = (31 downto 0 => 'X')
report "incorrect read 32" severity error;
-- TODO
when 6 =>
-- Test MBLT
-- Set ADER
write8_conf (x"7_ff63", x"64");
write8_conf (x"7_ff6f", c_AM_A32_MBLT & "00");
-- Enable card
write8_conf (x"7_fffb", b"0001_0000");
read64_mblt (x"64_00_00_10", c_AM_A32_MBLT, v64 (0 to 1));
assert v64 (0) = x"0000_0004_0000_0500"
and v64 (1) = x"0006_0000_0700_0000"
report "incorrect MBLT data 64" severity error;
v64 (0 to 3) := (x"00_11_22_33_44_55_66_77",
x"88_99_aa_bb_cc_dd_ee_ff",
x"01_23_45_67_89_ab_cd_ef",
x"fe_dc_ba_98_76_54_32_10");
write64_mblt (x"64_00_01_00", c_AM_A32_MBLT, v64 (0 to 3));
read64_mblt (x"64_00_01_00", c_AM_A32_MBLT, v64 (0 to 3));
assert v64 (0 to 3) = (x"00_11_22_33_44_55_66_77",
x"88_99_aa_bb_cc_dd_ee_ff",
x"01_23_45_67_89_ab_cd_ef",
x"fe_dc_ba_98_76_54_32_10")
report "incorrect MBLT data 64 r/w" severity error;
end case;
wait for 4 * g_CLOCK_PERIOD * 1 ns;
......
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