Commit c3937071 authored by Tristan Gingold's avatar Tristan Gingold

Rewrite decoder to decouple it from main FSM.

parent dca5417b
......@@ -311,8 +311,9 @@ architecture RTL of VME64xCore_Top is
-- Function decoders
signal s_addr_decoder_i : std_logic_vector(31 downto 0);
signal s_addr_decoder_o : std_logic_vector(31 downto 0);
signal s_decode : std_logic;
signal s_sel : std_logic;
signal s_decode_start : std_logic;
signal s_decode_done : std_logic;
signal s_decode_sel : std_logic;
signal s_function : std_logic_vector( 2 downto 0);
signal s_am : std_logic_vector( 5 downto 0);
......@@ -410,9 +411,10 @@ begin
-- Function decoder
addr_decoder_i => s_addr_decoder_o,
addr_decoder_o => s_addr_decoder_i,
decode_o => s_decode,
decode_start_o => s_decode_start,
decode_done_i => s_decode_done,
am_o => s_am,
sel_i => s_sel,
decode_sel_i => s_decode_sel,
-- CR/CSR signals
cr_csr_addr_o => s_cr_csr_addr,
......@@ -437,16 +439,17 @@ begin
g_AMCAP => c_AMCAP
)
port map (
clk_i => clk_i,
rst_n_i => s_reset_n,
addr_i => s_addr_decoder_i,
addr_o => s_addr_decoder_o,
decode_i => s_decode,
am_i => s_am,
ader_i => s_ader,
sel_o => s_sel,
function_o => s_function
clk_i => clk_i,
rst_n_i => s_reset_n,
addr_i => s_addr_decoder_i,
addr_o => s_addr_decoder_o,
decode_start_i => s_decode_start,
am_i => s_am,
ader_i => s_ader,
decode_sel_o => s_decode_sel,
decode_done_o => s_decode_done,
function_o => s_function
);
function_o (2 downto 0) <= s_function;
......
......@@ -42,87 +42,46 @@ entity VME_Funct_Match is
g_AMCAP : t_amcap_array(0 to 7)
);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
clk_i : in std_logic;
rst_n_i : in std_logic;
addr_i : in std_logic_vector(31 downto 0);
-- Input address (to be decoded).
addr_i : in std_logic_vector(31 downto 0);
-- Sub-address of the function (the part not masked by adem).
addr_o : out std_logic_vector(31 downto 0);
decode_i : in std_logic;
am_i : in std_logic_vector( 5 downto 0);
addr_o : out std_logic_vector(31 downto 0);
decode_start_i : in std_logic;
am_i : in std_logic_vector( 5 downto 0);
ader_i : in t_ader_array(0 to 7);
ader_i : in t_ader_array(0 to 7);
-- Set when a function is selected (ie function_o is valid).
sel_o : out std_logic;
decode_sel_o : out std_logic;
-- Set when sel_o is valid (decoding is done).
decode_done_o : out std_logic;
-- Selected function.
function_o : out std_logic_vector( 2 downto 0)
function_o : out std_logic_vector( 2 downto 0)
);
end VME_Funct_Match;
architecture rtl of VME_Funct_Match is
-- AM matches ADER AM bits for each function
signal s_am_match : std_logic_vector( 7 downto 0);
-- AM in AMCAP for each function
signal s_am_valid : std_logic_vector( 7 downto 0);
-- Function index and ADEM from priority encoder
signal s_function_sel : std_logic_vector( 7 downto 0);
signal s_adem_sel : std_logic_vector(31 downto 0);
signal s_function_sel : natural range 0 to 7;
signal s_function_sel_valid : std_logic;
signal s_decode_start_1 : std_logic;
-- Selected function
signal s_function : std_logic_vector( 7 downto 0);
signal s_function_ena : std_logic_vector( 7 downto 0);
signal s_function : std_logic_vector( 7 downto 0);
signal s_ader_am_valid : std_logic_vector( 7 downto 0);
-- List of supported AM.
constant c_AMCAP_ALLOWED : std_logic_vector(63 downto 0) :=
(16#38# to 16#3f# => '1', -- A24
16#2f# => '1', -- CR/CSR
16#2d# | 16#29# => '1', -- A16
16#08# to 16#0f# => '1', -- A32
(16#3d# to 16#3f# => '1', -- A24
16#39# to 16#3b# => '1',
16#2d# | 16#29# => '1', -- A16
16#0d# to 16#0f# => '1', -- A32
16#09# to 16#0b# => '1',
others => '0');
------------------------------------------------------------------------------
-- Generate AM lookup table
------------------------------------------------------------------------------
-- There are 64 positions in the LUT corresponding to each AM. Each position
-- is a vector whose bit N indicate whether function N accepts this AM.
-- For example if s_am_lut(9) = "00001010", this means that functions 1 & 3
-- accept AM=9.
type t_am_lut is array (0 to 63) of std_logic_vector(7 downto 0);
function f_gen_am_lut return t_am_lut is
variable lut : t_am_lut := (others => "00000000");
begin
for i in 0 to 63 loop
for j in 0 to 7 loop
lut(i)(j) := g_AMCAP(j)(i);
end loop;
end loop;
return lut;
end function;
constant c_am_lut : t_am_lut := f_gen_am_lut;
------------------------------------------------------------------------------
-- Generate function enabled vector
------------------------------------------------------------------------------
function f_function_ena return std_logic_vector is
variable ena : std_logic_vector(7 downto 0) := (others => '0');
begin
for i in 0 to 7 loop
if g_AMCAP(i) /= (63 downto 0 => '0') then
ena(i) := '1';
end if;
end loop;
return ena;
end function;
-- c_ENABLED is true when a function's AMCAP /= 0 and the previous
-- function does not have the EFM bit set.
constant c_ENABLED : std_logic_vector(7 downto 0) := f_function_ena;
------------------------------------------------------------------------------
-- Generate EFD lookup table
------------------------------------------------------------------------------
......@@ -161,14 +120,18 @@ begin
end generate;
------------------------------------------------------------------------------
-- Function match
-- Address and AM comparators
------------------------------------------------------------------------------
gen_match_loop : for i in 0 to 7 generate
-- True in case of match
s_function(i) <=
'1' when (((addr_i(c_ADEM_M) and g_ADEM(i)(c_ADEM_M))
= ader_i(i)(c_ADEM_M))
and (am_i = ader_i(i)(c_ADER_AM)))
else '0';
-- True if the AM part of ADER is enabled by AMCAP
s_ader_am_valid(i) <=
g_AMCAP(i)(to_integer(unsigned(ader_i(i)(c_ADER_AM))));
end generate;
------------------------------------------------------------------------------
......@@ -176,17 +139,18 @@ begin
------------------------------------------------------------------------------
process (clk_i) begin
if rising_edge(clk_i) then
s_function_sel <= 0;
s_function_sel_valid <= '0';
s_decode_start_1 <= '0';
if rst_n_i = '0' then
s_function_sel <= (others => '0');
s_adem_sel <= (others => '0');
else
s_function_sel <= (others => '0');
s_adem_sel <= (others => '0');
null;
elsif decode_start_i = '1' then
s_decode_start_1 <= '1';
for i in 0 to 7 loop
if s_function(i) = '1' then
s_function_sel(i) <= '1';
s_adem_sel (c_ADEM_M) <= g_adem(i)(c_ADEM_M);
s_function_sel <= i;
s_function_sel_valid <= s_ader_am_valid(i);
exit;
end if;
end loop;
......@@ -194,55 +158,30 @@ begin
end if;
end process;
-----------------------------------------------------------------------------
-- AM lookup table
-----------------------------------------------------------------------------
process (clk_i) begin
if rising_edge(clk_i) then
s_am_valid <= c_am_lut(to_integer(unsigned(am_i)));
end if;
end process;
-- Check of AM against AMCAP
s_function_ena <= s_function_sel and s_am_valid;
------------------------------------------------------------------------------
-- Address output latch
------------------------------------------------------------------------------
process (clk_i) begin
process (clk_i) is
variable mask : std_logic_vector(31 downto 0);
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
if rst_n_i = '0' or s_decode_start_1 = '0' then
addr_o <= (others => '0');
else
if decode_i = '1' then
addr_o <= addr_i and not s_adem_sel;
end if;
end if;
end if;
end process;
------------------------------------------------------------------------------
-- EFD decoder and output latch
------------------------------------------------------------------------------
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
function_o <= (others => '0');
decode_done_o <= '0';
decode_sel_o <= '0';
else
if decode_i = '1' then
sel_o <= '1';
case s_function_ena is
when "00000001" => function_o <= c_EFD_LUT(0);
when "00000010" => function_o <= c_EFD_LUT(1);
when "00000100" => function_o <= c_EFD_LUT(2);
when "00001000" => function_o <= c_EFD_LUT(3);
when "00010000" => function_o <= c_EFD_LUT(4);
when "00100000" => function_o <= c_EFD_LUT(5);
when "01000000" => function_o <= c_EFD_LUT(6);
when "10000000" => function_o <= c_EFD_LUT(7);
when others => function_o <= (others => '0');
sel_o <= '0';
end case;
-- s_decode_start_1 is set.
decode_done_o <= '1';
if s_function_sel_valid = '1' then
function_o <= c_EFD_LUT(s_function_sel);
mask := (others => '0');
mask(c_ADEM_M) := g_adem(s_function_sel)(c_ADEM_M);
addr_o <= addr_i and not mask;
decode_sel_o <= '1';
else
decode_sel_o <= '0';
end if;
end if;
end if;
......
......@@ -79,7 +79,6 @@ entity VME_Wb_master is
port (
memReq_i : in std_logic;
clk_i : in std_logic;
cardSel_i : in std_logic;
reset_i : in std_logic;
BERRcondition_i : in std_logic;
sel_i : in std_logic_vector(3 downto 0);
......@@ -114,7 +113,7 @@ begin
if rising_edge(clk_i) then
if reset_i = '1' or (stall_i = '0' and s_cyc = '1') then
memReq_o <= '0';
elsif memReq_i = '1' and cardSel_i = '1' and BERRcondition_i = '0' then
elsif memReq_i = '1' and BERRcondition_i = '0' then
memReq_o <= '1';
end if;
end if;
......@@ -126,7 +125,7 @@ begin
if rising_edge(clk_i) then
if reset_i = '1' or memAckWB_i = '1' then
s_cyc <= '0';
elsif memReq_i = '1' and cardSel_i = '1' and BERRcondition_i = '0' then
elsif memReq_i = '1' and BERRcondition_i = '0' then
s_cyc <= '1';
end if;
end if;
......@@ -137,7 +136,7 @@ begin
begin
if rising_edge(clk_i) then
RW_o <= RW_i;
s_AckWithError <= (memReq_i and cardSel_i and BERRcondition_i);
s_AckWithError <= (memReq_i and BERRcondition_i);
end if;
end process;
......
......@@ -116,9 +116,10 @@ entity VME_bus is
-- Function decoder
addr_decoder_i : in std_logic_vector(31 downto 0);
addr_decoder_o : out std_logic_vector(31 downto 0);
decode_o : out std_logic;
decode_start_o : out std_logic;
decode_done_i : in std_logic;
am_o : out std_logic_vector( 5 downto 0);
sel_i : in std_logic;
decode_sel_i : in std_logic;
--CR/CSR space signals:
cr_csr_addr_o : out std_logic_vector(18 downto 2);
......@@ -185,9 +186,7 @@ architecture RTL of VME_bus is
REFORMAT_ADDRESS,
-- Decoding ADDR and AM (selecting card or conf).
DECODE_ACCESS_0,
DECODE_ACCESS_1,
DECODE_ACCESS_2,
DECODE_ACCESS,
-- Wait until DS is asserted.
WAIT_FOR_DS,
......@@ -218,6 +217,7 @@ architecture RTL of VME_bus is
signal s_mainFSMstate : t_mainFSMstates;
signal s_mainDTACK : std_logic; -- DTACK driving
signal s_memReq : std_logic; -- Global memory request
signal s_WBReq : std_logic; -- WB memory request
signal s_dataPhase : std_logic; -- for MBLT
signal s_transferActive : std_logic; -- active VME transfer
signal s_retry : std_logic; -- RETRY signal
......@@ -241,7 +241,6 @@ architecture RTL of VME_bus is
signal s_sw_reset : std_logic;
-- Set on the cycle to decode access (ADDR + AM)
signal s_decode : std_logic;
signal s_AckWb : std_logic;
signal s_err : std_logic;
signal s_rty : std_logic;
......@@ -340,7 +339,7 @@ begin
-- software reset, manually reset,
-- on rising edge of AS.
s_memReq <= '0';
s_decode <= '0';
decode_start_o <= '0';
s_dtackOE <= '0';
s_mainDTACK <= '1';
s_dataDir <= '0';
......@@ -360,9 +359,11 @@ begin
VME_LWORD_n_o <= '1';
VME_DATA_o <= (others => '0');
s_card_sel <= '0';
s_conf_sel <= '0';
else
s_memReq <= '0';
s_decode <= '0';
decode_start_o <= '0';
s_dtackOE <= '0';
s_mainDTACK <= '1';
s_dataDir <= '0';
......@@ -401,39 +402,42 @@ begin
case s_addressingType is
when A16 =>
s_ADDRlatched (31 downto 16) <= (others => '0'); -- A16
when A24 | A24_BLT | A24_MBLT | CR_CSR =>
when A24 | A24_BLT | A24_MBLT =>
s_ADDRlatched (31 downto 24) <= (others => '0'); -- A24
when others =>
null; -- A32
end case;
s_mainFSMstate <= DECODE_ACCESS_0;
s_decode <= '1';
when DECODE_ACCESS_0 =>
s_mainFSMstate <= DECODE_ACCESS_1;
s_decode <= '1';
when DECODE_ACCESS_1 =>
s_mainFSMstate <= DECODE_ACCESS_2;
s_decode <= '0';
if s_ADDRlatched(23 downto 19) = bar_i
and s_AMlatched = c_AM_CR_CSR
then
-- conf_sel = '1' it means CR/CSR space addressed
s_conf_sel <= '1';
s_mainFSMstate <= WAIT_FOR_DS;
else
s_mainFSMstate <= DECODE_ACCESS;
decode_start_o <= '1';
end if;
when DECODE_ACCESS_2 =>
when DECODE_ACCESS =>
-- check if this slave board is addressed and if it is, check
-- the access mode
if s_conf_sel = '1' then
-- conf_sel = '1' it means CR/CSR space addressed
s_mainFSMstate <= WAIT_FOR_DS;
elsif s_card_sel = '1' then
-- card_sel = '1' it means WB application addressed
s_mainFSMstate <= WAIT_FOR_DS;
-- Keep only the local part of the address
s_ADDRlatched <= addr_decoder_i (31 downto 1);
if decode_done_i = '1' then
if decode_sel_i = '1' and module_enable_i = '1' then
-- card_sel = '1' it means WB application addressed
s_card_sel <= '1';
s_mainFSMstate <= WAIT_FOR_DS;
-- Keep only the local part of the address
s_ADDRlatched <= addr_decoder_i (31 downto 1);
else
-- another board will answer; wait here the rising edge on
-- VME_AS_i (done by top if).
s_mainFSMstate <= WAIT_END;
end if;
else
-- another board will answer; wait here the rising edge on
-- VME_AS_i (done by top if).
s_mainFSMstate <= WAIT_END;
-- Not yet decoded.
s_mainFSMstate <= DECODE_ACCESS;
end if;
when WAIT_FOR_DS =>
......@@ -538,10 +542,7 @@ begin
s_locDataOut <= s_locDataOutWb;
end if;
elsif s_conf_sel = '1' then
s_locDataOut <= (others => '0');
s_locDataOut(7 downto 0) <= cr_csr_data_i;
else
s_locDataOut <= (others => '0');
end if;
s_mainFSMstate <= DATA_TO_BUS;
......@@ -637,11 +638,8 @@ begin
s_mainFSMstate <= WAIT_FOR_DS;
when WAIT_END =>
if VME_AS_n_i = '1' then
s_mainFSMstate <= IDLE;
else
s_mainFSMstate <= WAIT_END;
end if;
-- Will stay here until AS is released.
s_mainFSMstate <= WAIT_END;
when others =>
s_mainFSMstate <= IDLE;
......@@ -800,9 +798,8 @@ begin
g_WB_ADDR_WIDTH => g_WB_ADDR_WIDTH
)
port map (
memReq_i => s_memReq,
memReq_i => s_WBReq,
clk_i => clk_i,
cardSel_i => s_card_sel,
reset_i => s_wbMaster_rst,
BERRcondition_i => s_BERRcondition,
sel_i => s_sel,
......@@ -828,18 +825,13 @@ begin
we_o <= not s_rw;
s_WBReq <= s_card_sel and s_memReq;
------------------------------------------------------------------------------
-- Function Decoder
------------------------------------------------------------------------------
addr_decoder_o <= s_ADDRlatched & '0';
decode_o <= s_decode;
am_o <= s_AMlatched;
s_card_sel <= sel_i and module_enable_i;
-- Decode accesses to CR/CSR
s_conf_sel <= '1' when s_ADDRlatched(23 downto 19) = bar_i
and s_AMlatched = c_AM_CR_CSR
else '0';
------------------------------------------------------------------------------
-- CR/CSR In/Out
......
......@@ -257,9 +257,10 @@ package vme64x_pack is
stall_i : in std_logic;
addr_decoder_i : in std_logic_vector(31 downto 0);
addr_decoder_o : out std_logic_vector(31 downto 0);
decode_o : out std_logic;
decode_start_o : out std_logic;
decode_done_i : in std_logic;
am_o : out std_logic_vector( 5 downto 0);
sel_i : in std_logic;
decode_sel_i : in std_logic;
cr_csr_addr_o : out std_logic_vector(18 downto 2);
cr_csr_data_i : in std_logic_vector( 7 downto 0);
cr_csr_data_o : out std_logic_vector( 7 downto 0);
......@@ -276,15 +277,16 @@ package vme64x_pack is
g_AMCAP : t_amcap_array(0 to 7)
);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
addr_i : in std_logic_vector(31 downto 0);
addr_o : out std_logic_vector(31 downto 0);
decode_i : in std_logic;
am_i : in std_logic_vector( 5 downto 0);
ader_i : in t_ader_array(0 to 7);
sel_o : out std_logic;
function_o : out std_logic_vector( 2 downto 0)
clk_i : in std_logic;
rst_n_i : in std_logic;
addr_i : in std_logic_vector(31 downto 0);
addr_o : out std_logic_vector(31 downto 0);
decode_start_i : in std_logic;
am_i : in std_logic_vector( 5 downto 0);
ader_i : in t_ader_array(0 to 7);
decode_sel_o : out std_logic;
decode_done_o : out std_logic;
function_o : out std_logic_vector( 2 downto 0)
);
end component VME_Funct_Match;
......@@ -358,7 +360,6 @@ package vme64x_pack is
port (
memReq_i : in std_logic;
clk_i : in std_logic;
cardSel_i : in std_logic;
reset_i : in std_logic;
BERRcondition_i : in std_logic;
sel_i : in std_logic_vector(3 downto 0);
......
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