Commit 8bee5b5a authored by twlostow's avatar twlostow

fixed several bugs: race condition on address decoding (the CTR interrupt…

fixed several bugs: race condition on address decoding (the CTR interrupt issue), invalid reset handling in CROM init sequence & strange combinatorial loop in VME_IRQ_Controller. More bugs await.

git-svn-id: http://svn.ohwr.org/vme64x-core/trunk@194 665b4545-5c6b-4c24-801b-41150b02b44b
parent ca638b8e
......@@ -93,15 +93,15 @@
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
---------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;
use work.vme64x_pack.all;
use work.VME_CR_pack.all;
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;
use work.vme64x_pack.all;
use work.VME_CR_pack.all;
--===========================================================================
-- Entity declaration
--===========================================================================
entity VME64xCore_Top is
entity VME64xCore_Top is
generic(
-- clock period (ns)
g_clock : integer := c_clk_period; -- 100 MHz
......@@ -127,8 +127,8 @@
);
port(
clk_i : in std_logic;
-- for the IRQ_Generator and relative registers
reset_o : out std_logic; -- asserted when '1'
rst_n_i : in std_logic;
-- VME
VME_AS_n_i : in std_logic;
VME_RST_n_i : in std_logic; -- asserted when '0'
......@@ -183,13 +183,13 @@
debug : out std_logic_vector(7 downto 0)
);
end VME64xCore_Top;
end VME64xCore_Top;
--===========================================================================
-- Architecture declaration
--===========================================================================
architecture RTL of VME64xCore_Top is
architecture RTL of VME64xCore_Top is
signal s_CRAMdataOut : std_logic_vector(7 downto 0);
signal s_CRAMaddr : std_logic_vector(f_log2_size(g_cram_size)-1 downto 0);
......@@ -324,7 +324,7 @@ begin
RisEdge_o => s_IRQ
);
Inst_VME_bus: VME_bus
Inst_VME_bus : VME_bus
generic map(
g_clock => g_clock,
g_wb_data_width => g_wb_data_width,
......@@ -333,6 +333,8 @@ begin
)
port map(
clk_i => clk_i,
rst_n_i => rst_n_i,
reset_o => s_reset, -- asserted when '1'
-- VME
VME_RST_n_i => VME_RST_n_oversampled,
......@@ -404,21 +406,21 @@ begin
-- output
VME_IRQ_o <= not s_VME_IRQ_n_o; --The buffers will invert again the logic level
WE_o <= not s_RW;
reset_o <= s_reset;
INT_ack_o <= s_VME_DTACK_IRQ;
--------------------------------------------------------------------------------
--Multiplexer added on the output signal used by either VMEbus.vhd and the IRQ_controller.vhd
VME_DATA_o <= s_VME_DATA_VMEbus when VME_IACK_n_oversampled ='1' else
VME_DATA_o <= s_VME_DATA_VMEbus when VME_IACK_n_oversampled = '1' else
s_VME_DATA_IRQ;
VME_DTACK_n_o <= s_VME_DTACK_VMEbus when VME_IACK_n_oversampled ='1' else
s_VME_DTACK_IRQ;
VME_DTACK_OE_o <= s_VME_DTACK_OE_VMEbus when VME_IACK_n_oversampled ='1' else
s_VME_DTACK_OE_IRQ;
VME_DATA_DIR_o <= s_VME_DATA_DIR_VMEbus when VME_IACK_n_oversampled ='1' else
VME_DTACK_n_o <= s_VME_DTACK_VMEbus and s_VME_DTACK_IRQ; --when VME_IACK_n_oversampled = '1' else
-- s_VME_DTACK_IRQ;
VME_DTACK_OE_o <= s_VME_DTACK_OE_VMEbus or s_VME_DTACK_OE_IRQ; --when VME_IACK_n_oversampled = '1' else
-- s_VME_DTACK_OE_IRQ;
VME_DATA_DIR_o <= s_VME_DATA_DIR_VMEbus when VME_IACK_n_oversampled = '1' else
s_VME_DATA_DIR_IRQ;
--------------------------------------------------------------------------------
-- Interrupter
Inst_VME_IRQ_Controller: VME_IRQ_Controller port map(
Inst_VME_IRQ_Controller : VME_IRQ_Controller
port map(
clk_i => clk_i,
reset_n_i => s_reset_IRQ, -- asserted when low
VME_IACKIN_n_i => VME_IACKIN_n_oversampled,
......@@ -441,7 +443,7 @@ begin
s_reset_IRQ <= not(s_reset);
--------------------------------------------------------------------------
--CR/CSR space
Inst_VME_CR_CSR_Space: VME_CR_CSR_Space
Inst_VME_CR_CSR_Space : VME_CR_CSR_Space
generic map(
g_cram_size => g_cram_size,
g_wb_data_width => g_wb_data_width,
......@@ -485,7 +487,7 @@ begin
INT_Vector => s_INT_Vector
);
end RTL;
end RTL;
--===========================================================================
-- Architecture end
--===========================================================================
......@@ -99,14 +99,15 @@
-- http://www.gnu.org/licenses/lgpl-2.1.html
---------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;
use work.vme64x_pack.all;
--===========================================================================
-- Entity declaration
--===========================================================================
entity VME_IRQ_Controller is
Port ( clk_i : in std_logic;
port (
clk_i : in std_logic;
reset_n_i : in std_logic;
VME_IACKIN_n_i : in std_logic;
VME_AS_n_i : in std_logic;
......@@ -138,7 +139,7 @@ architecture Behavioral of VME_IRQ_Controller is
--
signal s_AS_FallingEdge : std_logic;
signal s_AS_RisingEdge : std_logic;
type t_MainFSM is (IDLE, IRQ, WAIT_AS, WAIT_DS, LATCH_DS, CHECK, DATA_OUT, DTACK,IACKOUT1,IACKOUT2);
type t_MainFSM is (IDLE, IRQ, WAIT_AS, WAIT_DS, CHECK, DATA_OUT, DTACK, IACKOUT1, IACKOUT2);
signal s_currs, s_nexts : t_MainFSM;
signal s_ack_int : std_logic;
signal s_VME_ADDR_123_latched : std_logic_vector(2 downto 0);
......@@ -168,10 +169,8 @@ begin
INT_ReqinputSample : process(clk_i)
begin
if rising_edge(clk_i) then
if s_enable = '1' then
s_INT_Req_sample <= INT_Req_i;
end if;
end if;
end process;
--Output registers:
......@@ -226,7 +225,7 @@ begin
end if;
end process;
-- Update next state
process(s_currs,s_INT_Req_sample,VME_AS_n_i,VME_DS_n_i,s_ack_int,VME_IACKIN_n_i,s_AS_RisingEdge)
process(s_currs, s_INT_Req_sample, VME_AS_n_i, VME_DS_n_i, s_ack_int, VME_IACKIN_n_i, s_AS_RisingEdge)
begin
case s_currs is
when IDLE =>
......@@ -278,7 +277,7 @@ begin
end if;
when DATA_OUT=>
when DATA_OUT =>
s_nexts <= DTACK;
when IACKOUT2 =>
......@@ -288,7 +287,7 @@ begin
s_nexts <= IACKOUT2;
end if;
when DTACK=>
when DTACK =>
if s_AS_RisingEdge = '1' then
s_nexts <= IDLE;
else
......@@ -300,25 +299,46 @@ begin
end process;
-- Update Outputs
-- Mealy FSM
process(s_currs,VME_AS1_n_i)
process(s_currs, VME_AS1_n_i)
begin
s_FSM_IRQ <= c_FSM_IRQ;
case s_currs is
when IDLE =>
s_FSM_IRQ <= c_FSM_IRQ;
s_FSM_IRQ.s_IACKOUT <= '1';
s_FSM_IRQ.s_DataDir <= '0';
s_FSM_IRQ.s_DTACK <= '1';
s_FSM_IRQ.s_enableIRQ <= '0';
s_FSM_IRQ.s_resetIRQ <= '1';
s_FSM_IRQ.s_DSlatch <= '0';
s_FSM_IRQ.s_DTACK_OE <= '0';
when IRQ =>
s_FSM_IRQ <= c_FSM_IRQ;
s_FSM_IRQ.s_IACKOUT <= '1';
s_FSM_IRQ.s_DataDir <= '0';
s_FSM_IRQ.s_DTACK <= '1';
s_FSM_IRQ.s_DSlatch <= '0';
s_FSM_IRQ.s_DTACK_OE <= '0';
s_FSM_IRQ.s_enableIRQ <= '1';
s_FSM_IRQ.s_resetIRQ <= '0';
when WAIT_AS =>
s_FSM_IRQ <= c_FSM_IRQ;
s_FSM_IRQ.s_IACKOUT <= '1';
s_FSM_IRQ.s_DataDir <= '0';
s_FSM_IRQ.s_DTACK <= '1';
s_FSM_IRQ.s_enableIRQ <= '0';
s_FSM_IRQ.s_DSlatch <= '0';
s_FSM_IRQ.s_DTACK_OE <= '0';
s_FSM_IRQ.s_resetIRQ <= '0';
when WAIT_DS =>
s_FSM_IRQ <= c_FSM_IRQ;
s_FSM_IRQ.s_IACKOUT <= '1';
s_FSM_IRQ.s_DataDir <= '0';
s_FSM_IRQ.s_DTACK <= '1';
s_FSM_IRQ.s_enableIRQ <= '0';
s_FSM_IRQ.s_DSlatch <= '0';
s_FSM_IRQ.s_DTACK_OE <= '0';
s_FSM_IRQ.s_resetIRQ <= '0';
-- when LATCH_DS =>
......@@ -331,32 +351,51 @@ begin
-- s_DTACK_OE <= '0';
when CHECK =>
s_FSM_IRQ <= c_FSM_IRQ;
s_FSM_IRQ.s_IACKOUT <= '1';
s_FSM_IRQ.s_DataDir <= '0';
s_FSM_IRQ.s_DTACK <= '1';
s_FSM_IRQ.s_enableIRQ <= '0';
s_FSM_IRQ.s_DSlatch <= '0';
s_FSM_IRQ.s_DTACK_OE <= '0';
s_FSM_IRQ.s_resetIRQ <= '0';
when IACKOUT1 =>
s_FSM_IRQ <= c_FSM_IRQ;
s_FSM_IRQ. s_DataDir <= '0';
s_FSM_IRQ. s_DTACK <= '1';
s_FSM_IRQ. s_enableIRQ <= '0';
s_FSM_IRQ. s_DSlatch <= '0';
s_FSM_IRQ. s_DTACK_OE <= '0';
s_FSM_IRQ.s_resetIRQ <= '0';
s_FSM_IRQ.s_IACKOUT <= VME_AS1_n_i;
s_FSM_IRQ.s_IACKOUT <= '0';
when IACKOUT2 =>
s_FSM_IRQ <= c_FSM_IRQ;
s_FSM_IRQ. s_DataDir <= '0';
s_FSM_IRQ. s_DTACK <= '1';
s_FSM_IRQ. s_enableIRQ <= '0';
s_FSM_IRQ. s_DSlatch <= '0';
s_FSM_IRQ. s_DTACK_OE <= '0';
s_FSM_IRQ.s_resetIRQ <= '0';
s_FSM_IRQ.s_IACKOUT <= VME_AS1_n_i;
s_FSM_IRQ.s_IACKOUT <= '0';
when DATA_OUT=>
s_FSM_IRQ <= c_FSM_IRQ;
when DATA_OUT =>
s_FSM_IRQ.s_IACKOUT <= '1';
s_FSM_IRQ. s_DTACK <= '1';
s_FSM_IRQ. s_enableIRQ <= '0';
s_FSM_IRQ. s_DSlatch <= '0';
s_FSM_IRQ.s_DataDir <= '1';
s_FSM_IRQ.s_resetIRQ <= '0';
s_FSM_IRQ.s_DTACK_OE <= '1';
when DTACK=>
s_FSM_IRQ <= c_FSM_IRQ;
when DTACK =>
s_FSM_IRQ.s_IACKOUT <= '1';
s_FSM_IRQ. s_enableIRQ <= '0';
s_FSM_IRQ. s_resetIRQ <= '1';
s_FSM_IRQ. s_DSlatch <= '0';
s_FSM_IRQ.s_DataDir <= '1';
s_FSM_IRQ.s_DTACK <= '0';
s_FSM_IRQ.s_DTACK_OE <= '1';
when others => null;
-- when others => null;
end case;
end process;
......@@ -417,7 +456,7 @@ begin
-- for a D32 Interrupter
s_Data <= x"000000" & INT_Vector_i;
s_enable <= (not s_INT_Req_sample) or ((not s_FSM_IRQ.s_DTACK) and (s_AS_RisingEdge));
s_enable <= ((not s_FSM_IRQ.s_DTACK) and (s_AS_RisingEdge));
-- the INT_Vector is in the D0:D7 lines (byte3 in big endian order)
VME_DTACK_OE_o <= s_DTACK_OE_o;
VME_IACKOUT_n_o <= s_FSM_IRQ.s_IACKOUT;
......
......@@ -38,7 +38,7 @@ use work.vme64x_pack.all;
--===========================================================================
entity VME_Init is
Port ( clk_i : in std_logic;
RSTedge_i : in std_logic;
rst_n_i : in std_logic;
CRAddr_i : in std_logic_vector (18 downto 0);
CRdata_i : in std_logic_vector (7 downto 0);
InitReadCount_o : out std_logic_vector (8 downto 0);
......@@ -109,7 +109,7 @@ begin
p_coreInit : process(clk_i)
begin
if rising_edge(clk_i) then
if RSTedge_i = '1' then
if rst_n_i = '0' then
s_initState <= IDLE;
s_initReadCounter <= to_unsigned(0, s_initReadCounter'length);
s_latchCRdata <= '0';
......
This diff is collapsed.
......@@ -214,7 +214,7 @@ package vme64x_pack is
-- to 'Z' in the default configuration.
-- If the S_FPGA will be provided to a core who drive these lines without erase the
-- A_FPGA the above mentioned lines should be changed to 'Z' !!!
constant c_FSM_default : t_FSM :=(
constant c_FSM_default : t_FSM := (
s_memReq => '0',
s_decode => '0',
s_dtackOE => '0',
......@@ -233,9 +233,9 @@ package vme64x_pack is
s_retry => '0',
s_berr => '0',
s_BERR_out => '0'
);
);
constant c_FSM_IRQ : t_FSM_IRQ :=(
constant c_FSM_IRQ : t_FSM_IRQ := (
s_IACKOUT => '1',
s_DataDir => '0',
s_DTACK => '1',
......@@ -243,7 +243,7 @@ package vme64x_pack is
s_resetIRQ => '1',
s_DSlatch => '0',
s_DTACK_OE => '0'
);
);
-- CSR address:
constant c_BAR_addr : unsigned(19 downto 0) := x"7FFFF"; -- VME64x defined CSR
......@@ -298,7 +298,7 @@ package vme64x_pack is
--___________________________________________________________________________________________
-- TYPE:
type t_typeOfDataTransfer is ( D08_0,
type t_typeOfDataTransfer is (D08_0,
D08_1,
D08_2,
D08_3,
......@@ -309,7 +309,7 @@ package vme64x_pack is
TypeError
);
type t_addressingType is ( A24,
type t_addressingType is (A24,
A24_BLT,
A24_MBLT,
CR_CSR,
......@@ -324,14 +324,14 @@ package vme64x_pack is
AM_Error
);
type t_transferType is ( SINGLE,
type t_transferType is (SINGLE,
BLT,
MBLT,
TWOe,
error
);
type t_XAMtype is ( A32_2eVME,
type t_XAMtype is (A32_2eVME,
A64_2eVME,
A32_2eSST,
A64_2eSST,
......@@ -340,11 +340,11 @@ package vme64x_pack is
XAM_error
);
type t_2eType is ( TWOe_VME,
type t_2eType is (TWOe_VME,
TWOe_SST
);
type t_mainFSMstates is ( IDLE,
type t_mainFSMstates is (IDLE,
DECODE_ACCESS,
WAIT_FOR_DS,
LATCH_DS1,
......@@ -388,7 +388,7 @@ package vme64x_pack is
-- TWOe_END_2
);
type t_initState is ( IDLE,
type t_initState is (IDLE,
SET_ADDR,
GET_DATA,
END_INIT
......@@ -404,21 +404,22 @@ package vme64x_pack is
type t_cr_array is array (natural range <>) of std_logic_vector(7 downto 0);
-- functions
function f_div8 (width : integer) return integer;
function f_log2_size (A : natural) return natural;
function f_set_CR_space (BoardID : integer; cr_default : t_cr_array;
ManufacturerID : integer; RevisionID : integer; ProgramID : integer) return t_cr_array;
function f_latchDS (clk_period : integer) return integer;
function f_div8 (width : integer) return integer;
function f_log2_size (A : natural) return natural;
function f_set_CR_space (BoardID : integer; cr_default : t_cr_array;
ManufacturerID : integer; RevisionID : integer; ProgramID : integer) return t_cr_array;
function f_latchDS (clk_period : integer) return integer;
--_____________________________________________________________________________________________________
--COMPONENTS:
component VME_bus is
generic( g_clock : integer := c_clk_period;
generic(g_clock : integer := c_clk_period;
g_wb_data_width : integer := c_width;
g_wb_addr_width : integer := c_addr_width;
g_cram_size : integer := c_CRAM_SIZE
);
port(
clk_i : in std_logic;
rst_n_i : in std_logic;
VME_RST_n_i : in std_logic;
VME_AS_n_i : in std_logic;
VME_LWORD_n_i : in std_logic;
......@@ -684,9 +685,9 @@ function f_latchDS (clk_period : integer) return integer;
component VME_Init is
port(
clk_i : in std_logic;
rst_n_i : in std_logic;
CRAddr_i : in std_logic_vector(18 downto 0);
CRdata_i : in std_logic_vector(7 downto 0);
RSTedge_i : in std_logic;
InitReadCount_o : out std_logic_vector(8 downto 0);
InitInProgress_o : out std_logic;
BEG_USR_CR_o : out std_logic_vector(23 downto 0);
......@@ -731,20 +732,20 @@ function f_latchDS (clk_period : integer) return integer;
end component VME_swapper;
component Reg32bit is
port (
reset, clk_i, enable: in std_logic;
reset, clk_i, enable : in std_logic;
di : in std_logic_vector(31 downto 0);
do: out std_logic_vector(31 downto 0)
do : out std_logic_vector(31 downto 0)
);
end component Reg32bit;
component FlipFlopD is
port (
reset,enable,sig_i,clk_i : in std_logic;
reset, enable, sig_i, clk_i : in std_logic;
sig_o : out std_logic := '0'
);
end component FlipFlopD;
component EdgeDetection is
port (
sig_i,clk_i : in std_logic;
sig_i, clk_i : in std_logic;
sigEdge_o : out std_logic := '0'
);
end component EdgeDetection;
......@@ -845,7 +846,7 @@ function f_latchDS (clk_period : integer) return integer;
end vme64x_pack;
package body vme64x_pack is
function f_div8 (width : integer) return integer is
function f_div8 (width : integer) return integer is
begin
for I in 1 to 8 loop
if (8*I >= width) then
......@@ -854,7 +855,7 @@ function f_div8 (width : integer) return integer is
end loop;
end function f_div8;
function f_log2_size (A : natural) return natural is
function f_log2_size (A : natural) return natural is
begin
for I in 1 to 64 loop -- Works for up to 64 bits
if (2**I >= A) then
......@@ -874,10 +875,10 @@ function f_log2_size (A : natural) return natural is
variable v_ProgramID : std_logic_vector(7 downto 0);
begin
v_BoardID := std_logic_vector(to_unsigned(BoardID,32));
v_ManufacturerID := std_logic_vector(to_unsigned(ManufacturerID,24));
v_RevisionID := std_logic_vector(to_unsigned(RevisionID,32));
v_ProgramID := std_logic_vector(to_unsigned(ProgramID,8));
v_BoardID := std_logic_vector(to_unsigned(BoardID, 32));
v_ManufacturerID := std_logic_vector(to_unsigned(ManufacturerID, 24));
v_RevisionID := std_logic_vector(to_unsigned(RevisionID, 32));
v_ProgramID := std_logic_vector(to_unsigned(ProgramID, 8));
for i in cr_default'range loop
case i is
when c_BOARD_ID_p1 => v_CR_space(i) := v_BoardID(31 downto 24);
......
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