Commit d1f969c8 authored by Tristan Gingold's avatar Tristan Gingold

xvme64x_core is now the top-level entity, vme64x_core is a wrapper.

parent 22994dc6
-------------------------------------------------------------------------------- ----------------------------------------------------------------
-- CERN (BE-CO-HT) -- This file was automatically generated by vhdl-unwrap for
-- VME64x Core -- entity xvme64x_core.
-- http://www.ohwr.org/projects/vme64x-core -- DO NOT EDIT.
-------------------------------------------------------------------------------- ----------------------------------------------------------------
--
-- unit name: vme64x_core
--
-- author: Pablo Alvarez Sanchez <pablo.alvarez.sanchez@cern.ch>
-- Davide Pedretti <davide.pedretti@cern.ch>
--
-- description:
--
-- This core implements an interface to transfer data between the VMEbus and
-- the WBbus. This core is a Slave in the VME side and Master in the WB side.
--
-- The main blocks:
--
-- _______________________vme64x_core_______________________
-- | ________________ ________ ___________________ |
-- |___ | | | | | | |
-- | | | VME Bus | | Funct | | | |
-- | | | | | Match | | VME to WB FIFO | |
-- | S | | | | | | | (not implemented) | |
-- V | A | | VME | WB | |________| | | | W
-- M | M | | slave | master | ________ | | | B
-- E | P | | | | | | | | |
-- | L | | | | | CR/CSR | | | | B
-- B | I | | | | | Space | |___________________| | U
-- U | N | | | |________| ___________________ | S
-- S | G | | | ________ | | |
-- | | | | | | | IRQ Controller | |
-- |___| | | | User | | | |
-- | | | | CSR | | | |
-- | |________________| |________| |___________________| |
-- |_________________________________________________________|
--
-- This core complies with the VME64x specifications and allows "plug and
-- play" configuration of VME crates.
-- The base address is setted by the Geographical lines.
-- The base address can't be setted by hand with the switches on the board.
-- If the core is used in an old VME system without GA lines, the core should
-- be provided with a logic that detects if GA = "11111" and if it is the base
-- address of the module, this logic should derive the GA from the switches on
-- the board.
-- All the VMEbus's asynchronous signals must be sampled 2 or 3 times to avoid
-- metastability problem.
-- All the output signals on the WB bus are registered.
-- The Input signals from the WB bus aren't registered indeed the WB is a
-- synchronous protocol and some registers in the WB side will introduce a
-- delay that make impossible reproduce the WB PIPELINED protocol.
-- The WB Slave application must work with the same frequency as this vme64x
-- core.
-- The main component of this core is the VME_bus on the left in the block
-- diagram. Inside this component you can find the main finite state machine
-- that coordinates all the synchronisms.
-- The WB protocol is more faster than the VME protocol so to make independent
-- the two protocols a FIFO memory can be introduced.
-- The FIFO is necessary only during 2eSST access mode.
-- During the block transfer without FIFO the VME_bus accesses directly the Wb
-- bus in Single pipelined read/write mode. If this is the only Wb master this
-- solution is better than the solution with FIFO.
-- In this base version of the core the FIFO is not implemented indeed the 2e
-- access modes aren't supported yet.
-- A Configuration ROM/Control Status Register (CR/CSR) address space has been
-- introduced. The CR/CSR space can be accessed with the data transfer type
-- D08_3, D16_23, D32.
-- To access the CR/CSR space: AM = 0x2f --> this is A24 addressing type,
-- SINGLE transfer type. Base Address = Slot Number.
-- This interface is provided with an Interrupter. The IRQ Controller receives
-- from the Application (WB bus) an interrupt request and transfers this
-- interrupt request on the VMEbus. This component acts also during the
-- Interrupt acknowledge cycle, sending the status/ID to the Interrupt
-- handler.
-- Inside each component, a detailed description is provided.
-- Access modes supported:
-- http://www.ohwr.org/projects/vme64x-core/repository/changes/trunk/
-- documentation/user_guides/VME_access_modes.pdf
--
-- standards:
--
-- * VMEbus ANSI/IEEE Std 1014-1987
-- * VME64 ANSI/VITA 1-1994
-- * VME64x Extensions ANSI/VITA 1.1-1997
-- * VME 2eSST ANSI/VITA 1.5-2003
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
--------------------------------------------------------------------------------
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your
-- option) any later version. This source is distributed in the hope that it
-- will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details. You should have
-- received a copy of the GNU Lesser General Public License along with this
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
--------------------------------------------------------------------------------
-- last changes: see log.
--------------------------------------------------------------------------------
-- TODO: -
--------------------------------------------------------------------------------
library ieee; library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_1164.all;
use ieee.numeric_std.all; use work.wishbone_pkg.all;
use work.vme64x_pkg.all; use work.vme64x_pkg.all;
entity vme64x_core is entity vme64x_core is
generic ( generic (
g_CLOCK_PERIOD : integer := c_CLOCK_PERIOD; -- Clock period (ns) g_clock_period : integer;
g_WB_DATA_WIDTH : integer := c_DATA_WIDTH; -- WB data width: = 32 g_decode_am : boolean;
g_WB_ADDR_WIDTH : integer := c_ADDR_WIDTH; -- WB addr width: <= 32 g_user_csr_ext : boolean;
g_USER_CSR_EXT : boolean := false; -- Use external user CSR g_manufacturer_id : std_logic_vector(23 downto 0);
g_board_id : std_logic_vector(31 downto 0);
-- Consider AM field of ADER to decode addresses. This is what the VME64x g_revision_id : std_logic_vector(31 downto 0);
-- standard says. However, for compatibility with previous implementations g_program_id : std_logic_vector(7 downto 0);
-- (or to reduce resources), it is possible for a decoder to allow all AM g_ascii_ptr : std_logic_vector(23 downto 0);
-- declared in the AMCAP. g_beg_user_cr : std_logic_vector(23 downto 0);
g_DECODE_AM : boolean := true; g_end_user_cr : std_logic_vector(23 downto 0);
g_beg_cram : std_logic_vector(23 downto 0);
-- Manufacturer ID: IEEE OUID g_end_cram : std_logic_vector(23 downto 0);
-- e.g. CERN is 0x080030 g_beg_user_csr : std_logic_vector(23 downto 0);
g_MANUFACTURER_ID : std_logic_vector(23 downto 0) := c_CERN_ID; g_end_user_csr : std_logic_vector(23 downto 0);
g_beg_sn : std_logic_vector(23 downto 0);
-- Board ID: Per manufacturer, each board shall have an unique ID g_end_sn : std_logic_vector(23 downto 0);
-- e.g. SVEC = 408 (CERN IDs: http://cern.ch/boardid) g_nbr_decoders : natural range 1 to 8;
g_BOARD_ID : std_logic_vector(31 downto 0) := c_SVEC_ID; g_decoder_0_adem : std_logic_vector(31 downto 0);
g_decoder_0_amcap : std_logic_vector(63 downto 0);
-- Revision ID: user defined revision code g_decoder_0_dawpr : std_logic_vector(7 downto 0);
g_REVISION_ID : std_logic_vector(31 downto 0) := c_REVISION_ID; g_decoder_1_adem : std_logic_vector(31 downto 0);
g_decoder_1_amcap : std_logic_vector(63 downto 0);
-- Program ID: Defined per AV1: g_decoder_1_dawpr : std_logic_vector(7 downto 0);
-- 0x00 = Not used g_decoder_2_adem : std_logic_vector(31 downto 0);
-- 0x01 = No program, ID ROM only g_decoder_2_amcap : std_logic_vector(63 downto 0);
-- 0x02-0x4F = Manufacturer defined g_decoder_2_dawpr : std_logic_vector(7 downto 0);
-- 0x50-0x7F = User defined g_decoder_3_adem : std_logic_vector(31 downto 0);
-- 0x80-0xEF = Reserved for future use g_decoder_3_amcap : std_logic_vector(63 downto 0);
-- 0xF0-0xFE = Reserved for Boot Firmware (P1275) g_decoder_3_dawpr : std_logic_vector(7 downto 0);
-- 0xFF = Not to be used g_decoder_4_adem : std_logic_vector(31 downto 0);
g_PROGRAM_ID : std_logic_vector(7 downto 0) := c_PROGRAM_ID; g_decoder_4_amcap : std_logic_vector(63 downto 0);
g_decoder_4_dawpr : std_logic_vector(7 downto 0);
-- Pointer to a user defined ASCII string g_decoder_5_adem : std_logic_vector(31 downto 0);
g_ASCII_PTR : std_logic_vector(23 downto 0) := x"000000"; g_decoder_5_amcap : std_logic_vector(63 downto 0);
g_decoder_5_dawpr : std_logic_vector(7 downto 0);
-- User CR/CSR, CRAM & serial number pointers g_decoder_6_adem : std_logic_vector(31 downto 0);
g_BEG_USER_CR : std_logic_vector(23 downto 0) := x"000000"; g_decoder_6_amcap : std_logic_vector(63 downto 0);
g_END_USER_CR : std_logic_vector(23 downto 0) := x"000000"; g_decoder_6_dawpr : std_logic_vector(7 downto 0);
g_decoder_7_adem : std_logic_vector(31 downto 0);
g_BEG_CRAM : std_logic_vector(23 downto 0) := x"000000"; -- 0x1003 g_decoder_7_amcap : std_logic_vector(63 downto 0);
g_END_CRAM : std_logic_vector(23 downto 0) := x"000000"; -- 0x13ff g_decoder_7_dawpr : std_logic_vector(7 downto 0));
g_BEG_USER_CSR : std_logic_vector(23 downto 0) := x"07ff33";
g_END_USER_CSR : std_logic_vector(23 downto 0) := x"07ff5f";
g_BEG_SN : std_logic_vector(23 downto 0) := x"000000";
g_END_SN : std_logic_vector(23 downto 0) := x"000000";
-- Function 0
g_F0_ADEM : std_logic_vector( 31 downto 0) := x"ff000000";
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"ff000000_00000000";
g_F1_DAWPR : std_logic_vector( 7 downto 0) := x"84";
-- Function 2
g_F2_ADEM : std_logic_vector( 31 downto 0) := x"00000000";
g_F2_AMCAP : std_logic_vector( 63 downto 0) := x"00000000_00000000";
g_F2_DAWPR : std_logic_vector( 7 downto 0) := x"84";
-- Function 3
g_F3_ADEM : std_logic_vector( 31 downto 0) := x"00000000";
g_F3_AMCAP : std_logic_vector( 63 downto 0) := x"00000000_00000000";
g_F3_DAWPR : std_logic_vector( 7 downto 0) := x"84";
-- Function 4
g_F4_ADEM : std_logic_vector( 31 downto 0) := x"00000000";
g_F4_AMCAP : std_logic_vector( 63 downto 0) := x"00000000_00000000";
g_F4_DAWPR : std_logic_vector( 7 downto 0) := x"84";
-- Function 5
g_F5_ADEM : std_logic_vector( 31 downto 0) := x"00000000";
g_F5_AMCAP : std_logic_vector( 63 downto 0) := x"00000000_00000000";
g_F5_DAWPR : std_logic_vector( 7 downto 0) := x"84";
-- Function 6
g_F6_ADEM : std_logic_vector( 31 downto 0) := x"00000000";
g_F6_AMCAP : std_logic_vector( 63 downto 0) := x"00000000_00000000";
g_F6_DAWPR : std_logic_vector( 7 downto 0) := x"84";
-- Function 7
g_F7_ADEM : std_logic_vector( 31 downto 0) := x"00000000";
g_F7_AMCAP : std_logic_vector( 63 downto 0) := x"00000000_00000000";
g_F7_DAWPR : std_logic_vector( 7 downto 0) := x"84"
);
port ( port (
clk_i : in std_logic; clk_i : std_logic;
rst_n_i : in std_logic; rst_n_i : std_logic;
rst_n_o : out std_logic; -- To wishbone rst_n_o : out std_logic;
vme_as_n_i : std_logic;
-- VME vme_rst_n_i : std_logic;
VME_AS_n_i : in std_logic; vme_write_n_i : std_logic;
VME_RST_n_i : in std_logic; -- asserted when '0' vme_am_i : std_logic_vector(5 downto 0);
VME_WRITE_n_i : in std_logic; vme_ds_n_i : std_logic_vector(1 downto 0);
VME_AM_i : in std_logic_vector(5 downto 0); vme_ga_i : std_logic_vector(5 downto 0);
VME_DS_n_i : in std_logic_vector(1 downto 0); vme_lword_n_i : std_logic;
VME_GA_i : in std_logic_vector(5 downto 0); vme_data_i : std_logic_vector(31 downto 0);
VME_BERR_o : out std_logic; -- [In the VME standard this line is vme_addr_i : std_logic_vector(31 downto 1);
-- asserted when low. Here is asserted vme_iack_n_i : std_logic;
-- when high indeed the logic will be vme_iackin_n_i : std_logic;
-- inverted again in the VME transceivers vme_iackout_n_o : out std_logic;
-- on the board]*. vme_dtack_n_o : out std_logic;
VME_DTACK_n_o : out std_logic; vme_dtack_oe_o : out std_logic;
VME_RETRY_n_o : out std_logic; vme_lword_n_o : out std_logic;
VME_LWORD_n_i : in std_logic; vme_data_o : out std_logic_vector(31 downto 0);
VME_LWORD_n_o : out std_logic; vme_data_dir_o : out std_logic;
VME_ADDR_i : in std_logic_vector(31 downto 1); vme_data_oe_n_o : out std_logic;
VME_ADDR_o : out std_logic_vector(31 downto 1); vme_addr_o : out std_logic_vector(31 downto 1);
VME_DATA_i : in std_logic_vector(31 downto 0); vme_addr_dir_o : out std_logic;
VME_DATA_o : out std_logic_vector(31 downto 0); vme_addr_oe_n_o : out std_logic;
VME_IRQ_o : out std_logic_vector( 7 downto 1); -- the same as []* vme_retry_n_o : out std_logic;
VME_IACKIN_n_i : in std_logic; vme_retry_oe_o : out std_logic;
VME_IACK_n_i : in std_logic; vme_berr_n_o : out std_logic;
VME_IACKOUT_n_o : out std_logic; vme_irq_n_o : out std_logic_vector(6 downto 0);
wb_ack_i : std_logic;
-- VME buffers wb_err_i : std_logic;
VME_DTACK_OE_o : out std_logic; wb_rty_i : std_logic;
VME_DATA_DIR_o : out std_logic; wb_stall_i : std_logic;
VME_DATA_OE_N_o : out std_logic; wb_int_i : std_logic;
VME_ADDR_DIR_o : out std_logic; wb_dat_i : t_wishbone_data;
VME_ADDR_OE_N_o : out std_logic; wb_cyc_o : out std_logic;
VME_RETRY_OE_o : out std_logic; wb_stb_o : out std_logic;
wb_adr_o : out t_wishbone_address;
-- WishBone wb_sel_o : out t_wishbone_byte_select;
DAT_i : in std_logic_vector(g_WB_DATA_WIDTH-1 downto 0); wb_we_o : out std_logic;
DAT_o : out std_logic_vector(g_WB_DATA_WIDTH-1 downto 0); wb_dat_o : out t_wishbone_data;
ADR_o : out std_logic_vector(g_WB_ADDR_WIDTH-1 downto 0); irq_ack_o : out std_logic;
CYC_o : out std_logic; irq_level_i : std_logic_vector(7 downto 0);
ERR_i : in std_logic; irq_vector_i : std_logic_vector(7 downto 0);
SEL_o : out std_logic_vector(g_WB_DATA_WIDTH / 8 - 1 downto 0);
STB_o : out std_logic;
ACK_i : in std_logic;
WE_o : out std_logic;
STALL_i : in std_logic;
-- User CSR
-- The following signals are used when g_USER_CSR_EXT = true
-- otherwise they are connected to the internal user CSR.
irq_level_i : in std_logic_vector( 7 downto 0) := (others => '0');
irq_vector_i : in std_logic_vector( 7 downto 0) := (others => '0');
user_csr_addr_o : out std_logic_vector(18 downto 2); user_csr_addr_o : out std_logic_vector(18 downto 2);
user_csr_data_i : in std_logic_vector( 7 downto 0) := (others => '0'); user_csr_data_i : std_logic_vector(7 downto 0);
user_csr_data_o : out std_logic_vector( 7 downto 0); user_csr_data_o : out std_logic_vector(7 downto 0);
user_csr_we_o : out std_logic; user_csr_we_o : out std_logic;
-- User CR
user_cr_addr_o : out std_logic_vector(18 downto 2); user_cr_addr_o : out std_logic_vector(18 downto 2);
user_cr_data_i : in std_logic_vector( 7 downto 0) := (others => '0'); user_cr_data_i : std_logic_vector(7 downto 0));
-- IRQ Generator
irq_ack_o : out std_logic; -- when the IRQ controller acknowledges the
-- Interrupt cycle it sends a pulse to the
-- IRQ Generator
irq_i : in std_logic -- Interrupt request; the IRQ Generator/your
-- Wb application sends a pulse to the IRQ
-- Controller which asserts one of the IRQ
-- lines.
);
end vme64x_core; end vme64x_core;
architecture rtl of vme64x_core is architecture unwrap of vme64x_core is
signal s_reset : std_logic;
signal s_reset_n : std_logic;
signal s_VME_IRQ_n_o : std_logic_vector( 7 downto 1);
signal s_irq_ack : std_logic;
signal s_irq_pending : std_logic;
-- CR/CSR
signal s_cr_csr_addr : std_logic_vector(18 downto 2);
signal s_cr_csr_data_o : std_logic_vector( 7 downto 0);
signal s_cr_csr_data_i : std_logic_vector( 7 downto 0);
signal s_cr_csr_we : std_logic;
signal s_ader : t_ader_array(0 to 7);
signal s_module_reset : std_logic;
signal s_module_enable : std_logic;
signal s_bar : std_logic_vector( 4 downto 0);
signal s_vme_berr_n : std_logic;
signal s_irq_vector : std_logic_vector( 7 downto 0);
signal s_irq_level : std_logic_vector( 2 downto 0);
signal s_user_csr_addr : std_logic_vector(18 downto 2);
signal s_user_csr_data_i : std_logic_vector( 7 downto 0);
signal s_user_csr_data_o : std_logic_vector( 7 downto 0);
signal s_user_csr_we : std_logic;
-- 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_start : std_logic;
signal s_decode_done : std_logic;
signal s_decode_sel : std_logic;
signal s_am : std_logic_vector( 5 downto 0);
-- Oversampled input signals
signal s_VME_RST_n : std_logic;
signal s_VME_AS_n : std_logic;
signal s_VME_WRITE_n : std_logic;
signal s_VME_DS_n : std_logic_vector(1 downto 0);
signal s_VME_IACK_n : std_logic;
signal s_VME_IACKIN_n : std_logic;
-- CR/CSR parameter arrays
-- ADEM array has an extra index (-1) to simplify looping while checking the
-- EFM bit of the previous function.
constant c_ADEM : t_adem_array(0 to 7) := (
g_F0_ADEM, g_F1_ADEM, g_F2_ADEM, g_F3_ADEM,
g_F4_ADEM, g_F5_ADEM, g_F6_ADEM, g_F7_ADEM
);
constant c_AMCAP : t_amcap_array(0 to 7) := (
g_F0_AMCAP, g_F1_AMCAP, g_F2_AMCAP, g_F3_AMCAP,
g_F4_AMCAP, g_F5_AMCAP, g_F6_AMCAP, g_F7_AMCAP
);
constant c_DAWPR : t_dawpr_array(0 to 7) := (
g_F0_DAWPR, g_F1_DAWPR, g_F2_DAWPR, g_F3_DAWPR,
g_F4_DAWPR, g_F5_DAWPR, g_F6_DAWPR, g_F7_DAWPR
);
-- List of supported AM.
constant c_AMCAP_ALLOWED : std_logic_vector(63 downto 0) :=
(16#3c# to 16#3f# => '1', -- A24
16#38# to 16#3b# => '1',
16#2d# | 16#29# => '1', -- A16
16#0c# to 16#0f# => '1', -- A32
16#08# to 16#0b# => '1',
others => '0');
begin begin
-- Check for invalid bits in ADEM/AMCAP inst : entity work.xvme64x_core
gen_gchecks: for i in 7 downto 0 generate
assert c_ADEM(i)(c_ADEM_FAF) = '0' report "FAF bit set in ADEM"
severity failure;
assert c_ADEM(i)(c_ADEM_DFS) = '0' report "DFS bit set in ADEM"
severity failure;
assert c_ADEM(i)(c_ADEM_EFM) = '0' report "EFM bit set in ADEM"
severity failure;
assert (c_AMCAP(i) and c_AMCAP_ALLOWED) = c_AMCAP(i)
report "bit set in AMCAP for not supported AM"
severity failure;
end generate;
------------------------------------------------------------------------------
-- Metastability
------------------------------------------------------------------------------
-- Input oversampling: oversampling the input data is
-- necessary to avoid metastability problems, but of course the transfer rate
-- will be slow down a little.
-- NOTE: the reset value is '0', which means that all signals are active
-- at reset. But not for a long time and so is s_VME_RST_n.
inst_vme_rst_resync: entity work.gc_sync_register
generic map (g_width => 1)
port map (clk_i => clk_i,
rst_n_a_i => rst_n_i,
d_i(0) => VME_RST_n_i,
q_o(0) => s_VME_RST_n);
inst_vme_as_resync: entity work.gc_sync_register
generic map (g_width => 1)
port map (clk_i => clk_i,
rst_n_a_i => rst_n_i,
d_i(0) => VME_AS_n_i,
q_o(0) => s_VME_AS_n);
inst_vme_write_resync: entity work.gc_sync_register
generic map (g_width => 1)
port map (clk_i => clk_i,
rst_n_a_i => rst_n_i,
d_i(0) => VME_WRITE_n_i,
q_o(0) => s_VME_WRITE_n);
inst_vme_ds_resync: entity work.gc_sync_register
generic map (g_width => 2)
port map (clk_i => clk_i,
rst_n_a_i => rst_n_i,
d_i => VME_DS_n_i,
q_o => s_VME_DS_n);
inst_vme_iack_resync: entity work.gc_sync_register
generic map (g_width => 1)
port map (clk_i => clk_i,
rst_n_a_i => rst_n_i,
d_i(0) => VME_IACK_n_i,
q_o(0) => s_VME_IACK_n);
inst_vme_iackin_resync: entity work.gc_sync_register
generic map (g_width => 1)
port map (clk_i => clk_i,
rst_n_a_i => rst_n_i,
d_i(0) => VME_IACKIN_n_i,
q_o(0) => s_VME_IACKIN_n);
------------------------------------------------------------------------------
-- VME Bus
------------------------------------------------------------------------------
inst_vme_bus : entity work.vme_bus
generic map ( generic map (
g_CLOCK_PERIOD => g_CLOCK_PERIOD, g_clock_period => g_clock_period,
g_WB_DATA_WIDTH => g_WB_DATA_WIDTH, g_decode_am => g_decode_am,
g_WB_ADDR_WIDTH => g_WB_ADDR_WIDTH g_user_csr_ext => g_user_csr_ext,
) g_manufacturer_id => g_manufacturer_id,
g_board_id => g_board_id,
g_revision_id => g_revision_id,
g_program_id => g_program_id,
g_ascii_ptr => g_ascii_ptr,
g_beg_user_cr => g_beg_user_cr,
g_end_user_cr => g_end_user_cr,
g_beg_cram => g_beg_cram,
g_end_cram => g_end_cram,
g_beg_user_csr => g_beg_user_csr,
g_end_user_csr => g_end_user_csr,
g_beg_sn => g_beg_sn,
g_end_sn => g_end_sn,
g_nbr_decoders => g_nbr_decoders,
g_decoder(0).adem => g_decoder_0_adem,
g_decoder(0).amcap => g_decoder_0_amcap,
g_decoder(0).dawpr => g_decoder_0_dawpr,
g_decoder(1).adem => g_decoder_1_adem,
g_decoder(1).amcap => g_decoder_1_amcap,
g_decoder(1).dawpr => g_decoder_1_dawpr,
g_decoder(2).adem => g_decoder_2_adem,
g_decoder(2).amcap => g_decoder_2_amcap,
g_decoder(2).dawpr => g_decoder_2_dawpr,
g_decoder(3).adem => g_decoder_3_adem,
g_decoder(3).amcap => g_decoder_3_amcap,
g_decoder(3).dawpr => g_decoder_3_dawpr,
g_decoder(4).adem => g_decoder_4_adem,
g_decoder(4).amcap => g_decoder_4_amcap,
g_decoder(4).dawpr => g_decoder_4_dawpr,
g_decoder(5).adem => g_decoder_5_adem,
g_decoder(5).amcap => g_decoder_5_amcap,
g_decoder(5).dawpr => g_decoder_5_dawpr,
g_decoder(6).adem => g_decoder_6_adem,
g_decoder(6).amcap => g_decoder_6_amcap,
g_decoder(6).dawpr => g_decoder_6_dawpr,
g_decoder(7).adem => g_decoder_7_adem,
g_decoder(7).amcap => g_decoder_7_amcap,
g_decoder(7).dawpr => g_decoder_7_dawpr)
port map ( port map (
clk_i => clk_i, clk_i => clk_i,
rst_i => s_reset, rst_n_i => rst_n_i,
rst_n_o => rst_n_o,
-- VME vme_i.as_n => vme_as_n_i,
VME_AS_n_i => s_VME_AS_n, vme_i.rst_n => vme_rst_n_i,
VME_LWORD_n_o => VME_LWORD_n_o, vme_i.write_n => vme_write_n_i,
VME_LWORD_n_i => VME_LWORD_n_i, vme_i.am => vme_am_i,
VME_RETRY_n_o => VME_RETRY_n_o, vme_i.ds_n => vme_ds_n_i,
VME_RETRY_OE_o => VME_RETRY_OE_o, vme_i.ga => vme_ga_i,
VME_WRITE_n_i => s_VME_WRITE_n, vme_i.lword_n => vme_lword_n_i,
VME_DS_n_i => s_VME_DS_n, vme_i.data => vme_data_i,
VME_DTACK_n_o => VME_DTACK_n_o, vme_i.addr => vme_addr_i,
VME_DTACK_OE_o => VME_DTACK_OE_o, vme_i.iack_n => vme_iack_n_i,
VME_BERR_n_o => s_vme_berr_n, vme_i.iackin_n => vme_iackin_n_i,
VME_ADDR_i => VME_ADDR_i, vme_o.iackout_n => vme_iackout_n_o,
VME_ADDR_o => VME_ADDR_o, vme_o.dtack_n => vme_dtack_n_o,
VME_ADDR_DIR_o => VME_ADDR_DIR_o, vme_o.dtack_oe => vme_dtack_oe_o,
VME_ADDR_OE_N_o => VME_ADDR_OE_N_o, vme_o.lword_n => vme_lword_n_o,
VME_DATA_i => VME_DATA_i, vme_o.data => vme_data_o,
VME_DATA_o => VME_DATA_o, vme_o.data_dir => vme_data_dir_o,
VME_DATA_DIR_o => VME_DATA_DIR_o, vme_o.data_oe_n => vme_data_oe_n_o,
VME_DATA_OE_N_o => VME_DATA_OE_N_o, vme_o.addr => vme_addr_o,
VME_AM_i => VME_AM_i, vme_o.addr_dir => vme_addr_dir_o,
VME_IACKIN_n_i => s_VME_IACKIN_n, vme_o.addr_oe_n => vme_addr_oe_n_o,
VME_IACK_n_i => s_VME_IACK_n, vme_o.retry_n => vme_retry_n_o,
VME_IACKOUT_n_o => VME_IACKOUT_n_o, vme_o.retry_oe => vme_retry_oe_o,
vme_o.berr_n => vme_berr_n_o,
-- WB signals vme_o.irq_n => vme_irq_n_o,
stb_o => STB_o, wb_i.ack => wb_ack_i,
ack_i => ACK_i, wb_i.err => wb_err_i,
dat_o => DAT_o, wb_i.rty => wb_rty_i,
dat_i => DAT_i, wb_i.stall => wb_stall_i,
adr_o => ADR_o, wb_i.int => wb_int_i,
sel_o => SEL_o, wb_i.dat => wb_dat_i,
we_o => WE_o, wb_o.cyc => wb_cyc_o,
cyc_o => CYC_o, wb_o.stb => wb_stb_o,
err_i => ERR_i, wb_o.adr => wb_adr_o,
stall_i => STALL_i, wb_o.sel => wb_sel_o,
wb_o.we => wb_we_o,
-- Function decoder wb_o.dat => wb_dat_o,
addr_decoder_i => s_addr_decoder_o, irq_ack_o => irq_ack_o,
addr_decoder_o => s_addr_decoder_i, irq_level_i => irq_level_i,
decode_start_o => s_decode_start, irq_vector_i => irq_vector_i,
decode_done_i => s_decode_done, user_csr_addr_o => user_csr_addr_o,
am_o => s_am, user_csr_data_i => user_csr_data_i,
decode_sel_i => s_decode_sel, user_csr_data_o => user_csr_data_o,
user_csr_we_o => user_csr_we_o,
-- CR/CSR signals user_cr_addr_o => user_cr_addr_o,
cr_csr_addr_o => s_cr_csr_addr, user_cr_data_i => user_cr_data_i);
cr_csr_data_i => s_cr_csr_data_o, end unwrap;
cr_csr_data_o => s_cr_csr_data_i,
cr_csr_we_o => s_cr_csr_we,
module_enable_i => s_module_enable,
bar_i => s_bar,
INT_Level_i => s_irq_level,
INT_Vector_i => s_irq_vector,
irq_pending_i => s_irq_pending,
irq_ack_o => s_irq_ack
);
s_reset <= (not rst_n_i) or (not s_VME_RST_n);
s_reset_n <= not s_reset;
rst_n_o <= not (s_reset or s_module_reset);
VME_BERR_o <= not s_vme_berr_n; -- The VME_BERR is asserted when '1' because
-- the buffers on the board invert the logic.
inst_vme_funct_match : entity work.vme_funct_match
generic map (
g_ADEM => c_ADEM,
g_AMCAP => c_AMCAP,
g_DECODE_AM => g_DECODE_AM
)
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_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
);
------------------------------------------------------------------------------
-- Output
------------------------------------------------------------------------------
VME_IRQ_o <= not s_VME_IRQ_n_o; -- The buffers will invert again the signal
irq_ack_o <= s_irq_ack;
------------------------------------------------------------------------------
-- Interrupter
------------------------------------------------------------------------------
inst_vme_irq_controller : entity work.vme_irq_controller
generic map (
g_RETRY_TIMEOUT => 1000000 / g_CLOCK_PERIOD -- 1ms timeout
)
port map (
clk_i => clk_i,
reset_n_i => s_reset_n, -- asserted when low
INT_Level_i => s_irq_level,
INT_Req_i => irq_i,
irq_pending_o => s_irq_pending,
irq_ack_i => s_irq_ack,
VME_IRQ_n_o => s_VME_IRQ_n_o
);
------------------------------------------------------------------------------
-- CR/CSR space
------------------------------------------------------------------------------
inst_vme_cr_csr_space : entity work.vme_cr_csr_space
generic map (
g_MANUFACTURER_ID => g_MANUFACTURER_ID,
g_BOARD_ID => g_BOARD_ID,
g_REVISION_ID => g_REVISION_ID,
g_PROGRAM_ID => g_PROGRAM_ID,
g_ASCII_PTR => g_ASCII_PTR,
g_BEG_USER_CR => g_BEG_USER_CR,
g_END_USER_CR => g_END_USER_CR,
g_BEG_CRAM => g_BEG_CRAM,
g_END_CRAM => g_END_CRAM,
g_BEG_USER_CSR => g_BEG_USER_CSR,
g_END_USER_CSR => g_END_USER_CSR,
g_BEG_SN => g_BEG_SN,
g_END_SN => g_END_SN,
g_ADEM => c_ADEM,
g_AMCAP => c_AMCAP,
g_DAWPR => c_DAWPR
)
port map (
clk_i => clk_i,
rst_n_i => s_reset_n,
vme_ga_i => VME_GA_i,
vme_berr_n_i => s_vme_berr_n,
bar_o => s_bar,
vme_sysfail_i => '0',
vme_sysfail_ena_o => open,
module_enable_o => s_module_enable,
module_reset_o => s_module_reset,
addr_i => s_cr_csr_addr,
data_i => s_cr_csr_data_i,
data_o => s_cr_csr_data_o,
we_i => s_cr_csr_we,
user_csr_addr_o => s_user_csr_addr,
user_csr_data_i => s_user_csr_data_i,
user_csr_data_o => s_user_csr_data_o,
user_csr_we_o => s_user_csr_we,
user_cr_addr_o => user_cr_addr_o,
user_cr_data_i => user_cr_data_i,
ader_o => s_ader
);
-- User CSR space
gen_int_user_csr : if g_USER_CSR_EXT = false generate
inst_vme_user_csr : entity work.vme_user_csr
port map (
clk_i => clk_i,
rst_n_i => s_reset_n,
addr_i => s_user_csr_addr,
data_i => s_user_csr_data_o,
data_o => s_user_csr_data_i,
we_i => s_user_csr_we,
irq_vector_o => s_irq_vector,
irq_level_o => s_irq_level
);
end generate;
gen_ext_user_csr : if g_USER_CSR_EXT = true generate
s_user_csr_data_i <= user_csr_data_i;
s_irq_vector <= irq_vector_i;
s_irq_level <= irq_level_i(2 downto 0);
end generate;
user_csr_addr_o <= s_user_csr_addr;
user_csr_data_o <= s_user_csr_data_o;
user_csr_we_o <= s_user_csr_we;
end rtl;
...@@ -128,7 +128,6 @@ package vme64x_pkg is ...@@ -128,7 +128,6 @@ package vme64x_pkg is
am : std_logic_vector(5 downto 0); am : std_logic_vector(5 downto 0);
ds_n : std_logic_vector(1 downto 0); ds_n : std_logic_vector(1 downto 0);
ga : std_logic_vector(5 downto 0); ga : std_logic_vector(5 downto 0);
bbsy_n : std_logic;
lword_n : std_logic; lword_n : std_logic;
data : std_logic_vector(31 downto 0); data : std_logic_vector(31 downto 0);
addr : std_logic_vector(31 downto 1); addr : std_logic_vector(31 downto 1);
...@@ -149,7 +148,7 @@ package vme64x_pkg is ...@@ -149,7 +148,7 @@ package vme64x_pkg is
addr_oe_n : std_logic; addr_oe_n : std_logic;
retry_n : std_logic; retry_n : std_logic;
retry_oe : std_logic; retry_oe : std_logic;
berr : std_logic; berr_n : std_logic;
irq_n : std_logic_vector(6 downto 0); irq_n : std_logic_vector(6 downto 0);
end record; end record;
...@@ -180,14 +179,43 @@ package vme64x_pkg is ...@@ -180,14 +179,43 @@ package vme64x_pkg is
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
component xvme64x_core component xvme64x_core
generic ( generic (
g_CLOCK_PERIOD : integer := -1; -- Clock period (ns). Used for DS synchronization.
g_DECODE_AM : boolean := true; g_CLOCK_PERIOD : integer := -1;
g_USER_CSR_EXT : boolean := false;
-- Consider AM field of ADER to decode addresses. This is what the VME64x
-- standard says. However, for compatibility with previous implementations
-- (or to reduce resources), it is possible for a decoder to allow all AM
-- declared in the AMCAP.
g_DECODE_AM : boolean := true;
-- Use external user CSR
g_USER_CSR_EXT : boolean := false;
-- Manufacturer ID: IEEE OUID
-- e.g. CERN is 0x080030
g_MANUFACTURER_ID : std_logic_vector(23 downto 0); g_MANUFACTURER_ID : std_logic_vector(23 downto 0);
-- Board ID: Per manufacturer, each board shall have an unique ID
-- e.g. SVEC = 408 (CERN IDs: http://cern.ch/boardid)
g_BOARD_ID : std_logic_vector(31 downto 0); g_BOARD_ID : std_logic_vector(31 downto 0);
-- Revision ID: user defined revision code
g_REVISION_ID : std_logic_vector(31 downto 0); g_REVISION_ID : std_logic_vector(31 downto 0);
g_PROGRAM_ID : std_logic_vector(7 downto 0) := c_PROGRAM_ID;
-- Program ID: Defined per VME64:
-- 0x00 = Not used
-- 0x01 = No program, ID ROM only
-- 0x02-0x4F = Manufacturer defined
-- 0x50-0x7F = User defined
-- 0x80-0xEF = Reserved for future use
-- 0xF0-0xFE = Reserved for Boot Firmware (P1275)
-- 0xFF = Not to be used
g_PROGRAM_ID : std_logic_vector( 7 downto 0);
-- Pointer to a user defined ASCII string.
g_ASCII_PTR : std_logic_vector(23 downto 0) := x"000000"; g_ASCII_PTR : std_logic_vector(23 downto 0) := x"000000";
-- User CR/CSR, CRAM & serial number pointers
g_BEG_USER_CR : std_logic_vector(23 downto 0) := x"000000"; g_BEG_USER_CR : std_logic_vector(23 downto 0) := x"000000";
g_END_USER_CR : std_logic_vector(23 downto 0) := x"000000"; g_END_USER_CR : std_logic_vector(23 downto 0) := x"000000";
g_BEG_CRAM : std_logic_vector(23 downto 0) := x"000000"; g_BEG_CRAM : std_logic_vector(23 downto 0) := x"000000";
...@@ -197,126 +225,41 @@ package vme64x_pkg is ...@@ -197,126 +225,41 @@ package vme64x_pkg is
g_BEG_SN : std_logic_vector(23 downto 0) := x"000000"; g_BEG_SN : std_logic_vector(23 downto 0) := x"000000";
g_END_SN : std_logic_vector(23 downto 0) := x"000000"; g_END_SN : std_logic_vector(23 downto 0) := x"000000";
g_nbr_decoders : natural range 1 to 8 := 2; -- Number of function decoder implemented and decoder parameters.
g_address_decoder : t_vme64x_decoder_arr := c_vme64x_decoders_default); g_NBR_DECODERS : natural range 1 to 8 := 2;
g_DECODER : t_vme64x_decoder_arr := c_vme64x_decoders_default);
port ( port (
-- Main clock and reset.
clk_i : in std_logic; clk_i : in std_logic;
rst_n_i : in std_logic; rst_n_i : in std_logic;
-- Reset for wishbone core.
rst_n_o : out std_logic; rst_n_o : out std_logic;
-- VME slave interface.
vme_i : in t_vme64x_in; vme_i : in t_vme64x_in;
vme_o : in t_vme64x_out; vme_o : out t_vme64x_out;
wb_o : out t_wishbone_master_out; -- Wishbone interface.
wb_i : in t_wishbone_master_in; wb_i : in t_wishbone_master_in;
wb_o : out t_wishbone_master_out;
irq_i : in std_logic; -- When the IRQ controller acknowledges the Interrupt cycle it sends a
-- pulse to the IRQ Generator.
irq_ack_o : out std_logic; irq_ack_o : out std_logic;
irq_level_i : in std_logic_vector( 7 downto 0) := (others => '0');
irq_vector_i : in std_logic_vector( 7 downto 0) := (others => '0');
endian_i : in std_logic_vector( 2 downto 0) := (others => '0');
user_csr_addr_o : out std_logic_vector(18 downto 2);
user_csr_data_i : in std_logic_vector( 7 downto 0) := (others => '0');
user_csr_data_o : out std_logic_vector( 7 downto 0);
user_csr_we_o : out std_logic;
user_cr_addr_o : out std_logic_vector(18 downto 2);
user_cr_data_i : in std_logic_vector( 7 downto 0) := (others => '0')
);
end component xvme64x_core;
component vme64x_core -- User CSR
generic ( -- The following signals are used when g_USER_CSR_EXT = true
g_CLOCK_PERIOD : integer := -1; -- otherwise they are connected to the internal user CSR.
g_DECODE_AM : boolean := true;
g_USER_CSR_EXT : boolean := false;
g_MANUFACTURER_ID : std_logic_vector(23 downto 0);
g_BOARD_ID : std_logic_vector(31 downto 0);
g_REVISION_ID : std_logic_vector(31 downto 0);
g_PROGRAM_ID : std_logic_vector( 7 downto 0) := c_PROGRAM_ID;
g_ASCII_PTR : std_logic_vector(23 downto 0) := x"000000";
g_BEG_USER_CR : std_logic_vector(23 downto 0) := x"000000";
g_END_USER_CR : std_logic_vector(23 downto 0) := x"000000";
g_BEG_CRAM : std_logic_vector(23 downto 0) := x"000000";
g_END_CRAM : std_logic_vector(23 downto 0) := x"000000";
g_BEG_USER_CSR : std_logic_vector(23 downto 0) := x"07ff33";
g_END_USER_CSR : std_logic_vector(23 downto 0) := x"07ff5f";
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_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"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";
g_F2_DAWPR : std_logic_vector( 7 downto 0) := x"84";
g_F3_ADEM : std_logic_vector(31 downto 0) := x"00000000";
g_F3_AMCAP : std_logic_vector(63 downto 0) := x"00000000_00000000";
g_F3_DAWPR : std_logic_vector( 7 downto 0) := x"84";
g_F4_ADEM : std_logic_vector(31 downto 0) := x"00000000";
g_F4_AMCAP : std_logic_vector(63 downto 0) := x"00000000_00000000";
g_F4_DAWPR : std_logic_vector( 7 downto 0) := x"84";
g_F5_ADEM : std_logic_vector(31 downto 0) := x"00000000";
g_F5_AMCAP : std_logic_vector(63 downto 0) := x"00000000_00000000";
g_F5_DAWPR : std_logic_vector( 7 downto 0) := x"84";
g_F6_ADEM : std_logic_vector(31 downto 0) := x"00000000";
g_F6_AMCAP : std_logic_vector(63 downto 0) := x"00000000_00000000";
g_F6_DAWPR : std_logic_vector( 7 downto 0) := x"84";
g_F7_ADEM : std_logic_vector(31 downto 0) := x"00000000";
g_F7_AMCAP : std_logic_vector(63 downto 0) := x"00000000_00000000";
g_F7_DAWPR : std_logic_vector( 7 downto 0) := x"84"
);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
rst_n_o : out std_logic;
VME_AS_n_i : in std_logic;
VME_RST_n_i : in std_logic;
VME_WRITE_n_i : in std_logic;
VME_AM_i : in std_logic_vector(5 downto 0);
VME_DS_n_i : in std_logic_vector(1 downto 0);
VME_GA_i : in std_logic_vector(5 downto 0);
VME_BERR_o : out std_logic;
VME_DTACK_n_o : out std_logic;
VME_RETRY_n_o : out std_logic;
VME_LWORD_n_i : in std_logic;
VME_LWORD_n_o : out std_logic;
VME_ADDR_i : in std_logic_vector(31 downto 1);
VME_ADDR_o : out std_logic_vector(31 downto 1);
VME_DATA_i : in std_logic_vector(31 downto 0);
VME_DATA_o : out std_logic_vector(31 downto 0);
VME_IRQ_o : out std_logic_vector( 7 downto 1);
VME_IACKIN_n_i : in std_logic;
VME_IACK_n_i : in std_logic;
VME_IACKOUT_n_o : out std_logic;
VME_DTACK_OE_o : out std_logic;
VME_DATA_DIR_o : out std_logic;
VME_DATA_OE_N_o : out std_logic;
VME_ADDR_DIR_o : out std_logic;
VME_ADDR_OE_N_o : out std_logic;
VME_RETRY_OE_o : out std_logic;
DAT_i : in std_logic_vector(31 downto 0);
DAT_o : out std_logic_vector(31 downto 0);
ADR_o : out std_logic_vector(31 downto 0);
CYC_o : out std_logic;
ERR_i : in std_logic;
SEL_o : out std_logic_vector(3 downto 0);
STB_o : out std_logic;
ACK_i : in std_logic;
WE_o : out std_logic;
STALL_i : in std_logic;
irq_level_i : in std_logic_vector( 7 downto 0) := (others => '0'); irq_level_i : in std_logic_vector( 7 downto 0) := (others => '0');
irq_vector_i : in std_logic_vector( 7 downto 0) := (others => '0'); irq_vector_i : in std_logic_vector( 7 downto 0) := (others => '0');
user_csr_addr_o : out std_logic_vector(18 downto 2); user_csr_addr_o : out std_logic_vector(18 downto 2);
user_csr_data_i : in std_logic_vector( 7 downto 0) := (others => '0'); user_csr_data_i : in std_logic_vector( 7 downto 0) := (others => '0');
user_csr_data_o : out std_logic_vector( 7 downto 0); user_csr_data_o : out std_logic_vector( 7 downto 0);
user_csr_we_o : out std_logic; user_csr_we_o : out std_logic;
-- User CR
user_cr_addr_o : out std_logic_vector(18 downto 2); user_cr_addr_o : out std_logic_vector(18 downto 2);
user_cr_data_i : in std_logic_vector( 7 downto 0) := (others => '0'); user_cr_data_i : in std_logic_vector( 7 downto 0) := (others => '0'));
irq_ack_o : out std_logic; end component xvme64x_core;
irq_i : in std_logic
);
end component;
end vme64x_pkg; end vme64x_pkg;
...@@ -69,9 +69,7 @@ use work.vme64x_pkg.all; ...@@ -69,9 +69,7 @@ use work.vme64x_pkg.all;
entity vme_bus is entity vme_bus is
generic ( generic (
g_CLOCK_PERIOD : integer; g_CLOCK_PERIOD : integer
g_WB_DATA_WIDTH : integer;
g_WB_ADDR_WIDTH : integer
); );
port ( port (
clk_i : in std_logic; clk_i : in std_logic;
...@@ -104,9 +102,9 @@ entity vme_bus is ...@@ -104,9 +102,9 @@ entity vme_bus is
-- WB signals -- WB signals
stb_o : out std_logic; stb_o : out std_logic;
ack_i : in std_logic; ack_i : in std_logic;
dat_o : out std_logic_vector(g_WB_DATA_WIDTH-1 downto 0); dat_o : out std_logic_vector(31 downto 0);
dat_i : in std_logic_vector(g_WB_DATA_WIDTH-1 downto 0); dat_i : in std_logic_vector(31 downto 0);
adr_o : out std_logic_vector(g_WB_ADDR_WIDTH-1 downto 0); adr_o : out std_logic_vector(31 downto 0);
sel_o : out std_logic_vector(3 downto 0); sel_o : out std_logic_vector(3 downto 0);
we_o : out std_logic; we_o : out std_logic;
cyc_o : out std_logic; cyc_o : out std_logic;
...@@ -241,10 +239,6 @@ architecture rtl of vme_bus is ...@@ -241,10 +239,6 @@ architecture rtl of vme_bus is
signal s_DS_latch_count : unsigned (2 downto 0); signal s_DS_latch_count : unsigned (2 downto 0);
begin begin
-- Consistency check.
assert g_WB_DATA_WIDTH = 32 report "g_WB_DATA_WIDTH must be set to 32"
severity failure;
-- These output signals are connected to the buffers on the board -- These output signals are connected to the buffers on the board
-- SN74VMEH22501A Function table: (A is fpga, B is VME connector) -- SN74VMEH22501A Function table: (A is fpga, B is VME connector)
-- OEn | DIR | OUTPUT OEAB | OEBYn | OUTPUT -- OEn | DIR | OUTPUT OEAB | OEBYn | OUTPUT
......
...@@ -8,7 +8,83 @@ ...@@ -8,7 +8,83 @@
-- --
-- author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch> -- author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
-- --
-- description: Wrapped VME64x Core -- description:
--
-- This core implements an interface to transfer data between the VMEbus and
-- the WBbus. This core is a Slave in the VME side and Master in the WB side.
--
-- The main blocks:
--
-- _______________________vme64x_core_______________________
-- | ________________ ________ ___________________ |
-- |___ | | | | | | |
-- | | | VME Bus | | Funct | | | |
-- | | | | | Match | | VME to WB FIFO | |
-- | S | | | | | | | (not implemented) | |
-- V | A | | VME | WB | |________| | | | W
-- M | M | | slave | master | ________ | | | B
-- E | P | | | | | | | | |
-- | L | | | | | CR/CSR | | | | B
-- B | I | | | | | Space | |___________________| | U
-- U | N | | | |________| ___________________ | S
-- S | G | | | ________ | | |
-- | | | | | | | IRQ Controller | |
-- |___| | | | User | | | |
-- | | | | CSR | | | |
-- | |________________| |________| |___________________| |
-- |_________________________________________________________|
--
-- This core complies with the VME64x specifications and allows "plug and
-- play" configuration of VME crates.
-- The base address is setted by the Geographical lines.
-- The base address can't be setted by hand with the switches on the board.
-- If the core is used in an old VME system without GA lines, the core should
-- be provided with a logic that detects if GA = "11111" and if it is the base
-- address of the module, this logic should derive the GA from the switches on
-- the board.
-- All the VMEbus's asynchronous signals must be sampled 2 or 3 times to avoid
-- metastability problem.
-- All the output signals on the WB bus are registered.
-- The Input signals from the WB bus aren't registered indeed the WB is a
-- synchronous protocol and some registers in the WB side will introduce a
-- delay that make impossible reproduce the WB PIPELINED protocol.
-- The WB Slave application must work with the same frequency as this vme64x
-- core.
-- The main component of this core is the VME_bus on the left in the block
-- diagram. Inside this component you can find the main finite state machine
-- that coordinates all the synchronisms.
-- The WB protocol is more faster than the VME protocol so to make independent
-- the two protocols a FIFO memory can be introduced.
-- The FIFO is necessary only during 2eSST access mode.
-- During the block transfer without FIFO the VME_bus accesses directly the Wb
-- bus in Single pipelined read/write mode. If this is the only Wb master this
-- solution is better than the solution with FIFO.
-- In this base version of the core the FIFO is not implemented indeed the 2e
-- access modes aren't supported yet.
-- A Configuration ROM/Control Status Register (CR/CSR) address space has been
-- introduced. The CR/CSR space can be accessed with the data transfer type
-- D08_3, D16_23, D32.
-- To access the CR/CSR space: AM = 0x2f --> this is A24 addressing type,
-- SINGLE transfer type. Base Address = Slot Number.
-- This interface is provided with an Interrupter. The IRQ Controller receives
-- from the Application (WB bus) an interrupt request and transfers this
-- interrupt request on the VMEbus. This component acts also during the
-- Interrupt acknowledge cycle, sending the status/ID to the Interrupt
-- handler.
-- Interrupt request; the IRQ Generator/your Wb application sends a pulse
-- to the IRQ Controller which asserts one of the IRQ line defined by
-- irq_level_i.
-- Inside each component, a detailed description is provided.
-- Access modes supported:
-- http://www.ohwr.org/projects/vme64x-core/repository/changes/trunk/
-- documentation/user_guides/VME_access_modes.pdf
--
-- standards:
--
-- * VMEbus ANSI/IEEE Std 1014-1987
-- * VME64 ANSI/VITA 1-1994
-- * VME64x Extensions ANSI/VITA 1.1-1997
-- * VME 2eSST ANSI/VITA 1.5-2003
-- --
-- dependencies: -- dependencies:
-- --
...@@ -25,10 +101,6 @@ ...@@ -25,10 +101,6 @@
-- received a copy of the GNU Lesser General Public License along with this -- received a copy of the GNU Lesser General Public License along with this
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html -- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- last changes: see log.
--------------------------------------------------------------------------------
-- TODO: -
--------------------------------------------------------------------------------
library ieee; library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_1164.all;
...@@ -36,60 +108,410 @@ use work.wishbone_pkg.all; ...@@ -36,60 +108,410 @@ use work.wishbone_pkg.all;
use work.vme64x_pkg.all; use work.vme64x_pkg.all;
entity xvme64x_core is entity xvme64x_core is
generic ( generic (
g_CLOCK_PERIOD : integer := -1; -- Clock period (ns). Used for DS synchronization.
g_DECODE_AM : boolean := true; g_CLOCK_PERIOD : integer := -1;
g_USER_CSR_EXT : boolean := false;
-- Consider AM field of ADER to decode addresses. This is what the VME64x
g_MANUFACTURER_ID : std_logic_vector(23 downto 0); -- standard says. However, for compatibility with previous implementations
g_BOARD_ID : std_logic_vector(31 downto 0); -- (or to reduce resources), it is possible for a decoder to allow all AM
g_REVISION_ID : std_logic_vector(31 downto 0); -- declared in the AMCAP.
g_PROGRAM_ID : std_logic_vector( 7 downto 0) := c_PROGRAM_ID; g_DECODE_AM : boolean := true;
g_ASCII_PTR : std_logic_vector(23 downto 0) := x"000000";
g_BEG_USER_CR : std_logic_vector(23 downto 0) := x"000000"; -- Use external user CSR
g_END_USER_CR : std_logic_vector(23 downto 0) := x"000000"; g_USER_CSR_EXT : boolean := false;
g_BEG_CRAM : std_logic_vector(23 downto 0) := x"000000";
g_END_CRAM : std_logic_vector(23 downto 0) := x"000000"; -- Manufacturer ID: IEEE OUID
g_BEG_USER_CSR : std_logic_vector(23 downto 0) := x"07ff33"; -- e.g. CERN is 0x080030
g_END_USER_CSR : std_logic_vector(23 downto 0) := x"07ff5f"; g_MANUFACTURER_ID : std_logic_vector(23 downto 0);
g_BEG_SN : std_logic_vector(23 downto 0) := x"000000";
g_END_SN : std_logic_vector(23 downto 0) := x"000000"; -- Board ID: Per manufacturer, each board shall have an unique ID
-- e.g. SVEC = 408 (CERN IDs: http://cern.ch/boardid)
g_nbr_decoders : natural range 1 to 8 := 2; g_BOARD_ID : std_logic_vector(31 downto 0);
g_address_decoder : t_vme64x_decoder_arr := c_vme64x_decoders_default);
port ( -- Revision ID: user defined revision code
clk_i : in std_logic; g_REVISION_ID : std_logic_vector(31 downto 0);
rst_n_i : in std_logic;
rst_n_o : out std_logic; -- Program ID: Defined per VME64:
-- 0x00 = Not used
vme_i : in t_vme64x_in; -- 0x01 = No program, ID ROM only
vme_o : in t_vme64x_out; -- 0x02-0x4F = Manufacturer defined
-- 0x50-0x7F = User defined
wb_o : out t_wishbone_master_out; -- 0x80-0xEF = Reserved for future use
wb_i : in t_wishbone_master_in; -- 0xF0-0xFE = Reserved for Boot Firmware (P1275)
-- 0xFF = Not to be used
irq_i : in std_logic; g_PROGRAM_ID : std_logic_vector( 7 downto 0);
irq_ack_o : out std_logic;
irq_level_i : in std_logic_vector( 7 downto 0) := (others => '0'); -- Pointer to a user defined ASCII string.
irq_vector_i : in std_logic_vector( 7 downto 0) := (others => '0'); g_ASCII_PTR : std_logic_vector(23 downto 0) := x"000000";
endian_i : in std_logic_vector( 2 downto 0) := (others => '0');
user_csr_addr_o : out std_logic_vector(18 downto 2); -- User CR/CSR, CRAM & serial number pointers
user_csr_data_i : in std_logic_vector( 7 downto 0) := (others => '0'); g_BEG_USER_CR : std_logic_vector(23 downto 0) := x"000000";
user_csr_data_o : out std_logic_vector( 7 downto 0); g_END_USER_CR : std_logic_vector(23 downto 0) := x"000000";
user_csr_we_o : out std_logic; g_BEG_CRAM : std_logic_vector(23 downto 0) := x"000000";
user_cr_addr_o : out std_logic_vector(18 downto 2); g_END_CRAM : std_logic_vector(23 downto 0) := x"000000";
user_cr_data_i : in std_logic_vector( 7 downto 0) := (others => '0') g_BEG_USER_CSR : std_logic_vector(23 downto 0) := x"07ff33";
); g_END_USER_CSR : std_logic_vector(23 downto 0) := x"07ff5f";
g_BEG_SN : std_logic_vector(23 downto 0) := x"000000";
g_END_SN : std_logic_vector(23 downto 0) := x"000000";
-- Number of function decoder implemented and decoder parameters.
g_NBR_DECODERS : natural range 1 to 8 := 2;
g_DECODER : t_vme64x_decoder_arr := c_vme64x_decoders_default);
port (
-- Main clock and reset.
clk_i : in std_logic;
rst_n_i : in std_logic;
-- Reset for wishbone core.
rst_n_o : out std_logic;
-- VME slave interface.
vme_i : in t_vme64x_in;
vme_o : out t_vme64x_out;
-- Wishbone interface.
wb_i : in t_wishbone_master_in;
wb_o : out t_wishbone_master_out;
-- When the IRQ controller acknowledges the Interrupt cycle it sends a
-- pulse to the IRQ Generator.
irq_ack_o : out std_logic;
-- User CSR
-- The following signals are used when g_USER_CSR_EXT = true
-- otherwise they are connected to the internal user CSR.
irq_level_i : in std_logic_vector( 7 downto 0) := (others => '0');
irq_vector_i : in std_logic_vector( 7 downto 0) := (others => '0');
user_csr_addr_o : out std_logic_vector(18 downto 2);
user_csr_data_i : in std_logic_vector( 7 downto 0) := (others => '0');
user_csr_data_o : out std_logic_vector( 7 downto 0);
user_csr_we_o : out std_logic;
-- User CR
user_cr_addr_o : out std_logic_vector(18 downto 2);
user_cr_data_i : in std_logic_vector( 7 downto 0) := (others => '0'));
end xvme64x_core; end xvme64x_core;
architecture wrapper of xvme64x_core is architecture rtl of xvme64x_core is
signal s_reset : std_logic;
signal s_reset_n : std_logic;
signal s_VME_IRQ_n_o : std_logic_vector( 7 downto 1);
signal s_irq_ack : std_logic;
signal s_irq_pending : std_logic;
-- CR/CSR
signal s_cr_csr_addr : std_logic_vector(18 downto 2);
signal s_cr_csr_data_o : std_logic_vector( 7 downto 0);
signal s_cr_csr_data_i : std_logic_vector( 7 downto 0);
signal s_cr_csr_we : std_logic;
signal s_ader : t_ader_array(0 to 7);
signal s_module_reset : std_logic;
signal s_module_enable : std_logic;
signal s_bar : std_logic_vector( 4 downto 0);
signal s_vme_berr_n : std_logic;
signal s_irq_vector : std_logic_vector( 7 downto 0);
signal s_irq_level : std_logic_vector( 2 downto 0);
signal s_user_csr_addr : std_logic_vector(18 downto 2);
signal s_user_csr_data_i : std_logic_vector( 7 downto 0);
signal s_user_csr_data_o : std_logic_vector( 7 downto 0);
signal s_user_csr_we : std_logic;
-- 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_start : std_logic;
signal s_decode_done : std_logic;
signal s_decode_sel : std_logic;
signal s_am : std_logic_vector( 5 downto 0);
-- Oversampled input signals
signal s_VME_RST_n : std_logic;
signal s_VME_AS_n : std_logic;
signal s_VME_WRITE_n : std_logic;
signal s_VME_DS_n : std_logic_vector(1 downto 0);
signal s_VME_IACK_n : std_logic;
signal s_VME_IACKIN_n : std_logic;
-- CR/CSR parameter arrays
constant c_ADEM : t_adem_array(0 to 7) := (
g_decoder(0).adem, g_decoder(1).adem,
g_decoder(2).adem, g_decoder(3).adem,
g_decoder(4).adem, g_decoder(5).adem,
g_decoder(6).adem, g_decoder(7).adem);
constant c_AMCAP : t_amcap_array(0 to 7) := (
g_decoder(0).amcap, g_decoder(1).amcap,
g_decoder(2).amcap, g_decoder(3).amcap,
g_decoder(4).amcap, g_decoder(5).amcap,
g_decoder(6).amcap, g_decoder(7).amcap);
constant c_DAWPR : t_dawpr_array(0 to 7) := (
g_decoder(0).dawpr, g_decoder(1).dawpr,
g_decoder(2).dawpr, g_decoder(3).dawpr,
g_decoder(4).dawpr, g_decoder(5).dawpr,
g_decoder(6).dawpr, g_decoder(7).dawpr);
-- List of supported AM.
constant c_AMCAP_ALLOWED : std_logic_vector(63 downto 0) :=
(16#3c# to 16#3f# => '1', -- A24
16#38# to 16#3b# => '1',
16#2d# | 16#29# => '1', -- A16
16#0c# to 16#0f# => '1', -- A32
16#08# to 16#0b# => '1',
others => '0');
begin
assert g_CLOCK_PERIOD > 0 report "g_CLOCK_PERIOD generic must be set"
severity failure;
-- Check for invalid bits in ADEM/AMCAP
gen_gchecks: for i in 7 downto 0 generate
assert c_ADEM(i)(c_ADEM_FAF) = '0' report "FAF bit set in ADEM"
severity failure;
assert c_ADEM(i)(c_ADEM_DFS) = '0' report "DFS bit set in ADEM"
severity failure;
assert c_ADEM(i)(c_ADEM_EFM) = '0' report "EFM bit set in ADEM"
severity failure;
assert (c_AMCAP(i) and c_AMCAP_ALLOWED) = c_AMCAP(i)
report "bit set in AMCAP for not supported AM"
severity failure;
end generate;
------------------------------------------------------------------------------
-- Metastability
------------------------------------------------------------------------------
-- Input oversampling: oversampling the input data is
-- necessary to avoid metastability problems, but of course the transfer rate
-- will be slow down a little.
-- NOTE: the reset value is '0', which means that all signals are active
-- at reset. But not for a long time and so is s_VME_RST_n.
inst_vme_rst_resync: entity work.gc_sync_register
generic map (g_width => 1)
port map (clk_i => clk_i,
rst_n_a_i => rst_n_i,
d_i(0) => vme_i.rst_n,
q_o(0) => s_vme_rst_n);
inst_vme_as_resync: entity work.gc_sync_register
generic map (g_width => 1)
port map (clk_i => clk_i,
rst_n_a_i => rst_n_i,
d_i(0) => vme_i.as_n,
q_o(0) => s_vme_as_n);
inst_vme_write_resync: entity work.gc_sync_register
generic map (g_width => 1)
port map (clk_i => clk_i,
rst_n_a_i => rst_n_i,
d_i(0) => vme_i.write_n,
q_o(0) => s_vme_write_n);
inst_vme_ds_resync: entity work.gc_sync_register
generic map (g_width => 2)
port map (clk_i => clk_i,
rst_n_a_i => rst_n_i,
d_i => vme_i.ds_n,
q_o => s_vme_ds_n);
inst_vme_iack_resync: entity work.gc_sync_register
generic map (g_width => 1)
port map (clk_i => clk_i,
rst_n_a_i => rst_n_i,
d_i(0) => vme_i.iack_n,
q_o(0) => s_vme_iack_n);
inst_vme_iackin_resync: entity work.gc_sync_register
generic map (g_width => 1)
port map (clk_i => clk_i,
rst_n_a_i => rst_n_i,
d_i(0) => vme_i.iackin_n,
q_o(0) => s_VME_IACKIN_n);
------------------------------------------------------------------------------
-- VME Bus
------------------------------------------------------------------------------
inst_vme_bus : entity work.vme_bus
generic map (
g_CLOCK_PERIOD => g_CLOCK_PERIOD
)
port map (
clk_i => clk_i,
rst_i => s_reset,
-- VME
VME_AS_n_i => s_VME_AS_n,
VME_LWORD_n_o => vme_o.lword_n,
VME_LWORD_n_i => vme_i.lword_n,
VME_RETRY_n_o => vme_o.retry_n,
VME_RETRY_OE_o => vme_o.retry_oe,
VME_WRITE_n_i => s_VME_WRITE_n,
VME_DS_n_i => s_VME_DS_n,
VME_DTACK_n_o => vme_o.dtack_n,
VME_DTACK_OE_o => vme_o.dtack_oe,
VME_BERR_n_o => s_vme_berr_n,
VME_ADDR_i => vme_i.addr,
VME_ADDR_o => vme_o.addr,
VME_ADDR_DIR_o => vme_o.addr_dir,
VME_ADDR_OE_N_o => vme_o.addr_oe_n,
VME_DATA_i => vme_i.data,
VME_DATA_o => vme_o.data,
VME_DATA_DIR_o => vme_o.data_dir,
VME_DATA_OE_N_o => vme_o.data_oe_n,
VME_AM_i => vme_i.am,
VME_IACKIN_n_i => s_VME_IACKIN_n,
VME_IACK_n_i => s_VME_IACK_n,
VME_IACKOUT_n_o => vme_o.iackout_n,
-- WB signals
stb_o => wb_o.stb,
ack_i => wb_i.ack,
dat_o => wb_o.dat,
dat_i => wb_i.dat,
adr_o => wb_o.adr,
sel_o => wb_o.sel,
we_o => wb_o.we,
cyc_o => wb_o.cyc,
err_i => wb_i.err,
stall_i => wb_i.stall,
-- Function decoder
addr_decoder_i => s_addr_decoder_o,
addr_decoder_o => s_addr_decoder_i,
decode_start_o => s_decode_start,
decode_done_i => s_decode_done,
am_o => s_am,
decode_sel_i => s_decode_sel,
-- CR/CSR signals
cr_csr_addr_o => s_cr_csr_addr,
cr_csr_data_i => s_cr_csr_data_o,
cr_csr_data_o => s_cr_csr_data_i,
cr_csr_we_o => s_cr_csr_we,
module_enable_i => s_module_enable,
bar_i => s_bar,
INT_Level_i => s_irq_level,
INT_Vector_i => s_irq_vector,
irq_pending_i => s_irq_pending,
irq_ack_o => s_irq_ack
);
s_reset <= (not rst_n_i) or (not s_VME_RST_n);
s_reset_n <= not s_reset;
rst_n_o <= not (s_reset or s_module_reset);
vme_o.berr_n <= s_vme_berr_n;
inst_vme_funct_match : entity work.vme_funct_match
generic map (
g_ADEM => c_ADEM,
g_AMCAP => c_AMCAP,
g_DECODE_AM => g_DECODE_AM
)
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_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
);
------------------------------------------------------------------------------
-- Output
------------------------------------------------------------------------------
irq_ack_o <= s_irq_ack;
------------------------------------------------------------------------------
-- Interrupter
------------------------------------------------------------------------------
inst_vme_irq_controller : entity work.vme_irq_controller
generic map (
g_RETRY_TIMEOUT => 1000000 / g_CLOCK_PERIOD -- 1ms timeout
)
port map (
clk_i => clk_i,
reset_n_i => s_reset_n, -- asserted when low
INT_Level_i => s_irq_level,
INT_Req_i => wb_i.int,
irq_pending_o => s_irq_pending,
irq_ack_i => s_irq_ack,
VME_IRQ_n_o => vme_o.irq_n
);
------------------------------------------------------------------------------
-- CR/CSR space
------------------------------------------------------------------------------
inst_vme_cr_csr_space : entity work.vme_cr_csr_space
generic map (
g_MANUFACTURER_ID => g_MANUFACTURER_ID,
g_BOARD_ID => g_BOARD_ID,
g_REVISION_ID => g_REVISION_ID,
g_PROGRAM_ID => g_PROGRAM_ID,
g_ASCII_PTR => g_ASCII_PTR,
g_BEG_USER_CR => g_BEG_USER_CR,
g_END_USER_CR => g_END_USER_CR,
g_BEG_CRAM => g_BEG_CRAM,
g_END_CRAM => g_END_CRAM,
g_BEG_USER_CSR => g_BEG_USER_CSR,
g_END_USER_CSR => g_END_USER_CSR,
g_BEG_SN => g_BEG_SN,
g_END_SN => g_END_SN,
g_ADEM => c_ADEM,
g_AMCAP => c_AMCAP,
g_DAWPR => c_DAWPR
)
port map (
clk_i => clk_i,
rst_n_i => s_reset_n,
vme_ga_i => vme_i.ga,
vme_berr_n_i => s_vme_berr_n,
bar_o => s_bar,
vme_sysfail_i => '0',
vme_sysfail_ena_o => open,
module_enable_o => s_module_enable,
module_reset_o => s_module_reset,
addr_i => s_cr_csr_addr,
data_i => s_cr_csr_data_i,
data_o => s_cr_csr_data_o,
we_i => s_cr_csr_we,
user_csr_addr_o => s_user_csr_addr,
user_csr_data_i => s_user_csr_data_i,
user_csr_data_o => s_user_csr_data_o,
user_csr_we_o => s_user_csr_we,
user_cr_addr_o => user_cr_addr_o,
user_cr_data_i => user_cr_data_i,
ader_o => s_ader
);
signal dat_out, -- User CSR space
dat_in : std_logic_vector(31 downto 0); gen_int_user_csr : if g_USER_CSR_EXT = false generate
signal adr_out : std_logic_vector(31 downto 0); inst_vme_user_csr : entity work.vme_user_csr
port map (
clk_i => clk_i,
rst_n_i => s_reset_n,
addr_i => s_user_csr_addr,
data_i => s_user_csr_data_o,
data_o => s_user_csr_data_i,
we_i => s_user_csr_we,
irq_vector_o => s_irq_vector,
irq_level_o => s_irq_level
);
end generate;
gen_ext_user_csr : if g_USER_CSR_EXT = true generate
s_user_csr_data_i <= user_csr_data_i;
s_irq_vector <= irq_vector_i;
s_irq_level <= irq_level_i(2 downto 0);
end generate;
begin -- wrapper user_csr_addr_o <= s_user_csr_addr;
user_csr_data_o <= s_user_csr_data_o;
user_csr_we_o <= s_user_csr_we;
assert wb_i.rty = '0' report "rty not supported"; assert wb_i.rty = '0' report "rty not supported";
assert endian_i = "000" report "endian_i not supported"; end rtl;
end wrapper;
...@@ -197,10 +197,6 @@ architecture behaviour of top_tb is ...@@ -197,10 +197,6 @@ architecture behaviour of top_tb is
-- Clock -- Clock
constant g_CLOCK_PERIOD : natural := 10; -- in ns constant g_CLOCK_PERIOD : natural := 10; -- in ns
-- WB widths
constant g_WB_DATA_WIDTH : integer := 32;
constant g_WB_ADDR_WIDTH : integer := 32;
-- VME core -- VME core
signal clk_i : std_logic; signal clk_i : std_logic;
signal rst_n_i : std_logic; signal rst_n_i : std_logic;
...@@ -211,7 +207,7 @@ architecture behaviour of top_tb is ...@@ -211,7 +207,7 @@ architecture behaviour of top_tb is
signal VME_AM_i : std_logic_vector(5 downto 0); signal VME_AM_i : std_logic_vector(5 downto 0);
signal VME_DS_n_i : std_logic_vector(1 downto 0); signal VME_DS_n_i : std_logic_vector(1 downto 0);
signal VME_GA_i : std_logic_vector(5 downto 0); signal VME_GA_i : std_logic_vector(5 downto 0);
signal VME_BERR_o : std_logic; signal VME_BERR_n_o : std_logic;
signal VME_DTACK_n_o : std_logic; signal VME_DTACK_n_o : std_logic;
signal VME_RETRY_n_o : std_logic; signal VME_RETRY_n_o : std_logic;
signal VME_LWORD_n_i : std_logic; signal VME_LWORD_n_i : std_logic;
...@@ -220,7 +216,7 @@ architecture behaviour of top_tb is ...@@ -220,7 +216,7 @@ architecture behaviour of top_tb is
signal VME_ADDR_o : std_logic_vector(31 downto 1); signal VME_ADDR_o : std_logic_vector(31 downto 1);
signal VME_DATA_i : std_logic_vector(31 downto 0); signal VME_DATA_i : std_logic_vector(31 downto 0);
signal VME_DATA_o : std_logic_vector(31 downto 0); signal VME_DATA_o : std_logic_vector(31 downto 0);
signal VME_IRQ_o : std_logic_vector(6 downto 0); signal VME_IRQ_n_o : std_logic_vector(6 downto 0);
signal VME_IACKIN_n_i : std_logic; signal VME_IACKIN_n_i : std_logic;
signal VME_IACK_n_i : std_logic; signal VME_IACK_n_i : std_logic;
signal VME_IACKOUT_n_o : std_logic; signal VME_IACKOUT_n_o : std_logic;
...@@ -230,16 +226,17 @@ architecture behaviour of top_tb is ...@@ -230,16 +226,17 @@ architecture behaviour of top_tb is
signal VME_ADDR_DIR_o : std_logic; signal VME_ADDR_DIR_o : std_logic;
signal VME_ADDR_OE_N_o : std_logic; signal VME_ADDR_OE_N_o : std_logic;
signal VME_RETRY_OE_o : std_logic; signal VME_RETRY_OE_o : std_logic;
signal DAT_i : std_logic_vector(g_WB_DATA_WIDTH-1 downto 0); signal DAT_i : std_logic_vector(31 downto 0);
signal DAT_o : std_logic_vector(g_WB_DATA_WIDTH-1 downto 0); signal DAT_o : std_logic_vector(31 downto 0);
signal ADR_o : std_logic_vector(g_WB_ADDR_WIDTH-1 downto 0); signal ADR_o : std_logic_vector(31 downto 0);
signal CYC_o : std_logic; signal CYC_o : std_logic;
signal ERR_i : std_logic; signal ERR_i : std_logic;
signal SEL_o : std_logic_vector(g_WB_DATA_WIDTH / 8 - 1 downto 0); signal SEL_o : std_logic_vector(3 downto 0);
signal STB_o : std_logic; signal STB_o : std_logic;
signal ACK_i : std_logic; signal ACK_i : std_logic;
signal WE_o : std_logic; signal WE_o : std_logic;
signal STALL_i : std_logic; signal STALL_i : std_logic;
signal rty_i : std_logic := '0';
signal irq_level_i : std_logic_vector(7 downto 0) := (others => '0'); signal irq_level_i : std_logic_vector(7 downto 0) := (others => '0');
signal irq_vector_i : std_logic_vector(7 downto 0) := (others => '0'); signal irq_vector_i : std_logic_vector(7 downto 0) := (others => '0');
signal user_csr_addr_o : std_logic_vector(18 downto 2); signal user_csr_addr_o : std_logic_vector(18 downto 2);
...@@ -265,9 +262,49 @@ begin ...@@ -265,9 +262,49 @@ begin
vme64xcore: entity work.vme64x_core vme64xcore: entity work.vme64x_core
generic map (g_CLOCK_PERIOD => g_CLOCK_PERIOD, generic map (g_CLOCK_PERIOD => g_CLOCK_PERIOD,
g_WB_DATA_WIDTH => g_WB_DATA_WIDTH, g_DECODE_AM => (g_SCENARIO /= 9),
g_WB_ADDR_WIDTH => g_WB_ADDR_WIDTH, g_USER_CSR_EXT => false,
g_DECODE_AM => (g_SCENARIO /= 9))
g_MANUFACTURER_ID => c_CERN_ID,
g_BOARD_ID => c_SVEC_ID,
g_REVISION_ID => c_SVEC_REVISION_ID,
g_PROGRAM_ID => c_PROGRAM_ID,
g_ASCII_PTR => x"000000",
g_BEG_USER_CR => x"000000",
g_END_USER_CR => x"000000",
g_BEG_CRAM => x"000000",
g_END_CRAM => x"000000",
g_BEG_USER_CSR => x"07ff33",
g_END_USER_CSR => x"07ff5f",
g_BEG_SN => x"000000",
g_END_SN => x"000000",
g_NBR_DECODERS => 2,
g_decoder_0_adem => x"ff000000",
g_decoder_0_amcap => x"00000000_0000bb00",
g_decoder_0_dawpr => x"84",
g_decoder_1_adem => x"fff80000",
g_decoder_1_amcap => x"bb000000_00000000",
g_decoder_1_dawpr => x"84",
g_decoder_2_adem => x"00000000",
g_decoder_2_amcap => x"00000000_00000000",
g_decoder_2_dawpr => x"84",
g_decoder_3_adem => x"00000000",
g_decoder_3_amcap => x"00000000_00000000",
g_decoder_3_dawpr => x"84",
g_decoder_4_adem => x"00000000",
g_decoder_4_amcap => x"00000000_00000000",
g_decoder_4_dawpr => x"84",
g_decoder_5_adem => x"00000000",
g_decoder_5_amcap => x"00000000_00000000",
g_decoder_5_dawpr => x"84",
g_decoder_6_adem => x"00000000",
g_decoder_6_amcap => x"00000000_00000000",
g_decoder_6_dawpr => x"84",
g_decoder_7_adem => x"00000000",
g_decoder_7_amcap => x"00000000_00000000",
g_decoder_7_dawpr => x"84")
port map ( port map (
clk_i => clk_i, clk_i => clk_i,
rst_n_i => rst_n_i, rst_n_i => rst_n_i,
...@@ -278,7 +315,7 @@ begin ...@@ -278,7 +315,7 @@ begin
VME_AM_i => VME_AM_i, VME_AM_i => VME_AM_i,
VME_DS_n_i => VME_DS_n_i, VME_DS_n_i => VME_DS_n_i,
VME_GA_i => VME_GA_i, VME_GA_i => VME_GA_i,
VME_BERR_o => VME_BERR_o, VME_BERR_n_o => VME_BERR_n_o,
VME_DTACK_n_o => VME_DTACK_n_o, VME_DTACK_n_o => VME_DTACK_n_o,
VME_RETRY_n_o => VME_RETRY_n_o, VME_RETRY_n_o => VME_RETRY_n_o,
VME_LWORD_n_i => VME_LWORD_n_i, VME_LWORD_n_i => VME_LWORD_n_i,
...@@ -287,7 +324,7 @@ begin ...@@ -287,7 +324,7 @@ begin
VME_ADDR_o => VME_ADDR_o, VME_ADDR_o => VME_ADDR_o,
VME_DATA_i => VME_DATA_i, VME_DATA_i => VME_DATA_i,
VME_DATA_o => VME_DATA_o, VME_DATA_o => VME_DATA_o,
VME_IRQ_o => VME_IRQ_o, VME_IRQ_n_o => VME_IRQ_n_o,
VME_IACKIN_n_i => VME_IACKIN_n_i, VME_IACKIN_n_i => VME_IACKIN_n_i,
VME_IACK_n_i => VME_IACK_n_i, VME_IACK_n_i => VME_IACK_n_i,
VME_IACKOUT_n_o => VME_IACKOUT_n_o, VME_IACKOUT_n_o => VME_IACKOUT_n_o,
...@@ -297,16 +334,18 @@ begin ...@@ -297,16 +334,18 @@ begin
VME_ADDR_DIR_o => VME_ADDR_DIR_o, VME_ADDR_DIR_o => VME_ADDR_DIR_o,
VME_ADDR_OE_N_o => VME_ADDR_OE_N_o, VME_ADDR_OE_N_o => VME_ADDR_OE_N_o,
VME_RETRY_OE_o => VME_RETRY_OE_o, VME_RETRY_OE_o => VME_RETRY_OE_o,
DAT_i => DAT_i, wb_DAT_i => DAT_i,
DAT_o => DAT_o, wb_DAT_o => DAT_o,
ADR_o => ADR_o, wb_ADR_o => ADR_o,
CYC_o => CYC_o, wb_CYC_o => CYC_o,
ERR_i => ERR_i, wb_ERR_i => ERR_i,
SEL_o => SEL_o, wb_SEL_o => SEL_o,
STB_o => STB_o, wb_STB_o => STB_o,
ACK_i => ACK_i, wb_ACK_i => ACK_i,
WE_o => WE_o, wb_WE_o => WE_o,
STALL_i => STALL_i, wb_STALL_i => STALL_i,
wb_rty_i => rty_i,
wb_int_i => irq_i,
irq_level_i => irq_level_i, irq_level_i => irq_level_i,
irq_vector_i => irq_vector_i, irq_vector_i => irq_vector_i,
user_csr_addr_o => user_csr_addr_o, user_csr_addr_o => user_csr_addr_o,
...@@ -315,8 +354,7 @@ begin ...@@ -315,8 +354,7 @@ begin
user_csr_we_o => user_csr_we_o, user_csr_we_o => user_csr_we_o,
user_cr_addr_o => user_cr_addr_o, user_cr_addr_o => user_cr_addr_o,
user_cr_data_i => user_cr_data_i, user_cr_data_i => user_cr_data_i,
irq_ack_o => irq_ack_o, irq_ack_o => irq_ack_o);
irq_i => irq_i);
clk_gen: process clk_gen: process
begin begin
...@@ -484,8 +522,8 @@ begin ...@@ -484,8 +522,8 @@ begin
wait for 35 ns; wait for 35 ns;
VME_AS_n_i <= '0'; VME_AS_n_i <= '0';
VME_WRITE_n_i <= '1'; VME_WRITE_n_i <= '1';
if not (VME_DTACK_OE_o = '0' and VME_BERR_o = '0') then if not (VME_DTACK_OE_o = '0' and VME_BERR_n_o = '1') then
wait until VME_DTACK_OE_o = '0' and VME_BERR_o = '0'; wait until VME_DTACK_OE_o = '0' and VME_BERR_n_o = '1';
end if; end if;
end read_setup_addr; end read_setup_addr;
...@@ -632,7 +670,7 @@ begin ...@@ -632,7 +670,7 @@ begin
begin begin
VME_DS_n_i <= "11"; VME_DS_n_i <= "11";
wait until (VME_DTACK_OE_o = '0' or VME_DTACK_n_o = '1') wait until (VME_DTACK_OE_o = '0' or VME_DTACK_n_o = '1')
and VME_BERR_o = '0'; and VME_BERR_n_o = '1';
end read_blt_end_cycle; end read_blt_end_cycle;
procedure read32_blt (addr : std_logic_vector (31 downto 0); procedure read32_blt (addr : std_logic_vector (31 downto 0);
...@@ -718,8 +756,8 @@ begin ...@@ -718,8 +756,8 @@ begin
lword_n : std_logic; lword_n : std_logic;
am : vme_am_t) is am : vme_am_t) is
begin begin
if not (VME_DTACK_OE_o = '0' and VME_BERR_o = '0') then if not (VME_DTACK_OE_o = '0' and VME_BERR_n_o = '1') then
wait until VME_DTACK_OE_o = '0' and VME_BERR_o = '0'; wait until VME_DTACK_OE_o = '0' and VME_BERR_n_o = '1';
end if; end if;
VME_ADDR_i <= addr(31 downto 1); VME_ADDR_i <= addr(31 downto 1);
VME_AM_i <= am; VME_AM_i <= am;
...@@ -851,13 +889,13 @@ begin ...@@ -851,13 +889,13 @@ begin
procedure ack_int (vec : out byte_t) is procedure ack_int (vec : out byte_t) is
begin begin
if VME_IRQ_o = "0000000" then if VME_IRQ_n_o = "1111111" then
vec := (others => 'X'); vec := (others => 'X');
return; return;
end if; end if;
for i in 6 downto 0 loop for i in 6 downto 0 loop
if VME_IRQ_o (i) = '1' then if VME_IRQ_n_o (i) = '0' then
VME_ADDR_i (3 downto 1) <= std_logic_vector (to_unsigned (i + 1, 3)); VME_ADDR_i (3 downto 1) <= std_logic_vector (to_unsigned (i + 1, 3));
exit; exit;
end if; end if;
...@@ -866,8 +904,8 @@ begin ...@@ -866,8 +904,8 @@ begin
VME_WRITE_n_i <= '1'; VME_WRITE_n_i <= '1';
wait for 35 ns; wait for 35 ns;
VME_AS_n_i <= '0'; VME_AS_n_i <= '0';
if not (VME_DTACK_OE_o = '0' and VME_BERR_o = '0') then if not (VME_DTACK_OE_o = '0' and VME_BERR_n_o = '1') then
wait until VME_DTACK_OE_o = '0' and VME_BERR_o = '0'; wait until VME_DTACK_OE_o = '0' and VME_BERR_n_o = '1';
end if; end if;
VME_DS_n_i <= "10"; VME_DS_n_i <= "10";
...@@ -1127,27 +1165,27 @@ begin ...@@ -1127,27 +1165,27 @@ begin
write8 (x"67_00_80_03", c_AM_A32, x"02"); write8 (x"67_00_80_03", c_AM_A32, x"02");
wait for 2 * g_CLOCK_PERIOD * 1 ns; wait for 2 * g_CLOCK_PERIOD * 1 ns;
assert VME_IRQ_o = "0000100" report "IRQ incorrectly reported" assert VME_IRQ_n_o = "1111011" report "IRQ incorrectly reported"
severity error; severity error;
ack_int (d8); ack_int (d8);
assert d8 = x"00" report "incorrect vector" severity error; assert d8 = x"00" report "incorrect vector" severity error;
assert VME_IRQ_o = "0000000" report "IRQ not disabled after ack" assert VME_IRQ_n_o = "1111111" report "IRQ not disabled after ack"
severity error; severity error;
-- Set IRQ vector -- Set IRQ vector
write8_conf (x"7_ff5f", x"a3"); write8_conf (x"7_ff5f", x"a3");
write8 (x"67_00_80_03", c_AM_A32, x"20"); write8 (x"67_00_80_03", c_AM_A32, x"20");
assert VME_IRQ_o = "0000000" report "IRQ not expected" assert VME_IRQ_n_o = "1111111" report "IRQ not expected"
severity error; severity error;
wait for 32 * g_CLOCK_PERIOD * 1 ns; wait for 32 * g_CLOCK_PERIOD * 1 ns;
assert VME_IRQ_o = "0000100" report "IRQ incorrectly reported" assert VME_IRQ_n_o = "1111011" report "IRQ incorrectly reported"
severity error; severity error;
ack_int (d8); ack_int (d8);
assert d8 = x"a3" report "incorrect vector" severity error; assert d8 = x"a3" report "incorrect vector" severity error;
assert VME_IRQ_o = "0000000" report "IRQ not disabled after ack" assert VME_IRQ_n_o = "1111111" report "IRQ not disabled after ack"
severity error; severity error;
when 3 => when 3 =>
......
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