Commit af4ec2d0 authored by Tom Levens's avatar Tom Levens

Major cleanup of VHDL code

Signed-off-by: Tom Levens's avatarTom Levens <tom.levens@cern.ch>
parent ae18039d
--_____________________________________________________________________________|
-- VME TO WB INTERFACE |
-- |
-- CERN,BE/CO-HT |
--_____________________________________________________________________________|
-- File: VME64xCore_Top.vhd |
--_____________________________________________________________________________|
-- 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.
--------------------------------------------------------------------------------
-- CERN (BE-CO-HT)
-- VME64x Core
-- http://www.ohwr.org/projects/vme64x-core
--------------------------------------------------------------------------------
--
-- unit name: VME64xCore_Top (VME64xCore_Top.vhd)
--
-- 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:
--
-- ________________________________________________________________
......@@ -29,113 +35,123 @@
-- | | | | CR | | | |
-- | |____________________| |_______| |_________________| |
-- |________________________________________________________________|
-- This core complies with the VME64x specifications and allows "plug and play"
-- configuration of VME crates.
--
-- 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 of
-- a logic that detects if GA = "11111" and if it is the base address of the module
-- should be derived from the switches on the board.
-- If the core is used in an old VME system without GA lines, the core should
-- be provided of a logic that detects if GA = "11111" and if it is the base
-- address of the module should be derived 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 at the same frequency of this vme64x core.
-- The main component is the VME_bus on the left of the block diagram. Inside this component
-- you can find the main finite state machine that coordinates all the synchronisms.
-- 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 at the same frequency of this vme64x
-- core.
-- The main component is the VME_bus on the left of 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.
-- 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.
-- 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 is possible to read a more detailed description.
-- 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
--
-- References:
-- The VMEbus specification ANSI/IEEE STD1014-1987
-- The VME64std ANSI/VITA 1-1994
-- The VME64x ANSI/VITA 1.1-1997
--______________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--______________________________________________________________________________
-- Modifications:
-- 2016-08-24: by Jan Pospisil (j.pospisil@cern.ch)
-- * commented out unused code
-- * added default values for determined start-up state
--______________________________________________________________________________
-- dependencies:
--
--------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
-- 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
--------------------------------------------------------------------------------
-- 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;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.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
generic(
-- clock period (ns)
g_clock : integer := c_clk_period; -- 100 MHz
--WB data width:
g_wb_data_width : integer := c_width; -- must be 32 or 64
--WB address width:
g_wb_addr_width : integer := c_addr_width; -- 64 or less
generic (
g_clock : integer := c_clk_period; -- Clock period (ns)
g_wb_data_width : integer := c_width; -- WB data width: must be 32 or 64
g_wb_addr_width : integer := c_addr_width; -- WB address width: 64 or less
---------------------------------------------------------------------------
-- CR/CSR
---------------------------------------------------------------------------
-- CRAM
g_cram_size : integer := c_CRAM_SIZE;
-- Board ID; each board shall have an unique ID. eg: SVEC_ID = 408.
-- loc: 0x33, 0x37, 0x3B, 0x3F CR space
g_BoardID : integer := c_SVEC_ID; -- 4 bytes: 0x00000198
-- Manufacturer ID: eg the CERN ID is 0x080030
-- loc: 0x27, 0x2B, 0x2F CR space
g_ManufacturerID : integer := c_CERN_ID; -- 3 bytes: 0x080030
-- Revision ID
-- loc: 0x43, 0x47, 0x4B, 0x4F CR space
g_RevisionID : integer := c_RevisionID; -- 4 bytes: 0x00000001
-- Program ID: this is the firmware ID
-- loc: 0x7f CR space
g_ProgramID : integer := 90; -- 1 byte : 0x5a
g_CRAM_Size : integer := c_CRAM_SIZE;
-- Manufacturer ID: IEEE OUID
-- e.g. CERN is 0x080030
g_ManufacturerID : integer := c_CERN_ID;
-- Board ID: Per manufacturer, each board shall have an unique ID
-- e.g. SVEC = 408 (CERN IDs: http://cern.ch/boardid)
g_BoardID : integer := c_SVEC_ID;
-- Revision ID: user defined revision code
g_RevisionID : integer := c_RevisionID;
-- Program ID: Defined per AV1:
-- 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_ProgramID : integer := 90;
-- The default values can be found in the vme64x_pack;
g_adem_a24 : std_logic_vector(31 downto 0) := x"ff800000";
g_adem_a32 : std_logic_vector(31 downto 0) := x"ff000000"
);
port(
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
-- VME
VME_AS_n_i : in std_logic;
VME_RST_n_i : in std_logic; -- asserted when '0'
......@@ -143,9 +159,11 @@ entity VME64xCore_Top is
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; -- [In the VME standard this line is asserted when low.
-- Here is asserted when high indeed the logic will be
-- inverted again in the VME transceivers on the board]*.
VME_BERR_o : out std_logic; -- [In the VME standard this line is
-- asserted when low. Here is asserted
-- when high indeed the logic will be
-- inverted again in the VME transceivers
-- on the board]*.
VME_DTACK_n_o : out std_logic;
VME_RETRY_n_o : out std_logic;
VME_LWORD_n_i : in std_logic;
......@@ -168,32 +186,31 @@ entity VME64xCore_Top is
VME_RETRY_OE_o : out std_logic;
-- WishBone
DAT_i : in std_logic_vector(g_wb_data_width - 1 downto 0);
DAT_o : out std_logic_vector(g_wb_data_width - 1 downto 0);
ADR_o : out std_logic_vector(g_wb_addr_width - 1 downto 0);
DAT_i : in std_logic_vector(g_wb_data_width-1 downto 0);
DAT_o : out std_logic_vector(g_wb_data_width-1 downto 0);
ADR_o : out std_logic_vector(g_wb_addr_width-1 downto 0);
CYC_o : out std_logic;
ERR_i : in std_logic;
RTY_i : in std_logic;
SEL_o : out std_logic_vector(f_div8(g_wb_data_width) - 1 downto 0);
SEL_o : out std_logic_vector(f_div8(g_wb_data_width)-1 downto 0);
STB_o : out std_logic;
ACK_i : in std_logic;
WE_o : out std_logic;
STALL_i : in std_logic;
-- IRQ Generator
INT_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.
INT_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 VME64xCore_Top;
--===========================================================================
-- Architecture declaration
--===========================================================================
architecture RTL of VME64xCore_Top is
impure function f_setup_window_sizes(cr : t_cr_array) return t_cr_array is
......@@ -267,26 +284,27 @@ architecture RTL of VME64xCore_Top is
signal VME_IACKIN_n_oversampled : std_logic;
signal s_reg_1 : std_logic_vector(1 downto 0) := (others => '0');
signal s_reg_2 : std_logic_vector(1 downto 0) := (others => '0');
--===========================================================================
-- Architecture begin
--===========================================================================
begin
---------------------METASTABILITY-----------------------------------------
-- Input oversampling & edge detection; oversampling the input data is necessary to avoid
-- metastability problems. With 3 samples the probability of metastability problem will
-- be very low but of course the transfer rate will be slow down a little.
------------------------------------------------------------------------------
-- Metastability
------------------------------------------------------------------------------
-- Input oversampling & edge detection; oversampling the input data is
-- necessary to avoid metastability problems. With 3 samples the probability
-- of metastability problem will be very low but of course the transfer rate
-- will be slow down a little.
GAinputSample : RegInputSample
generic map(
generic map (
width => 6
)
port map(
port map (
reg_i => VME_GA_i,
reg_o => VME_GA_oversampled,
clk_i => clk_i
);
-- DSinputSample : RegInputSample
RegInputSample : process(clk_i)
begin
if rising_edge(clk_i) then
......@@ -296,57 +314,58 @@ begin
end if;
end process;
-- to avoid timing problem during BLT and MBLT accesses
VME_DS_n_oversampled_1 <= s_reg_2;
VME_DS_n_oversampled_1 <= s_reg_2; -- to avoid timing problem during BLT and
-- MBLT accesses
WRITEinputSample : SigInputSample
port map(
port map (
sig_i => VME_WRITE_n_i,
sig_o => VME_WRITE_n_oversampled,
clk_i => clk_i
);
ASinputSample : SigInputSample
port map(
port map (
sig_i => VME_AS_n_i,
sig_o => VME_AS_n_oversampled,
clk_i => clk_i
);
RSTinputSample : SigInputSample
port map(
port map (
sig_i => VME_RST_n_i,
sig_o => VME_RST_n_oversampled,
clk_i => clk_i
);
IACKinputSample : SigInputSample
port map(
port map (
sig_i => VME_IACK_n_i,
sig_o => VME_IACK_n_oversampled,
clk_i => clk_i
);
IACKINinputSample : SigInputSample
port map(
port map (
sig_i => VME_IACKIN_n_i,
sig_o => VME_IACKIN_n_oversampled,
clk_i => clk_i
);
------------------------------------------------------------------------------
-- VME Bus
------------------------------------------------------------------------------
Inst_VME_bus : VME_bus
generic map(
generic map (
g_clock => g_clock,
g_wb_data_width => g_wb_data_width,
g_wb_addr_width => g_wb_addr_width,
g_cram_size => g_cram_size
)
port map(
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,
VME_AS_n_i => VME_AS_n_oversampled,
......@@ -370,6 +389,7 @@ begin
VME_DATA_OE_N_o => VME_DATA_OE_N_o,
VME_AM_i => VME_AM_i,
VME_IACK_n_i => VME_IACK_n_oversampled,
-- WB
memReq_o => STB_o,
memAckWB_i => ACK_i,
......@@ -382,6 +402,7 @@ begin
err_i => ERR_i,
rty_i => RTY_i,
stall_i => STALL_i,
-- CR/CSR signals
CRAMaddr_o => s_CRAMaddr,
CRAMdata_o => s_CRAMdataIn,
......@@ -409,28 +430,39 @@ begin
BAR_i => s_BAR
);
---------------------------------------------------------------------------------
-- output
VME_IRQ_o <= not s_VME_IRQ_n_o; --The buffers will invert again the logic level
------------------------------------------------------------------------------
-- Output
------------------------------------------------------------------------------
VME_IRQ_o <= not s_VME_IRQ_n_o; -- The buffers will invert again the logic level
WE_o <= not s_RW;
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
s_VME_DATA_IRQ;
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;
--------------------------------------------------------------------------------
-- 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 s_VME_DATA_IRQ;
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
generic map (
g_retry_timeout => 62500 -- 1ms timeout
)
port map(
port map (
clk_i => clk_i,
reset_n_i => s_reset_IRQ, -- asserted when low
VME_IACKIN_n_i => VME_IACKIN_n_oversampled,
......@@ -449,10 +481,12 @@ begin
);
s_reset_IRQ <= not(s_reset);
--------------------------------------------------------------------------
--CR/CSR space
------------------------------------------------------------------------------
-- CR/CSR space
------------------------------------------------------------------------------
Inst_VME_CR_CSR_Space : VME_CR_CSR_Space
generic map(
generic map (
g_cram_size => g_cram_size,
g_wb_data_width => g_wb_data_width,
g_CRspace => f_setup_window_sizes(c_cr_array),
......@@ -461,7 +495,7 @@ begin
g_RevisionID => g_RevisionID,
g_ProgramID => g_ProgramID
)
port map(
port map (
clk_i => clk_i,
reset => s_reset,
CR_addr => s_CRaddr,
......@@ -496,6 +530,3 @@ begin
);
end RTL;
--===========================================================================
-- Architecture end
--===========================================================================
--__________________________________________________________________________________
-- VME TO WB INTERFACE
--------------------------------------------------------------------------------
-- CERN (BE-CO-HT)
-- VME64x Core
-- http://www.ohwr.org/projects/vme64x-core
--------------------------------------------------------------------------------
--
-- CERN,BE/CO-HT
--_________________________________________________________________________________
-- File: VME_Access_Decode.vhd
--_________________________________________________________________________________
-- Description: This component checks if the board is addressed and if it is, allows
-- the access to CR/CSR space by asserting the Confaccess signal, or allows the access
-- to WB bus by asserting the CardSel signal.
-- unit name: VME_Access_Decode (VME_Access_Decode.vhd)
--
-- author: Pablo Alvarez Sanchez <pablo.alvarez.sanchez@cern.ch>
-- Davide Pedretti <davide.pedretti@cern.ch>
--
-- description:
--
-- This component checks if the board is addressed and if it is, allows
-- the access to CR/CSR space by asserting the Confaccess signal, or allows
-- the access to WB bus by asserting the CardSel signal.
--
-- The access to CR/CSR space is possible if:
-- 1) Addr[23:19] = BAR[7:3], (BAR[7:3] = not VME_GA_i), (VME_GA_i = not Slot number)
-- 1) Addr[23:19] = BAR[7:3], (BAR[7:3] = not VME_GA_i = not Slot number)
-- 2) AM = 0x2f
-- 3) The initialization is finished (wait about 8800 ns after power-up or software reset)
-- 3) The initialization is finished (wait about 8800 ns after power-up or
-- software reset)
--
-- To Access the Wb bus we have 7 functions; only one at time can be selected.
-- If one of these functions is selected the CardSel signal is asserted (this
-- is the responding Slave). To access the Wb bus we need to decode the AM and
-- the address lines; so as shown in the block diagram the main components are
-- two: VME_Funct_Match, VME_Am_Match.
--
-- To Access the Wb bus we have 7 functions; only one at time can be selected. If one of
-- these functions is selected the CardSel signal is asserted (this is the responding Slave).
-- To access the Wb bus we need to decode the AM and the address lines; so as shown in
-- the block diagram the main components are two: VME_Funct_Match, VME_Am_Match.
-- ___________________________________________
-- | VME_Access_Decode.vhd |
-- | |
......@@ -35,184 +43,187 @@
-- | |____________| |____________| |
-- | |
-- |___________________________________________|
--
-- Each function has one ADER, one ADEM, one AMCAP and one XAMCAP register.
-- The ADEM, AMCAP, XAMCAP are in the CR memory; the Master can't write these registers
-- The ADER registers are located in the CSR space so the VME master has to write
-- these registers properly after the initialization.
-- The ADEM, AMCAP, XAMCAP are in the CR memory; the Master can't write these
-- registers. The ADER registers are located in the CSR space so the VME
-- master has to write these registers properly after the initialization.
--
-- How to access:
-- ADER[31:0]
-- [31:8] --> compare bits (put here the base address)
--
-- ADER[31:8] --> compare bits (put here the base address)
-- [7:2] --> AM
-- [1] --> '0'
-- [0] --> XAM bit: '0'; '1' only for 2e access mode
--
-- If XAM is '1' it will be:
-- [31:10] --> compare bits (put here the base address)
--
-- ADER[31:10] --> compare bits (put here the base address)
-- [9:2] --> XAM
-- [1] --> '0'
-- [0] --> '1'
-- ADEM[31:0]
-- [31:8] --> mask bits
--
-- ADEM[31:8] --> mask bits
-- [7:4] --> "0000"
-- [3] --> '0' --> The ADER is programmable
-- [2] --> DFS
-- [1] --> '0'
-- [0] --> EFM : '0'
-- EFM = Extra Function Mask: if '1' the next ADEM (and so the next AMCAP, XAMCAP
-- and ADER) provides the upper bit's mask for a 64 bit decoder.
-- [0] --> EFM
--
-- EFM = Extra Function Mask: if '1' the next ADEM (and so the next AMCAP,
-- XAMCAP and ADER) provides the upper bit's mask for a 64 bit decoder.
-- This bit is '1' during A64 and 2e access.
-- DFS = Dynamic Function Decoder: a '1' here means this function can be used
-- to decode different address length (eg. A16 or A24 or A32) so the mask bits
-- should be all '1'.
-- DFS = Dynamic Function Decoder: a '1' here means this function can be
-- used to decode different address length (eg. A16 or A24 or A32) so
-- the mask bits should be all '1'.
--
-- AMCAP[63:0]
-- 6 AM lines --> 2**6 = 64 different configurations
-- This register is 64 bits wide and each bit rappresents one AM configuration.
-- If the bit is '1' it means that the corresponding AM is supported by this function.
-- If the corresponding ADEM's DFS is 0, only the AMCAP's bits with the same address
-- width must be '1'.
-- If the corresponding ADEM's DFS is 1, one or more AMCAP's bits can be '1'
-- eg: "1011101100000000001000100000000100000000000000001011101100000000" this
-- function supports the following access mode:
-- A24_S, A24_BLT, A24_MBLT, A16_S, A32_S, A32_BLT, A32_MBLT supervisor and user
-- access
-- This register is 64 bits wide and each bit rappresents one AM
-- configuration. If the bit is '1' it means that the corresponding AM is
-- supported by this function.
-- If the corresponding ADEM's DFS is 0, only the AMCAP's bits with the
-- same address width must be '1'.
-- If the corresponding ADEM's DFS is 1, one or more AMCAP's bits can be
-- '1'
-- eg: "1011101100000000001000100000000100000000000000001011101100000000"
-- this function supports the following access mode: A24_S, A24_BLT,
-- A24_MBLT, A16_S, A32_S, A32_BLT, A32_MBLT supervisor and user access
--
-- XAMCAP[255:0]
-- 8 XAM lines --> 2**8 = 256 different configurations
-- This register is 256 bits wide and each bit rappresents one XAM configuration.
-- If the bit is '1' it means that the corresponding XAM is supported
-- by this function.
-- This register is used during the decode phase if the XAM bit is asserted (1).
-- Before accessing the board the VME Master must write the ADER registers. Of course for
-- writing properly the ADER the VME Master needs to know the corresponding ADEM and check if
-- EFM or DFS bits are asserted. The VME Master can read also
-- the AMCAP and XAMCAP and check the access mode supported by each function.
-- This register is 256 bits wide and each bit rappresents one XAM
-- configuration. If the bit is '1' it means that the corresponding XAM is
-- supported by this function.
-- This register is used during the decode phase if the XAM bit is
-- asserted (1).
--
-- Before accessing the board the VME Master must write the ADER registers. Of
-- course for writing properly the ADER the VME Master needs to know the
-- corresponding ADEM and check if EFM or DFS bits are asserted. The VME
-- Master can read also the AMCAP and XAMCAP and check the access mode
-- supported by each function.
--
-- eg.1 let's imagine that we want to access different storage device; we can assign
-- one base address and one function at each storage.
-- Now the VME Master has to write the base address of each storage in the corresponding
-- ADER's compare bits and after this operation each function decodes the access to
-- the corresponding storage.
-- eg.2 this example is relative to our application; the vme64x interface has to transfer
-- data from the VMEbus to WB bus and in this core we have only one WB master. We
-- can use the same base address for all the functions because we will access always
-- the same WB master, and use the different functions to access with different mode eg:
-- eg.1 let's imagine that we want to access different storage device; we can
-- assign one base address and one function at each storage.
-- Now the VME Master has to write the base address of each storage in the
-- corresponding ADER's compare bits and after this operation each function
-- decodes the access to the corresponding storage.
-- eg.2 this example is relative to our application; the vme64x interface has
-- to transfer data from the VMEbus to WB bus and in this core we have only
-- one WB master. We can use the same base address for all the functions
-- because we will access always the same WB master, and use the different
-- functions to access with different mode eg:
-- function0 --> A32_S, A32_BLT, A32_MBLT modes
-- function1 --> A24_S, A24_BLT, A24_MBLT modes
-- function2 --> A16 mode
-- function3 and function4 --> A64, A64_BLT, A64_MBLT
-- function5 and function6 --> 2eVME and 2eSST modes
-- Note that if the address is 64 bits wide we need of two ADER and two ADEM to decode the
-- address so we need two functions. (see also EFM bit definition)
-- Of course you can mix these two example and set up one system with more storage devices
-- each with its base address and to assign each storage more than one function to access it
-- with all the access modes.
-- It is also possible extend the number of the functions defining other ADEM, AMCAP, XAMCAP
-- and ADER in the User CR Space and User CSR Space (see the VME_CR_CSR_Space.vhd component)
-- respectively.
-- In the VME_Funct_Match.vhd and VME_Am_Match.vhd components you can find more details
-- about the decode process.
-- Note that if the address is 64 bits wide we need of two ADER and two ADEM
-- to decode the address so we need two functions. (see also EFM
-- bit definition) Of course you can mix these two example and set up one
-- system with more storage devices each with its base address and to assign
-- each storage more than one function to access it with all the access modes.
-- It is also possible extend the number of the functions defining other ADEM,
-- AMCAP, XAMCAP and ADER in the User CR Space and User CSR Space (see the
-- VME_CR_CSR_Space.vhd component) respectively.
-- In the VME_Funct_Match.vhd and VME_Am_Match.vhd components you can find
-- more detailsabout the decode process.
--
-- To access the board both the FunctMatch(i) and AmMatch(i) must be equal to
-- one.
--
-- To access the board both the FunctMatch(i) and AmMatch(i) must be equal to one.
--________________________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--________________________________________________________________________________________
-- dependencies:
--
--------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
--------------------------------------------------------------------------------
-- 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
-----------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- 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: -
--------------------------------------------------------------------------------
use IEEE.NUMERIC_STD.ALL;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.vme64x_pack.all;
--===========================================================================
-- Entity declaration
--===========================================================================
entity VME_Access_Decode is
Port (clk_i : in STD_LOGIC;
reset : in STD_LOGIC;
mainFSMreset : in STD_LOGIC;
decode : in STD_LOGIC;
ModuleEnable : in STD_LOGIC;
InitInProgress : in STD_LOGIC;
Addr : in STD_LOGIC_VECTOR (63 downto 0);
Ader0 : in STD_LOGIC_VECTOR (31 downto 0);
Ader1 : in STD_LOGIC_VECTOR (31 downto 0);
Ader2 : in STD_LOGIC_VECTOR (31 downto 0);
Ader3 : in STD_LOGIC_VECTOR (31 downto 0);
Ader4 : in STD_LOGIC_VECTOR (31 downto 0);
Ader5 : in STD_LOGIC_VECTOR (31 downto 0);
Ader6 : in STD_LOGIC_VECTOR (31 downto 0);
Ader7 : in STD_LOGIC_VECTOR (31 downto 0);
Adem0 : in STD_LOGIC_VECTOR (31 downto 0);
Adem1 : in STD_LOGIC_VECTOR (31 downto 0);
Adem2 : in STD_LOGIC_VECTOR (31 downto 0);
Adem3 : in STD_LOGIC_VECTOR (31 downto 0);
Adem4 : in STD_LOGIC_VECTOR (31 downto 0);
Adem5 : in STD_LOGIC_VECTOR (31 downto 0);
Adem6 : in STD_LOGIC_VECTOR (31 downto 0);
Adem7 : in STD_LOGIC_VECTOR (31 downto 0);
AmCap0 : in STD_LOGIC_VECTOR (63 downto 0);
AmCap1 : in STD_LOGIC_VECTOR (63 downto 0);
AmCap2 : in STD_LOGIC_VECTOR (63 downto 0);
AmCap3 : in STD_LOGIC_VECTOR (63 downto 0);
AmCap4 : in STD_LOGIC_VECTOR (63 downto 0);
AmCap5 : in STD_LOGIC_VECTOR (63 downto 0);
AmCap6 : in STD_LOGIC_VECTOR (63 downto 0);
AmCap7 : in STD_LOGIC_VECTOR (63 downto 0);
XAmCap0 : in STD_LOGIC_VECTOR (255 downto 0);
XAmCap1 : in STD_LOGIC_VECTOR (255 downto 0);
XAmCap2 : in STD_LOGIC_VECTOR (255 downto 0);
XAmCap3 : in STD_LOGIC_VECTOR (255 downto 0);
XAmCap4 : in STD_LOGIC_VECTOR (255 downto 0);
XAmCap5 : in STD_LOGIC_VECTOR (255 downto 0);
XAmCap6 : in STD_LOGIC_VECTOR (255 downto 0);
XAmCap7 : in STD_LOGIC_VECTOR (255 downto 0);
Am : in STD_LOGIC_VECTOR (5 downto 0);
XAm : in STD_LOGIC_VECTOR (7 downto 0);
BAR_i : in STD_LOGIC_VECTOR (4 downto 0);
AddrWidth : in STD_LOGIC_VECTOR (1 downto 0);
Funct_Sel : out STD_LOGIC_VECTOR (7 downto 0);
Base_Addr : out STD_LOGIC_VECTOR (63 downto 0);
port (
clk_i : in std_logic;
reset : in std_logic;
mainFSMreset : in std_logic;
decode : in std_logic;
ModuleEnable : in std_logic;
InitInProgress : in std_logic;
Addr : in std_logic_vector(63 downto 0);
Ader0 : in std_logic_vector(31 downto 0);
Ader1 : in std_logic_vector(31 downto 0);
Ader2 : in std_logic_vector(31 downto 0);
Ader3 : in std_logic_vector(31 downto 0);
Ader4 : in std_logic_vector(31 downto 0);
Ader5 : in std_logic_vector(31 downto 0);
Ader6 : in std_logic_vector(31 downto 0);
Ader7 : in std_logic_vector(31 downto 0);
Adem0 : in std_logic_vector(31 downto 0);
Adem1 : in std_logic_vector(31 downto 0);
Adem2 : in std_logic_vector(31 downto 0);
Adem3 : in std_logic_vector(31 downto 0);
Adem4 : in std_logic_vector(31 downto 0);
Adem5 : in std_logic_vector(31 downto 0);
Adem6 : in std_logic_vector(31 downto 0);
Adem7 : in std_logic_vector(31 downto 0);
AmCap0 : in std_logic_vector(63 downto 0);
AmCap1 : in std_logic_vector(63 downto 0);
AmCap2 : in std_logic_vector(63 downto 0);
AmCap3 : in std_logic_vector(63 downto 0);
AmCap4 : in std_logic_vector(63 downto 0);
AmCap5 : in std_logic_vector(63 downto 0);
AmCap6 : in std_logic_vector(63 downto 0);
AmCap7 : in std_logic_vector(63 downto 0);
XAmCap0 : in std_logic_vector(255 downto 0);
XAmCap1 : in std_logic_vector(255 downto 0);
XAmCap2 : in std_logic_vector(255 downto 0);
XAmCap3 : in std_logic_vector(255 downto 0);
XAmCap4 : in std_logic_vector(255 downto 0);
XAmCap5 : in std_logic_vector(255 downto 0);
XAmCap6 : in std_logic_vector(255 downto 0);
XAmCap7 : in std_logic_vector(255 downto 0);
Am : in std_logic_vector(5 downto 0);
XAm : in std_logic_vector(7 downto 0);
BAR_i : in std_logic_vector(4 downto 0);
AddrWidth : in std_logic_vector(1 downto 0);
Funct_Sel : out std_logic_vector(7 downto 0);
Base_Addr : out std_logic_vector(63 downto 0);
Confaccess : out std_logic;
CardSel : out std_logic
);
end VME_Access_Decode;
--===========================================================================
-- Architecture declaration
--===========================================================================
architecture Behavioral of VME_Access_Decode is
signal s_Func_Match : std_logic_vector(7 downto 0);
signal s_Am_Match : std_logic_vector(7 downto 0);
signal s_nx_base_addr : std_logic_vector(63 downto 0);
signal s_func_sel : std_logic_vector(7 downto 0);
signal s_DFS : std_logic_vector(7 downto 0);
--===========================================================================
-- Architecture begin
--===========================================================================
begin
Funct_Sel <= s_func_sel;
Inst_Funct_Match: VME_Funct_Match port map(
Inst_Funct_Match: VME_Funct_Match
port map (
clk_i => clk_i,
reset => reset,
decode => decode,
......@@ -240,7 +251,8 @@ begin
Nx_Base_Addr => s_nx_base_addr
);
Inst_Am_Match: VME_Am_Match port map(
Inst_Am_Match: VME_Am_Match
port map (
clk_i => clk_i,
reset => reset,
mainFSMreset => mainFSMreset,
......@@ -275,8 +287,8 @@ begin
AmMatch => s_Am_Match
);
-- Check if the WB application is addressed
process(clk_i)
-- Check if the WB application is addressed
process (clk_i)
begin
if rising_edge(clk_i) then
CardSel <= '0';
......@@ -295,12 +307,8 @@ begin
s_func_sel <= s_Func_Match and s_Am_Match;
-- Check if the CR/CSR space is addressed
-- Check if the CR/CSR space is addressed
Confaccess <= '1' when unsigned(BAR_i) = unsigned(Addr(23 downto 19)) and
Am = c_CR_CSR and InitInProgress = '0' else '0';
end Behavioral;
--===========================================================================
-- Architecture end
--===========================================================================
--_______________________________________________________________________________________
-- VME TO WB INTERFACE
--------------------------------------------------------------------------------
-- CERN (BE-CO-HT)
-- VME64x Core
-- http://www.ohwr.org/projects/vme64x-core
--------------------------------------------------------------------------------
--
-- CERN,BE/CO-HT
--______________________________________________________________________________________
-- File: VME_Am_Match.vhd
--______________________________________________________________________________________
-- Description: this component checks if the AM match.
-- If it is the correspondent AmMatch's bit is asserted. This condition is necessary but
-- not sufficient to select the function and access the board.
-- If DFS = '0' the function supports only access modes with the same address width;
-- unit name: VME_Am_Match (VME_Am_Match.vhd)
--
-- author: Pablo Alvarez Sanchez <pablo.alvarez.sanchez@cern.ch>
-- Davide Pedretti <davide.pedretti@cern.ch>
--
-- description:
--
-- This component checks if the AM match. If it is the correspondent AmMatch's
-- bit is asserted. This condition is necessary but not sufficient to select
-- the function and access the board.
--
-- If DFS = '0' the function supports only access modes with the same address
-- width;
-- 1 function --> only 1 address width;
-- with address width I mean A16, A24, A32 or A64.
-- is sufficient check the AMCAP; AmMatch(i) <= s_FUNC_AMCAP(i)(to_integer(unsigned(Am))).
-- If DFS = '1' the function supports access modes with different address widths so AmMatch(i)
-- is asserted only if ADER[7:2] = AM and s_FUNC_AMCAP(i)(to_integer(unsigned(Am)))='1'.
-- If ADER(i)'s XAM bit is asserted than AmMatch(i) is asserted only if AM = 0x20 and if the
-- XAMCAP(i)(to_integer(unsigned(XAm))) = '1' and if DFS = '1' also ADER[9:2] must be equal
-- to XAM[7:0] lines.
--______________________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--______________________________________________________________________________________
-- is sufficient check the AMCAP;
-- AmMatch(i) <= s_FUNC_AMCAP(i)(to_integer(unsigned(Am))).
--
-- If DFS = '1' the function supports access modes with different address
-- widths so AmMatch(i) is asserted only if ADER[7:2] = AM and
-- s_FUNC_AMCAP(i)(to_integer(unsigned(Am)))='1'.
--
-- If ADER(i)'s XAM bit is asserted than AmMatch(i) is asserted only if
-- AM = 0x20 and if the -- XAMCAP(i)(to_integer(unsigned(XAm))) = '1' and if
-- DFS = '1' also ADER[9:2] must be equal -- to XAM[7:0] lines.
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
--------------------------------------------------------------------------------
-- 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
----------------------------------------------------------------------------------------
-- 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;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.vme64x_pack.all;
--===========================================================================
-- Entity declaration
--===========================================================================
entity VME_Am_Match is
Port ( clk_i : in std_logic;
port (
clk_i : in std_logic;
reset : in std_logic;
mainFSMreset : in std_logic;
Ader0 : in std_logic_vector (31 downto 0);
Ader1 : in std_logic_vector (31 downto 0);
Ader2 : in std_logic_vector (31 downto 0);
Ader3 : in std_logic_vector (31 downto 0);
Ader4 : in std_logic_vector (31 downto 0);
Ader5 : in std_logic_vector (31 downto 0);
Ader6 : in std_logic_vector (31 downto 0);
Ader7 : in std_logic_vector (31 downto 0);
AmCap0 : in std_logic_vector (63 downto 0);
AmCap1 : in std_logic_vector (63 downto 0);
AmCap2 : in std_logic_vector (63 downto 0);
AmCap3 : in std_logic_vector (63 downto 0);
AmCap4 : in std_logic_vector (63 downto 0);
AmCap5 : in std_logic_vector (63 downto 0);
AmCap6 : in std_logic_vector (63 downto 0);
AmCap7 : in std_logic_vector (63 downto 0);
XAmCap0 : in std_logic_vector (255 downto 0);
XAmCap1 : in std_logic_vector (255 downto 0);
XAmCap2 : in std_logic_vector (255 downto 0);
XAmCap3 : in std_logic_vector (255 downto 0);
XAmCap4 : in std_logic_vector (255 downto 0);
XAmCap5 : in std_logic_vector (255 downto 0);
XAmCap6 : in std_logic_vector (255 downto 0);
XAmCap7 : in std_logic_vector (255 downto 0);
Am : in std_logic_vector (5 downto 0);
XAm : in std_logic_vector (7 downto 0);
DFS_i : in std_logic_vector (7 downto 0);
Ader0 : in std_logic_vector(31 downto 0);
Ader1 : in std_logic_vector(31 downto 0);
Ader2 : in std_logic_vector(31 downto 0);
Ader3 : in std_logic_vector(31 downto 0);
Ader4 : in std_logic_vector(31 downto 0);
Ader5 : in std_logic_vector(31 downto 0);
Ader6 : in std_logic_vector(31 downto 0);
Ader7 : in std_logic_vector(31 downto 0);
AmCap0 : in std_logic_vector(63 downto 0);
AmCap1 : in std_logic_vector(63 downto 0);
AmCap2 : in std_logic_vector(63 downto 0);
AmCap3 : in std_logic_vector(63 downto 0);
AmCap4 : in std_logic_vector(63 downto 0);
AmCap5 : in std_logic_vector(63 downto 0);
AmCap6 : in std_logic_vector(63 downto 0);
AmCap7 : in std_logic_vector(63 downto 0);
XAmCap0 : in std_logic_vector(255 downto 0);
XAmCap1 : in std_logic_vector(255 downto 0);
XAmCap2 : in std_logic_vector(255 downto 0);
XAmCap3 : in std_logic_vector(255 downto 0);
XAmCap4 : in std_logic_vector(255 downto 0);
XAmCap5 : in std_logic_vector(255 downto 0);
XAmCap6 : in std_logic_vector(255 downto 0);
XAmCap7 : in std_logic_vector(255 downto 0);
Am : in std_logic_vector(5 downto 0);
XAm : in std_logic_vector(7 downto 0);
DFS_i : in std_logic_vector(7 downto 0);
decode : in std_logic;
AmMatch : out std_logic_vector (7 downto 0));
AmMatch : out std_logic_vector(7 downto 0)
);
end VME_Am_Match;
--===========================================================================
-- Architecture declaration
--===========================================================================
architecture Behavioral of VME_Am_Match is
signal s_FUNC_ADER : t_FUNC_32b_array;
signal s_FUNC_AMCAP : t_FUNC_64b_array;
signal s_FUNC_XAMCAP : t_FUNC_256b_array;
signal s_amcap_match : std_logic_vector(7 downto 0);
signal s_xamcap_match : std_logic_vector(7 downto 0);
--===========================================================================
-- Architecture begin
--===========================================================================
begin
s_FUNC_ADER(0) <= unsigned(Ader0);
......@@ -122,8 +129,7 @@ begin
s_FUNC_XAMCAP(6) <= unsigned(XAmCap6);
s_FUNC_XAMCAP(7) <= unsigned(XAmCap7);
p_AMmatch : process(clk_i)
begin
p_AMmatch: process(clk_i) begin
if rising_edge(clk_i) then
if mainFSMreset = '1' or reset = '1' then
AmMatch <= (others => '0');
......@@ -154,26 +160,21 @@ begin
end if;
end if;
end process;
------------------------------------------------------
-- Check if the AM is in the AMCAP register
process(s_FUNC_AMCAP, Am)
begin
-- Check if the AM is in the AMCAP register
process (s_FUNC_AMCAP, Am) begin
s_amcap_match <= (others => '0');
for i in 0 to 7 loop
s_amcap_match(i) <= s_FUNC_AMCAP(i)(to_integer(unsigned(Am)));
end loop;
end process;
-------------------------------------------------------
-- Check if the XAM is in the XAMCAP register
process(s_FUNC_XAMCAP, XAm)
begin
-- Check if the XAM is in the XAMCAP register
process (s_FUNC_XAMCAP, XAm) begin
s_xamcap_match <= (others => '0');
for i in 0 to 7 loop
s_xamcap_match(i) <= s_FUNC_XAMCAP(i)(to_integer(unsigned(XAm)));
end loop;
end process;
------------------------------------------------------
end Behavioral;
--===========================================================================
-- Architecture end
--===========================================================================
--______________________________________________________________________________|
-- VME TO WB INTERFACE |
-- |
-- CERN,BE/CO-HT |
--______________________________________________________________________________|
-- File: VME_CRAM.vhd |
--______________________________________________________________________________|
-- Description: RAM memory
--______________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--______________________________________________________________________________
--------------------------------------------------------------------------------
-- CERN (BE-CO-HT)
-- VME64x Core
-- http://www.ohwr.org/projects/vme64x-core
--------------------------------------------------------------------------------
--
-- unit name: VME_CRAM (VME_CRAM.vhd)
--
-- author: Pablo Alvarez Sanchez <pablo.alvarez.sanchez@cern.ch>
-- Davide Pedretti <davide.pedretti@cern.ch>
--
-- description: RAM memory
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
-- 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
--------------------------------------------------------------------------------
-- 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;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.vme64x_pack.all;
--===========================================================================
-- Entity declaration
--===========================================================================
entity VME_CRAM is
generic (dl : integer;
entity VME_CRAM is
generic (
dl : integer;
al : integer := f_log2_size(c_CRAM_SIZE)
);
port (clk : in std_logic;
port (
clk : in std_logic;
we : in std_logic;
aw : in std_logic_vector(al - 1 downto 0);
di : in std_logic_vector(dl - 1 downto 0);
dw : out std_logic_vector(dl - 1 downto 0)
aw : in std_logic_vector(al-1 downto 0);
di : in std_logic_vector(dl-1 downto 0);
dw : out std_logic_vector(dl-1 downto 0)
);
end VME_CRAM;
end VME_CRAM;
--===========================================================================
-- Architecture declaration
--===========================================================================
architecture syn of VME_CRAM is
architecture syn of VME_CRAM is
type ram_type is array (2**al - 1 downto 0) of std_logic_vector (dl - 1 downto 0);
type ram_type is array (2**al-1 downto 0) of std_logic_vector (dl-1 downto 0);
signal CRAM : ram_type;
--===========================================================================
-- Architecture begin
--===========================================================================
begin
process (clk)
begin
if (clk'event and clk = '1') then
process (clk) begin
if rising_edge(clk) then
if (we = '1') then
CRAM(conv_integer(aw)) <= di;
CRAM(to_integer(unsigned(aw))) <= di;
end if;
dw <= CRAM(conv_integer(aw));
dw <= CRAM(to_integer(unsigned(aw)));
end if;
end process;
end syn;
--===========================================================================
-- Architecture end
--===========================================================================
end syn;
--________________________________________________________________________________________________
-- VME TO WB INTERFACE
--------------------------------------------------------------------------------
-- CERN (BE-CO-HT)
-- VME64x Core
-- http://www.ohwr.org/projects/vme64x-core
--------------------------------------------------------------------------------
--
-- unit name: VME_CR_CSR_Space (VME_CR_CSR_Space.vhd)
--
-- author: Pablo Alvarez Sanchez <pablo.alvarez.sanchez@cern.ch>
-- Davide Pedretti <davide.pedretti@cern.ch>
--
-- description:
--
-- Please note that only every fourth location in the CR/CSR space is used so
-- it is possible write the CSR/CRAM selecting the data transfer mode
-- D08_Byte3, D16_Byte23, D32. If other data transfer modes are selected the
-- write operation will not be successful. If the Master access the board for
-- a reading operation with data transfer type different than D08_Byte3,
-- D16_Byte23, D32 the data that will be read is 0.
--
-- CERN,BE/CO-HT
--________________________________________________________________________________________________
-- File: VME_CR_CSR_Space.vhd
--________________________________________________________________________________________________
-- Description:
-- Please note that only every fourth location in the CR/CSR space is used so it is possible write
-- the CSR/CRAM selecting the data transfer mode D08_Byte3, D16_Byte23, D32. If other data transfer
-- modes are selected the write operation will not be successful.
-- If the Master access the board for a reading operation with data transfer type different than
-- D08_Byte3, D16_Byte23, D32 the data that will be read is 0.
-- width = 1 byte
-- /---------------------------------/
-- _________________________________
......@@ -31,8 +38,8 @@
-- | |
-- | |
-- | |
-- |_________________________________|0x1000
-- | |0xfff
-- |_________________________________|0x01000
-- | |0x00fff
-- | |
-- | Defined and reserved CR |
-- | |
......@@ -41,92 +48,99 @@
-- | ANSI/VITA 1.1-1997 |
-- | VME64 Extensions |
-- | |
-- |_________________________________| 0x00
-- |_________________________________|0x00000
--
-- If the size of the register is bigger than 1 byte, (eg: ADER is 4 bytes) these bytes are
-- stored in the BIG_ENDIAN ORDER.
-- If the size of the register is bigger than 1 byte, (eg: ADER is 4 bytes)
-- these bytes are stored in the BIG_ENDIAN ORDER.
-- User CR and User CSR are not implemented.
-- In addition to the registers of the table 10-13 in the CSR space you can find:
--
-- In addition to the registers of the table 10-13 in the CSR space you can
-- find:
-- _
-- IRQ_Vector --> 0x7FF5F |--> for the Interrupter
-- IRQ_level --> 0x7FF5B _|
--
-- Endian --> 0x7FF53 --> for the swapper
--
-- WB32bits --> 0x7FF33 --> if the bit 0 is '1' it means that the WB data bus is 32 bit
-- WB32bits --> 0x7FF33 --> if the bit 0 is '1' it means that the WB
-- data bus is 32 bit
-- _
-- TIME0_ns --> 0x7FF4f |
-- TIME1_ns --> 0x7FF4b |
-- TIME2_ns --> 0x7FF47 |
-- TIME3_ns --> 0x7FF43 | --> to calculate the transfer rate
-- TIME3_ns --> 0x7FF43 |--> to calculate the transfer rate
-- TIME4_ns --> 0x7FF3f |
-- BYTES0 --> 0x7FF3b |
-- BYTES1 --> 0x7FF37 _|
--
-- CRAM memory Added. How to use the CRAM: (1KB)
-- 1) The Master read the CRAM_OWNER Register location 0x7fff3; if 0 the CRAM is free
--
-- 1) The Master read the CRAM_OWNER Register location 0x7fff3; if 0 the
-- CRAM is free
-- 2) The Master write his ID in the CRAM_OWNER Register location 0x7fff3
-- 3) If the Master can read his ID in the CRAM_OWNER Register it means that it
-- is the owner of the CRAM.
-- If other Masters write their ID in the CRAM_OWNER Register when it contains a non-zero
-- value, the write operation will not be successful --> this allows the first
-- Master that writes a non-zero value to acquire ownership.
-- 4) When a Master has the ownership of the CRAM the Bit Set Register's bit 2,
-- location 0x7fffb, should be setted.
-- 5) The Master can release the ownership by writing '1' in the bit 2 to the Bit Set
-- Register location 0x7fffb.
-- If other Masters write their ID in the CRAM_OWNER Register when it
-- contains a non-zero value, the write operation will not be successful
-- --> this allows the first Master that writes a non-zero value to
-- acquire ownership.
-- 4) When a Master has the ownership of the CRAM the Bit Set Register's
-- bit 2, location 0x7fffb, should be setted.
-- 5) The Master can release the ownership by writing '1' in the bit 2 to
-- the Bit Set Register location 0x7fffb.
--
-- Other flags:
--
-- Module Enable --> Bit Set Register's bit 4 location 0x7fffb
-- If this bit is '0' the slave module's address decoder is not enable and
-- the Wb bus can't be accessed.
-- If this bit is '0' the slave module's address decoder
-- is not enable and the Wb bus can't be accessed.
-- Error flag --> Bit Set Register's bit 3 location 0x7fffb
-- When the Slave asserts the BERR* line should asserts also this bit.
-- When the Slave asserts the BERR* line should asserts
-- also this bit.
-- CRAM_OWNER flag --> Bit Set Register's bit 2 location 0x7fffb
-- The Master can clear these flags by writing '1' in the corresponding bits to the Bit Clr Register
-- location 0x7fff7.
--
-- The Master can clear these flags by writing '1' in the corresponding bits
-- to the Bit Clr Register location 0x7fff7.
--
-- Software reset --> Bit Set Register's bit 7 location 0x7fffb
-- This bit acts as software reset, indeed if the Master writes '1' here,
-- the module will be resetted and reinitializated.
-- The reset condition is temporary because during the initialization the default
-- configuration is uploaded again, so the Master don't need to remove the
-- module from reset mode by writing '1' in the bit 7 to the Bit Clr Register.
-- This bit acts as software reset, indeed if the Master
-- writes '1' here, the module will be resetted and
-- reinitializated. The reset condition is temporary
-- because during the initialization the default
-- configuration is uploaded again, so the Master don't
-- need to remove the module from reset mode by writing
-- '1' in the bit 7 to the Bit Clr Register.
--
-- dependencies:
--
--______________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--______________________________________________________________________________
-- Modifications:
-- 2016-08-24: by Jan Pospisil (j.pospisil@cern.ch)
-- * commented out unused code
--______________________________________________________________________________
--------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
-- 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
--------------------------------------------------------------------------------
-- 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
---------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
--------------------------------------------------------------------------------
-- last changes: see log.
--------------------------------------------------------------------------------
-- TODO: -
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.vme64x_pack.all;
use work.VME_CR_pack.all;
use work.VME_CSR_pack.all;
--===========================================================================
-- Entity declaration
--===========================================================================
entity VME_CR_CSR_Space is
generic(
generic (
g_cram_size : integer := c_CRAM_SIZE;
g_wb_data_width : integer := c_width;
g_CRspace : t_cr_array := c_cr_array;
......@@ -135,7 +149,8 @@ entity VME_CR_CSR_Space is
g_RevisionID : integer := c_RevisionID; -- 0x00000001
g_ProgramID : integer := 96 -- 0x00000060
);
Port ( -- VMEbus.vhd signals
port (
-- VMEbus.vhd signals
clk_i : in std_logic;
reset : in std_logic;
CR_addr : in std_logic_vector (11 downto 0);
......@@ -171,10 +186,9 @@ entity VME_CR_CSR_Space is
INT_Vector : out std_logic_vector(7 downto 0)
);
end VME_CR_CSR_Space;
--===========================================================================
-- Architecture declaration
--===========================================================================
architecture Behavioral of VME_CR_CSR_Space is
signal s_CSRarray : t_CSRarray; -- Array of CSR registers
signal s_bar_written : std_logic;
signal s_CSRdata : unsigned(7 downto 0);
......@@ -186,32 +200,36 @@ architecture Behavioral of VME_CR_CSR_Space is
signal s_odd_parity : std_logic;
--signal s_BARerror : std_logic;
signal s_BAR_o : std_logic_vector(4 downto 0);
--===========================================================================
-- Architecture begin
--===========================================================================
begin
-- check the parity:
s_odd_parity <= VME_GA_oversampled(5) xor VME_GA_oversampled(4) xor
-- check the parity:
s_odd_parity <= VME_GA_oversampled(5) xor VME_GA_oversampled(4) xor
VME_GA_oversampled(3) xor VME_GA_oversampled(2) xor
VME_GA_oversampled(1) xor VME_GA_oversampled(0);
-- If the crate is not driving the GA lines or the parity is even the BAR register
-- is set to 0x00 and the following flag is asserted; the board will not answer if the
-- master accesses its CR/CSR space and we can see a time out error in the VME bus.
--s_BARerror <= not(s_BAR_o(4) or s_BAR_o(3)or s_BAR_o(2) or s_BAR_o(1) or s_BAR_o(0));
--------------------------------------------------------------------------------
s_CR_Space <= f_set_CR_space(g_BoardID, g_CRspace, g_ManufacturerID, g_RevisionID, g_ProgramID);
-- CR
-- If the crate is not driving the GA lines or the parity is even the BAR
-- register is set to 0x00 and the following flag is asserted; the board will
-- not answer if the master accesses its CR/CSR space and we can see a time
-- out error in the VME bus.
--s_BARerror <= not(s_BAR_o(4) or s_BAR_o(3)or s_BAR_o(2) or s_BAR_o(1) or s_BAR_o(0));
s_CR_Space <= f_set_CR_space(g_BoardID, g_CRspace, g_ManufacturerID, g_RevisionID, g_ProgramID);
-- CR
process(clk_i)
begin
if rising_edge(clk_i) then
CR_data <= s_CR_Space(to_integer(unsigned(CR_addr))); -- c_cr_array(to_integer(unsigned(CR_addr)));
CR_data <= s_CR_Space(to_integer(unsigned(CR_addr)));
end if;
end process;
--------------------------------------------------------------------------------
-- CSR Write
-- CSR Write
s_locDataIn <= unsigned(locDataIn);
s_CrCsrOffsetAderIndex <= s_CrCsrOffsetAddr -
(c_FUNC0_ADER_3_addr(18 downto 0) srl 2) + FUNC0_ADER_3;
(c_FUNC0_ADER_3_addr(18 downto 0) srl 2) +
FUNC0_ADER_3;
p_CSR_Write : process(clk_i)
begin
if rising_edge(clk_i) then
......@@ -294,7 +312,7 @@ s_CR_Space <= f_set_CR_space(g_BoardID, g_CRspace, g_ManufacturerID, g_RevisionI
end if;
reset_flag <= '0';
s_CSRarray(BYTES0) <= unsigned(numBytes(7 downto 0));
s_CSRarray(BYTES1) <= resize(unsigned(numBytes(12 downto 8)),8);
s_CSRarray(BYTES1) <= resize(unsigned(numBytes(12 downto 8)), 8);
s_CSRarray(TIME0_ns) <= unsigned(transfTime(7 downto 0));
s_CSRarray(TIME1_ns) <= unsigned(transfTime(15 downto 8));
s_CSRarray(TIME2_ns) <= unsigned(transfTime(23 downto 16));
......@@ -303,9 +321,9 @@ s_CR_Space <= f_set_CR_space(g_BoardID, g_CRspace, g_ManufacturerID, g_RevisionI
end if;
end if;
end process;
------------------------------------------------------------------------------------------------------------------------------------
--CSR Read
process(s_CSRarray, s_CrCsrOffsetAddr,err_flag)
-- CSR Read
process(s_CSRarray, s_CrCsrOffsetAddr, err_flag)
begin
s_CSRdata <= (others => '0');
case (s_CrCsrOffsetAddr) is
......@@ -315,10 +333,8 @@ s_CR_Space <= f_set_CR_space(g_BoardID, g_CRspace, g_ManufacturerID, g_RevisionI
when "00" & c_BIT_CLR_REG_addr(18 downto 2) => s_CSRdata <= s_CSRarray(
BIT_SET_CLR_REG)(7 downto 4) & err_flag & s_CSRarray(BIT_SET_CLR_REG)(2 downto 0);
when "00" & c_CRAM_OWNER_addr(18 downto 2) => s_CSRdata <= s_CSRarray(CRAM_OWNER);
when "00" & c_USR_BIT_SET_REG_addr(18 downto 2) => s_CSRdata <= s_CSRarray(
USR_BIT_SET_CLR_REG);
when "00" & c_USR_BIT_CLR_REG_addr(18 downto 2) => s_CSRdata <= s_CSRarray(
USR_BIT_SET_CLR_REG);
when "00" & c_USR_BIT_SET_REG_addr(18 downto 2) => s_CSRdata <= s_CSRarray(USR_BIT_SET_CLR_REG);
when "00" & c_USR_BIT_CLR_REG_addr(18 downto 2) => s_CSRdata <= s_CSRarray(USR_BIT_SET_CLR_REG);
when "00" & c_FUNC7_ADER_0_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC7_ADER_0);
when "00" & c_FUNC7_ADER_1_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC7_ADER_1);
when "00" & c_FUNC7_ADER_2_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC7_ADER_2);
......@@ -363,20 +379,21 @@ s_CR_Space <= f_set_CR_space(g_BoardID, g_CRspace, g_ManufacturerID, g_RevisionI
when "00" & c_WB32bits_addr(18 downto 2) => s_CSRdata <= s_CSRarray(WB32bits);
when others => s_CSRdata <= (others => '0');
end case;
end process;
INT_Level <= std_logic_vector(s_CSRarray(IRQ_level));
INT_Vector <= std_logic_vector(s_CSRarray(IRQ_Vector));
CSRdata <= std_logic_vector(s_CSRdata);
s_CrCsrOffsetAddr <= unsigned(CrCsrOffsetAddr);
-- Generate a vector of 8 array (unsigned 32 bits).
-- Generate a vector of 8 array (unsigned 32 bits).
GADER_1 : for i in 0 to 7 generate
GADER_2 : for h in 0 to 3 generate
s_FUNC_ADER(i)(8*(4-h)-1 downto 8*(3-h)) <= s_CSRarray(FUNC0_ADER_3+(h+i*4));
end generate GADER_2;
end generate GADER_1;
-- to the decoder
-- To the decoder
Ader0 <= std_logic_vector(s_FUNC_ADER(0));
Ader1 <= std_logic_vector(s_FUNC_ADER(1));
Ader2 <= std_logic_vector(s_FUNC_ADER(2));
......@@ -390,18 +407,19 @@ s_CR_Space <= f_set_CR_space(g_BoardID, g_CRspace, g_ManufacturerID, g_RevisionI
Sw_Reset <= s_CSRarray(BIT_SET_CLR_REG)(7);
BAR_o <= s_BAR_o;
s_BAR_o <= std_logic_vector(s_CSRarray(BAR)(7 downto 3));
---------------------------------------------------------------------------------------------------------------
-- CRAM:
-- CRAM
CRAM_1 : VME_CRAM
generic map(dl => 8,
generic map (
dl => 8,
al => f_log2_size(g_cram_size)
)
port map(clk => clk_i,
port map (
clk => clk_i,
we => CRAM_Wen,
aw => CRAM_addr,
di => CRAM_data_i,
dw => CRAM_data_o);
dw => CRAM_data_o
);
end Behavioral;
--===========================================================================
-- Architecture end
--===========================================================================
--_______________________________________________________________________________________
-- VME TO WB INTERFACE
--------------------------------------------------------------------------------
-- CERN (BE-CO-HT)
-- VME64x Core
-- http://www.ohwr.org/projects/vme64x-core
--------------------------------------------------------------------------------
--
-- CERN,BE/CO-HT
--______________________________________________________________________________________
-- File: VME_CR_pack.vhd
--______________________________________________________________________________________
-- Description: ROM memory (CR space)
--______________________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 06/2012
-- Version v0.02
--______________________________________________________________________________________
-- unit name: VME_CR_pack (VME_CR_pack.vhd)
--
-- author: Pablo Alvarez Sanchez <pablo.alvarez.sanchez@cern.ch>
-- Davide Pedretti <davide.pedretti@cern.ch>
--
-- description: ROM memory (CR space)
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
--------------------------------------------------------------------------------
-- 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
---------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;
-- 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;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.vme64x_pack.all;
package VME_CR_pack is
-- type t_cr_array is array (natural range <>) of std_logic_vector(7 downto 0);
constant c_amcap : std_logic_vector(63 downto 0) :=
"1111111100000000001100100000000000000000000100001111111100001011";
constant c_amcap0 : std_logic_vector(63 downto 0) :=
"0000000000000000000000000000000000000000000000001011101100000000"; --A32
"0000000000000000000000000000000000000000000000001011101100000000"; -- A32
constant c_amcapMBLT : std_logic_vector(63 downto 0) :=
"0000000000000000000000000000000000000000000000000000000100000000";
constant c_amcap1 : std_logic_vector(63 downto 0) :=
"1011101100000000000000000000000000000000000000000000000000000000"; --A24
"1011101100000000000000000000000000000000000000000000000000000000"; -- A24
constant c_amcap2 : std_logic_vector(63 downto 0) :=
"0000000000000000000000000000000000000000000000000000000000000000"; --disabled
"0000000000000000000000000000000000000000000000000000000000000000"; -- disabled
constant c_amcapA64 : std_logic_vector(63 downto 0) :=
"0000000000000000000000000000000000000000000000000000000000000000"; --
-- disabled
"0000000000000000000000000000000000000000000000000000000000000000"; -- disabled
constant c_amcap2e : std_logic_vector(63 downto 0) :=
"0000000000000000000000000000000000000000000000000000000000000000"; -- disabled
constant c_xamcap0 : std_logic_vector(255 downto 0) :=
(others => '0');
constant c_xamcap2 : std_logic_vector(255 downto 0) :=
x"0000000000000000000000000000000000000000000000000000000000060006";
constant c_amb : t_cr_array(0 to 7) :=(
constant c_amb : t_cr_array(0 to 7) := (
c_amcap(7 downto 0), c_amcap(15 downto 8),
c_amcap(23 downto 16), c_amcap(31 downto 24),
c_amcap(39 downto 32), c_amcap(47 downto 40),
c_amcap(55 downto 48), c_amcap(63 downto 56));
c_amcap(55 downto 48), c_amcap(63 downto 56)
);
constant c_amb0 : t_cr_array(0 to 7) :=(
constant c_amb0 : t_cr_array(0 to 7) := (
c_amcap0(7 downto 0), c_amcap0(15 downto 8),
c_amcap0(23 downto 16), c_amcap0(31 downto 24),
c_amcap0(39 downto 32), c_amcap0(47 downto 40),
c_amcap0(55 downto 48), c_amcap0(63 downto 56));
c_amcap0(55 downto 48), c_amcap0(63 downto 56)
);
constant c_amb1 : t_cr_array(0 to 7) :=(
constant c_amb1 : t_cr_array(0 to 7) := (
c_amcap1(7 downto 0), c_amcap1(15 downto 8),
c_amcap1(23 downto 16), c_amcap1(31 downto 24),
c_amcap1(39 downto 32), c_amcap1(47 downto 40),
c_amcap1(55 downto 48), c_amcap1(63 downto 56));
c_amcap1(55 downto 48), c_amcap1(63 downto 56)
);
constant c_amb2 : t_cr_array(0 to 7) :=(
constant c_amb2 : t_cr_array(0 to 7) := (
c_amcap2(7 downto 0), c_amcap2(15 downto 8),
c_amcap2(23 downto 16), c_amcap2(31 downto 24),
c_amcap2(39 downto 32), c_amcap2(47 downto 40),
c_amcap2(55 downto 48), c_amcap2(63 downto 56));
c_amcap2(55 downto 48), c_amcap2(63 downto 56)
);
constant c_amb2e : t_cr_array(0 to 7) :=(
constant c_amb2e : t_cr_array(0 to 7) := (
c_amcap2e(7 downto 0), c_amcap2e(15 downto 8),
c_amcap2e(23 downto 16), c_amcap2e(31 downto 24),
c_amcap2e(39 downto 32), c_amcap2e(47 downto 40),
c_amcap2e(55 downto 48), c_amcap2e(63 downto 56));
constant c_amb64 : t_cr_array(0 to 7) :=(
c_amcap2e(55 downto 48), c_amcap2e(63 downto 56)
);
constant c_amb64 : t_cr_array(0 to 7) := (
c_amcapA64(7 downto 0), c_amcapA64(15 downto 8),
c_amcapA64(23 downto 16), c_amcapA64(31 downto 24),
c_amcapA64(39 downto 32), c_amcapA64(47 downto 40),
c_amcapA64(55 downto 48), c_amcapA64(63 downto 56));
c_amcapA64(55 downto 48), c_amcapA64(63 downto 56)
);
constant c_xam0 : t_cr_array(0 to 31) :=(
constant c_xam0 : t_cr_array(0 to 31) := (
c_xamcap0(7 downto 0), c_xamcap0(15 downto 8), c_xamcap0(23 downto 16),
c_xamcap0(31 downto 24), c_xamcap0(39 downto 32), c_xamcap0(47 downto 40),
c_xamcap0(55 downto 48), c_xamcap0(63 downto 56), c_xamcap0(71 downto 64),
......@@ -102,10 +110,10 @@ package VME_CR_pack is
c_xamcap0(175 downto 168), c_xamcap0(183 downto 176), c_xamcap0(191 downto 184),
c_xamcap0(199 downto 192), c_xamcap0(207 downto 200), c_xamcap0(215 downto 208),
c_xamcap0(223 downto 216), c_xamcap0(231 downto 224), c_xamcap0(239 downto 232),
c_xamcap0(247 downto 240), c_xamcap0(255 downto 248));
c_xamcap0(247 downto 240), c_xamcap0(255 downto 248)
);
constant c_xam2 : t_cr_array(0 to 31) :=(
constant c_xam2 : t_cr_array(0 to 31) := (
c_xamcap2(7 downto 0), c_xamcap2(15 downto 8), c_xamcap2(23 downto 16),
c_xamcap2(31 downto 24), c_xamcap2(39 downto 32), c_xamcap2(47 downto 40),
c_xamcap2(55 downto 48), c_xamcap2(63 downto 56), c_xamcap2(71 downto 64),
......@@ -116,85 +124,97 @@ package VME_CR_pack is
c_xamcap2(175 downto 168), c_xamcap2(183 downto 176), c_xamcap2(191 downto 184),
c_xamcap2(199 downto 192), c_xamcap2(207 downto 200), c_xamcap2(215 downto 208),
c_xamcap2(223 downto 216), c_xamcap2(231 downto 224), c_xamcap2(239 downto 232),
c_xamcap2(247 downto 240), c_xamcap2(255 downto 248));
c_xamcap2(247 downto 240), c_xamcap2(255 downto 248)
);
constant c_cr_array : t_cr_array(2**12 downto 0) :=
(
constant c_cr_array : t_cr_array(2**12 downto 0) := (
16#00# => (others => '0'),
-- Length of ROM
16#01# => x"00",
16#02# => x"10",
16#03# => x"00",
--Configuration ROM data acces width
16#04# => x"84", --D32, D16, D08
--CSR data acces width
16#05# => x"84", --D32, D16, D08
--CR/CSR Space Specification ID
16#06# => x"02",
--Ascii "C"
16#07# => x"43",
--Ascii "R"
-- Configuration ROM data acces width
16#04# => x"84", -- D32, D16, D08
-- CSR data acces width
16#05# => x"84", -- D32, D16, D08
-- CR/CSR Space Specification ID
16#06# => x"02", -- ASCII "C"
16#07# => x"43", -- ASCII "R"
16#08# => x"52",
--Manufacturer's ID -- for CERN: 0x080030
16#09# => x"08",
-- Manufacturer's ID
16#09# => x"08", -- for CERN: 0x080030
16#0A# => x"00",
16#0B# => x"30",
--board id -- eg: SVEC ID = 0x000198
16#0C# => x"03",
-- Board ID
16#0C# => x"03", -- eg: SVEC ID = 0x000198
16#0D# => x"04",
16#0E# => x"04",
16#0F# => x"03",
--Rev id
-- Rev ID
16#10# => x"00",
16#11# => x"00",
16#12# => x"00",
16#13# => x"02",
--Point to ascii null terminatied
-- Point to ASCII null terminatied
16#14# => x"00",
16#15# => x"00",
16#16# => x"00",
--Program Id code
-- Program ID code
16#1F# => x"5a",
--Offset to BEG_USER_CR
-- Offset to BEG_USER_CR
16#20# => x"00",
16#21# => x"00",
16#22# => x"00",
--Offset to END_USER_CR
-- Offset to END_USER_CR
16#23# => x"00",
16#24# => x"00",
16#25# => x"00",
--Offset to BEG_CRAM
-- Offset to BEG_CRAM
16#26# => x"00",
16#27# => x"10",
16#28# => x"00",
--Offset to END_CRAM
-- Offset to END_CRAM
16#29# => x"00",
16#2A# => x"13",
16#2B# => x"ff",
--Offset to BEG_USER_CSR
-- Offset to BEG_USER_CSR
16#2C# => x"00",
16#2D# => x"00",
16#2E# => x"00", -- 0x7fbf0 and NOT 0x7fbf3 because is possible access with D32 mode
--Offset to END_USER_CSR
-- Offset to END_USER_CSR
16#2F# => x"00",
16#30# => x"00",
16#31# => x"00",
--CRAM_ACCESS_WIDTH
16#3f# => x"84", --D32, D16, D08
--Function data access width
-- CRAM_ACCESS_WIDTH
16#3f# => x"84", -- D32, D16, D08
-- DAWPR
16#40# => x"84", -- Fun 0 accepts D64, D32, D16, D08(EO) cycles
16#41# => x"84", -- Fun 1
16#42# => x"84", -- Fun 2
16#43# => x"84", -- Fun 3
16#44# => x"84", -- Fun 4
16#45# => x"84", -- Fun 5
16#46# => x"84", -- Fun 6
16#47# => x"84", -- Fun 7
--Function AM code Mask
-- AMCAP
16#48# => c_amb0(7), -- Fun 0 for A32 S, A32 BLT, A32 MBLT
16#49# => c_amb0(6), -- Fun 0
16#4A# => c_amb0(5), -- Fun 0
......@@ -213,7 +233,6 @@ package VME_CR_pack is
16#56# => c_amb1(1), -- Fun 1
16#57# => c_amb1(0), -- Fun 1
16#58# => c_amb2(7), -- Fun 2 for A16
16#59# => c_amb2(6), -- Fun 2
16#5A# => c_amb2(5), -- Fun 2
......@@ -223,8 +242,7 @@ package VME_CR_pack is
16#5E# => c_amb2(1), -- Fun 2
16#5F# => c_amb2(0), -- Fun 2
16#60# => c_amb64(7), -- Fun 3 -- for A64 S, A64 BLT, A64 MBLT
16#60# => c_amb64(7), -- Fun 3 for A64 S, A64 BLT, A64 MBLT
16#61# => c_amb64(6), -- Fun 3
16#62# => c_amb64(5), -- Fun 3
16#63# => c_amb64(4), -- Fun 3
......@@ -233,9 +251,8 @@ package VME_CR_pack is
16#66# => c_amb64(1), -- Fun 3
16#67# => c_amb64(0), -- Fun 3
16#68# => x"00", -- Fun 3_b -- These are not used because the FUNC 3 decode
16#69# => x"00", -- Fun 3_b -- the access mode: A64 --> 2 ADER, 2 ADEM
16#68# => x"00", -- Fun 3_b These are not used because the FUNC 3 decode
16#69# => x"00", -- Fun 3_b the access mode: A64 --> 2 ADER, 2 ADEM
16#6A# => x"00", -- Fun 3_b
16#6B# => x"00", -- Fun 3_b
16#6C# => x"00", -- Fun 3_b
......@@ -261,8 +278,7 @@ package VME_CR_pack is
16#7E# => x"00", -- Fun 4_b
16#7F# => x"00", -- Fun 4_b
--Xamcap
-- XAMCAP
16#88# => c_xam0(31), -- Fun 0 XAMCAP MSB
16#89# => c_xam0(30),
16#8A# => c_xam0(29),
......@@ -296,7 +312,6 @@ package VME_CR_pack is
16#A6# => c_xam0(1),
16#A7# => c_xam0(0),
16#A8# => c_xam0(31), -- Fun 1 XAMCAP MSB
16#A9# => c_xam0(30),
16#AA# => c_xam0(29),
......@@ -528,13 +543,7 @@ package VME_CR_pack is
16#186# => c_xam0(1),
16#187# => c_xam0(0),
--...
--16#C6# => x"00", -- Fun 0 XAMCAP LSB
--16#C7# => x"01", -- Fun 0 XAMCAP LSB
--......
-- Address Decoder Mask ADEM
-- ADEM
16#188# => x"ff", -- Fun 0
16#189# => x"00", -- Fun 0
16#18A# => x"00", -- Fun 0
......@@ -560,7 +569,6 @@ package VME_CR_pack is
16#19a# => x"00", -- Fun 4 (used for decoding FUNC3)
16#19b# => x"00", -- Fun 4 (used for decoding FUNC3)
16#19c# => x"ff", -- Fun 5
16#19d# => x"00", -- Fun 5
16#19e# => x"00", -- Fun 5
......@@ -571,27 +579,7 @@ package VME_CR_pack is
16#1a2# => x"00", -- Fun 6
16#1a3# => x"00", -- Fun 6
others => (others => '0'));
others => (others => '0')
);
end VME_CR_pack;
--________________________________________________________________________________________________
-- VME TO WB INTERFACE
--------------------------------------------------------------------------------
-- CERN (BE-CO-HT)
-- VME64x Core
-- http://www.ohwr.org/projects/vme64x-core
--------------------------------------------------------------------------------
--
-- CERN,BE/CO-HT
--________________________________________________________________________________________________
-- File: VME_CSR_pack.vhd
--________________________________________________________________________________________________
-- Description: This file defines the default configuration of the CSR space after power-up or
-- software reset.
--______________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 06/2012
-- Version v0.02
--______________________________________________________________________________
-- unit name: VME_CSR_pack (VME_CSR_pack.vhd)
--
-- author: Pablo Alvarez Sanchez <pablo.alvarez.sanchez@cern.ch>
-- Davide Pedretti <davide.pedretti@cern.ch>
--
-- description: This file defines the default configuration of the CSR space
-- after power-up or software reset.
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
--------------------------------------------------------------------------------
-- 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
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;
-- 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;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.vme64x_pack.all;
package VME_CSR_pack is
constant c_csr_array : t_CSRarray :=
(
BAR => x"00", --CR/CSR BAR
BIT_SET_CLR_REG => x"00", --Bit set register -- 0x10=module enable
USR_BIT_SET_CLR_REG => x"00", --Bit clear register
CRAM_OWNER => x"00", --CRAM_OWNER
FUNC0_ADER_0 =>x"00", --A32_S "24"
FUNC0_ADER_1 =>x"00", -- "00"
FUNC0_ADER_2 =>x"00", -- "00"
FUNC0_ADER_3 =>x"00", -- "c0"
FUNC1_ADER_0 =>x"00", --A24_S "e4"
FUNC1_ADER_1 =>x"00", -- "00"
FUNC1_ADER_2 =>x"00", -- "c0"
FUNC1_ADER_3 =>x"00", -- "00"
FUNC2_ADER_0 =>x"00", --A16_S "a4"
FUNC2_ADER_1 =>x"00", -- "c0"
FUNC2_ADER_2 =>x"00", -- "00"
FUNC2_ADER_3 =>x"00", -- "00"
FUNC3_ADER_0 =>x"00", --A64_S "04"
FUNC3_ADER_1 =>x"00",
FUNC3_ADER_2 =>x"00",
FUNC3_ADER_3 =>x"00",
FUNC4_ADER_0 =>x"00", --used for decoding the FUNC3
FUNC4_ADER_1 =>x"00", --used for decoding the FUNC3
FUNC4_ADER_2 =>x"00", --used for decoding the FUNC3
FUNC4_ADER_3 =>x"00", --used for decoding the FUNC3 "c0"
FUNC5_ADER_0 =>x"00",
FUNC5_ADER_1 =>x"00",
FUNC5_ADER_2 =>x"00",
FUNC5_ADER_3 =>x"00",
FUNC6_ADER_0 =>x"00",
FUNC6_ADER_1 =>x"00",
FUNC6_ADER_2 =>x"00",
FUNC6_ADER_3 =>x"00",
package VME_CSR_pack is
IRQ_Vector =>x"00", --"00" because each Slot has a different IRQ Vector
constant c_csr_array : t_CSRarray := (
BAR => x"00", -- CR/CSR BAR
BIT_SET_CLR_REG => x"00", -- Bit set register
-- 0x10 = module enable
USR_BIT_SET_CLR_REG => x"00", -- Bit clear register
CRAM_OWNER => x"00", -- CRAM_OWNER
FUNC0_ADER_0 => x"00", -- A32_S "24"
FUNC0_ADER_1 => x"00", -- "00"
FUNC0_ADER_2 => x"00", -- "00"
FUNC0_ADER_3 => x"00", -- "c0"
FUNC1_ADER_0 => x"00", -- A24_S "e4"
FUNC1_ADER_1 => x"00", -- "00"
FUNC1_ADER_2 => x"00", -- "c0"
FUNC1_ADER_3 => x"00", -- "00"
FUNC2_ADER_0 => x"00", -- A16_S "a4"
FUNC2_ADER_1 => x"00", -- "c0"
FUNC2_ADER_2 => x"00", -- "00"
FUNC2_ADER_3 => x"00", -- "00"
FUNC3_ADER_0 => x"00", -- A64_S "04"
FUNC3_ADER_1 => x"00",
FUNC3_ADER_2 => x"00",
FUNC3_ADER_3 => x"00",
FUNC4_ADER_0 => x"00", -- used for decoding the FUNC3
FUNC4_ADER_1 => x"00", -- used for decoding the FUNC3
FUNC4_ADER_2 => x"00", -- used for decoding the FUNC3
FUNC4_ADER_3 => x"00", -- used for decoding the FUNC3 "c0"
FUNC5_ADER_0 => x"00",
FUNC5_ADER_1 => x"00",
FUNC5_ADER_2 => x"00",
FUNC5_ADER_3 => x"00",
FUNC6_ADER_0 => x"00",
FUNC6_ADER_1 => x"00",
FUNC6_ADER_2 => x"00",
FUNC6_ADER_3 => x"00",
IRQ_Vector => x"00", -- "00" because each Slot has a different IRQ Vector
-- and the VME Master should set this value
IRQ_level =>x"02",
WB32bits =>x"01", -- 32 bit WB of default
others => (others => '0'));
end VME_CSR_pack;
IRQ_level => x"02",
WB32bits => x"01", -- 32 bit WB of default
others => (others => '0')
);
end VME_CSR_pack;
--_________________________________________________________________________________________
-- VME TO WB INTERFACE
--------------------------------------------------------------------------------
-- CERN (BE-CO-HT)
-- VME64x Core
-- http://www.ohwr.org/projects/vme64x-core
--------------------------------------------------------------------------------
--
-- unit name: VME_Funct_Match (VME_Funct_Match.vhd)
--
-- author: Pablo Alvarez Sanchez <pablo.alvarez.sanchez@cern.ch>
-- Davide Pedretti <davide.pedretti@cern.ch>
--
-- description:
--
-- This component compares the Address with the ADER using the mask bits and
-- if the base address match it asserts the corresponding bit in the
-- FunctMatch vector and it latches the base address that will be subtracted
-- to the Address before accessing the WB bus.
--
-- FunctMatch /= 0 is necessary but not sufficient to select one function and
-- to access the board, indeed also the AM has to be checked (VME_AM_Match.vhd
-- component).
--
-- CERN,BE/CO-HT
--_________________________________________________________________________________________
-- File: VME_Funct_Match.vhd
--_________________________________________________________________________________________
-- Description: this component compares the Address with the ADER using the mask bits and
-- if the base address match it asserts the corresponding bit in the FunctMatch vector and it
-- latches the base address that will be subtracted to the Address before accessing the WB bus.
-- FunctMatch /= 0 is necessary but not sufficient to select one function and to access the board,
-- indeed also the AM has to be checked (VME_AM_Match.vhd component).
-- For better understanding how this component works here is one example:
-- base address = 0xc0
-- access mode: A32_S --> AM = 0x09
......@@ -18,6 +28,7 @@
-- The Master wants to access the location 0x08: Address= 0xc0000008
-- For i = 0 to 7 check:
-- Check if the ADEMi is compatible with the AM selected: ADEMi[31:8] /= 0
--
-- Address[31:8] and ADEMi[31:8] ADERi[31:8] and ADEMi[31:8]
-- | |
-- 0xc00000 0xc00000
......@@ -26,6 +37,7 @@
-- |_______|
-- No | |yes
-- FunctMatch(i) <= '0'_____| |______FunctMatch(i) <= '1'
--
-- Now with the same ADEMi the master accesses with A16 mode:
-- base address = 0xc0
-- access mode: A16_S --> AM = 0x29
......@@ -33,6 +45,7 @@
-- The Master wants to access the location 0x08: Address= 0x0000c008
-- For i = 0 to 7 check:
-- Check if the ADEMi is compatible with the AM selected: ADEMi[15:8] /= 0
--
-- Address[31:8] and ADEMi[31:8] ADERi[31:8] and ADEMi[31:8]
-- | |
-- 0x0000c0 0x0000c0
......@@ -43,15 +56,17 @@
-- FunctMatch(i) <= '0'_____| |______FunctMatch(i) <= '1'
--
-- DFS = '1' --> 1 function --> multiple access modes
-- The Master accesses with different modes only changing the ADER registers if the
-- DFS bit is asserted but:
-- It is easy to see that if DFS = '1' we can only address 256 bytes, indeed eg:
-- The Master accesses with different modes only changing the ADER registers
-- if the DFS bit is asserted but:
-- It is easy to see that if DFS = '1' we can only address 256 bytes, indeed
-- eg:
-- base address = 0xc0
-- access mode: A32_S --> AM = 0x09
-- The Master write the ADERi = 0xc0000024
-- The Master wants to access the location 0x4008: Address= 0xc0004008
-- For i = 0 to 7 check:
-- Check if the ADEMi is compatible with the AM selected: ADEMi[31:8] /= 0
--
-- Address[31:8] and ADEMi[31:8] ADERi[31:8] and ADEMi[31:8]
-- | |
-- 0xc00040 0xc00000
......@@ -60,6 +75,7 @@
-- |_______|
-- No | |yes
-- FunctMatch(i) <= '0'_____| |______FunctMatch(i) <= '1'
--
-- The Master can't access!!
-- Without DFS asserted:
-- base address = 0xc0
......@@ -69,6 +85,7 @@
-- The Master wants to access the location 0x4008: Address= 0xc0004008
-- For i = 0 to 7 check:
-- Check if the ADEMi is compatible with the AM selected: ADEM[31:8] /= 0
--
-- Address[31:8] and ADEMi[31:8] ADERi[31:8] and ADEMi[31:8]
-- | |
-- 0xc00000 0xc00000
......@@ -77,6 +94,7 @@
-- |_______|
-- No | |yes
-- FunctMatch(i) <= '0'_____| |______FunctMatch(i) <= '1'
--
-- The Master can access!
-- base address = 0xc0
-- access mode: A16_S --> AM = 0x29
......@@ -100,6 +118,7 @@
-- The Master wants to access the location 0x0008: Address= 0xc0000008
-- For i = 0 to 7 check:
-- Check if the ADEMi is compatible with the AM selected: ADEMi[31:8] /= 0
--
-- Address[31:8] and ADEMi[31:8] ADERi[31:8] and ADEMi[31:8]
-- | |
-- 0x000000 0x000000
......@@ -108,11 +127,14 @@
-- |_______|
-- No | |yes
-- FunctMatch(i) <= '0'_____| |______FunctMatch(i) <= '1'
-- FunctMatch(i) is asserted but our Slave will not be the responding Slave, indeed
-- the AmMatch(i) is zero becouse the Master is accessing with A32_S and if DFS is 0
-- the AMCAPi register has only the A16 or A16_SUP bits asserted!
-- If DFS is '1' AmMatch(i) is zero becouse ADER[7:2] is 0 (see VME_Am_Match.vhd) and
-- also FunctMatch(i) is 0 because ADEMi should has all the mask bits '1'.
--
-- FunctMatch(i) is asserted but our Slave will not be the responding Slave,
-- indeed the AmMatch(i) is zero becouse the Master is accessing with A32_S
-- and if DFS is 0 the AMCAPi register has only the A16 or A16_SUP bits
-- asserted!
-- If DFS is '1' AmMatch(i) is zero becouse ADER[7:2] is 0
-- (see VME_Am_Match.vhd) and also FunctMatch(i) is 0 because ADEMi should has
-- all the mask bits '1'.
--
-- An example about A64 access mode:
-- base address = 0xc0
......@@ -121,14 +143,16 @@
-- ADEM(i+1) = 0xff000000
-- ADEM64(i) = ADEM(i+1) & ADEM(i)
-- AMCAP(i) = "0000000000000000000000000000000000000000000000000000000000000010";
-- AMCAP(i+1) <= (others => '0')
-- AMCAP(i+1) = (others => '0')
-- ADER(i) = 0x00000004
-- ADER(i+1) = 0xc0000000
-- ADER64(i) = ADER(i+1) & ADER(i)
-- s_isprev_func64(i+1) --> '1' --> don't check if the function i + 1 is selected
-- because the next ADER and ADEM are used to decode the function i.
-- s_isprev_func64(i+1) --> '1' --> don't check if the function i + 1 is
-- selected because the next ADER and ADEM are used to decode the function i.
-- The Master accesses the location 0x0008: Address= 0xc000000000000008
-- Check if the ADEM64i is compatible with the AM selected: ADEM64(i)[63:10] /= 0
-- Check if the ADEM64i is compatible with the AM selected:
-- ADEM64(i)[63:10] /= 0
--
-- Address[63:10] and ADEM64(i)[63:10] ADER64(i)[63:10] and ADEM64(i)[63:10]
-- | |
-- 0xc0000000000000 0xc0000000000000
......@@ -138,39 +162,37 @@
-- No | |yes
-- FunctMatch(i) <= '0'_____| |______FunctMatch(i) <= '1'
--
-- For the 2e modes it is the same, it changes only the ADER(i)'s XAM bit that must
-- be '1'.
--______________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--______________________________________________________________________________
-- For the 2e modes it is the same, it changes only the ADER(i)'s XAM bit that
-- must be '1'.
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
--------------------------------------------------------------------------------
-- 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
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.vme64x_pack.all;
-- 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: -
--------------------------------------------------------------------------------
--===========================================================================
-- Entity declaration
--===========================================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.vme64x_pack.all;
entity VME_Funct_Match is
Port ( clk_i : in std_logic;
port (
clk_i : in std_logic;
reset : in std_logic;
decode : in std_logic;
mainFSMreset : in std_logic;
......@@ -195,23 +217,23 @@ entity VME_Funct_Match is
FunctMatch : out std_logic_vector(7 downto 0);
DFS_o : out std_logic_vector(7 downto 0);
Nx_Base_Addr : out std_logic_vector(63 downto 0)
);
);
end VME_Funct_Match;
--===========================================================================
-- Architecture declaration
--===========================================================================
architecture Behavioral of VME_Funct_Match is
signal s_FUNC_ADER, s_FUNC_ADEM : t_FUNC_32b_array;
signal s_FUNC_ADER_64, s_FUNC_ADEM_64: t_FUNC_64b_array;
signal s_FUNC_ADER,
s_FUNC_ADEM : t_FUNC_32b_array;
signal s_FUNC_ADER_64,
s_FUNC_ADEM_64 : t_FUNC_64b_array;
signal s_isprev_func64 : std_logic_vector(7 downto 0);
signal s_locAddr : unsigned(63 downto 0);
--===========================================================================
-- Architecture begin
--===========================================================================
begin
s_locAddr <= unsigned(Addr);
p_functMatch : process(clk_i)
p_functMatch : process (clk_i)
begin
if rising_edge(clk_i) then
if mainFSMreset = '1' or reset = '1' then
......@@ -223,10 +245,11 @@ begin
case AddrWidth is
when "11" =>
if (s_FUNC_ADEM(i)(0) = '1') and (s_isprev_func64(i) = '0') and
(s_FUNC_ADEM_64(i)(63 downto 10) /= 0) then
(s_FUNC_ADEM_64(i)(63 downto 10) /= 0)
then
if (s_FUNC_ADER_64(i)(63 downto 10) and s_FUNC_ADEM_64(i)(63 downto 10)) =
((s_locAddr(63 downto 10)) and s_FUNC_ADEM_64(i)(63 downto 10)) then
((s_locAddr(63 downto 10)) and s_FUNC_ADEM_64(i)(63 downto 10))
then
FunctMatch(i) <= '1';
Nx_Base_Addr(63 downto 10) <= std_logic_vector(s_FUNC_ADER_64(i)(63 downto 10));
Nx_Base_Addr(9 downto 0) <= (others => '0');
......@@ -235,9 +258,9 @@ begin
when "10" =>
if (s_FUNC_ADEM(i)(31 downto 8) /=0) and (s_isprev_func64(i) = '0') then
if (s_FUNC_ADER(i)(31 downto 8) and s_FUNC_ADEM(i)(31 downto 8)) =
((s_locAddr(31 downto 8)) and s_FUNC_ADEM(i)(31 downto 8)) then
((s_locAddr(31 downto 8)) and s_FUNC_ADEM(i)(31 downto 8))
then
FunctMatch(i) <= '1';
Nx_Base_Addr(31 downto 8) <= std_logic_vector(s_FUNC_ADER(i)(31 downto 8));
Nx_Base_Addr(63 downto 32) <= (others => '0');
......@@ -248,7 +271,8 @@ begin
when "01" =>
if (s_FUNC_ADEM(i)(23 downto 8) /=0) and (s_isprev_func64(i) = '0') then
if (s_FUNC_ADER(i)(23 downto 8) and s_FUNC_ADEM(i)(23 downto 8)) =
((s_locAddr(23 downto 8)) and s_FUNC_ADEM(i)(23 downto 8)) then
((s_locAddr(23 downto 8)) and s_FUNC_ADEM(i)(23 downto 8))
then
FunctMatch(i) <= '1';
Nx_Base_Addr(23 downto 8) <= std_logic_vector(s_FUNC_ADER(i)(23 downto 8));
Nx_Base_Addr(63 downto 24) <= (others => '0');
......@@ -259,7 +283,8 @@ begin
when "00" =>
if (s_FUNC_ADEM(i)(15 downto 8) /=0) and (s_isprev_func64(i) = '0') then
if (s_FUNC_ADER(i)(15 downto 8) and s_FUNC_ADEM(i)(15 downto 8)) =
((s_locAddr(15 downto 8)) and s_FUNC_ADEM(i)(15 downto 8)) then
((s_locAddr(15 downto 8)) and s_FUNC_ADEM(i)(15 downto 8))
then
FunctMatch(i) <= '1';
Nx_Base_Addr(15 downto 8) <= std_logic_vector(s_FUNC_ADER(i)(15 downto 8));
Nx_Base_Addr(63 downto 16) <= (others => '0');
......@@ -275,7 +300,6 @@ begin
end if;
end process;
------------------------------------------------------
s_FUNC_ADER(0) <= unsigned(Ader0);
s_FUNC_ADER(1) <= unsigned(Ader1);
s_FUNC_ADER(2) <= unsigned(Ader2);
......@@ -310,7 +334,5 @@ begin
s_isprev_func64(0) <= '0';
s_FUNC_ADEM_64(7) <= (others => '0');
end Behavioral;
--===========================================================================
-- Architecture end
--===========================================================================
--_________________________________________________________________________________________
-- VME TO WB INTERFACE
--------------------------------------------------------------------------------
-- CERN (BE-CO-HT)
-- VME64x Core
-- http://www.ohwr.org/projects/vme64x-core
--------------------------------------------------------------------------------
--
-- unit name: VME_IRQ_Controller (VME_IRQ_Controller.vhd)
--
-- author: Pablo Alvarez Sanchez <pablo.alvarez.sanchez@cern.ch>
-- Davide Pedretti <davide.pedretti@cern.ch>
--
-- description:
--
-- CERN,BE/CO-HT
--_________________________________________________________________________________________
-- File: VME_IRQ_Controller.vhd
--_________________________________________________________________________________________
-- Description:
-- This block acts as Interrupter. Phases of an interrupt cycle:
--
-- 1) The Interrupt Controller receives an interrupt request by the WB bus;
-- this request is a pulse on the INT_Req input
-- 2) The Interrupt Controller asserts ('0') one of the 7 VME_IRQ lines; --> request of a service.
-- The Interrupt priority is specificated by the Master writing the INT_Level register
-- in the CR/CSR space
-- 3) The Interrupter Controller wait for the falling edge on the VME_IACKIN line.
-- 4) When detects VME_IACKIN_n_i = '0' and the Interrupt Handler initiates the Interrupt
-- cycle by asserting AS,the Interrupt Controller check if it is the responding interrupter.
-- Indeed before responding to an interrupt acknowledge cycle the interrupter shall have
-- an interrupt request pending, shall check if the level of that request match the level
-- indicated on the address lines A1, A2 and A3,the data transfer width during the interrupt
-- acknowledge cycle should be equal or greater than the size the it can respond with, and
-- it shall receive a falling edge on its IACKIN*.
-- 5) If it is the responding interrupter should send the source/ID on the VME_DATA lines
-- (in our case the source/ID is the INT_Vector that the Master can write in the corresponding
-- register in the CR/CSR space) and it terminates the interrupt cycle with an acknowledge before
-- releasing the IRQ lines. If it isn't the responding interrupter, it should pass a falling edge on
-- down the daisy-chain so other interrupters can respond.
-- 2) The Interrupt Controller asserts ('0') one of the 7 VME_IRQ lines;
-- --> request of a service.
-- The Interrupt priority is specificated by the Master writing the
-- INT_Level register in the CR/CSR space
-- 3) The Interrupter Controller wait for the falling edge on the VME_IACKIN
-- line.
-- 4) When detects VME_IACKIN_n_i = '0' and the Interrupt Handler initiates
-- the Interrupt cycle by asserting AS,the Interrupt Controller check if it
-- is the responding interrupter. Indeed before responding to an interrupt
-- acknowledge cycle the interrupter shall have an interrupt request
-- pending, shall check if the level of that request match the level
-- indicated on the address lines A1, A2 and A3,the data transfer width
-- during the interrupt acknowledge cycle should be equal or greater than
-- the size the it can respond with, and it shall receive a falling edge on
-- its IACKIN*.
-- 5) If it is the responding interrupter should send the source/ID on the
-- VME_DATA lines (in our case the source/ID is the INT_Vector that the
-- Master can write in the corresponding register in the CR/CSR space) and
-- it terminates the interrupt cycle with an acknowledge before releasing
-- the IRQ lines. If it isn't the responding interrupter, it should pass a
-- falling edge on down the daisy-chain so other interrupters can respond.
--
-- All the output signals are registered
-- To implement the 5 phases before mentioned the follow FSM has been implemented:
--
-- To implement the 5 phases before mentioned the follow FSM has been
-- implemented:
-- __________
-- |--| IACKOUT2 |<-|
-- | |__________| |
-- | |
-- | _________ | _________ _________ _________
-- |-->| IDLE |--->| IRQ |-->| WAIT_AS |-->| WAIT_DS |---------------->|
-- |-->| IDLE |--->| IRQ |-->| WAIT_AS |-->| WAIT_DS |-------------->|
-- |_________| |_________| |_________| |_________| |
-- | | |
-- | | _________ _________ |
-- | |---------<------------| IACKOUT1| <--| CHECK |<----|
-- | |---------<------------| IACKOUT1| <--| CHECK |<--|
-- | |_________| |_________|
-- | __________ __________ |
-- |--<-----------------| DTACK |<--| DATA_OUT |---<----|
-- |__________| |__________|
--
-- The interrupter wait the IACKIN falling edge in the IRQ state, so if the interrupter
-- don't have interrupt pending for sure it will not respond because it is in IDLE.
-- If the slave module does not have an interrupt pending (IDLE state) and it receives
-- a falling edge on the IACKIN, it shall pass the falling edge through the daisy chain.
-- The interrupter wait the IACKIN falling edge in the IRQ state, so if the
-- interrupter don't have interrupt pending for sure it will not respond
-- because it is in IDLE.
-- If the slave module does not have an interrupt pending (IDLE state) and it
-- receives a falling edge on the IACKIN, it shall pass the falling edge
-- through the daisy chain.
-- To obtain this the IACKOUT2 state has been added.
--
-- Time constraint:
--
-- Time constraint n° 35:
--
-- Clk _____ _____ _____ _____ _____ _____
-- _____| |_____| |_____| |_____| |_____| |_____| |_____
--
-- VME_AS1_n_i ____________________________________________________________________
-- ________|
--
-- VME_AS_n_i ___________________________________
-- _________________________________________|
--
-- s_AS_RisingEdge ___________
-- _____________________________________________________| |___________
--
-- s_IACKOUT ____________________________________________________________________
-- ________|
--
-- VME_IACKOUT_o ____________________________________________________________________
-- ________|
--
-- _________________________________________________________________ __________
-- IACKOUT 1/2 \/ IDLE/IRQ
-- -----------------------------------------------------------------/\----------
-- _________________________________________________________________/\__________
--
-- To respect the time constraint indicated with the number 35 fig. 55 pag. 183
-- in the "VMEbus Specification" ANSI/IEEE STD1014-1987, is necessary to
-- generate the VME_AS1_n_i signal which is the AS signal not sampled, and
-- assign this signal to the s_IACKOUT signal when the fsm is in the IACKOUTx
-- state.
--
-- To respect the time constraint indicated with the number 35 fig. 55 pag. 183 in the
-- "VMEbus Specification" ANSI/IEEE STD1014-1987, is necessary to generate the VME_AS1_n_i
-- signal which is the AS signal not sampled, and assign this signal to the s_IACKOUT
-- signal when the fsm is in the IACKOUTx state.
-- The LWORD* input is not used now, since this is a D08(O) Interrupter (see
-- Table 31 page 157 VMEbus specification).
--
-- The LWORD* input is not used now, since this is a D08(O) Interrupter (see Table 31
-- page 157 VMEbus specification).
-- Since this is a D08 interrupter we do not need to monitor the LWORD* and DS1* lines
-- and the Vector (1 byte) is outputted in the D00-D07 data lines.
--____________________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--_____________________________________________________________________________________
-- Since this is a D08 interrupter we do not need to monitor the LWORD* and
-- DS1* lines and the Vector (1 byte) is outputted in the D00-D07 data lines.
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
--------------------------------------------------------------------------------
-- 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
---------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;
-- 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;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.vme64x_pack.all;
--===========================================================================
-- Entity declaration
--===========================================================================
entity VME_IRQ_Controller is
generic (
g_retry_timeout : integer range 1024 to 16777215 := 62500);
g_retry_timeout : integer range 1024 to 16777215 := 62500
);
port (
clk_i : in std_logic;
reset_n_i : in std_logic;
......@@ -123,11 +146,10 @@ entity VME_IRQ_Controller is
VME_DTACK_n_o : out std_logic;
VME_DTACK_OE_o : out std_logic;
VME_DATA_o : out std_logic_vector (31 downto 0);
VME_DATA_DIR_o : out std_logic);
VME_DATA_DIR_o : out std_logic
);
end VME_IRQ_Controller;
--===========================================================================
-- Architecture declaration
--===========================================================================
architecture Behavioral of VME_IRQ_Controller is
function f_select_irq_line (level : std_logic_vector) return std_logic_vector is
......@@ -144,29 +166,25 @@ architecture Behavioral of VME_IRQ_Controller is
end case;
end f_select_irq_Line;
--input signals
-- Input signals
type t_retry_state is (WAIT_IRQ, WAIT_RETRY);
type t_main_state is (IDLE, IRQ, WAIT_AS, WAIT_DS, CHECK, DATA_OUT, DTACK, IACKOUT1, IACKOUT2, SCHEDULE_IRQ);
type t_main_state is (IDLE, IRQ, WAIT_AS, WAIT_DS, CHECK, DATA_OUT, DTACK,
IACKOUT1, IACKOUT2, SCHEDULE_IRQ);
signal as_n_d0 : std_logic;
signal as_rising_p, as_falling_p : std_logic;
signal as_rising_p,
as_falling_p : std_logic;
signal vme_addr_latched : std_logic_vector(2 downto 0);
signal state : t_main_state;
signal retry_state : t_retry_state;
signal retry_count : unsigned(23 downto 0);
signal retry_mask : std_logic;
--===========================================================================
-- Architecture begin
--===========================================================================
begin
-- Input sampling and edge detection
p_detect_as_edges : process(clk_i)
-- Input sampling and edge detection
p_detect_as_edges : process (clk_i)
begin
if rising_edge(clk_i) then
as_n_d0 <= VME_AS_n_i;
......@@ -175,7 +193,7 @@ begin
end if;
end process;
process(clk_i)
process (clk_i)
begin
if rising_edge(clk_i) then
if as_falling_p = '1' then
......@@ -184,7 +202,7 @@ begin
end if;
end process;
p_retry_fsm : process(clk_i)
p_retry_fsm : process (clk_i)
begin
if rising_edge(clk_i) then
if reset_n_i = '0' then
......@@ -193,8 +211,7 @@ begin
else
case retry_state is
when WAIT_IRQ =>
if(state = IRQ and INT_Req_i = '1') then
if (state = IRQ and INT_Req_i = '1') then
retry_state <= WAIT_RETRY;
retry_count <= (others => '0');
retry_mask <= '0';
......@@ -203,11 +220,11 @@ begin
end if;
when WAIT_RETRY =>
if(INT_Req_i = '0') then
if (INT_Req_i = '0') then
retry_state <= WAIT_IRQ;
else
retry_count <= retry_count + 1;
if(retry_count = g_retry_timeout) then
if (retry_count = g_retry_timeout) then
retry_state <= WAIT_IRQ;
end if;
end if;
......@@ -217,7 +234,7 @@ begin
end if;
end process;
p_main_fsm : process(clk_i)
p_main_fsm : process (clk_i)
begin
if rising_edge(clk_i) then
if reset_n_i = '0' then
......@@ -229,7 +246,6 @@ begin
else
case state is
when IDLE =>
VME_IACKOUT_n_o <= '1';
VME_DATA_DIR_o <= '0';
VME_DTACK_n_o <= '1';
......@@ -244,21 +260,21 @@ begin
-- IACK in progress, wait until idle
state <= SCHEDULE_IRQ;
end if;
-- just forward IACK to the next card in the daisy chain.
-- Just forward IACK to the next card in the daisy chain.
elsif VME_IACKIN_n_i = '0' and VME_DS_n_i /= "11" then
VME_IACKOUT_n_o <= '0';
state <= IACKOUT2;
end if;
when SCHEDULE_IRQ =>
if(VME_IACKIN_n_i /= '0') then
if (VME_IACKIN_n_i /= '0') then
VME_IRQ_n_o <= f_select_irq_line(INT_Level_i);
state <= IRQ;
end if;
when IRQ =>
if VME_IACKIN_n_i = '0' then
-- Each Interrupter who is driving an interrupt request line
-- Each interrupter who is driving an interrupt request line
-- low waits for a falling edge on IACKIN input -->
-- the IRQ_Controller have to detect a falling edge on the IACKIN.
state <= WAIT_AS;
......@@ -270,20 +286,19 @@ begin
end if;
when WAIT_DS =>
if VME_DS_n_i /= "11" then
state <= CHECK;
end if;
when CHECK =>
if vme_addr_latched = INT_Level_i(2 downto 0) then
state <= DATA_OUT; -- The Interrupter send the INT_Vector
state <= DATA_OUT; -- The interrupter send the vector
VME_DATA_DIR_o <= '1';
VME_DTACK_OE_o <= '1';
VME_DTACK_n_o <= '1';
else
state <= IACKOUT1; -- the Interrupter must pass a falling edge on the IACKOUT output
state <= IACKOUT1; -- The interrupter must pass a
-- falling edge on the IACK output
VME_IACKOUT_n_o <= '0';
end if;
......@@ -315,10 +330,6 @@ begin
end if;
end process;
VME_DATA_o <= x"000000" & INT_Vector_i;
end Behavioral;
--===========================================================================
-- Architecture end
--===========================================================================
end Behavioral;
--_______________________________________________________________________________________
-- VME TO WB INTERFACE
--------------------------------------------------------------------------------
-- CERN (BE-CO-HT)
-- VME64x Core
-- http://www.ohwr.org/projects/vme64x-core
--------------------------------------------------------------------------------
--
-- CERN,BE/CO-HT
--________________________________________________________________________________________
-- File: VME_Init.vhd
--________________________________________________________________________________________
-- Description: Read important CR data (like FUNC_ADEMs etc.) and store it locally
-- This important CR data will be used in the decoder.
--________________________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--______________________________________________________________________________
-- Modifications:
-- 2016-08-24: by Jan Pospisil (j.pospisil@cern.ch)
-- * added default values for determined start-up state
--________________________________________________________________________________________
-- unit name: VME_Init (VME_Init.vhd)
--
-- author: Pablo Alvarez Sanchez <pablo.alvarez.sanchez@cern.ch>
-- Davide Pedretti <davide.pedretti@cern.ch>
--
-- description: Read important CR data (like FUNC_ADEMs etc.) and store it
-- locally. This important CR data will be used in the decoder.
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
--------------------------------------------------------------------------------
-- 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
------------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
-- 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;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.vme64x_pack.all;
--===========================================================================
-- Entity declaration
--===========================================================================
entity VME_Init is
Port ( clk_i : in std_logic;
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);
InitReadCount_o : out std_logic_vector (8 downto 0);
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);
InitInProgress_o : out std_logic;
BEG_USR_CR_o : out std_logic_vector (23 downto 0);
END_USR_CR_o : out std_logic_vector (23 downto 0);
BEG_USR_CSR_o : out std_logic_vector (23 downto 0);
END_USR_CSR_o : out std_logic_vector (23 downto 0);
BEG_CRAM_o : out std_logic_vector (23 downto 0);
END_CRAM_o : out std_logic_vector (23 downto 0);
FUNC0_ADEM_o : out std_logic_vector (31 downto 0);
FUNC1_ADEM_o : out std_logic_vector (31 downto 0);
FUNC2_ADEM_o : out std_logic_vector (31 downto 0);
FUNC3_ADEM_o : out std_logic_vector (31 downto 0);
FUNC4_ADEM_o : out std_logic_vector (31 downto 0);
FUNC5_ADEM_o : out std_logic_vector (31 downto 0);
FUNC6_ADEM_o : out std_logic_vector (31 downto 0);
FUNC7_ADEM_o : out std_logic_vector (31 downto 0);
FUNC0_AMCAP_o : out std_logic_vector (63 downto 0);
FUNC1_AMCAP_o : out std_logic_vector (63 downto 0);
FUNC2_AMCAP_o : out std_logic_vector (63 downto 0);
FUNC3_AMCAP_o : out std_logic_vector (63 downto 0);
FUNC4_AMCAP_o : out std_logic_vector (63 downto 0);
FUNC5_AMCAP_o : out std_logic_vector (63 downto 0);
FUNC6_AMCAP_o : out std_logic_vector (63 downto 0);
FUNC7_AMCAP_o : out std_logic_vector (63 downto 0);
FUNC0_XAMCAP_o : out std_logic_vector (255 downto 0);
FUNC1_XAMCAP_o : out std_logic_vector (255 downto 0);
FUNC2_XAMCAP_o : out std_logic_vector (255 downto 0);
FUNC3_XAMCAP_o : out std_logic_vector (255 downto 0);
FUNC4_XAMCAP_o : out std_logic_vector (255 downto 0);
FUNC5_XAMCAP_o : out std_logic_vector (255 downto 0);
FUNC6_XAMCAP_o : out std_logic_vector (255 downto 0);
FUNC7_XAMCAP_o : out std_logic_vector (255 downto 0));
BEG_USR_CR_o : out std_logic_vector(23 downto 0);
END_USR_CR_o : out std_logic_vector(23 downto 0);
BEG_USR_CSR_o : out std_logic_vector(23 downto 0);
END_USR_CSR_o : out std_logic_vector(23 downto 0);
BEG_CRAM_o : out std_logic_vector(23 downto 0);
END_CRAM_o : out std_logic_vector(23 downto 0);
FUNC0_ADEM_o : out std_logic_vector(31 downto 0);
FUNC1_ADEM_o : out std_logic_vector(31 downto 0);
FUNC2_ADEM_o : out std_logic_vector(31 downto 0);
FUNC3_ADEM_o : out std_logic_vector(31 downto 0);
FUNC4_ADEM_o : out std_logic_vector(31 downto 0);
FUNC5_ADEM_o : out std_logic_vector(31 downto 0);
FUNC6_ADEM_o : out std_logic_vector(31 downto 0);
FUNC7_ADEM_o : out std_logic_vector(31 downto 0);
FUNC0_AMCAP_o : out std_logic_vector(63 downto 0);
FUNC1_AMCAP_o : out std_logic_vector(63 downto 0);
FUNC2_AMCAP_o : out std_logic_vector(63 downto 0);
FUNC3_AMCAP_o : out std_logic_vector(63 downto 0);
FUNC4_AMCAP_o : out std_logic_vector(63 downto 0);
FUNC5_AMCAP_o : out std_logic_vector(63 downto 0);
FUNC6_AMCAP_o : out std_logic_vector(63 downto 0);
FUNC7_AMCAP_o : out std_logic_vector(63 downto 0);
FUNC0_XAMCAP_o : out std_logic_vector(255 downto 0);
FUNC1_XAMCAP_o : out std_logic_vector(255 downto 0);
FUNC2_XAMCAP_o : out std_logic_vector(255 downto 0);
FUNC3_XAMCAP_o : out std_logic_vector(255 downto 0);
FUNC4_XAMCAP_o : out std_logic_vector(255 downto 0);
FUNC5_XAMCAP_o : out std_logic_vector(255 downto 0);
FUNC6_XAMCAP_o : out std_logic_vector(255 downto 0);
FUNC7_XAMCAP_o : out std_logic_vector(255 downto 0)
);
end VME_Init;
--===========================================================================
-- Architecture declaration
--===========================================================================
architecture Behavioral of VME_Init is
signal s_initReadCounter : unsigned(8 downto 0) := to_unsigned(0, InitReadCount_o'length);
......@@ -92,7 +88,8 @@ architecture Behavioral of VME_Init is
signal s_CRaddr_base : unsigned(18 downto 0);
signal s_CRaddr : unsigned(18 downto 0);
signal s_latchCRdataPos : std_logic_vector(BEG_USER_CR to FUNC_ADEM);
-- CR image registers
-- CR image registers
signal s_FUNC_ADEM : t_FUNC_32b_array;
signal s_FUNC_AMCAP : t_FUNC_64b_array;
signal s_FUNC_XAMCAP : t_FUNC_256b_array;
......@@ -103,14 +100,12 @@ architecture Behavioral of VME_Init is
signal s_BEG_CRAM : unsigned(23 downto 0) := (others => '0');
signal s_END_CRAM : unsigned(23 downto 0) := (others => '0');
--===========================================================================
-- Architecture begin
--===========================================================================
begin
InitReadCount_o <= std_logic_vector(s_initReadCounter);
s_CRaddr <= unsigned(CRAddr_i);
p_coreInit : process(clk_i)
p_coreInit : process (clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
......@@ -124,12 +119,10 @@ begin
s_initReadCounter <= to_unsigned(0, s_initReadCounter'length);
s_latchCRdata <= '0';
s_initState <= SET_ADDR;
when SET_ADDR =>
s_initReadCounter <= s_initReadCounter+1;
s_latchCRdata <= '0';
s_initState <= GET_DATA;
when GET_DATA =>
s_initReadCounter <= s_initReadCounter;
s_latchCRdata <= '1';
......@@ -138,12 +131,10 @@ begin
else
s_initState <= END_INIT;
end if;
when END_INIT => -- will wait in this state until reset
s_initReadCounter <= s_initReadCounter;
s_latchCRdata <= '0';
s_initState <= END_INIT;
when others =>
s_initState <= IDLE;
s_initReadCounter <= to_unsigned(0, s_initReadCounter'length);
......@@ -158,13 +149,14 @@ begin
InitInProgress_o <= s_initInProgress;
s_CRadd_offset <= s_CRaddr - s_CRaddr_base;
process(s_latchCRdata, s_initReadCounter)
process (s_latchCRdata, s_initReadCounter)
begin
s_latchCRdataPos <= (others => '0');
s_CRaddr_base <= (others => '0');
for I in c_CRinitAddr'range loop
if (s_initReadCounter >= c_CRinitAddr(I).add) and
(s_initReadCounter <= (c_CRinitAddr(I).add+(c_CRinitAddr(I).len-1))) then
(s_initReadCounter <= (c_CRinitAddr(I).add + (c_CRinitAddr(I).len-1)))
then
s_CRaddr_base <= to_unsigned(c_CRinitAddr(I).add, s_CRaddr_base'length);
s_latchCRdataPos(I) <= s_latchCRdata;
exit;
......@@ -172,59 +164,60 @@ begin
end loop;
end process;
process(clk_i)
process (clk_i)
begin
if rising_edge(clk_i) then
for I in 0 to 2 loop
if (s_latchCRdataPos(BEG_USER_CR) = '1') and (unsigned(s_CRadd_offset) = I) then
s_BEG_USER_CR(((3-I)*8 - 1) downto (2-I)*8) <= unsigned(CRdata_i);
s_BEG_USER_CR(((3-I)*8-1) downto (2-I)*8) <= unsigned(CRdata_i);
end if;
if s_latchCRdataPos(END_USER_CR) = '1' and (unsigned(s_CRadd_offset) = I) then
s_END_USER_CR(((3-I)*8 - 1) downto (2-I)*8) <= unsigned(CRdata_i);
s_END_USER_CR(((3-I)*8-1) downto (2-I)*8) <= unsigned(CRdata_i);
end if;
if (s_latchCRdataPos(BEG_USER_CSR) = '1') and (unsigned(s_CRadd_offset) = I) then
s_BEG_USER_CSR(((3-I)*8 - 1) downto (2-I)*8) <= unsigned(CRdata_i);
s_BEG_USER_CSR(((3-I)*8-1) downto (2-I)*8) <= unsigned(CRdata_i);
end if;
if (s_latchCRdataPos(END_USER_CSR) = '1') and (unsigned(s_CRadd_offset) = I) then
s_END_USER_CSR(((3-I)*8 - 1) downto (2-I)*8) <= unsigned(CRdata_i);
s_END_USER_CSR(((3-I)*8-1) downto (2-I)*8) <= unsigned(CRdata_i);
end if;
if (s_latchCRdataPos(BEG_CRAM) = '1') and (unsigned(s_CRadd_offset) = I) then
s_BEG_CRAM(((3-I)*8 - 1) downto (2-I)*8) <= unsigned(CRdata_i);
s_BEG_CRAM(((3-I)*8-1) downto (2-I)*8) <= unsigned(CRdata_i);
end if;
if (s_latchCRdataPos(END_CRAM) = '1') and (unsigned(s_CRadd_offset) = I) then
s_END_CRAM(((3-I)*8 - 1) downto (2-I)*8) <= unsigned(CRdata_i);
s_END_CRAM(((3-I)*8-1) downto (2-I)*8) <= unsigned(CRdata_i);
end if;
end loop;
for I in 0 to 7 loop
if (s_latchCRdataPos(FUNC_AMCAP) = '1') and (unsigned(s_CRadd_offset(5 downto 3)) = I) then
for H in 0 to 7 loop
if (unsigned(s_CRadd_offset(2 downto 0)) = H) then
s_FUNC_AMCAP(I)(((8-h)*8 - 1) downto (7-h)*8) <= unsigned(CRdata_i);
s_FUNC_AMCAP(I)(((8-h)*8-1) downto (7-h)*8) <= unsigned(CRdata_i);
end if;
end loop;
end if;
if (s_latchCRdataPos(FUNC_ADEM) = '1') and (unsigned(s_CRadd_offset(5 downto 2)) = I) then
for H in 0 to 3 loop
if (unsigned(s_CRadd_offset(1 downto 0)) = H) then
s_FUNC_ADEM(I)(((4-h)*8 - 1) downto (3-h)*8) <= unsigned(CRdata_i);
s_FUNC_ADEM(I)(((4-h)*8-1) downto (3-h)*8) <= unsigned(CRdata_i);
end if;
end loop;
end if;
if (s_latchCRdataPos(FUNC_XAMCAP) = '1') and (unsigned(s_CRadd_offset(7 downto 5)) = I) then
for H in 0 to 31 loop
if (unsigned(s_CRadd_offset(4 downto 0)) = H) then
s_FUNC_XAMCAP(I)(((32-h)*8 - 1) downto (31-h)*8) <= unsigned(CRdata_i);
s_FUNC_XAMCAP(I)(((32-h)*8-1) downto (31-h)*8) <= unsigned(CRdata_i);
end if;
end loop;
end if;
end loop;
end if;
end process;
......@@ -260,6 +253,3 @@ begin
FUNC7_XAMCAP_o <= std_logic_vector(s_FUNC_XAMCAP(7));
end Behavioral;
--===========================================================================
-- Architecture end
--===========================================================================
--_______________________________________________________________________________________
-- VME TO WB INTERFACE
--------------------------------------------------------------------------------
-- CERN (BE-CO-HT)
-- VME64x Core
-- http://www.ohwr.org/projects/vme64x-core
--------------------------------------------------------------------------------
--
-- CERN,BE/CO-HT
--_______________________________________________________________________________________
-- File: VME_SharedComps.vhd
--_______________________________________________________________________________________
-- Description: This component implements the rising and falling edge detection and the
-- tripple and double sample entities
--_______________________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--_______________________________________________________________________________________
-- unit name: VME_SharedComps (VME_SharedComps.vhd)
--
-- author: Pablo Alvarez Sanchez <pablo.alvarez.sanchez@cern.ch>
-- Davide Pedretti <davide.pedretti@cern.ch>
--
-- description: This component implements the rising and falling edge
-- detection and the triple and double sample entities.
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
--------------------------------------------------------------------------------
-- 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
----------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
-- tripple sample sig_i signals to avoid metastable states
-- 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;
use ieee.std_logic_1164.all;
-- triple sample sig_i signals to avoid metastable states
entity SigInputSample is
port (
sig_i, clk_i: in std_logic;
sig_o: out std_logic );
sig_i,
clk_i : in std_logic;
sig_o : out std_logic
);
end SigInputSample;
architecture RTL of SigInputSample is
signal s_1: std_logic;
signal s_2: std_logic;
begin
process(clk_i)
begin
process (clk_i) begin
if rising_edge(clk_i) then
s_1 <= sig_i;
s_2 <= s_1;
......@@ -51,262 +57,257 @@ begin
end process;
end RTL;
-- ***************************************************
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
library ieee;
use ieee.std_logic_1164.all;
-- double sample sig_i signals to avoid metastable states
entity DoubleSigInputSample is
port (
sig_i, clk_i: in std_logic;
sig_o: out std_logic );
sig_i,
clk_i : in std_logic;
sig_o : out std_logic
);
end DoubleSigInputSample;
architecture RTL of DoubleSigInputSample is
signal s_1: std_logic;
-- signal s_2: std_logic;
signal s_1 : std_logic;
begin
process(clk_i)
begin
process (clk_i) begin
if rising_edge(clk_i) then
s_1 <= sig_i;
sig_o <= s_1;
end if;
end process;
end RTL;
--***************************************************
library IEEE;
use IEEE.STD_LOGIC_1164.all;
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity SingleRegInputSample is
generic(
width: natural:=8
generic (
width : natural := 8
);
port (
reg_i: in std_logic_vector(width-1 downto 0);
reg_o: out std_logic_vector(width-1 downto 0);
clk_i: in std_logic
reg_i : in std_logic_vector(width-1 downto 0);
reg_o : out std_logic_vector(width-1 downto 0);
clk_i : in std_logic
);
end SingleRegInputSample;
architecture RTL of SingleRegInputSample is
begin
process(clk_i)
begin
process (clk_i) begin
if rising_edge(clk_i) then
reg_o <= reg_i;
end if;
end process;
end RTL;
-- ***************************************************
--FlipFlopD
library IEEE;
use IEEE.STD_LOGIC_1164.all;
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity FlipFlopD is
port (
reset, sig_i, clk_i, enable: in std_logic;
sig_o: out std_logic );
reset,
sig_i,
clk_i,
enable : in std_logic;
sig_o : out std_logic
);
end FlipFlopD;
architecture RTL of FlipFlopD is
-- signal s_1: std_logic;
-- signal s_2: std_logic;
begin
process(clk_i)
begin
process (clk_i) begin
if rising_edge(clk_i) then
if reset = '1' then
sig_o <= '0';
elsif enable = '1' then
sig_o <= sig_i;
--sig_o <= s_1;
end if;
end if;
end process;
end RTL;
--Register 32 bits
library IEEE;
use IEEE.STD_LOGIC_1164.all;
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity 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 Reg32bit;
architecture RTL of Reg32bit is
--signal s_reg : std_logic_vector(31 downto 0);
begin
process(clk_i)
begin
process (clk_i) begin
if rising_edge(clk_i) then
if reset = '0' then
do <= (others => '0');
--s_reg <= (others => '0');
elsif enable = '1' then
do <= di;
--s_reg <= di;
end if;
end if;
--do <= s_reg;
end process;
end RTL;
--
library IEEE;
use IEEE.STD_LOGIC_1164.all;
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
-- detect rising edge
entity RisEdgeDetection is
port (
sig_i, clk_i: in std_logic;
RisEdge_o: out std_logic );
sig_i,
clk_i : in std_logic;
RisEdge_o : out std_logic
);
end RisEdgeDetection;
architecture RTL of RisEdgeDetection is
signal s_1: std_logic;
begin
process(clk_i)
begin
process (clk_i) begin
if rising_edge(clk_i) then
s_1 <= sig_i;
if s_1 = '0' and sig_i = '1' then
RisEdge_o <= '1';
else
RisEdge_o <= '0';
end if;
end if;
end process;
end RTL;
-- ***************************************************
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
library ieee;
use ieee.std_logic_1164.all;
-- detect falling edge
entity FallingEdgeDetection is
port (
sig_i, clk_i: in std_logic;
FallEdge_o: out std_logic );
sig_i,
clk_i : in std_logic;
FallEdge_o : out std_logic
);
end FallingEdgeDetection;
architecture RTL of FallingEdgeDetection is
signal s_1: std_logic;
begin
process(clk_i)
begin
process (clk_i) begin
if rising_edge(clk_i) then
s_1 <= sig_i;
if s_1 = '1' and sig_i = '0' then
FallEdge_o <= '1';
else
FallEdge_o <= '0';
end if;
end if;
end process;
end RTL;
-- ***************************************************
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
library ieee;
use ieee.std_logic_1164.all;
-- give pulse (sigEdge_o) at rising and falling edge
entity EdgeDetection is
port (
sig_i,
clk_i: in std_logic;
sigEdge_o: out std_logic
clk_i : in std_logic;
sigEdge_o : out std_logic
);
end EdgeDetection;
architecture RTL of EdgeDetection is
signal s_1: std_logic;
begin
process(clk_i)
begin
process (clk_i) begin
if rising_edge(clk_i) then
s_1 <= sig_i;
if (s_1 = '0' and sig_i = '1') or (s_1 = '1' and sig_i = '0') then
sigEdge_o <= '1';
else
sigEdge_o <= '0';
end if;
end if;
end process;
end RTL;
-- ***************************************************
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
library ieee;
use ieee.std_logic_1164.all;
-- triple sample input register reg_i to avoid metastable states
-- and catching of transition values
entity RegInputSample is
generic(
width: natural:=8
generic (
width : natural := 8
);
port (
reg_i: in std_logic_vector(width-1 downto 0);
reg_o: out std_logic_vector(width-1 downto 0);
clk_i: in std_logic
reg_i : in std_logic_vector(width-1 downto 0);
reg_o : out std_logic_vector(width-1 downto 0);
clk_i : in std_logic
);
end RegInputSample;
architecture RTL of RegInputSample is
signal reg_1, reg_2: std_logic_vector(width-1 downto 0);
signal reg_1,
reg_2 : std_logic_vector(width-1 downto 0);
begin
process(clk_i)
begin
process (clk_i) begin
if rising_edge(clk_i) then
reg_1 <= reg_i;
reg_2 <= reg_1;
reg_o <= reg_2;
end if;
end process;
end RTL;
--------------------------------------------------------------------------------
-- ***************************************************
library IEEE;
use IEEE.STD_LOGIC_1164.all;
library ieee;
use ieee.std_logic_1164.all;
-- triple sample input register reg_i to avoid metastable states
-- and catching of transition values
entity DoubleRegInputSample is
generic(
width: natural:=8
generic (
width : natural := 8
);
port (
reg_i: in std_logic_vector(width-1 downto 0);
reg_o: out std_logic_vector(width-1 downto 0);
clk_i: in std_logic
reg_i : in std_logic_vector(width-1 downto 0);
reg_o : out std_logic_vector(width-1 downto 0);
clk_i : in std_logic
);
end DoubleRegInputSample;
architecture RTL of DoubleRegInputSample is
signal reg_1, reg_2: std_logic_vector(width-1 downto 0);
signal reg_1,
reg_2 : std_logic_vector(width-1 downto 0);
begin
process(clk_i)
process (clk_i)
begin
if rising_edge(clk_i) then
reg_1 <= reg_i;
reg_o <= reg_1;
end if;
end process;
end RTL;
--___________________________________________________________________________________
-- VME TO WB INTERFACE
--------------------------------------------------------------------------------
-- CERN (BE-CO-HT)
-- VME64x Core
-- http://www.ohwr.org/projects/vme64x-core
--------------------------------------------------------------------------------
--
-- unit name: VME_Wb_master (VME_Wb_master.vhd)
--
-- author: Pablo Alvarez Sanchez <pablo.alvarez.sanchez@cern.ch>
-- Davide Pedretti <davide.pedretti@cern.ch>
--
-- description:
--
-- CERN,BE/CO-HT
--___________________________________________________________________________________
-- File: VME_Wb_master.vhd
--___________________________________________________________________________________
-- Description:
-- This component implements the WB master side in the vme64x core.
--
-- Work mode:
-- PIPELINED
-- SINGLE READ/WRITE
--
-- The WB bus can be 64 bit wide or 32 bit wide and the data organization is BIG ENDIAN
-- --> the most significant byte is carried in the lower position of the bus.
-- Eg:
-- The WB bus can be 64 bit wide or 32 bit wide and the data organization is
-- BIG ENDIAN --> the most significant byte is carried in the lower position
-- of the bus. Eg:
-- _______________________________________________________________________
-- | Byte(0)| Byte(1)| Byte(2)| Byte(3)| Byte(4)| Byte(5)| Byte(6)| Byte(7)|
-- |________|________|________|________|________|________|________|________|
......@@ -23,51 +29,55 @@
--
-- Clk _____ _____ _____ _____ _____ _____ _____
-- _____| |_____| |_____| |_____| |_____| |_____| |_____|
--
-- cyc_o ____________________________________________________________
-- _____| |________________
--
-- stb_o ________________________________________________
-- _____| |____________________________
--
-- __________________________________________
-- stall_i |________________________________________
--
-- ack_i ___________
-- ______________________________________________________| |________________
--
-- The ack_i can be asserted with some Tclk of delay, not immediately.
-- This component implements the correct shift of the data in input/output from/to WB bus
-- This component implements the correct shift of the data in input/output
-- from/to WB bus
--
-- dependencies:
--
--______________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--______________________________________________________________________________
--------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
--------------------------------------------------------------------------------
-- 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
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
-- 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;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.vme64x_pack.all;
--===========================================================================
-- Entity declaration
--===========================================================================
entity VME_Wb_master is
generic(g_wb_data_width : integer := c_width;
generic (
g_wb_data_width : integer := c_width;
g_wb_addr_width : integer := c_addr_width
);
Port ( memReq_i : in std_logic;
port (
memReq_i : in std_logic;
clk_i : in std_logic;
cardSel_i : in std_logic;
reset_i : in std_logic;
......@@ -85,34 +95,32 @@ entity VME_Wb_master is
err_i : in std_logic;
cyc_o : out std_logic;
memReq_o : out std_logic;
WBdata_o : out std_logic_vector(g_wb_data_width - 1 downto 0);
wbData_i : in std_logic_vector(g_wb_data_width - 1 downto 0);
locAddr_o : out std_logic_vector(g_wb_addr_width - 1 downto 0);
WBdata_o : out std_logic_vector(g_wb_data_width-1 downto 0);
wbData_i : in std_logic_vector(g_wb_data_width-1 downto 0);
locAddr_o : out std_logic_vector(g_wb_addr_width-1 downto 0);
memAckWB_i : in std_logic;
WbSel_o : out std_logic_vector(f_div8(g_wb_data_width) - 1 downto 0);
RW_o : out std_logic);
WbSel_o : out std_logic_vector(f_div8(g_wb_data_width)-1 downto 0);
RW_o : out std_logic
);
end VME_Wb_master;
--===========================================================================
-- Architecture declaration
--===========================================================================
architecture Behavioral of VME_Wb_master is
signal s_shift_dx : std_logic;
signal s_cyc : std_logic;
signal s_AckWithError : std_logic;
signal s_wbData_i : std_logic_vector(63 downto 0);
signal s_select : std_logic_vector(8 downto 0);
signal s_DATi_sample : std_logic_vector(g_wb_data_width - 1 downto 0);
--===========================================================================
-- Architecture begin
--===========================================================================
signal s_shift_dx : std_logic;
signal s_cyc : std_logic;
signal s_AckWithError : std_logic;
signal s_wbData_i : std_logic_vector(63 downto 0);
signal s_select : std_logic_vector(8 downto 0);
signal s_DATi_sample : std_logic_vector(g_wb_data_width-1 downto 0);
begin
s_select <= cardSel_i & sel_i;
s_select <= cardSel_i & sel_i;
s_wbData_i <= std_logic_vector(resize(unsigned(s_DATi_sample),s_wbData_i'length));
-- stb handler
process(clk_i)
s_wbData_i <= std_logic_vector(resize(unsigned(s_DATi_sample),s_wbData_i'length));
-- stb handler
process (clk_i)
begin
if rising_edge(clk_i) then
if reset_i = '1' or (stall_i = '0' and s_cyc = '1') then
......@@ -123,8 +131,8 @@ s_wbData_i <= std_logic_vector(resize(unsigned(s_DATi_sample),s_wbData_i'length)
end if;
end process;
-- cyc_o handler
process(clk_i)
-- cyc_o handler
process (clk_i)
begin
if rising_edge(clk_i) then
if reset_i = '1' or memAckWB_i = '1' then
......@@ -136,7 +144,7 @@ s_wbData_i <= std_logic_vector(resize(unsigned(s_DATi_sample),s_wbData_i'length)
end process;
cyc_o <= s_cyc;
process(clk_i)
process (clk_i)
begin
if rising_edge(clk_i) then
RW_o <= RW_i;
......@@ -144,17 +152,16 @@ s_wbData_i <= std_logic_vector(resize(unsigned(s_DATi_sample),s_wbData_i'length)
end if;
end process;
-- shift data and address for WB data bus 64 bits
-- shift data and address for WB data bus 64 bits
gen64: if (g_wb_data_width = 64) generate
process(clk_i)
process (clk_i)
begin
if rising_edge(clk_i) then
locAddr_o <= std_logic_vector(resize(unsigned(rel_locAddr_i) srl 3,g_wb_addr_width));
end if;
end process;
process(clk_i)
process (clk_i)
begin
if rising_edge(clk_i) then
case sel_i is
......@@ -165,13 +172,13 @@ s_wbData_i <= std_logic_vector(resize(unsigned(s_DATi_sample),s_wbData_i'length)
when "00001000" => WBdata_o <= std_logic_vector(unsigned(locDataInSwap_i) sll 24);
when "00000100" => WBdata_o <= std_logic_vector(unsigned(locDataInSwap_i) sll 16);
when "00000010" => WBdata_o <= std_logic_vector(unsigned(locDataInSwap_i) sll 8);
when "00000001" => WBdata_o <= locDataInSwap_i;
when "11000000" => WBdata_o <= std_logic_vector(unsigned(locDataInSwap_i) sll 48);
when "00110000" => WBdata_o <= std_logic_vector(unsigned(locDataInSwap_i) sll 32);
when "00001100" => WBdata_o <= std_logic_vector(unsigned(locDataInSwap_i) sll 16);
when "00000011" => WBdata_o <= locDataInSwap_i;
when "11110000" => WBdata_o <= std_logic_vector(unsigned(locDataInSwap_i) sll 32);
when "00001111" => WBdata_o <= locDataInSwap_i;
when "00000001" => WBdata_o <= locDataInSwap_i;
when "00000011" => WBdata_o <= locDataInSwap_i;
when "11111111" => WBdata_o <= locDataInSwap_i;
when others => null;
end case;
......@@ -179,85 +186,85 @@ s_wbData_i <= std_logic_vector(resize(unsigned(s_DATi_sample),s_wbData_i'length)
end if;
end process;
process (s_select,s_wbData_i)
process (s_select, s_wbData_i)
begin
case s_select is
when "100000010" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(15 downto 0)) srl 8, locDataOut_o'length));
when "100000100" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(23 downto 0)) srl 16,locDataOut_o'length));
when "100001000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)) srl 24,locDataOut_o'length));
when "100010000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(39 downto 0)) srl 32,locDataOut_o'length));
when "100100000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(47 downto 0)) srl 40,locDataOut_o'length));
when "101000000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(55 downto 0)) srl 48,locDataOut_o'length));
when "110000000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i) srl 56,locDataOut_o'length));
when "100001100" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)) srl 16,locDataOut_o'length));
when "100110000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(47 downto 0)) srl 32,locDataOut_o'length));
when "111000000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i) srl 48,locDataOut_o'length));
when "100000001" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(7 downto 0)), locDataOut_o'length));
when "100000011" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(15 downto 0)), locDataOut_o'length));
when "100001111" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)), locDataOut_o'length));
when "111110000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i) srl 32, locDataOut_o'length));
when "111111111" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i),locDataOut_o'length));
when others => locDataOut_o <= (others => '0');
when "100000010" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(15 downto 0)) srl 8, locDataOut_o'length));
when "100000100" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(23 downto 0)) srl 16, locDataOut_o'length));
when "100001000" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(31 downto 0)) srl 24, locDataOut_o'length));
when "100010000" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(39 downto 0)) srl 32, locDataOut_o'length));
when "100100000" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(47 downto 0)) srl 40, locDataOut_o'length));
when "101000000" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(55 downto 0)) srl 48, locDataOut_o'length));
when "110000000" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(63 downto 0)) srl 56, locDataOut_o'length));
when "100001100" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(31 downto 0)) srl 16, locDataOut_o'length));
when "100110000" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(47 downto 0)) srl 32, locDataOut_o'length));
when "111000000" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(63 downto 0)) srl 48, locDataOut_o'length));
when "100000001" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(7 downto 0)), locDataOut_o'length));
when "100000011" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(15 downto 0)), locDataOut_o'length));
when "100001111" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(31 downto 0)), locDataOut_o'length));
when "111110000" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(63 downto 0)) srl 32, locDataOut_o'length));
when "111111111" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(63 downto 0)), locDataOut_o'length));
when others =>
locDataOut_o <= (others => '0');
end case;
end process;
end generate gen64;
-- shift data and address for WB data bus 32 bits
gen32: if (g_wb_data_width = 32) generate
process(clk_i)
process (clk_i)
begin
if rising_edge(clk_i) then
locAddr_o <= std_logic_vector(resize(unsigned(rel_locAddr_i) srl 2,g_wb_addr_width));
locAddr_o <= std_logic_vector(resize(unsigned(rel_locAddr_i) srl 2, g_wb_addr_width));
end if;
end process;
process(sel_i)
process (sel_i)
begin
if sel_i = "10000000" or sel_i = "01000000" or sel_i = "00100000" or sel_i = "00010000"
or sel_i = "11000000" or sel_i = "00110000" or sel_i = "11110000" then
if sel_i = "10000000" or sel_i = "01000000" or sel_i = "00100000" or
sel_i = "00010000" or sel_i = "11000000" or sel_i = "00110000" or
sel_i = "11110000"
then
s_shift_dx <= '1';
else
s_shift_dx <= '0';
end if;
end process;
process(clk_i)
process (clk_i)
begin
if rising_edge(clk_i) then
case sel_i is
when "10000000" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i) sll 24,g_wb_data_width));
when "01000000" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i) sll 16,g_wb_data_width));
when "00100000" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i) sll 8,g_wb_data_width));
when "00010000" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i),g_wb_data_width));
when "00001000" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i) sll 24,g_wb_data_width));
when "00000100" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i) sll 16,g_wb_data_width));
when "00000010" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i) sll 8,g_wb_data_width));
when "11000000" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i) sll 16,g_wb_data_width));
when "00110000" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i),g_wb_data_width));
when "00001100" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i) sll 16,g_wb_data_width));
when "11110000" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i),g_wb_data_width));
when "00001111" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i),g_wb_data_width));
when "00000001" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i),g_wb_data_width));
when "00000011" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i),g_wb_data_width));
when "11111111" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i),g_wb_data_width));
when "10000000" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i) sll 24, g_wb_data_width));
when "01000000" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i) sll 16, g_wb_data_width));
when "00100000" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i) sll 8, g_wb_data_width));
when "00010000" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i), g_wb_data_width));
when "00001000" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i) sll 24, g_wb_data_width));
when "00000100" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i) sll 16, g_wb_data_width));
when "00000010" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i) sll 8, g_wb_data_width));
when "00000001" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i), g_wb_data_width));
when "11000000" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i) sll 16, g_wb_data_width));
when "00110000" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i), g_wb_data_width));
when "00001100" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i) sll 16, g_wb_data_width));
when "00000011" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i), g_wb_data_width));
when "11110000" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i), g_wb_data_width));
when "00001111" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i), g_wb_data_width));
when "11111111" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i), g_wb_data_width));
when others => null;
end case;
......@@ -269,51 +276,52 @@ s_wbData_i <= std_logic_vector(resize(unsigned(s_DATi_sample),s_wbData_i'length)
end if;
end process;
process (s_select,s_wbData_i)
process (s_select, s_wbData_i)
begin
case s_select is
when "100000010" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(15 downto 0)) srl 8, locDataOut_o'length));
when "100000100" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(23 downto 0)) srl 16,locDataOut_o'length));
when "100001000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)) srl 24,locDataOut_o'length));
when "100010000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(7 downto 0)),locDataOut_o'length));
when "100100000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(15 downto 0)) srl 8,locDataOut_o'length));
when "101000000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(23 downto 0)) srl 16,locDataOut_o'length));
when "110000000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)) srl 24,locDataOut_o'length));
when "100001100" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)) srl 16,locDataOut_o'length));
when "100110000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(15 downto 0)),locDataOut_o'length));
when "111000000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)) srl 16,locDataOut_o'length));
when "100000001" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(7 downto 0)), locDataOut_o'length));
when "100000011" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(15 downto 0)), locDataOut_o'length));
when "100001111" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)), locDataOut_o'length));
when "111110000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)), locDataOut_o'length));
when others => locDataOut_o <= (others => '0');
when "100000010" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(15 downto 0)) srl 8, locDataOut_o'length));
when "100000100" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(23 downto 0)) srl 16, locDataOut_o'length));
when "100001000" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(31 downto 0)) srl 24, locDataOut_o'length));
when "100010000" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(7 downto 0)), locDataOut_o'length));
when "100100000" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(15 downto 0)) srl 8, locDataOut_o'length));
when "101000000" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(23 downto 0)) srl 16, locDataOut_o'length));
when "110000000" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(31 downto 0)) srl 24, locDataOut_o'length));
when "100001100" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(31 downto 0)) srl 16, locDataOut_o'length));
when "100110000" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(15 downto 0)), locDataOut_o'length));
when "111000000" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(31 downto 0)) srl 16, locDataOut_o'length));
when "100000001" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(7 downto 0)), locDataOut_o'length));
when "100000011" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(15 downto 0)), locDataOut_o'length));
when "100001111" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(31 downto 0)), locDataOut_o'length));
when "111110000" =>
locDataOut_o <= std_logic_vector(resize(unsigned(s_wbData_i(31 downto 0)), locDataOut_o'length));
when others =>
locDataOut_o <= (others => '0');
end case;
end process;
end generate gen32;
err_o <= err_i;
rty_o <= rty_i;
memAckWb_o <= memAckWB_i or s_AckWithError or rty_i;
------------------------------------------------------------------------
-- This process registers the WB data input; this is a warranty that this
-- data will be stable during all the time the VME_bus component needs to
-- transfers its to the VME bus.
process(clk_i)
process (clk_i)
begin
if rising_edge(clk_i) then
if memAckWB_i = '1' then
......@@ -322,8 +330,4 @@ s_wbData_i <= std_logic_vector(resize(unsigned(s_DATi_sample),s_wbData_i'length)
end if;
end process;
------------------------------------------------------------------------
end Behavioral;
--===========================================================================
-- Architecture end
--===========================================================================
--______________________________________________________________________________|
-- VME TO WB INTERFACE |
-- |
-- CERN,BE/CO-HT |
--______________________________________________________________________________|
-- File: VME_bus.vhd |
--______________________________________________________________________________|
-- Description: |
-- This block acts as interface between the VMEbus and the CR/CSR space or WBbus.
-- |
-- _____________VME_bus________________ |
-- | _______ | |
-- | ______ | M | | |
-- | | A D | | A F | ____| |
-- | | C E | | I S | | W | |
-- | | C C | | N M | | B | |
-- VME | | E O | | | | | |
-- BUS | | S D | |_______| | M | |
-- | | S E | | A | |
-- | |______| | S | |
-- | ______ ___________ | T | |
-- | | I | | OTHER || E | |
-- | | N | | DATA & || R | |
-- | | I | | ADDR ||____| |
-- | | T | | PROCESS | | |
-- | |______| |___________| | |
-- |____________________________________| |
-- |
-- The INIT component performs the initialization of the core after the power-up|
-- or reset. |
-- The Access decode component decodes the address to check if the board is the |
-- responding Slave. This component is of fundamental importance, indeed only |
-- one Slave can answer to the Master! |
-- In the right side you can see the WB Master who implements the Wb Pipelined |
--------------------------------------------------------------------------------
-- CERN (BE-CO-HT)
-- VME64x Core
-- http://www.ohwr.org/projects/vme64x-core
--------------------------------------------------------------------------------
--
-- unit name: VME_bus (VME_bus.vhd)
--
-- author: Pablo Alvarez Sanchez <pablo.alvarez.sanchez@cern.ch>
-- Davide Pedretti <davide.pedretti@cern.ch>
--
-- description:
--
-- This block acts as interface between the VMEbus and the CR/CSR space or
-- WBbus.
--
-- _____________VME_bus________________
-- | _______ |
-- | ______ | M | |
-- | | A D | | A F | ____|
-- | | C E | | I S | | W |
-- | | C C | | N M | | B |
-- VME | | E O | | | | |
-- BUS | | S D | |_______| | M |
-- | | S E | | A |
-- | |______| | S |
-- | ______ ___________ | T |
-- | | I | | OTHER || E |
-- | | N | | DATA & || R |
-- | | I | | ADDR ||____|
-- | | T | | PROCESS | |
-- | |______| |___________| |
-- |____________________________________|
--
-- The INIT component performs the initialization of the core after the
-- power-up or reset.
-- The Access decode component decodes the address to check if the board is
-- the responding Slave. This component is of fundamental importance, indeed
-- only one Slave can answer to the Master!
-- In the right side you can see the WB Master who implements the Wb Pipelined
-- single read/write protocol.
-- Each VME board plugged in a slot acts as a VME slave module and it has only
-- one CR/CSR space (conforming with the specification) so only one FPGA at time
-- must drive the output lines on the VME bus; only one FPGA at time can carry
-- the vme64x core or other similar VME slave core.
-- Inside each component is possible read a more detailed description. |
--______________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--______________________________________________________________________________
-- Modifications:
-- 2016-08-24: by Jan Pospisil (j.pospisil@cern.ch)
-- * commented out unused code
-- * added default values for determined start-up state
--______________________________________________________________________________
-- one CR/CSR space (conforming with the specification) so only one FPGA at
-- time must drive the output lines on the VME bus; only one FPGA at time can
-- carry the vme64x core or other similar VME slave core.
-- Inside each component is possible read a more detailed description.
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
--------------------------------------------------------------------------------
-- 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
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;
-- 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;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.vme64x_pack.all;
--===========================================================================
-- Entity declaration
--===========================================================================
entity 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(
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
reset_o : out std_logic; -- to the Interrupt Generator and IRQ controller
reset_o : out std_logic; -- to the Interrupt Generator and IRQ
-- controller
-- VME signals
VME_RST_n_i : in std_logic;
VME_AS_n_i : in std_logic;
......@@ -104,16 +104,16 @@ entity VME_bus is
VME_DATA_DIR_o : out std_logic;
VME_DATA_OE_N_o : out std_logic;
VME_AM_i : in std_logic_vector(5 downto 0);
VME_IACK_n_i : in std_logic; -- USE VME_IACK_n_i and NOT VME_IACKIN_n_i !!!!
-- because VME_IACKIN_n_i is delayed the more you
-- are away from Slots 0
VME_IACK_n_i : in std_logic; -- USE VME_IACK_n_i and NOT VME_IACKIN_n_i
-- because VME_IACKIN_n_i is delayed the
-- more you are away from Slots 0
-- WB signals
memReq_o : out std_logic;
memAckWB_i : in std_logic;
wbData_o : out std_logic_vector(g_wb_data_width - 1 downto 0);
wbData_i : in std_logic_vector(g_wb_data_width - 1 downto 0);
locAddr_o : out std_logic_vector(g_wb_addr_width - 1 downto 0);
wbSel_o : out std_logic_vector(f_div8(g_wb_data_width) - 1 downto 0);
wbData_o : out std_logic_vector(g_wb_data_width-1 downto 0);
wbData_i : in std_logic_vector(g_wb_data_width-1 downto 0);
locAddr_o : out std_logic_vector(g_wb_addr_width-1 downto 0);
wbSel_o : out std_logic_vector(f_div8(g_wb_data_width)-1 downto 0);
RW_o : out std_logic;
cyc_o : out std_logic;
err_i : in std_logic;
......@@ -147,9 +147,7 @@ entity VME_bus is
BAR_i : in std_logic_vector(4 downto 0)
);
end VME_bus;
--===========================================================================
-- Architecture declaration
--===========================================================================
architecture RTL of VME_bus is
signal s_reset : std_logic;
......@@ -186,11 +184,11 @@ architecture RTL of VME_bus is
signal s_locDataOutWb : std_logic_vector(63 downto 0);
-- Latched signals
signal s_VMEaddrLatched : unsigned(63 downto 1); --Latch on AS falling edge
signal s_VMEaddrLatched : unsigned(63 downto 1); -- Latch on AS falling edge
signal s_LWORDlatched : std_logic; -- Stores LWORD on falling edge of AS
signal s_DSlatched : std_logic_vector(1 downto 0) := (others => '0'); -- Stores DS
signal s_AMlatched : std_logic_vector(5 downto 0); --Latch on AS f. edge
signal s_XAM : unsigned(7 downto 0) := (others => '0'); -- Stores received XAM -- TODO: what's this?
signal s_AMlatched : std_logic_vector(5 downto 0); -- Latch on AS f. edge
signal s_XAM : unsigned(7 downto 0) := (others => '0'); -- Stores received XAM
-- Type of data transfer (depending on VME_DS_n, VME_LWORD_n and VME_ADDR(1))
signal s_typeOfDataTransfer : t_typeOfDataTransfer;
......@@ -221,12 +219,13 @@ architecture RTL of VME_bus is
signal s_mainFSMreset : std_logic; -- Resets main FSM on AS r. edge
signal s_dataPhase : std_logic; -- for A64 and multipl. transf.
signal s_transferActive : std_logic; -- active VME transfer
-- signal s_retry : std_logic; -- RETRY signal
--signal s_retry : std_logic; -- RETRY signal
signal s_retry_out : std_logic;
-- uncomment if 2e is implemented:
--signal s_berr : std_logic; -- BERR signal
-- signal s_berr_1 : std_logic; -- -- uncomment if 2e is implemented:
-- signal s_berr_2 : std_logic; -- -- uncomment if 2e is implemented:
--signal s_berr_1 : std_logic; --
--signal s_berr_2 : std_logic; --
-- Access decode signals
signal s_confAccess : std_logic; -- Asserted when CR or CSR is addressed
......@@ -262,7 +261,7 @@ architecture RTL of VME_bus is
signal s_rty1 : std_logic;
-- Initialization signals
signal s_initInProgress : std_logic; --The initialization is in progress
signal s_initInProgress : std_logic; -- The initialization is in progress
signal s_initReadCounter : unsigned(8 downto 0); -- Counts read operations
signal s_initReadCounter1 : std_logic_vector(8 downto 0);
signal s_CRaddr : unsigned(18 downto 0);
......@@ -282,21 +281,25 @@ architecture RTL of VME_bus is
signal s_CRCSRtype : std_logic;
signal s_err : std_logic;
signal s_rty : std_logic;
--
signal s_wbMaster_rst : std_logic;
signal s_num_latchDS : integer;
begin
-- calculate the number of LATCH DS states necessary to match the timing
-- Calculate the number of LATCH DS states necessary to match the timing
-- rule 2.39 page 113 VMEbus specification ANSI/IEEE STD1014-1987.
s_num_latchDS <= f_latchDS(g_clock);
---------
s_is_d64 <= '1' when s_sel = "11111111" else '0'; --used to drive the VME_ADDR_DIR_o
---------
-- Used to drive the VME_ADDR_DIR_o
s_is_d64 <= '1' when s_sel = "11111111" else '0';
s_RW <= VME_WRITE_n_i;
s_reset <= (not rst_n_i) or not(VME_RST_n_i) or s_sw_reset; -- hw and sw reset
-- HW and SW reset
s_reset <= (not rst_n_i) or (not VME_RST_n_i) or s_sw_reset;
reset_o <= s_reset; -- Asserted when high
-------------------------------------------------------------------------
-- These output signals are connected to the buffers on the board
-- SN74VMEH22501A Function table:
-- OEn | DIR | OUTPUT OEAB | OEBYn | OUTPUT
......@@ -309,11 +312,14 @@ begin
VME_DATA_OE_N_o <= s_dataOE;
VME_ADDR_DIR_o <= s_addrDir;
VME_ADDR_OE_N_o <= s_addrOE;
VME_DTACK_OE_o <= s_dtackOE; -- |
VME_DTACK_OE_o <= s_dtackOE;
-- VME DTACK:
VME_DTACK_n_o <= s_mainDTACK;
--------------------------ACCESS MODE DECODERS----------------------------
------------------------------------------------------------------------------
-- Access Mode Decoders
------------------------------------------------------------------------------
-- Type of data transfer decoder
-- VME64 ANSI/VITA 1-1994...Table 2-2 "Signal levels during data transfers"
-- A2 is used to select the D64 type (D64 --> MBLT and 2edge cycles)
......@@ -326,7 +332,9 @@ begin
-- transfer type; indeed the D32 access with A2 = '0' (eg 0x010)
-- fall within D64 access --> The data transfer type have to be evaluated
-- jointly with the address type.
--
-- Bytes position on VMEbus:
--
-- A24-A31 | A16-A23 | A08-A15 | A00-A07 | D24-D31 | D16-D23 | D08-D15 | D00-D07
-- | | | | | | BYTE(0) |
-- | | | | | | | BYTE(1)
......@@ -336,10 +344,8 @@ begin
-- | | | | | | BYTE(2) | BYTE(3)
-- | | | | BYTE(0)| BYTE(1) | BYTE(2) | BYTE(3)
-- BYTE(0)| BYTE(1) | BYTE(2) | BYTE(3) | BYTE(4)| BYTE(5) | BYTE(6) | BYTE(7)
with s_typeOfDataTransferSelect select
s_typeOfDataTransfer <= D08_0 when "01010",
with s_typeOfDataTransferSelect select s_typeOfDataTransfer <=
D08_0 when "01010",
D08_0 when "01011",
D08_1 when "10010",
D08_1 when "10011",
......@@ -355,8 +361,8 @@ begin
D64 when "00000",
TypeError when others;
with s_typeOfDataTransferSelect select
s_DataShift <= b"001000" when "01010",
with s_typeOfDataTransferSelect select s_DataShift <=
b"001000" when "01010",
b"001000" when "01011",
b"001000" when "01110",
b"001000" when "01111",
......@@ -366,8 +372,8 @@ begin
-- Either the supervisor or user access modes are supported
s_addressingTypeSelect <= s_AMlatched;
with s_addressingTypeSelect select
s_addressingType <= A24 when c_A24_S_sup,
with s_addressingTypeSelect select s_addressingType <=
A24 when c_A24_S_sup,
A24 when c_A24_S,
A24_BLT when c_A24_BLT,
A24_BLT when c_A24_BLT_sup,
......@@ -389,8 +395,8 @@ begin
AM_Error when others;
-- Transfer type decoder
with s_addressingType select
s_transferType <= SINGLE when A24,
with s_addressingType select s_transferType <=
SINGLE when A24,
SINGLE when CR_CSR,
SINGLE when A16,
SINGLE when A32,
......@@ -404,14 +410,12 @@ begin
TWOe when TWOedge,
error when others;
s_addrWidth <= s_addrWidth1;
-- To implement the A32 2eVME and A32 2eSST accesses the following logic
-- must be changed:
with s_addressingType select
s_addrWidth1 <= "00" when A16,
-- To implement the A32 2eVME and A32 2eSST accesses the following logic
-- must be changed:
with s_addressingType select s_addrWidth1 <=
"00" when A16,
"01" when A24,
"01" when A24_BLT,
"01" when A24_MBLT,
......@@ -421,7 +425,9 @@ begin
"10" when A32_MBLT,
"11" when others;
-------------------------------------MAIN FSM--------------------------------|
------------------------------------------------------------------------------
-- MAIN FSM
------------------------------------------------------------------------------
s_memReq <= s_FSM.s_memReq;
s_decode <= s_FSM.s_decode;
s_dtackOE <= s_FSM.s_dtackOE;
......@@ -443,10 +449,11 @@ begin
--s_berr <= s_FSM.s_berr;
s_BERR_out <= s_FSM.s_BERR_out;
p_VMEmainFSM : process(clk_i)
p_VMEmainFSM : process (clk_i)
begin
if rising_edge(clk_i) then
if s_reset = '1' or s_mainFSMreset = '1' then -- FSM resetted after power up,
if s_reset = '1' or s_mainFSMreset = '1' then
-- FSM resetted after power up,
-- software reset, manually reset,
-- on rising edge of AS.
s_FSM <= c_FSM_default;
......@@ -461,7 +468,8 @@ begin
-- The VME_IACK_n_i signal is asserted by the Interrupt handler
-- during all the Interrupt cycle.
if s_VMEaddrLatch = '1' and VME_IACK_n_i = '1' then
s_mainFSMstate <= DECODE_ACCESS; -- if AS falling edge --> go in DECODE_ACCESS
-- if AS falling edge --> go in DECODE_ACCESS
s_mainFSMstate <= DECODE_ACCESS;
else
s_mainFSMstate <= IDLE;
end if;
......@@ -472,18 +480,20 @@ begin
s_FSM.s_decode <= '1';
s_FSM.s_DSlatch <= '1';
-- uncomment for using 2e modes:
-- if s_addressingType = TWOedge then -- start 2e transfer
-- s_mainFSMstate <= WAIT_FOR_DS_2e;
if s_confAccess = '1' or (s_cardSel = '1') then
--confAccess = '1' it means CR/CSR space addressed
--s_cardSel = '1' it means WB application addressed
--if s_addressingType = TWOedge then
---- start 2e transfer
--s_mainFSMstate <= WAIT_FOR_DS_2e;
if s_confAccess = '1' or s_cardSel = '1' then
-- confAccess = '1' it means CR/CSR space addressed
-- s_cardSel = '1' it means WB application addressed
s_mainFSMstate <= WAIT_FOR_DS;
else
s_mainFSMstate <= DECODE_ACCESS;
-- another board will answer; wait here the rising edge on VME_AS_i
end if;
when WAIT_FOR_DS => -- wait until DS /= "11"
when WAIT_FOR_DS =>
-- wait until DS /= "11"
s_FSM <= c_FSM_default;
s_FSM.s_dtackOE <= '1';
s_FSM.s_addrDir <= (s_is_d64) and VME_WRITE_n_i;
......@@ -558,7 +568,6 @@ begin
s_mainFSMstate <= CHECK_TRANSFER_TYPE;
when CHECK_TRANSFER_TYPE =>
s_FSM <= c_FSM_default;
s_FSM.s_dtackOE <= '1';
......@@ -566,12 +575,18 @@ begin
s_FSM.s_addrDir <= (s_is_d64) and VME_WRITE_n_i;
s_FSM.s_dataPhase <= s_dataPhase;
s_FSM.s_transferActive <= '1';
if (s_transferType = SINGLE or s_transferType = BLT) and s_addrWidth /= "11" then
if (s_transferType = SINGLE or s_transferType = BLT) and
s_addrWidth /= "11"
then
s_mainFSMstate <= MEMORY_REQ;
s_FSM.s_memReq <= '1';
elsif (s_transferType = MBLT or s_addrWidth = "11") and s_dataPhase = '0' then
elsif (s_transferType = MBLT or s_addrWidth = "11") and
s_dataPhase = '0'
then
s_mainFSMstate <= DTACK_LOW;
elsif (s_transferType = MBLT or s_addrWidth = "11") and s_dataPhase = '1' then
elsif (s_transferType = MBLT or s_addrWidth = "11") and
s_dataPhase = '1'
then
s_mainFSMstate <= MEMORY_REQ;
s_FSM.s_memReq <= '1';
end if;
......@@ -639,15 +654,20 @@ begin
s_FSM.s_dataPhase <= s_dataPhase;
s_FSM.s_transferActive <= '1';
if (s_transferType = SINGLE and s_addrWidth /= "11") or
(s_transferType = SINGLE and s_addrWidth = "11" and s_dataPhase = '1') then
(s_transferType = SINGLE and s_addrWidth = "11" and s_dataPhase = '1')
then
s_mainFSMstate <= WAIT_FOR_DS;
elsif (s_transferType = BLT and s_addrWidth /= "11") or
(s_transferType = BLT and s_addrWidth = "11" and s_dataPhase = '1') or
(s_transferType = MBLT and s_dataPhase = '1') then
(s_transferType = MBLT and s_dataPhase = '1')
then
s_mainFSMstate <= INCREMENT_ADDR;
elsif (s_transferType = MBLT or s_addrWidth = "11")and s_dataPhase = '0' then
elsif (s_transferType = MBLT or s_addrWidth = "11") and
s_dataPhase = '0'
then
s_mainFSMstate <= SET_DATA_PHASE;
else s_mainFSMstate <= DECIDE_NEXT_CYCLE;
else
s_mainFSMstate <= DECIDE_NEXT_CYCLE;
end if;
when INCREMENT_ADDR =>
......@@ -676,7 +696,9 @@ begin
end if;
end process;
------------------------- RETRY and ERROR drivers----------------------|
------------------------------------------------------------------------------
-- Retry and Error Drivers
------------------------------------------------------------------------------
-- s_rty is asserted by the WB application
-- s_retry is used during the 2e cycles.
-- 2.3.13 Retry Capability...vme64 ANSI/VITA 1-1994 (R2002):
......@@ -689,8 +711,7 @@ begin
-- Please note that the VME_WB_Master component supports single write/read
-- pipelined cycles, so the WB Slave should drive the stall signal to '1' if
-- the resource is busy
p_RETRYdriver : process(clk_i)
p_RETRYdriver : process (clk_i)
begin
if rising_edge(clk_i) then
if s_retry_out = '1' then
......@@ -704,15 +725,15 @@ begin
end process;
-- BERR driver
-- The slave asserts the Error line during the Decode access phase when an error
-- condition is detected and the s_BERRcondition is asserted.
-- When the FSM is in the DTACK_LOW state one of the VME_DTACK and VME_BERR lines
-- is asserted.
-- The VME_BERR line can not be asserted by the slave at anytime, but only during
-- the DTACK_LOW state; this to avoid that one temporary error condition
-- during the decode access phase causes an undesired assertion of VME_BERR line.
p_BERRdriver : process(clk_i)
-- The slave asserts the Error line during the Decode access phase when an
-- error condition is detected and the s_BERRcondition is asserted.
-- When the FSM is in the DTACK_LOW state one of the VME_DTACK and VME_BERR
-- lines is asserted.
-- The VME_BERR line can not be asserted by the slave at anytime, but only
-- during the DTACK_LOW state; this to avoid that one temporary error
-- condition during the decode access phase causes an undesired assertion of
-- VME_BERR line.
p_BERRdriver : process (clk_i)
begin
if rising_edge(clk_i) then
-- uncomment if 2e is implemented:
......@@ -725,13 +746,13 @@ begin
VME_BERR_o <= '0';
end if;
end if;
end process;
-- When the VME_BERR line is asserted this process asserts the error flag; This flag
-- acts as the BERR flag --> BIT SET REGISTER's bit 3 in the CSR space
end process;
FlagError : process(clk_i)
begin
-- When the VME_BERR line is asserted this process asserts the error flag;
-- This flag acts as the BERR flag --> BIT SET REGISTER's bit 3 in the CSR
-- space
FlagError : process (clk_i)
begin
if rising_edge (clk_i) then
if s_resetflag = '1' or s_reset = '1' then
s_errorflag <= '0';
......@@ -739,46 +760,50 @@ begin
s_errorflag <= '1';
end if;
end if;
end process;
-- This process detects an error condition and assert the s_BERRcondition signal
-- A transfer cycle is terminated with assertion of this signal if the VME64x
-- slave does not recognize the data or addressing type used in the transfer cycle,
-- if a Master attempts to access in BLT mode with D08 or D16, if the master attempts
-- to access in MBLT mode and the WB data bus is 32 bits, or if the read only memory
-- is addressed during a write only cycle!
end process;
process(clk_i)
begin
-- This process detects an error condition and assert the s_BERRcondition
-- signal. A transfer cycle is terminated with assertion of this signal if
-- the VME64x slave does not recognize the data or addressing type used in
-- the transfer cycle, if a Master attempts to access in BLT mode with D08
-- or D16, if the master attempts to access in MBLT mode and the WB data bus
-- is 32 bits, or if the read only memory is addressed during a write only
-- cycle!
process (clk_i)
begin
if rising_edge(clk_i) then
if s_reset = '1' then s_BERRcondition <= '0';
elsif (s_CRAMaddressed = '1' and s_CRaddressed = '1') or (s_CRAMaddressed = '1' and
s_CSRaddressed = '1') or (s_CRaddressed = '1' and s_confAccess = '1' and s_RW = '0')
or (s_CSRaddressed = '1' and s_CRaddressed = '1') or ((s_transferType = error or
s_wberr1 = '1') and s_transferActive='1') or (s_typeOfDataTransfer = TypeError) or
(s_addressingType = AM_Error) or s_blockTransferLimit = '1' or
(s_transferType = BLT and (not(s_typeOfDataTransfer = D32 or
s_typeOfDataTransfer = D64))) or (s_transferType = MBLT and
s_typeOfDataTransfer /= D64) or (s_is_d64 = '1' and g_wb_data_width = 32) then
elsif
(s_CRAMaddressed = '1' and s_CRaddressed = '1') or
(s_CRAMaddressed = '1' and s_CSRaddressed = '1') or
(s_CRaddressed = '1' and s_confAccess = '1' and s_RW = '0') or
(s_CSRaddressed = '1' and s_CRaddressed = '1') or
((s_transferType = error or s_wberr1 = '1') and s_transferActive = '1') or
(s_typeOfDataTransfer = TypeError) or
(s_addressingType = AM_Error) or
(s_blockTransferLimit = '1') or
(s_transferType = BLT and (not(s_typeOfDataTransfer = D32 or s_typeOfDataTransfer = D64))) or
(s_transferType = MBLT and s_typeOfDataTransfer /= D64) or
(s_is_d64 = '1' and g_wb_data_width = 32)
then
s_BERRcondition <= '1';
else
s_BERRcondition <= '0';
end if;
end if;
end process;
end process;
-- generate the error condition if block transfer overflows the limit
-- BLT --> block transfer limit = 256 bytes (rule 2.12a VME64 std ANSI/VITA 1-1994)
-- MBLT --> block transfer limit = 2048 bytes (rule 2.78 VME64 std ANSI/VITA 1-1994)
with s_transferType select
s_blockTransferLimit <= s_addrOffset(8) when BLT,
-- generate the error condition if block transfer overflows the limit
-- BLT --> block transfer limit = 256 bytes (rule 2.12a ANSI/VITA 1-1994)
-- MBLT --> block transfer limit = 2048 bytes (rule 2.78 ANSI/VITA 1-1994)
with s_transferType select s_blockTransferLimit <=
s_addrOffset(8) when BLT,
s_addrOffset(11) when MBLT,
'0' when others;
-- wb err handler
process(clk_i)
begin
-- wb err handler
process (clk_i)
begin
if rising_edge(clk_i) then
if s_mainFSMreset = '1' or s_reset = '1' then
s_wberr1 <= '0';
......@@ -786,11 +811,11 @@ begin
s_wberr1 <= '1';
end if;
end if;
end process;
end process;
-- wb retry handler
process(clk_i)
begin
-- wb retry handler
process (clk_i)
begin
if rising_edge(clk_i) then
if s_mainFSMreset = '1' or s_reset = '1' then
s_rty1 <= '0';
......@@ -798,21 +823,21 @@ begin
s_rty1 <= '1';
end if;
end if;
end process;
end process;
---------------------------------------------------------------------|
--These two mux are inserted to provide the MBLT access mode
p_ADDRmux : process(clk_i)
begin
-- These two mux are inserted to provide the MBLT access mode
p_ADDRmux : process (clk_i)
begin
if rising_edge(clk_i) then
if s_dataToAddrBus = '1' then
VME_ADDR_o <= s_locDataSwap(63 downto 33);
VME_LWORD_n_o <= s_locDataSwap(32);
end if;
end if;
end process;
p_DATAmux : process(clk_i)
begin
end process;
p_DATAmux : process (clk_i)
begin
if rising_edge(clk_i) then
if s_dataToAddrBus = '1' or s_dataToOutput = '1' then
if s_addressingType = CR_CSR then
......@@ -822,14 +847,18 @@ begin
end if;
end if;
end if;
end process;
---------------------ADDRESS_HANDLER_PROCESS------------------------|
--Local address & AM & 2e address phase latching
s_VMEaddrInput <= unsigned(VME_ADDR_i);
s_LWORDinput <= VME_LWORD_n_i;
s_VMEdataInput <= unsigned(VME_DATA_i);
p_addrLatching : process(clk_i)
begin
end process;
------------------------------------------------------------------------------
-- Address Handler Process
------------------------------------------------------------------------------
--Local address & AM & 2e address phase latching
s_VMEaddrInput <= unsigned(VME_ADDR_i);
s_LWORDinput <= VME_LWORD_n_i;
s_VMEdataInput <= unsigned(VME_DATA_i);
p_addrLatching : process (clk_i)
begin
if rising_edge(clk_i) then
if s_reset = '1' or s_mainFSMreset = '1' then
s_VMEaddrLatched <= (others => '0');
......@@ -843,27 +872,27 @@ begin
end if;
end if;
end if;
end process;
end process;
with s_addrWidth select
s_locAddrBeforeOffset(63 downto 1) <= x"000000000000" & s_VMEaddrLatched(15 downto 1) when "00",
with s_addrWidth select s_locAddrBeforeOffset(63 downto 1) <=
x"000000000000" & s_VMEaddrLatched(15 downto 1) when "00",
x"0000000000" & s_VMEaddrLatched(23 downto 1) when "01",
x"00000000" & s_VMEaddrLatched(31 downto 1) when "10",
s_VMEaddrLatched(63 downto 1) when others;
with s_DSlatched select
s_locAddrBeforeOffset(0) <= '0' when "01",
with s_DSlatched select s_locAddrBeforeOffset(0) <=
'0' when "01",
'1' when "10",
'0' when others;
s_locAddr2e <= s_phase1addr(63 downto 8) & s_phase2addr(7 downto 0);
s_locAddr2e <= s_phase1addr(63 downto 8) & s_phase2addr(7 downto 0);
-- This process generates the s_locAddr that is used during the access decode process;
-- If the board is addressed the VME_Access_Decode component generates the s_base_addr
-- The s_rel_locAddr is used in the VME_WB_master to address the WB memory
process(clk_i)
begin
-- This process generates the s_locAddr that is used during the access decode
-- process; If the board is addressed the VME_Access_Decode component
-- generates the s_base_addr.
-- The s_rel_locAddr is used in the VME_WB_master to address the WB memory
process (clk_i)
begin
if rising_edge(clk_i) then
if s_addressingType = TWOedge then
s_rel_locAddr <= s_locAddr2e + s_addrOffset-s_base_addr;
......@@ -875,14 +904,14 @@ begin
s_locAddr <= s_locAddrBeforeOffset;
end if;
end if;
end process;
end process;
-- Local address incrementing
-- This process generates the s_addrOffset
-- The s_addrOffset is /= 0 during BLT, MBLT and 2e access modes, when
-- the vme64x core increments the address every cycle
p_addrIncrementing : process(clk_i)
begin
-- Local address incrementing
-- This process generates the s_addrOffset
-- The s_addrOffset is /= 0 during BLT, MBLT and 2e access modes, when
-- the vme64x core increments the address every cycle
p_addrIncrementing : process (clk_i)
begin
if rising_edge(clk_i) then
if s_reset = '1' or s_mainFSMreset = '1' then
s_addrOffset <= (others => '0');
......@@ -890,10 +919,15 @@ begin
if s_addressingType = TWOedge then
s_addrOffset <= s_addrOffset + 8; -- the TWOedge access is D64
else
if s_typeOfDataTransfer = D08_0 or s_typeOfDataTransfer = D08_1 or
s_typeOfDataTransfer = D08_2 or s_typeOfDataTransfer = D08_3 then
if s_typeOfDataTransfer = D08_0 or
s_typeOfDataTransfer = D08_1 or
s_typeOfDataTransfer = D08_2 or
s_typeOfDataTransfer = D08_3
then
s_addrOffset <= s_addrOffset + 1;
elsif s_typeOfDataTransfer = D16_01 or s_typeOfDataTransfer = D16_23 then
elsif s_typeOfDataTransfer = D16_01 or
s_typeOfDataTransfer = D16_23
then
s_addrOffset <= s_addrOffset + 2;
elsif s_typeOfDataTransfer = D64 then
if s_transferType = MBLT then
......@@ -911,114 +945,133 @@ begin
s_addrOffset <= s_addrOffset;
end if;
end if;
end process;
end process;
s_CrCsrOffsetAddr <= "00"&s_locAddr(18 downto 2) when s_mainFSMreset = '0' else
(others => '0');
s_CrCsrOffsetAddr <= "00" & s_locAddr(18 downto 2)
when s_mainFSMreset = '0'
else (others => '0');
s_CRaddr <= (s_CrCsrOffsetAddr) when s_initInProgress = '0' else
(resize(s_initReadCounter, s_CRaddr'length));
s_CRaddr <= s_CrCsrOffsetAddr
when s_initInProgress = '0'
else resize(s_initReadCounter, s_CRaddr'length);
CRaddr_o <= std_logic_vector(s_CRaddr(11 downto 0));
CRAMaddr_o <= std_logic_vector(resize(s_CrCsrOffsetAddr - unsigned(s_BEG_CRAM(18 downto 0)),
CRaddr_o <= std_logic_vector(s_CRaddr(11 downto 0));
CRAMaddr_o <= std_logic_vector(resize(s_CrCsrOffsetAddr - unsigned(s_BEG_CRAM(18 downto 0)),
f_log2_size(g_cram_size)));
--------------------DATA HANDLER PROCESS---------------------------- |
-- Data strobe latching
p_DSlatching : process(clk_i)
begin
------------------------------------------------------------------------------
-- Data Handler Process
------------------------------------------------------------------------------
-- Data strobe latching
p_DSlatching : process (clk_i)
begin
if rising_edge(clk_i) then
if s_DSlatch = '1' then
s_DSlatched <= VME_DS_ant_n_i;
end if;
end if;
end process;
end process;
s_VMEdata64In(63 downto 33) <= s_VMEaddrInput(31 downto 1);
s_VMEdata64In(32) <= (s_LWORDinput);
s_VMEdata64In(31 downto 0) <= s_VMEdataInput(31 downto 0);
s_VMEdata64In(63 downto 33) <= s_VMEaddrInput(31 downto 1);
s_VMEdata64In(32) <= s_LWORDinput;
s_VMEdata64In(31 downto 0) <= s_VMEdataInput(31 downto 0);
-- This process aligns the VME data input in the lsb
process(clk_i)
begin
-- This process aligns the VME data input in the lsb
process (clk_i)
begin
if rising_edge(clk_i) then
s_locDataIn <= unsigned(s_VMEdata64In) srl to_integer(unsigned(s_DataShift));
end if;
end process;
end process;
CSRData_o <= std_logic_vector(s_locDataIn(7 downto 0));
CSRData_o <= std_logic_vector(s_locDataIn(7 downto 0));
process(clk_i)
begin
process (clk_i)
begin
if rising_edge(clk_i) then
CRAMdata_o <= std_logic_vector(s_locDataIn(7 downto 0));
if (s_confAccess = '1' and s_CRAMaddressed = '1' and s_memReq = '1' and
s_RW = '0' and (s_typeOfDataTransfer = D08_3 or s_typeOfDataTransfer = D32 or
s_typeOfDataTransfer = D16_23 or (s_typeOfDataTransfer = D64 and
s_transferType /= MBLT))) then
if (
s_confAccess = '1' and s_CRAMaddressed = '1' and s_memReq = '1' and
s_RW = '0' and (
s_typeOfDataTransfer = D08_3 or s_typeOfDataTransfer = D32 or
s_typeOfDataTransfer = D16_23 or (
s_typeOfDataTransfer = D64 and s_transferType /= MBLT
)
)
) then
CRAMwea_o <= '1';
else
CRAMwea_o <= '0';
end if;
end if;
end process;
end process;
--swap the data during read or write operation
--sel= 000 --> No swap
--sel= 001 --> Swap Byte eg: 01234567 become 10325476
--sel= 010 --> Swap Word eg: 01234567 become 23016745
--sel= 011 --> Swap Word+ Swap Byte eg: 01234567 become 32107654
--sel= 100 --> Swap DWord + Swap Word+ Swap Byte eg: 01234567 become 76543210
swapper_write : VME_swapper port map(
-- Swap the data during read or write operation
-- sel= 000 --> No swap
-- sel= 001 --> Swap Byte eg: 01234567 become 10325476
-- sel= 010 --> Swap Word eg: 01234567 become 23016745
-- sel= 011 --> Swap Word+Swap Byte eg: 01234567 become 32107654
-- sel= 100 --> Swap DWord+Swap Word+Swap Byte eg: 01234567 become 76543210
swapper_write : VME_swapper
port map (
d_i => std_logic_vector(s_locDataIn),
sel => Endian_i,
d_o => s_locDataInSwap
);
swapper_read : VME_swapper port map(
swapper_read : VME_swapper
port map (
d_i => std_logic_vector(s_locData),
sel => Endian_i,
d_o => s_locDataSwap
);
-- data from WB or CR/CSR to VME bus
s_CRCSRtype <= '1' when (s_typeOfDataTransfer = D08_3 or s_typeOfDataTransfer = D32 or
s_typeOfDataTransfer = D16_23 or (s_typeOfDataTransfer = D64 and
s_transferType /= MBLT)) else
'0';
process(clk_i)
begin
-- Data from WB or CR/CSR to VME bus
s_CRCSRtype <= '1' when (
s_typeOfDataTransfer = D08_3 or
s_typeOfDataTransfer = D32 or
s_typeOfDataTransfer = D16_23 or
(s_typeOfDataTransfer = D64 and s_transferType /= MBLT)
) else '0';
process (clk_i)
begin
if rising_edge(clk_i) then
if s_cardSel = '1' then
s_locDataOut <= unsigned(s_locDataOutWb);
elsif s_confAccess = '1' and s_CSRaddressed = '1' and
s_CRAMaddressed = '0' and s_CRaddressed = '0' and
s_CRCSRtype = '1' then
s_CRCSRtype = '1'
then
s_locDataOut <= resize(s_CSRdata, s_locDataOut'length);
elsif s_confAccess = '1' and s_CRaddressed = '1' and
s_CRAMaddressed = '0' and s_CSRaddressed = '0' and
s_CRCSRtype = '1' then
s_CRCSRtype = '1'
then
s_locDataOut <= resize(unsigned(s_CRdataIn), s_locDataOut'length);
elsif s_confAccess = '1' and s_CRAMaddressed = '1' and
s_CRaddressed = '0' and s_CSRaddressed = '0' and
s_CRCSRtype = '1' then
s_CRCSRtype = '1'
then
s_locDataOut <= resize(unsigned(s_CRAMdataIn), s_locDataOut'length);
else
s_locDataOut <= (others => '0');
end if;
end if;
end process;
end process;
s_locData(63 downto 0) <= s_locDataOut(63 downto 0) sll to_integer(unsigned(s_DataShift));
s_CSRdata <= unsigned(CSRData_i);
s_locData(63 downto 0) <= s_locDataOut(63 downto 0) sll to_integer(unsigned(s_DataShift));
s_CSRdata <= unsigned(CSRData_i);
---------------------MEMORY MAPPING--------------------------------
-- WB bus width = 64-bits
-- Granularity = byte
-- WB bus --> BIG ENDIAN
p_memoryMapping : process(clk_i)
begin
------------------------------------------------------------------------------
-- Memory Mapping
------------------------------------------------------------------------------
-- WB bus width = 64-bits
-- Granularity = byte
-- WB bus --> BIG ENDIAN
p_memoryMapping : process (clk_i)
begin
if rising_edge(clk_i) then
if s_transferType = TWOe then
s_nx_sel <= "11111111";
......@@ -1062,7 +1115,7 @@ begin
end if;
when D64 =>
case s_transferType is
when MBLT => -- D64 |
when MBLT => -- D64
s_nx_sel <= "11111111";
when others => -- D32 BLT or SINGLE
if s_rel_locAddr(2) = '0' then
......@@ -1082,19 +1135,24 @@ begin
end case;
end if;
end if;
end process;
s_sel <= unsigned(s_nx_sel);
end process;
--------------------------WB MASTER-----------------------------------|
--This component acts as WB master for single read/write PIPELINED mode.
--The data and address lines are shifted inside this component.
s_wbMaster_rst <= s_reset or s_mainFSMreset;
Inst_Wb_master : VME_Wb_master
generic map(
s_sel <= unsigned(s_nx_sel);
------------------------------------------------------------------------------
-- WB Master
------------------------------------------------------------------------------
-- This component acts as WB master for single read/write PIPELINED mode.
-- The data and address lines are shifted inside this component.
s_wbMaster_rst <= s_reset or s_mainFSMreset;
Inst_Wb_master : VME_Wb_master
generic map (
g_wb_data_width => g_wb_data_width,
g_wb_addr_width => g_wb_addr_width
)
port map(
port map (
memReq_i => s_memReq,
clk_i => clk_i,
cardSel_i => s_cardSel,
......@@ -1121,11 +1179,15 @@ Inst_Wb_master : VME_Wb_master
RW_o => RW_o
);
--------------------------DECODER-------------------------------------|
-- DECODER: This component check if the board is addressed; if the CR/CSR
-- space is addressed the Confaccess signal is asserted
-- If the Wb memory is addressed the CardSel signal is asserted.
Inst_Access_Decode : VME_Access_Decode port map(
------------------------------------------------------------------------------
-- Decoder
------------------------------------------------------------------------------
-- This component check if the board is addressed; if the CR/CSR space is
-- addressed the Confaccess signal is asserted
-- If the Wb memory is addressed the CardSel signal is asserted.
Inst_Access_Decode : VME_Access_Decode
port map (
clk_i => clk_i,
reset => s_reset,
mainFSMreset => s_mainFSMreset,
......@@ -1174,39 +1236,51 @@ Inst_Access_Decode : VME_Access_Decode port map(
Confaccess => s_confAccess,
CardSel => s_cardSel
);
s_base_addr <= unsigned(s_nx_base_addr);
-- CR/CSR addressing
-- Please note that the location of the user defined CR and CSR regions as well as the CRAM
-- region are programmable. If these regions are overlapped the vme64x core asserts the BERR* line
s_CSRaddressed <= '1' when (s_locAddr(18 downto 0) <= x"7FFFF" and
s_locAddr(18 downto 0) >= x"7FC00") xor
(s_locAddr(18 downto 0) >= unsigned(s_BEG_USER_CSR(18 downto 0)) and
s_locAddr(18 downto 0) <= unsigned(s_END_USER_CSR(18 downto 0)) and
unsigned(s_BEG_USER_CSR) < unsigned(s_END_USER_CSR)) else '0';
s_CRaddressed <= '1' when (s_locAddr(18 downto 0) <= x"00FFF" and
s_locAddr(18 downto 0) >= x"00000") xor
(s_locAddr(18 downto 0) >= unsigned(s_BEG_USER_CR(18 downto 0)) and
s_base_addr <= unsigned(s_nx_base_addr);
-- CR/CSR addressing
-- Please note that the location of the user defined CR and CSR regions as
-- well as the CRAM region are programmable. If these regions are overlapped
-- the vme64x core asserts the BERR* line
s_CSRaddressed <= '1' when (
s_locAddr(18 downto 0) <= x"7FFFF" and
s_locAddr(18 downto 0) >= x"7FC00"
) xor (
s_locAddr(18 downto 0) >= unsigned(s_BEG_USER_CSR(18 downto 0)) and
s_locAddr(18 downto 0) <= unsigned(s_END_USER_CSR(18 downto 0)) and
unsigned(s_BEG_USER_CSR) < unsigned(s_END_USER_CSR)
) else '0';
s_CRaddressed <= '1' when (
s_locAddr(18 downto 0) <= x"00FFF" and
s_locAddr(18 downto 0) >= x"00000"
) xor (
s_locAddr(18 downto 0) >= unsigned(s_BEG_USER_CR(18 downto 0)) and
s_locAddr(18 downto 0) <= unsigned(s_END_USER_CR(18 downto 0)) and
unsigned(s_BEG_USER_CR) < unsigned(s_END_USER_CR)) else '0';
unsigned(s_BEG_USER_CR) < unsigned(s_END_USER_CR)
) else '0';
s_CRAMaddressed <= '1' when (s_locAddr(18 downto 0) >= unsigned(s_BEG_CRAM(18 downto 0)) and
s_CRAMaddressed <= '1' when (
s_locAddr(18 downto 0) >= unsigned(s_BEG_CRAM(18 downto 0)) and
s_locAddr(18 downto 0) <= unsigned(s_END_CRAM(18 downto 0)) and
unsigned(s_BEG_CRAM) < unsigned(s_END_CRAM)) else '0';
--------------------------ACKNOWLEDGE---------------------------------------|
--s_memAck should be asserted also if an error condition is detected.
process(clk_i)
begin
unsigned(s_BEG_CRAM) < unsigned(s_END_CRAM)
) else '0';
------------------------------------------------------------------------------
-- Acknowledge
------------------------------------------------------------------------------
-- s_memAck should be asserted also if an error condition is detected.
process (clk_i)
begin
if rising_edge(clk_i) then
s_memAck <= s_memAckCSR or s_AckWb or s_err;
end if;
end process;
-- CR/CSR memory acknowledge
end process;
-- CR/CSR memory acknowledge
p_memAckCSR : process(clk_i)
begin
p_memAckCSR : process (clk_i)
begin
if rising_edge(clk_i) then
if s_reset = '1' then
s_memAckCSR <= '0';
......@@ -1218,26 +1292,31 @@ begin
end if;
end if;
end if;
end process;
-----------------------CR/CSR IN/OUT----------------------------------------|
end process;
en_wr_CSR <= '1' when ((s_typeOfDataTransfer = D08_3 or s_typeOfDataTransfer = D32 or
s_typeOfDataTransfer = D16_23 or (s_typeOfDataTransfer = D64 and
s_transferType /= MBLT)) and s_memReq = '1' and
s_confAccess = '1' and s_RW = '0') else '0';
------------------------------------------------------------------------------
-- CR/CSR In/Out
------------------------------------------------------------------------------
en_wr_CSR <= '1'
when (
(s_typeOfDataTransfer = D08_3 or
s_typeOfDataTransfer = D32 or
s_typeOfDataTransfer = D16_23 or
(s_typeOfDataTransfer = D64 and s_transferType /= MBLT)
) and s_memReq = '1' and s_confAccess = '1' and s_RW = '0'
) else '0';
CrCsrOffsetAddr <= std_logic_vector(s_CrCsrOffsetAddr);
CrCsrOffsetAddr <= std_logic_vector(s_CrCsrOffsetAddr);
err_flag_o <= s_errorflag;
err_flag_o <= s_errorflag;
s_resetflag <= reset_flag_i;
s_resetflag <= reset_flag_i;
-- Software reset: the VME Master assert the BIT SET REGISTER's bit 7. The reset will be
-- effective the next AS rising edge at the end of the write operation in this register.
-- The sw reset is a pulse
process(clk_i)
begin
-- Software reset: the VME Master assert the BIT SET REGISTER's bit 7. The
-- reset will be effective the next AS rising edge at the end of the write
-- operation in this register. The sw reset is a pulse
process (clk_i)
begin
if rising_edge(clk_i) then
if s_mainFSMreset = '1' then
s_sw_reset <= Sw_Reset;
......@@ -1245,14 +1324,17 @@ begin
s_sw_reset <= '0';
end if;
end if;
end process;
end process;
------------------------------------------------------------------------------
-- Initialization
------------------------------------------------------------------------------
-- Initialization procedure (about 8800 ns)
-- Read important CR data (like FUNC_ADEMs etc.) and store it locally
s_initReadCounter <= unsigned(s_initReadCounter1);
---------------------------INITIALIZATION-------------------------------------|
-- Initialization procedure (about 8800 ns)
-- Read important CR data (like FUNC_ADEMs etc.) and store it locally
s_initReadCounter <= unsigned(s_initReadCounter1);
Inst_VME_Init : VME_Init
port map(
Inst_VME_Init : VME_Init
port map (
clk_i => clk_i,
rst_n_i => rst_n_i,
CRAddr_i => std_logic_vector(s_CRaddr),
......@@ -1291,45 +1373,41 @@ Inst_VME_Init : VME_Init
FUNC7_XAMCAP_o => s_FUNC_XAMCAP(7)
);
------------------EDGE DETECTION and SAMPLING-----------------------------------------
ASfallingEdge : FallingEdgeDetection
------------------------------------------------------------------------------
-- Edge Detection and Sampling
------------------------------------------------------------------------------
ASfallingEdge : FallingEdgeDetection
port map (
sig_i => VME_AS_n_i,
clk_i => clk_i,
FallEdge_o => s_VMEaddrLatch
);
ASrisingEdge : RisEdgeDetection
ASrisingEdge : RisEdgeDetection
port map (
sig_i => VME_AS_n_i,
clk_i => clk_i,
RisEdge_o => s_mainFSMreset
);
CRinputSample : DoubleRegInputSample
generic map(
CRinputSample : DoubleRegInputSample
generic map (
width => 8
)
port map(
port map (
reg_i => CRdata_i,
reg_o => s_CRdataIn,
clk_i => clk_i
);
CRAMinputSample : SingleRegInputSample
generic map(
CRAMinputSample : SingleRegInputSample
generic map (
width => 8
)
port map(
port map (
reg_i => CRAMdata_i,
reg_o => s_CRAMdataIn,
clk_i => clk_i
);
end RTL;
--===========================================================================
-- Architecture end
--===========================================================================
--______________________________________________________________________________
-- VME TO WB INTERFACE
--------------------------------------------------------------------------------
-- CERN (BE-CO-HT)
-- VME64x Core
-- http://www.ohwr.org/projects/vme64x-core
--------------------------------------------------------------------------------
--
-- CERN,BE/CO-HT
--______________________________________________________________________________
-- File: VME_swapper.vhd
--______________________________________________________________________________
-- Description:
--sel= 00 --> No swap
--sel= 01 --> Swap Byte eg: 01234567 became 10325476
--sel= 10 --> Swap Word eg: 01234567 became 23016745
--sel= 11 --> Swap Word+ Swap Byte eg: 01234567 became 32107654
--______________________________________________________________________________
-- Authors:
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--______________________________________________________________________________
-- unit name: VME_swapper (VME_swapper.vhd)
--
-- author: Pablo Alvarez Sanchez <pablo.alvarez.sanchez@cern.ch>
-- Davide Pedretti <davide.pedretti@cern.ch>
--
-- description:
--
-- sel = 00 --> No swap
-- sel = 01 --> Swap Byte (eg: 01234567 became 10325476)
-- sel = 10 --> Swap Word (eg: 01234567 became 23016745)
-- sel = 11 --> Swap Word+Swap Byte (eg: 01234567 became 32107654)
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
--------------------------------------------------------------------------------
-- 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
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--===========================================================================
-- Entity declaration
--===========================================================================
-- 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;
use ieee.std_logic_1164.all;
entity VME_swapper is
Port ( d_i : in STD_LOGIC_VECTOR (63 downto 0);
sel : in STD_LOGIC_VECTOR (2 downto 0);
d_o : out STD_LOGIC_VECTOR (63 downto 0));
port (
d_i : in std_logic_vector(63 downto 0);
sel : in std_logic_vector(2 downto 0);
d_o : out std_logic_vector(63 downto 0)
);
end VME_swapper;
--===========================================================================
-- Architecture declaration
--===========================================================================
architecture Behavioral of VME_swapper is
signal Byte0_i : std_logic_vector(7 downto 0);
signal Byte1_i : std_logic_vector(7 downto 0);
signal Byte2_i : std_logic_vector(7 downto 0);
signal Byte3_i : std_logic_vector(7 downto 0);
signal Byte4_i : std_logic_vector(7 downto 0);
signal Byte5_i : std_logic_vector(7 downto 0);
signal Byte6_i : std_logic_vector(7 downto 0);
signal Byte7_i : std_logic_vector(7 downto 0);
signal Byte0_o : std_logic_vector(7 downto 0);
signal Byte1_o : std_logic_vector(7 downto 0);
signal Byte2_o : std_logic_vector(7 downto 0);
signal Byte3_o : std_logic_vector(7 downto 0);
signal Byte4_o : std_logic_vector(7 downto 0);
signal Byte5_o : std_logic_vector(7 downto 0);
signal Byte6_o : std_logic_vector(7 downto 0);
signal Byte7_o : std_logic_vector(7 downto 0);
--===========================================================================
-- Architecture begin
--===========================================================================
begin
process (sel,Byte0_i,Byte1_i,Byte2_i,Byte3_i,Byte7_i)
signal Byte0_i : std_logic_vector(7 downto 0);
signal Byte1_i : std_logic_vector(7 downto 0);
signal Byte2_i : std_logic_vector(7 downto 0);
signal Byte3_i : std_logic_vector(7 downto 0);
signal Byte4_i : std_logic_vector(7 downto 0);
signal Byte5_i : std_logic_vector(7 downto 0);
signal Byte6_i : std_logic_vector(7 downto 0);
signal Byte7_i : std_logic_vector(7 downto 0);
signal Byte0_o : std_logic_vector(7 downto 0);
signal Byte1_o : std_logic_vector(7 downto 0);
signal Byte2_o : std_logic_vector(7 downto 0);
signal Byte3_o : std_logic_vector(7 downto 0);
signal Byte4_o : std_logic_vector(7 downto 0);
signal Byte5_o : std_logic_vector(7 downto 0);
signal Byte6_o : std_logic_vector(7 downto 0);
signal Byte7_o : std_logic_vector(7 downto 0);
begin
process (sel, Byte0_i, Byte1_i, Byte2_i, Byte3_i, Byte7_i)
begin
case sel is
when "000" => Byte0_o <= Byte0_i;
when "001" => Byte0_o <= Byte1_i;
......@@ -74,10 +78,10 @@ begin
when "100" => Byte0_o <= Byte7_i;
when others => Byte0_o <= Byte0_i;
end case;
end process;
end process;
process (sel,Byte0_i,Byte1_i,Byte2_i,Byte3_i,Byte6_i)
begin
process (sel, Byte0_i, Byte1_i, Byte2_i, Byte3_i, Byte6_i)
begin
case sel is
when "000" => Byte1_o <= Byte1_i;
when "001" => Byte1_o <= Byte0_i;
......@@ -86,10 +90,10 @@ begin
when "100" => Byte1_o <= Byte6_i;
when others => Byte1_o <= Byte1_i;
end case;
end process;
end process;
process (sel,Byte0_i,Byte1_i,Byte2_i,Byte3_i,Byte5_i)
begin
process (sel, Byte0_i, Byte1_i, Byte2_i, Byte3_i, Byte5_i)
begin
case sel is
when "000" => Byte2_o <= Byte2_i;
when "001" => Byte2_o <= Byte3_i;
......@@ -98,10 +102,10 @@ begin
when "100" => Byte2_o <= Byte5_i;
when others => Byte2_o <= Byte2_i;
end case;
end process;
end process;
process (sel,Byte0_i,Byte1_i,Byte2_i,Byte3_i,Byte4_i)
begin
process (sel, Byte0_i, Byte1_i, Byte2_i, Byte3_i, Byte4_i)
begin
case sel is
when "000" => Byte3_o <= Byte3_i;
when "001" => Byte3_o <= Byte2_i;
......@@ -110,10 +114,10 @@ begin
when "100" => Byte3_o <= Byte4_i;
when others => Byte3_o <= Byte3_i;
end case;
end process;
end process;
process (sel,Byte4_i,Byte5_i,Byte6_i,Byte7_i,Byte3_i)
begin
process (sel, Byte4_i, Byte5_i, Byte6_i, Byte7_i, Byte3_i)
begin
case sel is
when "000" => Byte4_o <= Byte4_i;
when "001" => Byte4_o <= Byte5_i;
......@@ -122,10 +126,10 @@ begin
when "100" => Byte4_o <= Byte3_i;
when others => Byte4_o <= Byte4_i;
end case;
end process;
end process;
process (sel,Byte4_i,Byte5_i,Byte6_i,Byte7_i,Byte2_i)
begin
process (sel, Byte4_i, Byte5_i, Byte6_i, Byte7_i, Byte2_i)
begin
case sel is
when "000" => Byte5_o <= Byte5_i;
when "001" => Byte5_o <= Byte4_i;
......@@ -134,10 +138,10 @@ begin
when "100" => Byte5_o <= Byte2_i;
when others => Byte5_o <= Byte5_i;
end case;
end process;
end process;
process (sel,Byte4_i,Byte5_i,Byte6_i,Byte7_i,Byte1_i)
begin
process (sel, Byte4_i, Byte5_i, Byte6_i, Byte7_i, Byte1_i)
begin
case sel is
when "000" => Byte6_o <= Byte6_i;
when "001" => Byte6_o <= Byte7_i;
......@@ -146,10 +150,10 @@ begin
when "100" => Byte6_o <= Byte1_i;
when others => Byte6_o <= Byte6_i;
end case;
end process;
end process;
process (sel,Byte4_i,Byte5_i,Byte6_i,Byte7_i,Byte0_i)
begin
process (sel, Byte4_i, Byte5_i, Byte6_i, Byte7_i, Byte0_i)
begin
case sel is
when "000" => Byte7_o <= Byte7_i;
when "001" => Byte7_o <= Byte6_i;
......@@ -158,26 +162,24 @@ begin
when "100" => Byte7_o <= Byte0_i;
when others => Byte7_o <= Byte7_i;
end case;
end process;
Byte0_i <= d_i(7 downto 0);
Byte1_i <= d_i(15 downto 8);
Byte2_i <= d_i(23 downto 16);
Byte3_i <= d_i(31 downto 24);
Byte4_i <= d_i(39 downto 32);
Byte5_i <= d_i(47 downto 40);
Byte6_i <= d_i(55 downto 48);
Byte7_i <= d_i(63 downto 56);
d_o(7 downto 0) <= Byte0_o;
d_o(15 downto 8) <= Byte1_o;
d_o(23 downto 16) <= Byte2_o;
d_o(31 downto 24) <= Byte3_o;
d_o(39 downto 32) <= Byte4_o;
d_o(47 downto 40) <= Byte5_o;
d_o(55 downto 48) <= Byte6_o;
d_o(63 downto 56) <= Byte7_o;
end process;
Byte0_i <= d_i(7 downto 0);
Byte1_i <= d_i(15 downto 8);
Byte2_i <= d_i(23 downto 16);
Byte3_i <= d_i(31 downto 24);
Byte4_i <= d_i(39 downto 32);
Byte5_i <= d_i(47 downto 40);
Byte6_i <= d_i(55 downto 48);
Byte7_i <= d_i(63 downto 56);
d_o(7 downto 0) <= Byte0_o;
d_o(15 downto 8) <= Byte1_o;
d_o(23 downto 16) <= Byte2_o;
d_o(31 downto 24) <= Byte3_o;
d_o(39 downto 32) <= Byte4_o;
d_o(47 downto 40) <= Byte5_o;
d_o(55 downto 48) <= Byte6_o;
d_o(63 downto 56) <= Byte7_o;
end Behavioral;
--===========================================================================
-- Architecture end
--===========================================================================
--______________________________________________________________________
-- VME TO WB INTERFACE
--------------------------------------------------------------------------------
-- CERN (BE-CO-HT)
-- VME64x Core
-- http://www.ohwr.org/projects/vme64x-core
--------------------------------------------------------------------------------
--
-- CERN,BE/CO-HT
--______________________________________________________________________
-- File: vme64x_pack.vhd
--______________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--______________________________________________________________________________
-- Modifications:
-- 2016-08-24: by Jan Pospisil (j.pospisil@cern.ch)
-- * added default (error) return value
--_______________________________________________________________________
-- unit name: vme64x_pack (vme64x_pack.vhd)
--
-- author: Pablo Alvarez Sanchez <pablo.alvarez.sanchez@cern.ch>
-- Davide Pedretti <davide.pedretti@cern.ch>
--
-- description: VME64x Core Package
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
-- 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
--------------------------------------------------------------------------------
-- 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
---------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;
--use work.VME_CR_pack.all;
--------------------------------------------------------------------------------
-- last changes: see log.
--------------------------------------------------------------------------------
-- TODO: -
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package vme64x_pack is
--__________________________________________________________________________________
-- Records:
------------------------------------------------------------------------------
-- Records
------------------------------------------------------------------------------
type t_rom_cell is
record
add : integer;
......@@ -73,72 +80,84 @@ package vme64x_pack is
s_DSlatch : std_logic;
s_DTACK_OE : std_logic;
end record;
--_______________________________________________________________________________
-- Constants:
------------------------------------------------------------------------------
-- Constants
------------------------------------------------------------------------------
--WB data width:
constant c_width : integer := 64; --must be 32 or 64!
constant c_width : integer := 64; -- must be 32 or 64!
--CRAM size in the CR/CSR space (bytes):
constant c_CRAM_SIZE : integer := 1024;
-- remember to set properly the "END_CRAM" register in the CR space
constant c_CRAM_SIZE : integer := 1024; -- remember to set properly the
-- "END_CRAM" register in the CR space
-- WB addr width:
constant c_addr_width : integer := 9;
--
constant DFS : integer := 2; -- for accessing at the ADEM's bit 2
constant XAM_MODE : integer := 0; -- for accessing at the ADER's bit 0
-- Tclk in ns used to calculate the data transfer rate
constant c_clk_period : integer := 10; --c_CLK_PERIOD : std_logic_vector(19 downto 0) := "00000000000000001010";
constant c_clk_period : integer := 10;
-- add here the default boards ID:
constant c_SVEC_ID : integer := 408; -- 0x00000198
constant c_CERN_ID : integer := 524336; -- 0x080030
constant c_RevisionID : integer := 1; -- 0x00000001
--BoardID positions:
constant c_BOARD_ID_p1 : integer := 12;
constant c_BOARD_ID_p2 : integer := 13;
constant c_BOARD_ID_p3 : integer := 14;
constant c_BOARD_ID_p4 : integer := 15;
--ManufacturerID positions:
constant c_Manuf_ID_p1 : integer := 9;
constant c_Manuf_ID_p2 : integer := 10;
constant c_Manuf_ID_p3 : integer := 11;
--RevisionID positions:
constant c_Rev_ID_p1 : integer := 16;
constant c_Rev_ID_p2 : integer := 17;
constant c_Rev_ID_p3 : integer := 18;
constant c_Rev_ID_p4 : integer := 19;
--ProgramID positions:
constant c_Prog_ID_p : integer := 31;
-- AM table.
-- References:
-- Table 2-3 "Address Modifier Codes" pages 21/22 VME64std ANSI/VITA 1-1994
-- Table 2.4 "Extended Address Modifier Code" page 12 2eSST ANSI/VITA 1.5-2003(R2009)
constant c_A24_S_sup : std_logic_vector(5 downto 0) := "111101"; -- hex code 0x3d
constant c_A24_S : std_logic_vector(5 downto 0) := "111001"; -- hex code 0x39
constant c_A24_BLT : std_logic_vector(5 downto 0) := "111011"; -- hex code 0x3b
constant c_A24_BLT_sup : std_logic_vector(5 downto 0) := "111111"; -- hex code 0x3f
constant c_A24_MBLT : std_logic_vector(5 downto 0) := "111000"; -- hex code 0x38
constant c_A24_MBLT_sup : std_logic_vector(5 downto 0) := "111100"; -- hex code 0x3c
constant c_A24_LCK : std_logic_vector(5 downto 0) := "110010"; -- hex code 0x32
constant c_CR_CSR : std_logic_vector(5 downto 0) := "101111"; -- hex code 0x2f
constant c_A16 : std_logic_vector(5 downto 0) := "101001"; -- hex code 0x29
constant c_A16_sup : std_logic_vector(5 downto 0) := "101101"; -- hex code 0x2d
constant c_A16_LCK : std_logic_vector(5 downto 0) := "101100"; -- hex code 0x2c
constant c_A32 : std_logic_vector(5 downto 0) := "001001"; -- hex code 0x09
constant c_A32_sup : std_logic_vector(5 downto 0) := "001101"; -- hex code 0x0d
constant c_A32_BLT : std_logic_vector(5 downto 0) := "001011"; -- hex code 0x0b
constant c_A32_BLT_sup : std_logic_vector(5 downto 0) := "001111"; -- hex code 0x0f
constant c_A32_MBLT : std_logic_vector(5 downto 0) := "001000"; -- hex code 0x08
constant c_A32_MBLT_sup : std_logic_vector(5 downto 0) := "001100"; -- hex code 0x0c
constant c_A32_LCK : std_logic_vector(5 downto 0) := "000101"; -- hex code 0x05
constant c_A64 : std_logic_vector(5 downto 0) := "000001"; -- hex code 0x01
constant c_A64_BLT : std_logic_vector(5 downto 0) := "000011"; -- hex code 0x03
constant c_A64_MBLT : std_logic_vector(5 downto 0) := "000000"; -- hex code 0x00
constant c_A64_LCK : std_logic_vector(5 downto 0) := "000100"; -- hex code 0x04
constant c_TWOedge : std_logic_vector(5 downto 0) := "100000"; -- hex code 0x20
constant c_A32_2eVME : std_logic_vector(7 downto 0) := "00000001"; -- hex code 0x21
constant c_A64_2eVME : std_logic_vector(7 downto 0) := "00000010"; -- hex code 0x22
constant c_A32_2eSST : std_logic_vector(7 downto 0) := "00010001"; -- hex code 0x11
constant c_A64_2eSST : std_logic_vector(7 downto 0) := "00010010"; -- hex code 0x12
--CSR array's index:
constant c_A24_S_sup : std_logic_vector(5 downto 0) := "111101"; -- 0x3d
constant c_A24_S : std_logic_vector(5 downto 0) := "111001"; -- 0x39
constant c_A24_BLT : std_logic_vector(5 downto 0) := "111011"; -- 0x3b
constant c_A24_BLT_sup : std_logic_vector(5 downto 0) := "111111"; -- 0x3f
constant c_A24_MBLT : std_logic_vector(5 downto 0) := "111000"; -- 0x38
constant c_A24_MBLT_sup : std_logic_vector(5 downto 0) := "111100"; -- 0x3c
constant c_A24_LCK : std_logic_vector(5 downto 0) := "110010"; -- 0x32
constant c_CR_CSR : std_logic_vector(5 downto 0) := "101111"; -- 0x2f
constant c_A16 : std_logic_vector(5 downto 0) := "101001"; -- 0x29
constant c_A16_sup : std_logic_vector(5 downto 0) := "101101"; -- 0x2d
constant c_A16_LCK : std_logic_vector(5 downto 0) := "101100"; -- 0x2c
constant c_A32 : std_logic_vector(5 downto 0) := "001001"; -- 0x09
constant c_A32_sup : std_logic_vector(5 downto 0) := "001101"; -- 0x0d
constant c_A32_BLT : std_logic_vector(5 downto 0) := "001011"; -- 0x0b
constant c_A32_BLT_sup : std_logic_vector(5 downto 0) := "001111"; -- 0x0f
constant c_A32_MBLT : std_logic_vector(5 downto 0) := "001000"; -- 0x08
constant c_A32_MBLT_sup : std_logic_vector(5 downto 0) := "001100"; -- 0x0c
constant c_A32_LCK : std_logic_vector(5 downto 0) := "000101"; -- 0x05
constant c_A64 : std_logic_vector(5 downto 0) := "000001"; -- 0x01
constant c_A64_BLT : std_logic_vector(5 downto 0) := "000011"; -- 0x03
constant c_A64_MBLT : std_logic_vector(5 downto 0) := "000000"; -- 0x00
constant c_A64_LCK : std_logic_vector(5 downto 0) := "000100"; -- 0x04
constant c_TWOedge : std_logic_vector(5 downto 0) := "100000"; -- 0x20
constant c_A32_2eVME : std_logic_vector(7 downto 0) := "00000001"; -- 0x21
constant c_A64_2eVME : std_logic_vector(7 downto 0) := "00000010"; -- 0x22
constant c_A32_2eSST : std_logic_vector(7 downto 0) := "00010001"; -- 0x11
constant c_A64_2eSST : std_logic_vector(7 downto 0) := "00010010"; -- 0x12
-- CSR array's index:
constant BAR : integer := 255;
constant BIT_SET_CLR_REG : integer := 254;
constant USR_BIT_SET_CLR_REG : integer := 253;
......@@ -175,17 +194,17 @@ package vme64x_pack is
constant FUNC0_ADER_1 : integer := FUNC7_ADER_0 - 29;
constant FUNC0_ADER_2 : integer := FUNC7_ADER_0 - 30;
constant FUNC0_ADER_3 : integer := FUNC7_ADER_0 - 31;
constant IRQ_Vector : integer := FUNC0_ADER_3 -1;
constant IRQ_level : integer := FUNC0_ADER_3 -2;
constant TIME0_ns : integer := FUNC0_ADER_3 -5;
constant TIME1_ns : integer := FUNC0_ADER_3 -6;
constant TIME2_ns : integer := FUNC0_ADER_3 -7;
constant TIME3_ns : integer := FUNC0_ADER_3 -8;
constant TIME4_ns : integer := FUNC0_ADER_3 -9;
constant BYTES0 : integer := FUNC0_ADER_3 -10;
constant BYTES1 : integer := FUNC0_ADER_3 -11;
constant WB32bits : integer := FUNC0_ADER_3 -12;
constant Endian : integer := FUNC0_ADER_3 -4;
constant IRQ_Vector : integer := FUNC0_ADER_3 - 1;
constant IRQ_level : integer := FUNC0_ADER_3 - 2;
constant TIME0_ns : integer := FUNC0_ADER_3 - 5;
constant TIME1_ns : integer := FUNC0_ADER_3 - 6;
constant TIME2_ns : integer := FUNC0_ADER_3 - 7;
constant TIME3_ns : integer := FUNC0_ADER_3 - 8;
constant TIME4_ns : integer := FUNC0_ADER_3 - 9;
constant BYTES0 : integer := FUNC0_ADER_3 - 10;
constant BYTES1 : integer := FUNC0_ADER_3 - 11;
constant WB32bits : integer := FUNC0_ADER_3 - 12;
constant Endian : integer := FUNC0_ADER_3 - 4;
-- Initialization CR:
constant BEG_USER_CR : integer := 1;
......@@ -210,7 +229,8 @@ package vme64x_pack is
FUNC_AMCAP => (add => 16#048#, len => 64),
FUNC_XAMCAP => (add => 16#088#, len => 256),
FUNC_ADEM => (add => 16#188#, len => 32));
FUNC_ADEM => (add => 16#188#, len => 32)
);
-- Main Finite State machine signals default:
-- When the S_FPGA detects the magic sequency, it erases the A_FPGA so
......@@ -300,9 +320,12 @@ package vme64x_pack is
constant c_WB32bits_addr : unsigned(19 downto 0) := x"7FF33";
constant c_Endian_addr : unsigned(19 downto 0) := x"7FF53"; -- VME64x reserved CSR
--___________________________________________________________________________________________
-- TYPE:
type t_typeOfDataTransfer is (D08_0,
------------------------------------------------------------------------------
-- Types
------------------------------------------------------------------------------
type t_typeOfDataTransfer is (
D08_0,
D08_1,
D08_2,
D08_3,
......@@ -313,7 +336,8 @@ package vme64x_pack is
TypeError
);
type t_addressingType is (A24,
type t_addressingType is (
A24,
A24_BLT,
A24_MBLT,
CR_CSR,
......@@ -328,14 +352,16 @@ 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,
......@@ -344,11 +370,13 @@ 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,
......@@ -362,67 +390,104 @@ package vme64x_pack is
DECIDE_NEXT_CYCLE,
INCREMENT_ADDR,
SET_DATA_PHASE
-- UGLY_WAIT_TO_MAKE_DECODING_WORK
--UGLY_WAIT_TO_MAKE_DECODING_WORK
-- uncomment for using 2e modes:
-- WAIT_FOR_DS_2e,
-- ADDR_PHASE_1,
-- ADDR_PHASE_2,
-- ADDR_PHASE_3,
-- DECODE_ACCESS_2e,
-- DTACK_PHASE_1,
-- DTACK_PHASE_2,
-- DTACK_PHASE_3,
-- TWOeVME_WRITE,
-- TWOeVME_READ,
-- TWOeVME_MREQ_RD,
-- WAIT_WR_1,
-- WAIT_WR_2,
-- WAIT_WB_ACK_WR,
-- WAIT_WB_ACK_RD,
-- TWOeVME_TOGGLE_WR,
-- TWOeVME_TOGGLE_RD,
-- TWOe_FIFO_WRITE,
-- TWOe_TOGGLE_DTACK,
-- TWOeVME_INCR_ADDR,
-- TWOe_WAIT_FOR_DS1,
-- TWOe_FIFO_WAIT_READ,
-- TWOe_FIFO_READ,
-- TWOe_CHECK_BEAT,
-- TWOe_RELEASE_DTACK,
-- TWOe_END_1,
-- TWOe_END_2
);
type t_initState is (IDLE,
--WAIT_FOR_DS_2e,
--ADDR_PHASE_1,
--ADDR_PHASE_2,
--ADDR_PHASE_3,
--DECODE_ACCESS_2e,
--DTACK_PHASE_1,
--DTACK_PHASE_2,
--DTACK_PHASE_3,
--TWOeVME_WRITE,
--TWOeVME_READ,
--TWOeVME_MREQ_RD,
--WAIT_WR_1,
--WAIT_WR_2,
--WAIT_WB_ACK_WR,
--WAIT_WB_ACK_RD,
--TWOeVME_TOGGLE_WR,
--TWOeVME_TOGGLE_RD,
--TWOe_FIFO_WRITE,
--TWOe_TOGGLE_DTACK,
--TWOeVME_INCR_ADDR,
--TWOe_WAIT_FOR_DS1,
--TWOe_FIFO_WAIT_READ,
--TWOe_FIFO_READ,
--TWOe_CHECK_BEAT,
--TWOe_RELEASE_DTACK,
--TWOe_END_1,
--TWOe_END_2
);
type t_initState is (
IDLE,
SET_ADDR,
GET_DATA,
END_INIT
);
type t_FUNC_32b_array is array (0 to 7) of unsigned(31 downto 0); -- ADER register array
type t_FUNC_64b_array is array (0 to 7) of unsigned(63 downto 0); -- AMCAP register array
type t_FUNC_256b_array is array (0 to 7) of unsigned(255 downto 0); -- XAMCAP register array
type t_FUNC_32b_array_std is array (0 to 7) of std_logic_vector(31 downto 0); -- ADER register array
type t_FUNC_64b_array_std is array (0 to 7) of std_logic_vector(63 downto 0); -- AMCAP register array
type t_FUNC_256b_array_std is array (0 to 7) of std_logic_vector(255 downto 0); -- XAMCAP register array
type t_CSRarray is array(BAR downto WB32bits) of unsigned(7 downto 0);
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;
--_____________________________________________________________________________________________________
--COMPONENTS:
type t_FUNC_32b_array is
array (0 to 7) of unsigned(31 downto 0); -- ADER register array
type t_FUNC_64b_array is
array (0 to 7) of unsigned(63 downto 0); -- AMCAP register array
type t_FUNC_256b_array is
array (0 to 7) of unsigned(255 downto 0); -- XAMCAP register array
type t_FUNC_32b_array_std is
array (0 to 7) of std_logic_vector(31 downto 0); -- ADER register array
type t_FUNC_64b_array_std is
array (0 to 7) of std_logic_vector(63 downto 0); -- AMCAP register array
type t_FUNC_256b_array_std is
array (0 to 7) of std_logic_vector(255 downto 0); -- XAMCAP register array
type t_CSRarray is
array(BAR downto WB32bits) of unsigned(7 downto 0);
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;
------------------------------------------------------------------------------
-- 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(
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
VME_RST_n_i : in std_logic;
......@@ -436,7 +501,7 @@ package vme64x_pack is
VME_AM_i : in std_logic_vector(5 downto 0);
VME_IACK_n_i : in std_logic;
memAckWB_i : in std_logic;
wbData_i : in std_logic_vector(g_wb_data_width - 1 downto 0);
wbData_i : in std_logic_vector(g_wb_data_width-1 downto 0);
err_i : in std_logic;
rty_i : in std_logic;
stall_i : in std_logic;
......@@ -470,9 +535,9 @@ package vme64x_pack is
VME_DATA_DIR_o : out std_logic;
VME_DATA_OE_N_o : out std_logic;
memReq_o : out std_logic;
wbData_o : out std_logic_vector(g_wb_data_width - 1 downto 0);
locAddr_o : out std_logic_vector(g_wb_addr_width - 1 downto 0);
wbSel_o : out std_logic_vector(f_div8(g_wb_data_width) - 1 downto 0);
wbData_o : out std_logic_vector(g_wb_data_width-1 downto 0);
locAddr_o : out std_logic_vector(g_wb_addr_width-1 downto 0);
wbSel_o : out std_logic_vector(f_div8(g_wb_data_width)-1 downto 0);
RW_o : out std_logic;
cyc_o : out std_logic;
CRAMaddr_o : out std_logic_vector(f_log2_size(g_cram_size)-1 downto 0);
......@@ -486,7 +551,6 @@ package vme64x_pack is
);
end component VME_bus;
component VME_Access_Decode is
port (
clk_i : in std_logic;
......@@ -540,7 +604,7 @@ package vme64x_pack is
end component VME_Access_Decode;
component VME_Funct_Match is
port(
port (
clk_i : in std_logic;
reset : in std_logic;
decode : in std_logic;
......@@ -570,16 +634,16 @@ package vme64x_pack is
end component VME_Funct_Match;
component VME_CR_CSR_Space is
generic(
generic (
g_cram_size : integer := c_CRAM_SIZE;
g_wb_data_width : integer := c_width;
g_CRspace : t_cr_array; -- := c_cr_array;
g_CRspace : t_cr_array;
g_BoardID : integer := c_SVEC_ID;
g_ManufacturerID : integer := c_CERN_ID;
g_RevisionID : integer := c_RevisionID;
g_ProgramID : integer := 96
);
port(
port (
clk_i : in std_logic;
reset : in std_logic;
CR_addr : in std_logic_vector(11 downto 0);
......@@ -615,7 +679,7 @@ package vme64x_pack is
end component VME_CR_CSR_Space;
component VME_Am_Match is
port(
port (
clk_i : in std_logic;
reset : in std_logic;
mainFSMreset : in std_logic;
......@@ -652,11 +716,11 @@ package vme64x_pack is
end component VME_Am_Match;
component VME_Wb_master is
generic(
generic (
g_wb_data_width : integer := c_width;
g_wb_addr_width : integer := c_addr_width
);
port(
port (
memReq_i : in std_logic;
clk_i : in std_logic;
cardSel_i : in std_logic;
......@@ -669,7 +733,7 @@ package vme64x_pack is
stall_i : in std_logic;
rty_i : in std_logic;
err_i : in std_logic;
wbData_i : in std_logic_vector(g_wb_data_width - 1 downto 0);
wbData_i : in std_logic_vector(g_wb_data_width-1 downto 0);
memAckWB_i : in std_logic;
locDataOut_o : out std_logic_vector(63 downto 0);
memAckWb_o : out std_logic;
......@@ -677,15 +741,15 @@ package vme64x_pack is
rty_o : out std_logic;
cyc_o : out std_logic;
memReq_o : out std_logic;
WBdata_o : out std_logic_vector(g_wb_data_width - 1 downto 0);
locAddr_o : out std_logic_vector(g_wb_addr_width - 1 downto 0);
WbSel_o : out std_logic_vector(f_div8(g_wb_data_width) - 1 downto 0);
WBdata_o : out std_logic_vector(g_wb_data_width-1 downto 0);
locAddr_o : out std_logic_vector(g_wb_addr_width-1 downto 0);
WbSel_o : out std_logic_vector(f_div8(g_wb_data_width)-1 downto 0);
RW_o : out std_logic
);
end component VME_Wb_master;
component VME_Init is
port(
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
CRAddr_i : in std_logic_vector(18 downto 0);
......@@ -726,58 +790,75 @@ package vme64x_pack is
end component VME_Init;
component VME_swapper is
port(
port (
d_i : in std_logic_vector(63 downto 0);
sel : in std_logic_vector(2 downto 0);
d_o : out std_logic_vector(63 downto 0)
);
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)
);
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;
component FallingEdgeDetection is
port (
sig_i, clk_i : in std_logic;
FallEdge_o : out std_logic);
sig_i,
clk_i : in std_logic;
FallEdge_o : out std_logic
);
end component FallingEdgeDetection;
component RisEdgeDetection is
port (
sig_i, clk_i : in std_logic;
RisEdge_o : out std_logic);
sig_i,
clk_i : in std_logic;
RisEdge_o : out std_logic
);
end component RisEdgeDetection;
component DoubleSigInputSample is
port (
sig_i, clk_i : in std_logic;
sig_o : out std_logic);
sig_i,
clk_i : in std_logic;
sig_o : out std_logic
);
end component DoubleSigInputSample;
component SigInputSample is
port (
sig_i, clk_i : in std_logic;
sig_o : out std_logic);
sig_i,
clk_i : in std_logic;
sig_o : out std_logic
);
end component SigInputSample;
component DoubleRegInputSample is
generic(
generic (
width : natural := 8
);
port (
......@@ -788,7 +869,7 @@ package vme64x_pack is
end component DoubleRegInputSample;
component RegInputSample is
generic(
generic (
width : natural := 8
);
port (
......@@ -799,7 +880,7 @@ package vme64x_pack is
end component RegInputSample;
component SingleRegInputSample is
generic(
generic (
width : natural := 8
);
port (
......@@ -811,7 +892,8 @@ package vme64x_pack is
component VME_IRQ_Controller
generic (
g_retry_timeout : integer range 1024 to 16777215);
g_retry_timeout : integer range 1024 to 16777215
);
port (
clk_i : in std_logic;
reset_n_i : in std_logic;
......@@ -827,24 +909,26 @@ package vme64x_pack is
VME_DTACK_n_o : out std_logic;
VME_DTACK_OE_o : out std_logic;
VME_DATA_o : out std_logic_vector (31 downto 0);
VME_DATA_DIR_o : out std_logic);
VME_DATA_DIR_o : out std_logic
);
end component;
component VME_CRAM is
generic (dl : integer := 8;
generic (
dl : integer := 8;
al : integer := f_log2_size(c_CRAM_SIZE)
);
port(
port (
clk : in std_logic;
we : in std_logic;
aw : in std_logic_vector(al - 1 downto 0);
di : in std_logic_vector(dl - 1 downto 0);
dw : out std_logic_vector(dl - 1 downto 0)
aw : in std_logic_vector(al-1 downto 0);
di : in std_logic_vector(dl-1 downto 0);
dw : out std_logic_vector(dl-1 downto 0)
);
end component VME_CRAM;
end vme64x_pack;
package body vme64x_pack is
function f_div8 (width : integer) return integer is
......@@ -867,15 +951,18 @@ package body vme64x_pack is
return(63);
end function f_log2_size;
function f_set_CR_space(BoardID : integer; cr_default : t_cr_array;
ManufacturerID : integer; RevisionID : integer;
ProgramID : integer) return t_cr_array is
function f_set_CR_space (
BoardID : integer;
cr_default : t_cr_array;
ManufacturerID : integer;
RevisionID : integer;
ProgramID : integer
) return t_cr_array is
variable v_CR_space : t_cr_array(2**12 downto 0);
variable v_BoardID : std_logic_vector(31 downto 0);
variable v_ManufacturerID : std_logic_vector(23 downto 0);
variable v_RevisionID : std_logic_vector(31 downto 0);
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));
......@@ -897,43 +984,15 @@ package body vme64x_pack is
when c_Prog_ID_p => v_CR_space(i) := v_ProgramID(7 downto 0);
when others => v_CR_space(i) := cr_default(i);
end case;
-- if i = c_BOARD_ID_p1 then
-- v_CR_space(i) := v_BoardID(31 downto 24);
-- elsif i = c_BOARD_ID_p2 then
-- v_CR_space(i) := v_BoardID(23 downto 16);
-- elsif i = c_BOARD_ID_p3 then
-- v_CR_space(i) := v_BoardID(15 downto 8);
-- elsif i = c_BOARD_ID_p4 then
-- v_CR_space(i) := v_BoardID(7 downto 0);
-- elsif i = c_Manuf_ID_p1 then
-- v_CR_space(i) := v_ManufacturerID(23 downto 16);
-- elsif i = c_Manuf_ID_p2 then
-- v_CR_space(i) := v_ManufacturerID(15 downto 8);
-- elsif i = c_Manuf_ID_p3 then
-- v_CR_space(i) := v_ManufacturerID(7 downto 0);
-- elsif i = c_Rev_ID_p1 then
-- v_CR_space(i) := v_RevisionID(31 downto 24);
-- elsif i = c_Rev_ID_p2 then
-- v_CR_space(i) := v_RevisionID(23 downto 16);
-- elsif i = c_Rev_ID_p3 then
-- v_CR_space(i) := v_RevisionID(15 downto 8);
-- elsif i = c_Rev_ID_p4 then
-- v_CR_space(i) := v_RevisionID(7 downto 0);
-- elsif i = c_Prog_ID_p then
-- v_CR_space(i) := v_ProgramID(7 downto 0);
-- else
-- v_CR_space(i) := cr_default(i);
-- end if;
end loop;
return(v_CR_space);
end function f_set_CR_space;
function f_latchDS(clk_period : integer) return integer is
function f_latchDS (clk_period : integer) return integer is
begin
for I in 1 to 4 loop
if (clk_period * I >= 20) then -- 20 is the max time between the assertion
-- of the DS lines.
return(I);
return(I); -- of the DS lines.
end if;
end loop;
return(4); -- works for up to 200 MHz
......
--------------------------------------------------------------------------------
-- CERN (BE-CO-HT)
--
-- VME64x Core
-- http://www.ohwr.org/projects/vme64x-core
--------------------------------------------------------------------------------
--
-- unit name: xvme64x_core.vhd
--
-- author:
--
-- date: 11-07-2012
-- unit name: xvme64x_core (xvme64x_core.vhd)
--
-- version: 1.0
-- author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
--
-- description:
-- description: Wrapped VME64x Core
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- Modifications:
-- 2016-08-24: by Jan Pospisil (j.pospisil@cern.ch)
-- * fixed typo (address <-> data)
--------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
--------------------------------------------------------------------------------
-- This source file is free software; you can redistribute it and/or modify it
......@@ -39,8 +31,8 @@
--------------------------------------------------------------------------------
library ieee;
use ieee.STD_LOGIC_1164.all;
use WORK.wishbone_pkg.all;
use ieee.std_logic_1164.all;
use work.wishbone_pkg.all;
use work.vme64x_pack.all;
entity xvme64x_core is
......@@ -52,6 +44,7 @@ entity xvme64x_core is
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
VME_AS_n_i : in std_logic;
VME_RST_n_i : in std_logic;
VME_WRITE_n_i : in std_logic;
......@@ -126,13 +119,13 @@ architecture wrapper of xvme64x_core is
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(g_wb_data_width - 1 downto 0);
DAT_o : out std_logic_vector(g_wb_data_width - 1 downto 0);
ADR_o : out std_logic_vector(g_wb_addr_width - 1 downto 0);
DAT_i : in std_logic_vector(g_wb_data_width-1 downto 0);
DAT_o : out std_logic_vector(g_wb_data_width-1 downto 0);
ADR_o : out std_logic_vector(g_wb_addr_width-1 downto 0);
CYC_o : out std_logic;
ERR_i : in std_logic;
RTY_i : in std_logic;
SEL_o : out std_logic_vector(f_div8(g_wb_data_width) - 1 downto 0);
SEL_o : out std_logic_vector(f_div8(g_wb_data_width)-1 downto 0);
STB_o : out std_logic;
ACK_i : in std_logic;
WE_o : out std_logic;
......@@ -150,7 +143,8 @@ begin -- wrapper
generic map (
g_adem_a32 => g_adem_a32,
g_adem_a24 => g_adem_a24,
g_clock => g_clock_freq)
g_clock => g_clock_freq
)
port map (
clk_i => clk_i,
rst_n_i => rst_n_i,
......
--------------------------------------------------------------------------------
-- CERN (BE-CO-HT)
-- VME64x core package
-- VME64x Core
-- http://www.ohwr.org/projects/vme64x-core
--------------------------------------------------------------------------------
--
-- unit name: xvme64x_core_pkg.vhd (xvme64x_core_pkg.vhd)
-- unit name: xvme64x_core_pkg (xvme64x_core_pkg.vhd)
--
-- author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
--
--
-- date: 05-07-2013
--
-- version: 1.0
--
-- description: Package for wrapped VME64x Core
--
-- dependencies:
--
......@@ -34,17 +30,16 @@
-- TODO: -
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use WORK.wishbone_pkg.all;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;
package xvme64x_core_pkg is
------------------------------------------------------------------------------
-- Types declaration
------------------------------------------------------------------------------
type t_vme64x_in is record
as_n : std_logic;
rst_n : std_logic;
......@@ -131,7 +126,8 @@ package xvme64x_core_pkg is
g_wb_addr_width : integer := 64;
g_cram_size : integer := 1024;
g_window_size_a24 : std_logic_vector(31 downto 0) := x"00080000";
g_window_size_a32 : std_logic_vector(31 downto 0) := x"00080000");
g_window_size_a32 : std_logic_vector(31 downto 0) := x"00080000"
);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
......@@ -141,7 +137,8 @@ package xvme64x_core_pkg is
master_o : out t_wishbone_master_out;
master_i : in t_wishbone_master_in;
irq_i : in std_logic;
irq_ack_o : out std_logic);
irq_ack_o : out std_logic
);
end component xvme64x_core_structs;
end xvme64x_core_pkg;
......
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