Commit 71c91f0b authored by dpedrett's avatar dpedrett

vme64x_core Program ID 0x54. CRAM reduced to 1 KByte. 100 MHz clock supported

git-svn-id: http://svn.ohwr.org/vme64x-core/trunk@154 665b4545-5c6b-4c24-801b-41150b02b44b
parent 94d5e1de
......@@ -48,7 +48,7 @@
-- 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 at the Wb bus in
-- 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
......@@ -65,8 +65,8 @@
-- 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/VFC_access.pdf
-- This core is
-- documentation/user_guides/VME_access_modes.pdf
--
--______________________________________________________________________________
--
-- References:
......@@ -77,8 +77,8 @@
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 06/2012
-- Version v0.01
-- Date 08/2012
-- Version v0.02
--______________________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
......@@ -97,8 +97,14 @@
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;
use work.vme64x_pack.all;
--===========================================================================
-- Entity declaration
--===========================================================================
entity VME64xCore_Top is
generic(g_width : integer := c_width;
g_addr_width : integer := c_addr_width;
g_CRAM_SIZE : integer := c_CRAM_SIZE
);
port(
clk_i : in std_logic;
-- for the IRQ_Generator and relative registers
......@@ -133,33 +139,37 @@
VME_RETRY_OE_o : out std_logic;
-- WishBone
DAT_i : in std_logic_vector(63 downto 0);
DAT_o : out std_logic_vector(63 downto 0);
ADR_o : out std_logic_vector(63 downto 0);
DAT_i : in std_logic_vector(g_width - 1 downto 0);
DAT_o : out std_logic_vector(g_width - 1 downto 0);
ADR_o : out std_logic_vector(g_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(7 downto 0);
SEL_o : out std_logic_vector(f_div8(g_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 : out std_logic;
IRQ_i : in std_logic;
INT_ack : 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 sends a pulse to
-- the IRQ Controller and it asserts one of the IRQ lines.
-- Add by Davide for debug:
leds : out std_logic_vector(7 downto 0)
);
end VME64xCore_Top;
--===========================================================================
-- Architecture declaration
--===========================================================================
architecture RTL of VME64xCore_Top is
signal s_CRAMdataOut : std_logic_vector(7 downto 0);
signal s_CRAMaddr : std_logic_vector(18 downto 0);
signal s_CRAMaddr : std_logic_vector(f_log2_size(g_CRAM_SIZE)-1 downto 0);
signal s_CRAMdataIn : std_logic_vector(7 downto 0);
signal s_CRAMwea : std_logic;
signal s_CRaddr : std_logic_vector(11 downto 0);
......@@ -171,7 +181,7 @@
signal s_VME_DATA_IRQ : std_logic_vector(31 downto 0);
signal s_VME_DATA_VMEbus : std_logic_vector(31 downto 0);
signal s_VME_DATA_b : std_logic_vector(31 downto 0);
signal s_DATi_sample : std_logic_vector(63 downto 0);
signal s_DATi_sample : std_logic_vector(g_width - 1 downto 0);
signal s_fifo : std_logic;
signal s_VME_DTACK_VMEbus : std_logic;
signal s_VME_DTACK_IRQ : std_logic;
......@@ -208,7 +218,7 @@
-- Oversampled input signals
signal VME_RST_n_oversampled : std_logic;
signal VME_AS_n_oversampled : std_logic;
signal VME_AS_n_oversampled1 : std_logic;
signal VME_AS_n_oversampled1 : std_logic; -- for the IRQ_Controller
signal VME_LWORD_n_oversampled : std_logic;
signal VME_WRITE_n_oversampled : std_logic;
signal VME_DS_n_oversampled : std_logic_vector(1 downto 0);
......@@ -219,8 +229,15 @@
signal VME_AM_oversampled : std_logic_vector(5 downto 0);
signal VME_IACK_n_oversampled : std_logic;
signal VME_IACKIN_n_oversampled : std_logic;
--===========================================================================
-- 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.
AMinputSample : RegInputSample
generic map(
width => 6
......@@ -320,7 +337,13 @@ begin
clk_i => clk_i
);
Inst_VME_bus: VME_bus PORT MAP(
Inst_VME_bus: VME_bus
generic map(
g_width => c_width,
g_addr_width => c_addr_width,
g_CRAM_SIZE => c_CRAM_SIZE
)
port map(
clk_i => clk_i,
reset_o => s_reset, -- asserted when '1'
-- VME
......@@ -332,7 +355,6 @@ begin
VME_RETRY_OE_o => VME_RETRY_OE_o,
VME_WRITE_n_i => VME_WRITE_n_oversampled,
VME_DS_n_i => VME_DS_n_oversampled,
VME_GA_i => VME_GA_oversampled,
VME_DTACK_n_o => s_VME_DTACK_VMEbus,
VME_DTACK_OE_o => s_VME_DTACK_OE_VMEbus,
VME_BERR_o => VME_BERR_o,
......@@ -407,17 +429,17 @@ begin
INT_ack <= s_VME_DTACK_IRQ;
--------------------------------------------------------------------------------
--Multiplexer added on the output signal used by either VMEbus.vhd and the IRQ_controller.vhd
VME_DATA_b_o <= s_VME_DATA_VMEbus WHEN VME_IACK_n_oversampled ='1' ELSE
VME_DATA_b_o <= s_VME_DATA_VMEbus when VME_IACK_n_oversampled ='1' else
s_VME_DATA_IRQ;
VME_DTACK_n_o <= s_VME_DTACK_VMEbus WHEN VME_IACK_n_oversampled ='1' ELSE
VME_DTACK_n_o <= s_VME_DTACK_VMEbus when VME_IACK_n_oversampled ='1' else
s_VME_DTACK_IRQ;
VME_DTACK_OE_o <= s_VME_DTACK_OE_VMEbus WHEN VME_IACK_n_oversampled ='1' ELSE
VME_DTACK_OE_o <= s_VME_DTACK_OE_VMEbus when VME_IACK_n_oversampled ='1' else
s_VME_DTACK_OE_IRQ;
VME_DATA_DIR_o <= s_VME_DATA_DIR_VMEbus WHEN VME_IACK_n_oversampled ='1' ELSE
VME_DATA_DIR_o <= s_VME_DATA_DIR_VMEbus when VME_IACK_n_oversampled ='1' else
s_VME_DATA_DIR_IRQ;
--------------------------------------------------------------------------------
-- Interrupter
Inst_VME_IRQ_Controller: VME_IRQ_Controller PORT MAP(
Inst_VME_IRQ_Controller: VME_IRQ_Controller port map(
clk_i => clk_i,
reset => s_reset_IRQ, -- asserted when low
VME_IACKIN_n_i => VME_IACKIN_n_oversampled,
......@@ -440,9 +462,13 @@ begin
s_reset_IRQ <= not(s_reset);
--------------------------------------------------------------------------
--CR/CSR space
Inst_VME_CR_CSR_Space: VME_CR_CSR_Space PORT MAP(
Inst_VME_CR_CSR_Space: VME_CR_CSR_Space
generic map(
g_CRAM_SIZE => c_CRAM_SIZE
)
port map(
clk_i => clk_i,
s_reset => s_reset,
reset => s_reset,
CR_addr => s_CRaddr,
CR_data => s_CRdata,
CRAM_addr => s_CRAMaddr,
......@@ -453,8 +479,8 @@ begin
CrCsrOffsetAddr => s_CrCsrOffsetAddr,
VME_GA_oversampled => VME_GA_oversampled,
locDataIn => s_CSRData_o,
s_err_flag => s_err_flag,
s_reset_flag => s_reset_flag,
err_flag => s_err_flag,
reset_flag => s_reset_flag,
CSRdata => s_CSRData_i,
Ader0 => s_Ader0,
Ader1 => s_Ader1,
......@@ -475,7 +501,7 @@ begin
INT_Vector => s_INT_Vector
);
------------------------------------------------------------------------
-- This process sampling the WB data input; this is a warranty that this
-- 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)
......@@ -489,3 +515,6 @@ begin
------------------------------------------------------------------------
end RTL;
--===========================================================================
-- Architecture end
--===========================================================================
\ No newline at end of file
......@@ -6,12 +6,14 @@
-- File: VME_Access_Decode.vhd
--_________________________________________________________________________________
-- Description: This component check if the board is addressed and if it is, allows
-- the access to CR/CSR space asserting the Confaccess signal, or allows the access
-- to WB bus asserting the CardSel signal.
-- 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)
-- 2) AM = 0x2f
-- 3) The initialization is finished (wait about 8800 ns after power-up or software reset)
--
-- To Access the Wb bus we have 7 function; 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
......@@ -34,9 +36,9 @@
-- | |
-- |___________________________________________|
-- Each function has one ADER, one ADEM, one AMCAP and one XAMCAP registers.
-- 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 collocated in the CSR space so the VME master has to write
-- 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]
......@@ -50,7 +52,7 @@
-- [1] --> '0'
-- [0] --> '1'
-- ADEM[31:0]
-- [31:8] --> mask bits (put here the base address)
-- [31:8] --> mask bits
-- [7:4] --> "0000"
-- [3] --> '0' --> The ADER is programmable
-- [2] --> DFS
......@@ -59,13 +61,12 @@
-- 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 access mode. Since different access mode have different AM this bit
-- influences the way of work of the AM Match component. If '1' this function has to
-- decode different address length (eg. A16 or A24 or A32) so the mask bits
-- 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 configuration
-- 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 corrisponding AM is supported by this function.
-- If the corresponding ADEM's DFS is 0, only the AMCAP's bits with the same address
......@@ -74,38 +75,41 @@
-- 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 configuration
-- 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 corrisponding 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 need to know the corrisponding ADEM and check if EFM
-- or DFS bits are asserted (Read CR memory). If DFS is asserted the VME Master can read also
-- or DFS bits are asserted. The VME Master can read also
-- the AMCAP and XAMCAP and check the access mode supported by each function.
-- How this decode process can be used:
-- eg1. lets imagine that we want be able to access different storage device; we can assign
--
-- eg.1 lets imagine that we want be able 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 corrisponding
-- ADER's compare bits and after this operation each function decodes the access to
-- the corresponding storage.
-- eg2. this example is relative to our application; the vme64x interface has to transfer
-- 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
-- at this WB master, and use the different functions to access with different mode eg:
-- function0 --> A24_S, A24_BLT, A24_MBLT, A16_S, A32_S, A32_BLT, A32_MBLT modes
-- function1 and function2 --> A64, A64_BLT, A64_MBLT
-- 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 of 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
-- 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.
-- respectively.
-- In the VME_Funct_Match.vhd and VME_Am_Match.vhd components you can find more details
-- about the decode process.
--
-- To access the board both the FunctMatch(i) and AmMatch(i) must be equal to one.
......@@ -113,8 +117,8 @@
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 06/2012
-- Version v0.01
-- Date 08/2012
-- Version v0.02
--______________________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
......@@ -135,12 +139,15 @@ 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;
s_reset : in STD_LOGIC;
s_mainFSMreset : in STD_LOGIC;
s_decode : in STD_LOGIC;
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);
......@@ -176,33 +183,38 @@ entity VME_Access_Decode is
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 : in STD_LOGIC_VECTOR (4 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
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,
s_reset => s_reset,
s_decode => s_decode,
s_mainFSMreset => s_mainFSMreset,
reset => reset,
decode => decode,
mainFSMreset => mainFSMreset,
Addr => Addr,
AddrWidth => AddrWidth,
Ader0 => Ader0,
......@@ -226,10 +238,10 @@ 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,
s_reset => s_reset,
s_mainFSMreset => s_mainFSMreset,
reset => reset,
mainFSMreset => mainFSMreset,
Ader0 => Ader0,
Ader1 => Ader1,
Ader2 => Ader2,
......@@ -257,11 +269,11 @@ begin
Am => Am,
XAm => XAm,
DFS_i => s_DFS,
s_decode => s_decode,
decode => decode,
AmMatch => s_Am_Match
);
-- Check if the WB application is addressed
process(clk_i)
begin
if rising_edge(clk_i) then
......@@ -280,11 +292,13 @@ begin
end process;
s_func_sel <= s_Func_Match and s_Am_Match;
Confaccess <= '1' when unsigned(BAR) = unsigned(Addr(23 downto 19)) and
-- 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
--===========================================================================
......@@ -5,15 +5,14 @@
--______________________________________________________________________________________
-- File: VME_ Am_Match.vhd
--______________________________________________________________________________________
-- Description: this component checks if the AM match the capability of the function.
-- Description: this component checks if the AM match.
-- If it is the corrispondent 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;
-- 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 wide so AmMatch(i)
-- is asserted only if AMCAP(i)(to_integer(unsigned(Am))) = '1' and ADER[7:2] = AM and
-- s_FUNC_AMCAP(i)(to_integer(unsigned(Am)))='1'.
-- 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.
......@@ -21,8 +20,8 @@
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 06/2012
-- Version v0.01
-- Date 08/2012
-- Version v0.02
--______________________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
......@@ -42,11 +41,14 @@ 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;
s_reset : in std_logic;
s_mainFSMreset : 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);
......@@ -74,10 +76,12 @@ entity VME_Am_Match is
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);
s_decode : in std_logic;
decode : in std_logic;
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;
......@@ -85,6 +89,9 @@ architecture Behavioral of VME_Am_Match is
signal s_amcap_match : std_logic_vector(7 downto 0);
signal s_xamcap_match : std_logic_vector(7 downto 0);
signal debugAm : integer;
--===========================================================================
-- Architecture begin
--===========================================================================
begin
s_FUNC_ADER(0) <= unsigned(Ader0);
......@@ -117,10 +124,10 @@ begin
p_AMmatch : process(clk_i)
begin
if rising_edge(clk_i) then
if s_mainFSMreset = '1' or s_reset = '1' then
if mainFSMreset = '1' or reset = '1' then
AmMatch <= (others => '0');
debugAm <= 0;
elsif s_decode = '1' then
elsif decode = '1' then
for i in AmMatch'range loop
if DFS_i(i) = '1' then
if s_FUNC_ADER(i)(XAM_MODE) = '0' then
......@@ -171,4 +178,6 @@ begin
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 06/2012
-- Version v0.02
--______________________________________________________________________________
-- 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.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use work.vme64x_pack.all;
--===========================================================================
-- Entity declaration
--===========================================================================
entity VME_CRAM is
generic (dl : integer;
al : integer := f_log2_size(c_CRAM_SIZE)
);
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)
);
end VME_CRAM;
--===========================================================================
-- Architecture declaration
--===========================================================================
architecture syn of VME_CRAM is
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
if (we = '1') then
CRAM(conv_integer(aw)) <= di;
end if;
dw <= CRAM(conv_integer(aw));
end if;
end process;
end syn;
--===========================================================================
-- Architecture end
--===========================================================================
......@@ -6,9 +6,9 @@
-- File: VME_CR_CSR_Space.vhd
--________________________________________________________________________________________________
-- Description:
-- Only the third location of each 4-byte group is implemented so is possible write the CSR/CRAM
-- selecting the data transfer mode D08_Byte3, D16_Byte23, D32. If other data transfer mode are
-- selected the write operation will not be successful.
-- Please note that only every fourth location in the CR/CSR space is used so is possible write
-- the CSR/CRAM selecting the data transfer mode D08_Byte3, D16_Byte23, D32. If other data transfer
-- mode 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
......@@ -23,7 +23,7 @@
-- | ANSI/VITA 1.1-1997 |
-- | VME64 Extensions |
-- |_________________________________|0x7fc00
-- | |0x7fbff
-- | |0x013ff
-- | |
-- | |
-- | CRAM |
......@@ -63,12 +63,12 @@
-- BYTES0 --> 0x7FF3b |
-- BYTES1 --> 0x7FF37 _|
--
-- CRAM memory Added. How to use the CRAM:
-- 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
-- 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 this master
-- 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 Master write their ID in the CRAM_OWNER Register when it contains a non-zero
-- 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,
......@@ -77,7 +77,7 @@
-- 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 decoding is not enable and
-- 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.
......@@ -96,8 +96,8 @@
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 06/2012
-- Version v0.01
-- Date 08/2012
-- Version v0.02
--______________________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
......@@ -118,14 +118,19 @@ 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(
g_CRAM_SIZE : integer := c_CRAM_SIZE
);
Port ( -- VMEbus.vhd signals
clk_i : in std_logic;
s_reset : in std_logic;
reset : in std_logic;
CR_addr : in std_logic_vector (11 downto 0);
CR_data : out std_logic_vector (7 downto 0);
CRAM_addr : in std_logic_vector (18 downto 0);
CRAM_addr : in std_logic_vector (f_log2_size(g_CRAM_SIZE)-1 downto 0);
CRAM_data_o : out std_logic_vector (7 downto 0);
CRAM_data_i : in std_logic_vector (7 downto 0);
CRAM_Wen : in std_logic;
......@@ -133,8 +138,8 @@ entity VME_CR_CSR_Space is
CrCsrOffsetAddr : in std_logic_vector (18 downto 0);
VME_GA_oversampled : in std_logic_vector (5 downto 0);
locDataIn : in std_logic_vector (7 downto 0);
s_err_flag : in std_logic;
s_reset_flag : out std_logic;
err_flag : in std_logic;
reset_flag : out std_logic;
CSRdata : out std_logic_vector(7 downto 0);
numBytes : in std_logic_vector(12 downto 0);
transfTime : in std_logic_vector(39 downto 0);
......@@ -157,7 +162,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;
......@@ -169,15 +176,17 @@ 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
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 odd 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.
-- 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));
--------------------------------------------------------------------------------
-- CR
......@@ -195,7 +204,7 @@ 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
p_CSR_Write : process(clk_i)
begin
if rising_edge(clk_i) then
if s_reset = '1' then
if reset = '1' then
s_CSRarray(BAR) <= (others => '0');
s_bar_written <= '0';
for i in 254 downto WB32or64 loop -- Initialization of the CSR memory
......@@ -225,7 +234,7 @@ 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
s_CSRarray(BIT_SET_CLR_REG)(i) <= '0';
s_CSRarray(CRAM_OWNER) <= x"00";
elsif s_locDataIn(i) = '1' and i = 3 then
s_reset_flag <= '1';
reset_flag <= '1';
else
if s_locDataIn(i) = '1' then
s_CSRarray(BIT_SET_CLR_REG)(i) <= '0';
......@@ -270,7 +279,12 @@ 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
end case;
else
s_reset_flag <= '0';
if c_width = 32 then
s_CSRarray(WB32or64) <= x"01";
else
s_CSRarray(WB32or64) <= x"00";
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(TIME0_ns) <= unsigned(transfTime(7 downto 0));
......@@ -283,15 +297,15 @@ 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
end process;
------------------------------------------------------------------------------------------------------------------------------------
--CSR Read
process(s_CSRarray, s_CrCsrOffsetAddr,s_err_flag)
process(s_CSRarray, s_CrCsrOffsetAddr,err_flag)
begin
s_CSRdata <= (others => '0');
case (s_CrCsrOffsetAddr) is
when "00" & c_BAR_addr(18 downto 2) => s_CSRdata <= s_CSRarray(BAR);
when "00" & c_BIT_SET_REG_addr(18 downto 2) => s_CSRdata <= s_CSRarray(
BIT_SET_CLR_REG)(7 downto 4) & s_err_flag & s_CSRarray(BIT_SET_CLR_REG)(2 downto 0);
BIT_SET_CLR_REG)(7 downto 4) & err_flag & s_CSRarray(BIT_SET_CLR_REG)(2 downto 0);
when "00" & c_BIT_CLR_REG_addr(18 downto 2) => s_CSRdata <= s_CSRarray(
BIT_SET_CLR_REG)(7 downto 4) & s_err_flag & s_CSRarray(BIT_SET_CLR_REG)(2 downto 0);
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);
......@@ -371,18 +385,16 @@ 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
s_BAR_o <= std_logic_vector(s_CSRarray(BAR)(7 downto 3));
---------------------------------------------------------------------------------------------------------------
-- CRAM:
CRAM_1 : dpblockram
generic map(dl => 8, -- Length of the data word
al => 19, -- Size of the addr map (10 = 1024 words)
nw => 2**19) -- Number of words
-- 'nw' has to be coherent with 'al'
port map(clk => clk_i, -- Global Clock
we => CRAM_Wen, -- Write Enable
aw => CRAM_addr, -- Write Address
ar => (others => '0'), -- Read Address
di => CRAM_data_i, -- Data input
dw => CRAM_data_o, -- Data write, normaly open
do => open); -- Data output
CRAM_1 : VME_CRAM
generic map(dl => 8,
al => f_log2_size(g_CRAM_SIZE)
)
port map(clk => clk_i,
we => CRAM_Wen,
aw => CRAM_addr,
di => CRAM_data_i,
dw => CRAM_data_o);
end Behavioral;
--===========================================================================
-- Architecture end
--===========================================================================
......@@ -11,7 +11,7 @@
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 06/2012
-- Version v0.01
-- Version v0.02
--______________________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
......@@ -42,7 +42,7 @@ package VME_CR_pack is
constant c_amcapMBLT : std_logic_vector(63 downto 0) :=
"0000000000000000000000000000000000000000000000000000000100000000";
constant c_amcap1 : std_logic_vector(63 downto 0) :=
"1011101100000000000000000000000000000000000000000000000000001011"; --A24
"1011101100000000000000000000000000000000000000000000000000000000"; --A24
constant c_amcap2 : std_logic_vector(63 downto 0) :=
"0000000000000000001000100000000000000000000000000000000000000000"; --A16
constant c_amcapA64 : std_logic_vector(63 downto 0) :=
......@@ -117,13 +117,13 @@ package VME_CR_pack is
(
16#00# => (others => '0'),
-- Length of ROM
16#01# => x"01",
16#02# => x"00",
16#01# => x"00",
16#02# => x"10",
16#03# => x"00",
--Configuration ROM data acces width
16#04# => x"00",
16#04# => x"84", --D32, D16, D08
--CSR data acces width
16#05# => x"81", -- it was 01...changed by Davide
16#05# => x"84", --D32, D16, D08
--CR/CSR Space Specification ID
16#06# => x"01",
--Ascii "C"
......@@ -144,48 +144,48 @@ package VME_CR_pack is
16#11# => x"04",
16#12# => x"04",
16#13# => x"03",
--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
16#1F# => x"02",
--Offset to BEG_USER_CR --Added by Davide
--Program Id code
16#1F# => x"54",
--Offset to BEG_USER_CR
16#20# => x"00",
16#21# => x"00",
16#22# => x"00",
--Offset to END_USER_CR --Added by Davide
--Offset to END_USER_CR
16#23# => x"00",
16#24# => x"00",
16#25# => x"00",
--Offset to BEG_CRAM --Added by Davide
--Offset to BEG_CRAM
16#26# => x"00",
16#27# => x"10", --10
16#28# => x"00", --00
--Offset to END_CRAM --Added by Davide
16#29# => x"07",
16#2A# => x"fb",
16#27# => x"10",
16#28# => x"00",
--Offset to END_CRAM
16#29# => x"00",
16#2A# => x"13",
16#2B# => x"ff",
--Offset to BEG_USER_CSR --Added by Davide
--Offset to BEG_USER_CSR
16#2C# => x"00",
16#2D# => x"00",
16#2E# => x"00", --NB: 0x7fbf0 and NOT 0x7fbf3 because is possible access with D32 mode
--Offset to END_USER_CSR --Added by Davide
16#2E# => x"00", -- 0x7fbf0 and NOT 0x7fbf3 because is possible access with D32 mode
--Offset to END_USER_CSR
16#2F# => x"00",
16#30# => x"00",
16#31# => x"00",
--CRAM_ACCESS_WIDTH
16#39# => x"81",
16#3f# => x"84", --D32, D16, D08
--Function data access width
16#40# => x"85", -- Fun 0 accepts MD32, D16, D08(EO) cycles
16#41# => x"85", -- Fun 1
16#42# => x"85", -- Fun 2
16#43# => x"85", -- Fun 3
16#44# => x"85", -- Fun 4
16#45# => x"85", -- Fun 5
16#46# => x"85", -- Fun 6
16#47# => x"85", -- Fun 7
16#40# => x"86", -- Fun 0 accepts D64, D32, D16, D08(EO) cycles
16#41# => x"86", -- Fun 1
16#42# => x"86", -- Fun 2
16#43# => x"86", -- Fun 3
16#44# => x"86", -- Fun 4
16#45# => x"86", -- Fun 5
16#46# => x"86", -- Fun 6
16#47# => x"86", -- Fun 7
--Function AM code Mask
......
......@@ -11,7 +11,7 @@
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 06/2012
-- Version v0.01
-- Version v0.02
--______________________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
......@@ -78,7 +78,7 @@ 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",
WB32or64 =>x"01", -- 32 bit WB of default
WB32or64 =>x"00", -- 32 bit WB of default
others => (others => '0'));
end VME_CSR_pack;
......
--==============================================================--
--Design Units : CTX1 Control and Statistics
--Size:
--Speed:
--File Name: MebRam.vhd
--
--Purpose: The dpblockram implements a synthetisable model of a
-- dual port RAM.
-- There are an input data and addr ports to allow the
-- writing at the reception of a GMT frame.
-- The output data and addr ports allow a simultanous
-- reading of the circular buffer by the user, at the
-- same time than it is beeing written.
--
-- The frame and the millisecond stamp are stored in the
-- same ram word. It is the task of the MEB block to
-- separate the frame data from the millisecond stamp data.
--
--Limitations:
--
--Errors:
--
--Libraries:
--
--Dependancies: It instantiates a synthetisable model of a DPRAM
-- See MebRam.vhd
--
--Author: Pablo Antonio Alvarez Sanchez
-- European Organisation for Nuclear Research
-- SL SPS/LHC -- Control -- Timing Division
-- CERN, Geneva, Switzerland, CH-1211
-- Building 864 Room 1 - A24
--
--Simulator: ModelSim XE 5.5e_p1
--==============================================================--
--Revision List
--Version Author Date Changes
--
--1.0 PAAS 30.09.2002 Added comments, tested with the
-- rest of the design
--==============================================================--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity dpblockram is
generic (dl : integer := 8; -- Length of the data word
al : integer := 19; -- Size of the addr map (10 = 1024 words)
nw : integer := 2**19); -- Number of words
-- 'nw' has to be coherent with 'al'
port (clk : in std_logic; -- Global Clock
we : in std_logic; -- Write Enable
aw : in std_logic_vector(al - 1 downto 0); -- Write Address
ar : in std_logic_vector(al - 1 downto 0); -- Read Address
di : in std_logic_vector(dl - 1 downto 0); -- Data input
dw : out std_logic_vector(dl - 1 downto 0); -- Data write, normaly open
do : out std_logic_vector(dl - 1 downto 0)); -- Data output
end dpblockram;
-- DATA OUTPUT NOT REGISTERED!
--library synplify;
--use synplify.attributes.all;
architecture syn of dpblockram is
type ram_type is array (nw - 1 downto 0) of std_logic_vector (dl - 1 downto 0);
signal CRAM : ram_type;
signal read_a : std_logic_vector(al - 1 downto 0);
signal read_ar : std_logic_vector(al - 1 downto 0);
--attribute syn_ramstyle of RAM : signal is "block_ram";
begin
process (clk)
begin
if (clk'event and clk = '1') then
if (we = '1') then
CRAM(conv_integer(aw)) <= di;
end if;
read_a <= aw;
read_ar <= ar;
end if;
end process;
dw <= CRAM(conv_integer(read_a));
do <= CRAM(conv_integer(read_ar)); -- Notice that the Data Output is not registered
end syn;
......@@ -6,16 +6,16 @@
-- File: VME_Funct_Match.vhd
--_________________________________________________________________________________________
-- Description: this component compares the Address with the ADER using the mask bits and
-- if the base address match asserts the corrisponding bit of the FunctMatch signal and
-- latches the base address that will be subtract at the Address before access the WB bus.
-- FunctMatch /= 0 is necessary but not sufficient to select one function and access the board,
-- if the base address match it asserts the corrisponding bit in the FunctMatch vector and it
-- latches the base address that will be subtract 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 one example:
-- base address = 0xc0
-- access mode: A32_S --> AM = 0x09
-- The Master write the ADERi = 0xc0000024
-- The Master writes the ADERi = 0xc0000024
-- ADEMi = 0xffffff04 --> DFS = '1' --> all the mask bits are '1'!!
-- The Master want access at the location 0x08: Address= 0xc0000008
-- 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]
......@@ -41,8 +41,9 @@
-- |_______|
-- No | |yes
-- FunctMatch(i) <= '0'_____| |______FunctMatch(i) <= '1'
-- DFS = '1' --> 1 function --> multiple access mode
-- The Master access with different mode only changing the ADER registers if the
--
-- 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:
-- base address = 0xc0
......@@ -93,7 +94,7 @@
-- Yes, it is. Indeed now suppose that we are in this situation:
-- ADERi = 0x00000000
-- ADEMi = 0x0000ff00 --> DFS = '0'
-- A VME Master access to VMEbus for accessing at another board:
-- A VME Master takes the ownership of the VMEbus for accessing another board:
-- base address = 0xc0
-- access mode: A32_S --> AM = 0x09
-- The Master want access at the location 0x0008: Address= 0xc0000008
......@@ -113,7 +114,7 @@
-- 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'.
--
--Follow an example about A64 access mode:
-- An example about A64 access mode:
-- base address = 0xc0
-- access mode: A64_S --> AM = 0x01
-- ADEM(i) = 0x00000001 --> EFM = '1' and DFS = '0'
......@@ -126,7 +127,7 @@
-- 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.
-- The Master want access at the location 0x0008: Address= 0xc000000000000008
-- The Master accesses the location 0x0008: Address= 0xc000000000000008
-- 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]
-- | |
......@@ -137,12 +138,12 @@
-- No | |yes
-- FunctMatch(i) <= '0'_____| |______FunctMatch(i) <= '1'
--
-- For the 2e modes is the same, change only the ADER(i)'s XAM bit that must be '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 06/2012
-- Date 08/2012
-- Version v0.01
--______________________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
......@@ -162,12 +163,15 @@ use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.vme64x_pack.all;
--===========================================================================
-- Entity declaration
--===========================================================================
entity VME_Funct_Match is
Port ( clk_i : in std_logic;
s_reset : in std_logic;
s_decode : in std_logic;
s_mainFSMreset : in std_logic;
reset : in std_logic;
decode : in std_logic;
mainFSMreset : in std_logic;
Addr : in std_logic_vector(63 downto 0);
AddrWidth : in std_logic_vector(1 downto 0);
Ader0 : in std_logic_vector(31 downto 0);
......@@ -191,24 +195,29 @@ entity VME_Funct_Match is
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_isprev_func64 : std_logic_vector(7 downto 0);
signal s_locAddr : unsigned(63 downto 0);
signal debugfunct : integer;
--===========================================================================
-- Architecture begin
--===========================================================================
begin
s_locAddr <= unsigned(Addr);
p_functMatch : process(clk_i)
begin
if rising_edge(clk_i) then
if s_mainFSMreset = '1' or s_reset = '1' then
if mainFSMreset = '1' or reset = '1' then
FunctMatch <= (others => '0');
Nx_Base_Addr <= (others => '0');
debugfunct <= 0;
elsif s_decode = '1' then
elsif decode = '1' then
for i in FunctMatch'range loop
case AddrWidth is
......@@ -306,4 +315,6 @@ begin
s_isprev_func64(0) <= '0';
s_FUNC_ADEM_64(7) <= (others => '0');
end Behavioral;
--===========================================================================
-- Architecture end
--===========================================================================
......@@ -6,7 +6,7 @@
-- File: VME_IRQ_Controller.vhd
--_________________________________________________________________________________________
-- Description:
-- This block acts as Interrupter; phases of an interrupt cycle:
-- 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.
......@@ -20,10 +20,10 @@
-- 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 the it is the responding interrupter should send the source/ID on the VME_DATA lines
-- 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 terminates the interrupt cycle with an acknowledge and
-- releases the IRQ line. If it isn't the responding interrupter should pass a falling edge on
-- 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
......@@ -75,8 +75,8 @@
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 06/2012
-- Version v0.01
-- Date 08/2012
-- Version v0.02
--______________________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
......@@ -94,7 +94,9 @@ 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
Port ( clk_i : in std_logic;
reset : in std_logic;
......@@ -114,7 +116,9 @@ entity VME_IRQ_Controller is
VME_DATA_o : out std_logic_vector (31 downto 0);
VME_DATA_DIR_o : out std_logic);
end VME_IRQ_Controller;
--===========================================================================
-- Architecture declaration
--===========================================================================
architecture Behavioral of VME_IRQ_Controller is
--input signals
signal INT_Req_sample : std_logic;
......@@ -140,7 +144,9 @@ architecture Behavioral of VME_IRQ_Controller is
signal VME_DS_latched : std_logic_vector(1 downto 0);
signal DSlatch : std_logic;
signal ADDRmatch : std_logic;
--===========================================================================
-- Architecture begin
--===========================================================================
begin
-- Input sampling and edge detection
......@@ -305,6 +311,7 @@ begin
end process;
-- Update Outputs
-- Mealy FSM
process(currs,VME_AS1_n_i)
begin
case currs is
......@@ -460,5 +467,7 @@ begin
VME_DTACK_OE_o <= s_DTACK_OE_o;
VME_IACKOUT_n_o <= s_IACKOUT_o;
end Behavioral;
--===========================================================================
-- Architecture end
--===========================================================================
......@@ -9,8 +9,8 @@
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 06/2012
-- Version v0.01
-- Date 08/2012
-- Version v0.02
--______________________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
......@@ -30,6 +30,9 @@ 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;
RSTedge : inout std_logic;
......@@ -69,7 +72,11 @@ entity VME_Init is
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);
signal s_initState : t_initState;
signal s_latchCRdata : std_logic; -- Stores read CR data
......@@ -88,7 +95,10 @@ architecture Behavioral of VME_Init is
signal s_END_USER_CR : unsigned(23 downto 0);
signal s_BEG_CRAM : unsigned(23 downto 0);
signal s_END_CRAM : unsigned(23 downto 0);
--===========================================================================
-- Architecture begin
--===========================================================================
begin
InitReadCount <= std_logic_vector(s_initReadCounter);
s_CRaddr <= unsigned(CRAddr);
......@@ -107,8 +117,8 @@ 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;
......@@ -243,4 +253,6 @@ begin
FUNC7_XAMCAP_o <= std_logic_vector(s_FUNC_XAMCAP(7));
end Behavioral;
--===========================================================================
-- Architecture end
--===========================================================================
......@@ -60,7 +60,30 @@ begin
end if;
end process;
end RTL;
--***************************************************
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity SingleRegInputSample is
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
);
end SingleRegInputSample;
architecture RTL of SingleRegInputSample is
begin
process(clk_i)
begin
if rising_edge(clk_i) then
reg_o <= reg_i;
end if;
end process;
end RTL;
-- ***************************************************
--FlipFlopD
library IEEE;
......
......@@ -11,8 +11,9 @@
-- PIPELINED
-- SINGLE READ/WRITE
--
-- The WB bus is 64 bit wide and the data organization is BIG ENDIAN --> the most
-- significant byte is carried in the lower position of the bus.
-- 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)|
-- |________|________|________|________|________|________|________|________|
......@@ -32,17 +33,18 @@
-- ______________________________________________________| |________________
--
-- 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 WB bus
-- This component implements the correct shift of the data in input/output from/to WB bus
--
--______________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 06/2012
-- Version v0.01
-- Date 08/2012
-- Version v0.02
--______________________________________________________________________________
-- 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.
......@@ -55,24 +57,30 @@
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_width : integer := c_width;
g_addr_width : integer := c_addr_width
);
Port ( s_memReq : in std_logic;
clk_i : in std_logic;
s_cardSel : in std_logic;
s_reset : in std_logic;
s_mainFSMreset : in std_logic;
s_BERRcondition : in std_logic;
s_sel : in std_logic_vector(7 downto 0);
s_beatCount : in std_logic_vector(8 downto 0);
s_locDataInSwap : in std_logic_vector(63 downto 0);
s_locDataOut : out std_logic_vector(63 downto 0);
s_rel_locAddr : in std_logic_vector(63 downto 0);
s_AckWithError : out std_logic;
cardSel : in std_logic;
reset : in std_logic;
mainFSMreset : in std_logic;
BERRcondition : in std_logic;
sel : in std_logic_vector(7 downto 0);
beatCount : in std_logic_vector(8 downto 0);
locDataInSwap : in std_logic_vector(63 downto 0);
locDataOut : out std_logic_vector(63 downto 0);
rel_locAddr : in std_logic_vector(63 downto 0);
memAckWb : out std_logic;
err : out std_logic;
rty : out std_logic;
s_RW : in std_logic;
RW : in std_logic;
psize_o : out std_logic_vector(8 downto 0);
stall_i : in std_logic;
rty_i : in std_logic;
......@@ -80,187 +88,241 @@ entity VME_Wb_master is
W32 : in std_logic;
cyc_o : out std_logic;
memReq_o : out std_logic;
WBdata_o : out std_logic_vector(63 downto 0);
wbData_i : in std_logic_vector(63 downto 0);
locAddr_o : out std_logic_vector(63 downto 0);
WBdata_o : out std_logic_vector(g_width - 1 downto 0);
wbData_i : in std_logic_vector(g_width - 1 downto 0);
locAddr_o : out std_logic_vector(g_addr_width - 1 downto 0);
memAckWB_i : in std_logic;
WbSel_o : out std_logic_vector(7 downto 0);
WbSel_o : out std_logic_vector(f_div8(g_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;
-- stb_o handler
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);
--===========================================================================
-- Architecture begin
--===========================================================================
begin
process(clk_i)
s_select <= cardSel & sel;
s_wbData_i <= std_logic_vector(resize(unsigned(wbData_i),s_wbData_i'length));
-- stb handler
process(clk_i)
begin
if rising_edge(clk_i) then
if s_reset = '1' or s_mainFSMreset = '1' or (stall_i = '0' and s_cyc = '1') then
if reset = '1' or mainFSMreset = '1' or (stall_i = '0' and s_cyc = '1') then
memReq_o <= '0';
elsif s_memReq = '1' and s_cardSel = '1' and s_BERRcondition = '0' then
elsif s_memReq = '1' and cardSel = '1' and BERRcondition = '0' then
memReq_o <= '1';
end if;
end if;
end process;
-- cyc_o handler
process(clk_i)
begin
if rising_edge(clk_i) then
if s_reset = '1' or s_mainFSMreset = '1' or memAckWB_i = '1' then
if reset = '1' or mainFSMreset = '1' or memAckWB_i = '1' then
s_cyc <= '0';
elsif s_memReq = '1' and s_cardSel = '1' and s_BERRcondition = '0' then
elsif s_memReq = '1' and cardSel = '1' and BERRcondition = '0' then
s_cyc <= '1';
end if;
end if;
end process;
cyc_o <= s_cyc;
-- shift s_sel, we need to this process when W32 is '1'.
process(s_sel)
begin
if s_sel = "10000000" or s_sel = "01000000" or s_sel = "00100000" or s_sel = "00010000"
or s_sel = "11000000" or s_sel = "00110000" or s_sel = "11110000"then
s_shift_dx <= '1';
else
s_shift_dx <= '0';
end if;
end process;
-- shift output data on WB bus
process(clk_i)
begin
process(clk_i)
begin
if rising_edge(clk_i) then
if W32 = '0' then
if s_sel = "10000000" then
WBdata_o <= std_logic_vector(unsigned(s_locDataInSwap) sll 56);
elsif s_sel = "01000000" then
WBdata_o <= std_logic_vector(unsigned(s_locDataInSwap) sll 48);
elsif s_sel = "00100000" then
WBdata_o <= std_logic_vector(unsigned(s_locDataInSwap) sll 40);
elsif s_sel = "00010000" then
WBdata_o <= std_logic_vector(unsigned(s_locDataInSwap) sll 32);
elsif s_sel = "00001000" then
WBdata_o <= std_logic_vector(unsigned(s_locDataInSwap) sll 24);
elsif s_sel = "00000100" then
WBdata_o <= std_logic_vector(unsigned(s_locDataInSwap) sll 16);
elsif s_sel = "00000010" then
WBdata_o <= std_logic_vector(unsigned(s_locDataInSwap) sll 8);
elsif s_sel = "11000000" then
WBdata_o <= std_logic_vector(unsigned(s_locDataInSwap) sll 48);
elsif s_sel = "00110000" then
WBdata_o <= std_logic_vector(unsigned(s_locDataInSwap) sll 32);
elsif s_sel = "00001100" then
WBdata_o <= std_logic_vector(unsigned(s_locDataInSwap) sll 16);
elsif s_sel = "11110000" then
WBdata_o <= std_logic_vector(unsigned(s_locDataInSwap) sll 32);
else
WBdata_o <= s_locDataInSwap;
end if;
WbSel_o <= std_logic_vector(s_sel);
else
if s_sel = "10000000" then
WBdata_o <= std_logic_vector(unsigned(s_locDataInSwap) sll 24);
elsif s_sel = "01000000" then
WBdata_o <= std_logic_vector(unsigned(s_locDataInSwap) sll 16);
elsif s_sel = "00100000" then
WBdata_o <= std_logic_vector(unsigned(s_locDataInSwap) sll 8);
elsif s_sel = "00001000" then
WBdata_o <= std_logic_vector(unsigned(s_locDataInSwap) sll 24);
elsif s_sel = "00000100" then
WBdata_o <= std_logic_vector(unsigned(s_locDataInSwap) sll 16);
elsif s_sel = "00000010" then
WBdata_o <= std_logic_vector(unsigned(s_locDataInSwap) sll 8);
elsif s_sel = "11000000" then
WBdata_o <= std_logic_vector(unsigned(s_locDataInSwap) sll 16);
elsif s_sel = "00001100" then
WBdata_o <= std_logic_vector(unsigned(s_locDataInSwap) sll 16);
else
WBdata_o <= s_locDataInSwap;
end if;
if s_shift_dx = '1' then
WbSel_o <= b"0000" & s_sel(7 downto 4);
else
WbSel_o <= std_logic_vector(s_sel);
end if;
end if;
RW_o <= s_RW;
s_AckWithError <=(s_memReq and s_cardSel and s_BERRcondition);
RW_o <= RW;
s_AckWithError <=(s_memReq and cardSel and BERRcondition);
end if;
end process;
end process;
-- shift input data from WB
s_locDataOut <= std_logic_vector(resize(unsigned(wbData_i(15 downto 0)) srl 8, s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "00000010" and W32 = '0' else
std_logic_vector(resize(unsigned(wbData_i(23 downto 0)) srl 16,s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "00000100" and W32 = '0' else
std_logic_vector(resize(unsigned(wbData_i(31 downto 0)) srl 24,s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "00001000" and W32 = '0' else
std_logic_vector(resize(unsigned(wbData_i(31 downto 0)) srl 24,s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "00001000" and W32 = '1' else
std_logic_vector(resize(unsigned(wbData_i(39 downto 0)) srl 32,s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "00010000" and W32 = '0' else
std_logic_vector(resize(unsigned(wbData_i(7 downto 0)),s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "00010000" and W32 = '1' else
std_logic_vector(resize(unsigned(wbData_i(47 downto 0)) srl 40,s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "00100000" and W32 = '0' else
std_logic_vector(resize(unsigned(wbData_i(15 downto 0)) srl 8,s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "00100000" and W32 = '1' else
std_logic_vector(resize(unsigned(wbData_i(55 downto 0)) srl 48,s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "01000000" and W32 = '0' else
std_logic_vector(resize(unsigned(wbData_i(23 downto 0)) srl 16,s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "01000000" and W32 = '1' else
std_logic_vector(resize(unsigned(wbData_i) srl 56,s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "10000000" and W32 = '0' else
std_logic_vector(resize(unsigned(wbData_i(31 downto 0)) srl 24,s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "10000000" and W32 = '1' else
std_logic_vector(resize(unsigned(wbData_i(31 downto 0)) srl 16,s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "00001100" and W32 = '0' else
std_logic_vector(resize(unsigned(wbData_i(31 downto 0)) srl 16,s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "00001100" and W32 = '1' else
std_logic_vector(resize(unsigned(wbData_i(47 downto 0)) srl 32,s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "00110000" and W32 = '0' else
std_logic_vector(resize(unsigned(wbData_i(15 downto 0)),s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "00110000" and W32 = '1' else
std_logic_vector(resize(unsigned(wbData_i) srl 48,s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "11000000" and W32 = '0' else
std_logic_vector(resize(unsigned(wbData_i(31 downto 0)) srl 16,s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "11000000" and W32 = '1' else
std_logic_vector(resize(unsigned(wbData_i(7 downto 0)), s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "00000001" and W32 = '0' else
std_logic_vector(resize(unsigned(wbData_i(7 downto 0)), s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "00000001" and W32 = '1' else
std_logic_vector(resize(unsigned(wbData_i(15 downto 0)), s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "00000011" and W32 = '0' else
std_logic_vector(resize(unsigned(wbData_i(15 downto 0)), s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "00000011" and W32 = '1' else
std_logic_vector(resize(unsigned(wbData_i(31 downto 0)), s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "00001111" and W32 = '0' else
std_logic_vector(resize(unsigned(wbData_i(31 downto 0)), s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "00001111" and W32 = '1' else
std_logic_vector(resize(unsigned(wbData_i) srl 32, s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "11110000" and W32 = '0' else
std_logic_vector(resize(unsigned(wbData_i(31 downto 0)),s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "11110000" and W32 = '1' else
std_logic_vector(resize(unsigned(wbData_i),s_locDataOut'length)) when
s_cardSel = '1' and s_sel = "11111111" and W32 = '0' else
(others => '0');
-- shift data and address for WB data bus 64 bits
gen64: if (g_width = 64) generate
process(clk_i)
begin
if rising_edge(clk_i) then
if W32 = '0' then
locAddr_o <= b"000" & s_rel_locAddr(63 downto 3);
else
locAddr_o <= b"00" & s_rel_locAddr(63 downto 2);
end if;
end if;
end process;
process(clk_i)
begin
if rising_edge(clk_i) then
locAddr_o <= std_logic_vector(resize(unsigned(rel_locAddr) srl 3,c_addr_width));
end if;
end process;
process(clk_i)
begin
if rising_edge(clk_i) then
if sel = "10000000" then
WBdata_o <= std_logic_vector(unsigned(locDataInSwap) sll 56);
elsif sel = "01000000" then
WBdata_o <= std_logic_vector(unsigned(locDataInSwap) sll 48);
elsif sel = "00100000" then
WBdata_o <= std_logic_vector(unsigned(locDataInSwap) sll 40);
elsif sel = "00010000" then
WBdata_o <= std_logic_vector(unsigned(locDataInSwap) sll 32);
elsif sel = "00001000" then
WBdata_o <= std_logic_vector(unsigned(locDataInSwap) sll 24);
elsif sel = "00000100" then
WBdata_o <= std_logic_vector(unsigned(locDataInSwap) sll 16);
elsif sel = "00000010" then
WBdata_o <= std_logic_vector(unsigned(locDataInSwap) sll 8);
elsif sel = "11000000" then
WBdata_o <= std_logic_vector(unsigned(locDataInSwap) sll 48);
elsif sel = "00110000" then
WBdata_o <= std_logic_vector(unsigned(locDataInSwap) sll 32);
elsif sel = "00001100" then
WBdata_o <= std_logic_vector(unsigned(locDataInSwap) sll 16);
elsif sel = "11110000" then
WBdata_o <= std_logic_vector(unsigned(locDataInSwap) sll 32);
else
WBdata_o <= locDataInSwap;
end if;
WbSel_o <= std_logic_vector(sel);
end if;
end process;
process (s_select,s_wbData_i)
begin
case s_select is
when "100000010" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(15 downto 0)) srl 8, locDataOut'length));
when "100000100" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(23 downto 0)) srl 16,locDataOut'length));
when "100001000" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)) srl 24,locDataOut'length));
when "100010000" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(39 downto 0)) srl 32,locDataOut'length));
when "100100000" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(47 downto 0)) srl 40,locDataOut'length));
when "101000000" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(55 downto 0)) srl 48,locDataOut'length));
when "110000000" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i) srl 56,locDataOut'length));
when "100001100" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)) srl 16,locDataOut'length));
when "100110000" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(47 downto 0)) srl 32,locDataOut'length));
when "111000000" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i) srl 48,locDataOut'length));
when "100000001" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(7 downto 0)), locDataOut'length));
when "100000011" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(15 downto 0)), locDataOut'length));
when "100001111" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)), locDataOut'length));
when "111110000" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i) srl 32, locDataOut'length));
when "111111111" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i),locDataOut'length));
when others => locDataOut <= (others => '0');
end case;
end process;
end generate gen64;
-- shift data and address for WB data bus 32 bits
gen32: if (g_width = 32) generate
process(clk_i)
begin
if rising_edge(clk_i) then
locAddr_o <= std_logic_vector(resize(unsigned(rel_locAddr) srl 2,c_addr_width));
end if;
end process;
process(sel)
begin
if sel = "10000000" or sel = "01000000" or sel = "00100000" or sel = "00010000"
or sel = "11000000" or sel = "00110000" or sel = "11110000" then
s_shift_dx <= '1';
else
s_shift_dx <= '0';
end if;
end process;
process(clk_i)
begin
if rising_edge(clk_i) then
if sel = "10000000" then
WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap) sll 24,c_width));
elsif sel = "01000000" then
WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap) sll 16,c_width));
elsif sel = "00100000" then
WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap) sll 8,c_width));
elsif sel = "00001000" then
WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap) sll 24,c_width));
elsif sel = "00000100" then
WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap) sll 16,c_width));
elsif sel = "00000010" then
WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap) sll 8,c_width));
elsif sel = "11000000" then
WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap) sll 16,c_width));
elsif sel = "00001100" then
WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap) sll 16,c_width));
else
WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap),c_width));
end if;
if s_shift_dx = '1' then
WbSel_o <= sel(7 downto 4); -- b"0000" &
else
WbSel_o <= sel(3 downto 0);
end if;
end if;
end process;
process (s_select,s_wbData_i)
begin
case s_select is
when "100000010" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(15 downto 0)) srl 8, locDataOut'length));
when "100000100" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(23 downto 0)) srl 16,locDataOut'length));
when "100001000" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)) srl 24,locDataOut'length));
when "100010000" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(7 downto 0)),locDataOut'length));
when "100100000" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(15 downto 0)) srl 8,locDataOut'length));
when "101000000" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(23 downto 0)) srl 16,locDataOut'length));
when "110000000" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)) srl 24,locDataOut'length));
when "100001100" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)) srl 16,locDataOut'length));
when "100110000" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(15 downto 0)),locDataOut'length));
when "111000000" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)) srl 16,locDataOut'length));
when "100000001" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(7 downto 0)), locDataOut'length));
when "100000011" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(15 downto 0)), locDataOut'length));
when "100001111" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)), locDataOut'length));
when "111110000" => locDataOut <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)), locDataOut'length));
when others => locDataOut <= (others => '0');
end case;
end process;
end generate gen32;
err <= err_i;
rty <= rty_i;
memAckWb <= memAckWB_i;
psize_o <= s_beatCount;
memAckWb <= memAckWB_i or s_AckWithError;
psize_o <= beatCount;
end Behavioral;
--===========================================================================
-- Architecture end
--===========================================================================
......@@ -28,20 +28,19 @@
-- |____________________________________| |
-- |
-- 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 |
-- 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. |
-- single read/write protocol. |
-- 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)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 06/2012
-- Date 08/2012
-- Version v0.02
--______________________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
......@@ -62,8 +61,14 @@ use IEEE.numeric_std.all;
use IEEE.numeric_std.unsigned;
use work.vme64x_pack.all;
--===========================================================================
-- Entity declaration
--===========================================================================
entity VME_bus is
generic(g_width : integer := c_width;
g_addr_width : integer := c_addr_width;
g_CRAM_SIZE : integer := c_CRAM_SIZE
);
port(
clk_i : in std_logic;
reset_o : out std_logic; -- to the Interrupt Generator
......@@ -76,7 +81,6 @@ entity VME_bus is
VME_RETRY_OE_o : out std_logic;
VME_WRITE_n_i : in std_logic;
VME_DS_n_i : in std_logic_vector(1 downto 0);
VME_GA_i : in std_logic_vector(5 downto 0); --Geograp. Address
VME_DTACK_n_o : out std_logic;
VME_DTACK_OE_o : out std_logic;
VME_BERR_o : out std_logic;
......@@ -95,10 +99,10 @@ entity VME_bus is
-- WB signals
memReq_o : out std_logic;
memAckWB_i : in std_logic;
wbData_o : out std_logic_vector(63 downto 0);
wbData_i : in std_logic_vector(63 downto 0);
locAddr_o : out std_logic_vector(63 downto 0);
wbSel_o : out std_logic_vector(7 downto 0);
wbData_o : out std_logic_vector(g_width - 1 downto 0);
wbData_i : in std_logic_vector(g_width - 1 downto 0);
locAddr_o : out std_logic_vector(g_addr_width - 1 downto 0);
wbSel_o : out std_logic_vector(f_div8(g_width) - 1 downto 0);
RW_o : out std_logic;
cyc_o : out std_logic;
err_i : in std_logic;
......@@ -114,7 +118,7 @@ entity VME_bus is
transfer_done_o : out std_logic;
--CR/CSR space signals:
CRAMaddr_o : out std_logic_vector(18 downto 0);
CRAMaddr_o : out std_logic_vector(f_log2_size(g_CRAM_SIZE)-1 downto 0);
CRAMdata_o : out std_logic_vector(7 downto 0);
CRAMdata_i : in std_logic_vector(7 downto 0);
CRAMwea_o : out std_logic;
......@@ -141,11 +145,13 @@ entity VME_bus is
BAR_i : in std_logic_vector(4 downto 0);
numBytes : out std_logic_vector(12 downto 0);
transfTime : out std_logic_vector(39 downto 0);
-- Debug Davide
-- Debug
leds : out std_logic_vector(7 downto 0)
);
end VME_bus;
--===========================================================================
-- Architecture declaration
--===========================================================================
architecture RTL of VME_bus is
signal s_reset : std_logic;
......@@ -179,6 +185,7 @@ architecture RTL of VME_bus is
signal s_locDataSwap : std_logic_vector(63 downto 0);
signal s_locDataInSwap : std_logic_vector(63 downto 0);
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_LWORDlatched : std_logic; -- Stores LWORD on falling edge of AS
......@@ -186,27 +193,25 @@ architecture RTL of VME_bus is
signal s_AMlatched : std_logic_vector(5 downto 0); --Latch on AS f. edge
signal s_XAM : unsigned(7 downto 0); -- Stores received XAM
signal s_RSTedge : std_logic;
-- Type of data transfer (depending on VME_DS_n, VME_LWORD_n and VME_ADDR(1))
signal s_typeOfDataTransfer : t_typeOfDataTransfer;
signal s_typeOfDataTransferSelect : std_logic_vector(4 downto 0);
-- Addressing type (depending on VME_AM)
-- Addressing type (depending on VME_AM_i)
signal s_addressingType : t_addressingType;
signal s_addressingTypeSelect : std_logic_vector(5 downto 0);
signal s_transferType : t_transferType;
signal s_XAMtype : t_XAMtype;
signal s_2eType : t_2eType;
signal s_addrWidth : std_logic_vector(1 downto 0);
-- Main FSM signals
signal s_mainFSMstate : t_mainFSMstates;
signal s_FSM : t_FSM;
signal s_dataToAddrBus : std_logic; -- (for D64) --> multiplexed transfer
signal s_dataToOutput : std_logic; -- Puts data to VME data bus
signal s_mainDTACK : std_logic; -- DTACK driving
signal s_memAck : std_logic; -- Memory acknowledge
signal s_memAckCSR : std_logic; -- CR/CSR acknowledge
signal s_memReq : std_logic; -- Global memory request
......@@ -254,10 +259,12 @@ architecture RTL of VME_bus is
signal s_END_USER_CR : std_logic_vector(23 downto 0);
signal s_BEG_CRAM : std_logic_vector(23 downto 0);
signal s_END_CRAM : std_logic_vector(23 downto 0);
-- Error signals
signal s_BERRcondition : std_logic; -- Condition for asserting BERR
signal s_wberr1 : std_logic;
signal s_rty1 : std_logic;
-- Initialization signals
signal s_initInProgress : std_logic; --The initialization is in progress
signal s_initReadCounter : unsigned(8 downto 0); -- Counts read operations
......@@ -272,9 +279,9 @@ architecture RTL of VME_bus is
--flag FIFO: if '1' the FIFO is used
signal s_FIFO : std_logic;
signal s_transfer_done_i : std_logic;
--
signal s_counter : unsigned(25 downto 0);
signal s_countcyc : unsigned(9 downto 0);
signal s_BERR_out : std_logic;
......@@ -285,10 +292,10 @@ architecture RTL of VME_bus is
signal s_led3 : std_logic;
signal s_led4 : std_logic;
signal s_led5 : std_logic;
signal s_AckWithError : std_logic;
signal s_sw_reset : std_logic;
signal s_decode : std_logic;
signal s_AckWb : std_logic;
signal s_CRCSRtype : std_logic;
signal s_err : std_logic;
signal s_rty : std_logic;
-- transfer rate signals:
......@@ -298,6 +305,9 @@ architecture RTL of VME_bus is
signal s_bytes : std_logic_vector(12 downto 0);
signal s_datawidth : unsigned(3 downto 0);
--
--===========================================================================
-- Architecture begin
--===========================================================================
begin
--
......@@ -394,7 +404,7 @@ begin
end process;
-- Address modifier decoder
-- Either the supervisor or user access mode are supported
-- Either the supervisor or user access modes are supported
s_addressingTypeSelect <= s_AMlatched;
with s_addressingTypeSelect select
......@@ -418,33 +428,83 @@ begin
A64_MBLT when c_A64_MBLT,
TWOedge when c_TWOedge,
AM_Error when others;
-- Transfer type decoder
s_transferType <= SINGLE when s_addressingType = A24 or s_addressingType = CR_CSR or
s_addressingType = A16 or s_addressingType = A32 or
s_addressingType = A64 else
BLT when s_addressingType = A24_BLT or s_addressingType = A32_BLT or
s_addressingType = A64_BLT else
MBLT when s_addressingType = A24_MBLT or s_addressingType = A32_MBLT or
s_addressingType = A64_MBLT else
TWOe when s_addressingType = TWOedge else
error;
s_datawidth <= "0001" when s_typeOfDataTransfer = D08_0 or s_typeOfDataTransfer = D08_1 or
s_typeOfDataTransfer = D08_2 or s_typeOfDataTransfer = D08_3 else
"0010" when s_typeOfDataTransfer = D16_01 or s_typeOfDataTransfer = D16_23 else
"0100" when s_typeOfDataTransfer = D32 or (s_typeOfDataTransfer = D64 and
(s_transferType = SINGLE or s_transferType = BLT)) else
"1000" when s_typeOfDataTransfer = D64 else
"1000";
s_addrWidth <= "00" when s_addressingType = A16 else
"01" when s_addressingType = A24 or s_addressingType = A24_BLT or
s_addressingType = A24_MBLT or s_addressingType = CR_CSR else
"10" when s_addressingType = A32 or s_addressingType = A32_BLT or
s_addressingType = A32_MBLT or (s_addressingType = TWOedge and
(s_XAMtype = A32_2eVME or s_XAMtype = A32_2eSST)) else
"11"; -- for A64, A64 BLT, A64 MBLT, A64_2eVME, A64_2eSST
-- Transfer type decoder
with s_addressingType select
s_transferType <= SINGLE when A24,
SINGLE when CR_CSR,
SINGLE when A16,
SINGLE when A32,
SINGLE when A64,
BLT when A24_BLT,
BLT when A32_BLT,
BLT when A64_BLT,
MBLT when A24_MBLT,
MBLT when A32_MBLT,
MBLT when A64_MBLT,
TWOe when TWOedge,
error when others;
process(clk_i)
begin
if rising_edge(clk_i) then
if s_typeOfDataTransfer = D08_0 or s_typeOfDataTransfer = D08_1 or
s_typeOfDataTransfer = D08_2 or s_typeOfDataTransfer = D08_3 then
s_datawidth <= "0001";
elsif s_typeOfDataTransfer = D16_01 or s_typeOfDataTransfer = D16_23 then
s_datawidth <= "0010";
elsif s_typeOfDataTransfer = D32 or (s_typeOfDataTransfer = D64 and
(s_transferType = SINGLE or s_transferType = BLT)) then
s_datawidth <= "0100";
else
s_datawidth <= "1000";
end if;
end if;
end process;
-- s_datawidth <= "0001" when s_typeOfDataTransfer = D08_0 or
-- s_typeOfDataTransfer = D08_1 or
-- s_typeOfDataTransfer = D08_2 or
-- s_typeOfDataTransfer = D08_3 else
-- "0010" when s_typeOfDataTransfer = D16_01 or
-- s_typeOfDataTransfer = D16_23 else
-- "0100" when s_typeOfDataTransfer = D32 or
-- (s_typeOfDataTransfer = D64 and
-- (s_transferType = SINGLE or s_transferType = BLT)) else
-- "1000" when s_typeOfDataTransfer = D64 else
-- "1000";
process(clk_i)
begin
if rising_edge(clk_i) then
if s_addressingType = A16 then
s_addrWidth <= "00";
elsif s_addressingType = A24 or s_addressingType = A24_BLT or
s_addressingType = A24_MBLT or s_addressingType = CR_CSR then
s_addrWidth <= "01";
elsif s_addressingType = A32 or s_addressingType = A32_BLT or
s_addressingType = A32_MBLT or (s_addressingType = TWOedge and
(s_XAMtype = A32_2eVME or s_XAMtype = A32_2eSST)) then
s_addrWidth <= "10";
else
s_addrWidth <= "11"; -- for A64, A64 BLT, A64 MBLT, A64_2eVME, A64_2eSST
end if;
end if;
end process;
-- s_addrWidth <= "00" when s_addressingType = A16 else
-- "01" when s_addressingType = A24 or
-- s_addressingType = A24_BLT or
-- s_addressingType = A24_MBLT or
-- s_addressingType = CR_CSR else
-- "10" when s_addressingType = A32 or
-- s_addressingType = A32_BLT or
-- s_addressingType = A32_MBLT or
-- (s_addressingType = TWOedge and
-- (s_XAMtype = A32_2eVME or s_XAMtype = A32_2eSST)) else
-- "11"; -- for A64, A64 BLT, A64 MBLT, A64_2eVME, A64_2eSST
-- uncomment for using 2e modes:
--with s_XAM select
-- s_XAMtype <= A32_2eVME when x"01",
......@@ -494,11 +554,11 @@ begin
-- If the S_FPGA will be provided to a core who drives these lines without
-- erase the A_FPGA the above mentioned lines should be changed to 'Z' !!!
-- During the Interrupt ack cycle the Slave can't be accessed
-- so if VME_IACK is asserted the FSM is blocked in IDLE state.
-- The VME_IACK signal is asserted by the Interrupt handler
-- so if VME_IACK_n_i is asserted the FSM is in IDLE state.
-- 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 fall. edge go in DECODE_ACCESS
s_mainFSMstate <= DECODE_ACCESS; -- if AS falling edge --> go in DECODE_ACCESS
else
s_mainFSMstate <= IDLE;
end if;
......@@ -511,7 +571,9 @@ begin
-- 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
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;
......@@ -521,7 +583,6 @@ begin
when WAIT_FOR_DS => -- wait until DS /= "11"
s_FSM <= c_FSM_default;
s_FSM.s_dtackOE <= '1';
s_FSM.s_dataDir <= VME_WRITE_n_i;
s_FSM.s_addrDir <= (s_is_d64) and VME_WRITE_n_i;
s_FSM.s_DSlatch <= '1';
s_FSM.s_dataPhase <= s_dataPhase;
......@@ -923,7 +984,19 @@ begin
end process;
------------------------- 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):
-- Master supports retry capability, it terminates the bus cycle when it
-- detects RETRY* low without waiting for either DTACK* or BERR*.
-- In the case of a busy condition, if the Master does not support Retry
-- and does not terminate the cycle the slave waits and asserts DTACK* low
-- once the busy resource becomes available, if the Bus Timer does not
-- detect a time out condition before.
-- 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)
begin
if rising_edge(clk_i) then
......@@ -938,9 +1011,10 @@ begin
end process;
-- BERR driver
-- The slave assert the Error line if during the Decode access phase an error
-- 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 line 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.
......@@ -948,8 +1022,9 @@ begin
p_BERRdriver: process(clk_i)
begin
if rising_edge(clk_i) then
s_berr_1 <= s_berr;
s_berr_2 <= s_berr and s_berr_1;
-- uncomment if 2e is implemented:
-- s_berr_1 <= s_berr;
-- s_berr_2 <= s_berr and s_berr_1;
if (s_BERR_out = '1') then
VME_BERR_o <= '1'; -- The VME_BERR is asserted when '1' becouse
-- the buffers on the board invert the logic
......@@ -959,7 +1034,7 @@ begin
end if;
end process;
-- When the VME_BERR line is asserted this process assert the error flag; This flag
-- 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)
......@@ -973,8 +1048,12 @@ begin
end if;
end process;
-- This process detect an error condition and assert the s_BERRcondition signal
-- If the VME master try to access with a not supported mode the slave answer with an error.
-- 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
......@@ -1008,7 +1087,7 @@ begin
s_addrOffset(11) when MBLT,
'0' when others;
-- handler of wb err pulse
-- wb err handler
process(clk_i)
begin
if rising_edge(clk_i) then
......@@ -1020,7 +1099,7 @@ begin
end if;
end process;
-- handler of wb retry pulse
-- wb retry handler
process(clk_i)
begin
if rising_edge(clk_i) then
......@@ -1033,7 +1112,7 @@ begin
end process;
---------------------------------------------------------------------|
--These two mux are inserted to provide the vme64x core of the MBLT access mode
--These two mux are inserted to provide the MBLT access mode
p_ADDRmux : process(clk_i)
begin
if rising_edge(clk_i) then
......@@ -1111,24 +1190,25 @@ begin
-- end if;
-- end process;
-- s_XAM <= s_phase1addr(7 downto 0);
-- Local address mapping
s_locAddrBeforeOffset(63 downto 1) <= x"000000000000" & s_VMEaddrLatched(15 downto 1)
when s_addrWidth = "00" else
x"0000000000" & s_VMEaddrLatched(23 downto 1)
when s_addrWidth = "01" else
x"00000000" & s_VMEaddrLatched(31 downto 1)
when s_addrWidth = "10" else
s_VMEaddrLatched(63 downto 1);
s_locAddrBeforeOffset(0) <= '0' when (s_DSlatched(1) = '0' and s_DSlatched(0) = '1') else
'1' when (s_DSlatched(1) = '1' and s_DSlatched(0) = '0') else
'0';
-- Local address mapping
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",
'1' when "10",
'0' when others;
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 by the VME_WB_master to address the WB memory
-- 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
......@@ -1143,6 +1223,7 @@ begin
end if;
end if;
end process;
-- Local address incrementing
-- This process generates the s_addrOffset
-- The s_addrOffset is /= 0 during BLT, MBLT and 2e access modes, when
......@@ -1186,7 +1267,8 @@ begin
(resize(s_initReadCounter, s_CRaddr'length));
CRaddr_o <= std_logic_vector(s_CRaddr(11 downto 0));
CRAMaddr_o <= std_logic_vector(s_CrCsrOffsetAddr - unsigned(s_BEG_CRAM(18 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
......@@ -1205,6 +1287,7 @@ begin
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
if rising_edge(clk_i) then
......@@ -1228,51 +1311,58 @@ begin
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 became 10325476
--sel= 010 --> Swap Word eg: 01234567 became 23016745
--sel= 011 --> Swap Word+ Swap Byte eg: 01234567 became 32107654
--sel= 100 --> Swap DWord + Swap Word+ Swap Byte eg: 01234567 became 76543210
swapper_write: VME_swapper PORT MAP(
swapper_write: VME_swapper port map(
d_i => std_logic_vector(s_locDataIn),
sel => MBLT_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 => MBLT_Endian_i,
d_o => s_locDataSwap
);
s_locDataOut <= unsigned(s_locDataOutWb) when s_cardSel = '1' else
resize(s_CSRdata, s_locDataOut'length) when
s_confAccess = '1' and s_CSRaddressed = '1' and
s_CRAMaddressed = '0' and s_CRaddressed = '0' and
(s_typeOfDataTransfer = D08_3 or s_typeOfDataTransfer = D32 or
s_typeOfDataTransfer = D16_23 or (s_typeOfDataTransfer = D64 and
s_transferType /= MBLT)) else
resize(unsigned(s_CRdataIn), s_locDataOut'length) when
s_confAccess = '1' and s_CRaddressed = '1' and
s_CRAMaddressed = '0' and s_CSRaddressed = '0' and
(s_typeOfDataTransfer = D08_3 or s_typeOfDataTransfer = D32 or
s_typeOfDataTransfer = D16_23 or (s_typeOfDataTransfer = D64 and
s_transferType /= MBLT)) else
resize(unsigned(s_CRAMdataIn), s_locDataOut'length) when
s_confAccess = '1' and s_CRAMaddressed = '1' and
s_CRaddressed = '0' and s_CSRaddressed = '0' and
(s_typeOfDataTransfer = D08_3 or s_typeOfDataTransfer = D32 or
s_typeOfDataTransfer = D16_23 or (s_typeOfDataTransfer = D64 and
s_transferType /= MBLT)) else
(others => '0');
);
-- 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_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_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_locDataOut <= resize(unsigned(s_CRAMdataIn), s_locDataOut'length);
else
s_locDataOut <= (others => '0');
end if;
end if;
end process;
s_locData(63 downto 0) <= s_locDataOut(63 downto 0) sll to_integer(unsigned(s_DataShift));
s_CSRdata <= unsigned(CSRData_i);
-------------------------BEAT COUNT--------------------------------|
-------------------------BEAT COUNT--------------------------------|
-- 2eSST:
-- The Cycle Count informs the slave in advance of the amount of data that
-- it is requested to receive in a write transaction or the amount of data
......@@ -1287,7 +1377,7 @@ begin
-- during 2e access the Master send this information, during
-- BLT and MBLT access the Beat Count is equal to the block transfer limit.
process(s_cycleCount,s_beatCount,s_XAMtype, s_transferType, s_typeOfDataTransfer)
begin -- |
begin --
if ((s_XAMtype = A32_2eVME) or (s_XAMtype = A64_2eVME) or (s_XAMtype = A32_2eSST)
or (s_XAMtype = A64_2eSST)) then
s_beatCount <= (resize(s_cycleCount*2, s_beatCount'length));
......@@ -1382,26 +1472,31 @@ end process;
end if;
end process;
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.
Inst_Wb_master: VME_Wb_master PORT MAP(
Inst_Wb_master: VME_Wb_master
generic map(
g_width => c_width,
g_addr_width => c_addr_width
)
port map(
s_memReq => s_memReq,
clk_i => clk_i,
s_cardSel => s_cardSel,
s_reset => s_reset,
s_mainFSMreset => s_mainFSMreset,
s_BERRcondition => s_BERRcondition,
s_sel => std_logic_vector(s_sel),
s_beatCount => std_logic_vector(s_beatCount),
s_locDataInSwap => s_locDataInSwap,
s_locDataOut => s_locDataOutWb,
s_rel_locAddr => std_logic_vector(s_rel_locAddr),
s_AckWithError => s_AckWithError,
cardSel => s_cardSel,
reset => s_reset,
mainFSMreset => s_mainFSMreset,
BERRcondition => s_BERRcondition,
sel => std_logic_vector(s_sel),
beatCount => std_logic_vector(s_beatCount),
locDataInSwap => s_locDataInSwap,
locDataOut => s_locDataOutWb,
rel_locAddr => std_logic_vector(s_rel_locAddr),
memAckWb => s_AckWb,
err => s_err,
rty => s_rty,
s_RW => s_RW,
RW => s_RW,
psize_o => psize_o,
stall_i => stall_i,
rty_i => rty_i,
......@@ -1416,15 +1511,16 @@ end process;
WbSel_o => wbSel_o,
RW_o => RW_o
);
--------------------------DECODER-------------------------------------|
-- DECODER: This component check if the board is addressed; if the CR/CSR
--space is addressed the Confaccess is asserted
-- If the Wb memory is addressed the CardSel is asserted.
Inst_Access_Decode: VME_Access_Decode PORT MAP(
-- 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,
s_reset => s_reset,
s_mainFSMreset => s_mainFSMreset,
s_decode => s_decode,
reset => s_reset,
mainFSMreset => s_mainFSMreset,
decode => s_decode,
ModuleEnable => ModuleEnable,
InitInProgress => s_initInProgress,
Addr => std_logic_vector(s_locAddr),
......@@ -1462,7 +1558,7 @@ end process;
XAmCap7 => s_FUNC_XAMCAP(7),
Am => s_AMlatched,
XAm => std_logic_vector(s_XAM),
BAR => BAR_i,
BAR_i => BAR_i,
AddrWidth => s_addrWidth,
Funct_Sel => s_func_sel,
Base_Addr => s_nx_base_addr,
......@@ -1472,6 +1568,8 @@ end process;
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
......@@ -1489,11 +1587,13 @@ end process;
unsigned(s_BEG_CRAM) < unsigned(s_END_CRAM)) else '0';
--------------------------ACKNOWLEDGE---------------------------------------|
-- The signal s_memAck is used as condition to pass from the MEMORY_REQ to DATA_TO_BUS
-- or DTACK_LOW state ,so is necessary assert s_memACk also if there is an error.
s_memAck <= s_memAckCSR or s_AckWb or s_AckWithError or s_err;
--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
p_memAckCSR : process(clk_i)
......@@ -1523,9 +1623,10 @@ end process;
err_flag_o <= s_errorflag;
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
if rising_edge(clk_i) then
......@@ -1537,17 +1638,16 @@ end process;
end if;
end process;
-- The following process are used to calculate the duration in ns of the
-- transfer (time between the As falling edge and the AS rising edge) and
-- The following process are used to calculate the transfer time in ns
-- (time between the As falling edge and the AS rising edge), and
-- the number of bytes transferred.
--
process(clk_i)
begin
if rising_edge(clk_i) then
if VME_RST_n_i = '0' or s_mainFSMreset = '1' then
if s_reset = '1' or s_mainFSMreset = '1' then
s_countertime <= (others => '0');
elsif VME_AS_n_i = '0' then
s_countertime <= s_countertime + unsigned(clk_period);
s_countertime <= s_countertime + unsigned(c_CLK_PERIOD);
end if;
end if;
end process;
......@@ -1555,7 +1655,7 @@ end process;
process(clk_i)
begin
if rising_edge(clk_i) then
if s_mainFSMreset = '1' and s_cardSel = '1' then
if (s_mainFSMreset = '1' and s_cardSel = '1') or s_reset = '1' then
s_time <= std_logic_vector(s_countertime);
end if;
end if;
......@@ -1564,7 +1664,7 @@ end process;
process(clk_i)
begin
if rising_edge(clk_i) then
if VME_RST_n_i = '0' or s_mainFSMreset = '1' then
if s_reset = '1' or s_mainFSMreset = '1' then
s_counterbytes <= (others => '0');
elsif s_memReq = '1' and s_cardSel = '1' then
s_counterbytes <= s_counterbytes + s_datawidth;
......@@ -1575,19 +1675,20 @@ end process;
process(clk_i)
begin
if rising_edge(clk_i) then
if s_mainFSMreset = '1' and s_cardSel = '1' then
s_bytes <= std_logic_vector(unsigned(s_counterbytes));
if (s_mainFSMreset = '1' and s_cardSel = '1') or s_reset = '1' then
s_bytes <= std_logic_vector(s_counterbytes);
end if;
end if;
end process;
numBytes <= s_bytes;
transfTime <= s_time;
---------------------------INITIALIZATION-------------------------------------|
-- Initialization procedure
-- 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,
RSTedge => s_RSTedge,
CRAddr => std_logic_vector(s_CRaddr),
......@@ -1626,10 +1727,7 @@ end process;
FUNC7_XAMCAP_o => s_FUNC_XAMCAP(7)
);
---------------------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.
------------------EDGE DETECTION and SAMPLING-----------------------------------------
ASfallingEdge : FallingEdgeDetection
port map (
......@@ -1669,7 +1767,7 @@ end process;
clk_i => clk_i
);
CRAMinputSample : DoubleRegInputSample
CRAMinputSample : SingleRegInputSample
generic map(
width => 8
)
......@@ -1679,8 +1777,6 @@ end process;
clk_i => clk_i
);
---------------------------Output for FIFO.vhd-------------------------------------|
VMEtoWB <= '1' when (s_cardSel = '1' and (s_transferType = BLT or s_transferType = MBLT) and
......@@ -1688,8 +1784,31 @@ end process;
WBtoVME <= '1' when (s_cardSel = '1' and (s_transferType = BLT or s_transferType = MBLT) and
VME_WRITE_n_i = '1' and VME_DS_n_i /= "11") else '0';
transfer_done_o <= s_mainFSMreset;
--------------------------Input from FIFO-----------------------------------------
s_transfer_done_i <= transfer_done_i when s_FIFO = '1' else '1';
------------------------------LEDS------------------------------------------------|
leds(6) <= not s_transferActive;
-- Debug
process(clk_i)
begin
if rising_edge(clk_i) then
if s_reset = '1' then
s_led1 <= '1'; -- off
s_led2 <= '1';
s_led3 <= '1';
s_led4 <= '1';
s_led5 <= '1';
else
s_led1 <= s_DSlatched(1);
s_led2 <= s_DSlatched(0);
s_led3 <= s_VMEaddrLatched(1);
s_led4 <= s_LWORDlatched;
s_led5 <= s_VMEaddrLatched(2);
end if;
end if;
end process;
leds(6) <= not s_transferActive;
leds(2) <= s_led2;
leds(7) <= s_counter(25);
leds(5) <= s_led5;
......@@ -1711,28 +1830,8 @@ end process;
end if;
end if;
end process;
--------------------------------------------------------------------------------------
s_transfer_done_i <= transfer_done_i when s_FIFO = '1' else '1';
process(clk_i)
begin
if rising_edge(clk_i) then
if s_reset = '1' then
s_led1 <= '1'; -- off
s_led2 <= '1';
s_led3 <= '1';
s_led4 <= '1';
s_led5 <= '1';
else
s_led1 <= s_DSlatched(1);
s_led2 <= s_DSlatched(0);
s_led3 <= s_VMEaddrLatched(1);
s_led4 <= s_LWORDlatched;
s_led5 <= s_VMEaddrLatched(2);
end if;
end if;
end process;
end RTL;
end RTL;
--===========================================================================
-- Architecture end
--===========================================================================
\ No newline at end of file
......@@ -13,8 +13,8 @@
--______________________________________________________________________________
-- Authors:
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 06/2012
-- Version v0.01
-- Date 08/2012
-- Version v0.02
--______________________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
......@@ -30,13 +30,17 @@
---------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--===========================================================================
-- Entity declaration
--===========================================================================
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));
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);
......@@ -54,7 +58,11 @@ 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)
begin
case sel is
......@@ -168,6 +176,7 @@ 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
--===========================================================================
......@@ -9,7 +9,7 @@
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 06/2012
-- Version v0.01
-- Version v0.02
--_______________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
......@@ -60,9 +60,18 @@ package vme64x_pack is
--_______________________________________________________________________________
-- Constants:
--WB data width:
constant c_width : integer := 32; --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
-- WB addr width:
constant c_addr_width : integer := 64;
--
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
constant clk_period : std_logic_vector(19 downto 0) := "00000000000000001101";
-- Tclk in ns used to calculate the data transfer rate
constant c_CLK_PERIOD : std_logic_vector(19 downto 0) := "00000000000000001010";
--AM table:
constant c_A24_S_sup : std_logic_vector(5 downto 0) := "111101";
constant c_A24_S : std_logic_vector(5 downto 0) := "111001";
......@@ -347,23 +356,30 @@ package vme64x_pack is
type t_CSRarray is array(BAR downto WB32or64) 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;
--_____________________________________________________________________________________________________
--COMPONENTS:
COMPONENT VME_bus
PORT(
component VME_bus is
generic(
g_width : integer := c_width;
g_addr_width : integer := c_addr_width;
g_CRAM_SIZE : integer := c_CRAM_SIZE
);
port(
clk_i : in std_logic;
VME_RST_n_i : in std_logic;
VME_AS_n_i : in std_logic;
VME_LWORD_n_b_i : in std_logic;
VME_WRITE_n_i : in std_logic;
VME_DS_n_i : in std_logic_vector(1 downto 0);
VME_GA_i : in std_logic_vector(5 downto 0);
VME_ADDR_b_i : in std_logic_vector(31 downto 1);
VME_DATA_b_i : in std_logic_vector(31 downto 0);
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(63 downto 0);
wbData_i : in std_logic_vector(g_width - 1 downto 0);
err_i : in std_logic;
rty_i : in std_logic;
stall_i : in std_logic;
......@@ -399,16 +415,16 @@ 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(63 downto 0);
locAddr_o : out std_logic_vector(63 downto 0);
wbSel_o : out std_logic_vector(7 downto 0);
wbData_o : out std_logic_vector(g_width - 1 downto 0);
locAddr_o : out std_logic_vector(g_addr_width - 1 downto 0);
wbSel_o : out std_logic_vector(f_div8(g_width) - 1 downto 0);
RW_o : out std_logic;
cyc_o : out std_logic;
psize_o : out std_logic_vector(8 downto 0);
VMEtoWB : out std_logic;
WBtoVME : out std_logic;
FifoMux : out std_logic;
CRAMaddr_o : out std_logic_vector(18 downto 0);
CRAMaddr_o : out std_logic_vector(f_log2_size(g_CRAM_SIZE)-1 downto 0);
CRAMdata_o : out std_logic_vector(7 downto 0);
CRAMwea_o : out std_logic;
CRaddr_o : out std_logic_vector(11 downto 0);
......@@ -421,15 +437,15 @@ package vme64x_pack is
leds : out std_logic_vector(7 downto 0);
transfer_done_o : out std_logic
);
END COMPONENT;
end component VME_bus;
COMPONENT VME_Access_Decode
PORT (
component VME_Access_Decode is
port (
clk_i : in std_logic;
s_reset : in std_logic;
s_mainFSMreset : in std_logic;
s_decode : 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);
......@@ -467,21 +483,21 @@ package vme64x_pack is
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 : in std_logic_vector(4 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 COMPONENT;
end component VME_Access_Decode;
COMPONENT VME_Funct_Match
PORT(
component VME_Funct_Match is
port(
clk_i : in std_logic;
s_reset : in std_logic;
s_decode : in std_logic;
s_mainFSMreset : in std_logic;
reset : in std_logic;
decode : in std_logic;
mainFSMreset : in std_logic;
Addr : in std_logic_vector(63 downto 0);
AddrWidth : in std_logic_vector(1 downto 0);
Ader0 : in std_logic_vector(31 downto 0);
......@@ -504,24 +520,27 @@ package vme64x_pack is
DFS_o : out std_logic_vector(7 downto 0);
Nx_Base_Addr : out std_logic_vector(63 downto 0)
);
END COMPONENT;
end component VME_Funct_Match;
COMPONENT VME_CR_CSR_Space
PORT(
component VME_CR_CSR_Space is
generic(
g_CRAM_SIZE : integer := c_CRAM_SIZE
);
port(
clk_i : in std_logic;
s_reset : in std_logic;
reset : in std_logic;
CR_addr : in std_logic_vector(11 downto 0);
CRAM_addr : in std_logic_vector(18 downto 0);
CRAM_addr : in std_logic_vector(f_log2_size(g_CRAM_SIZE)-1 downto 0);
CRAM_data_i : in std_logic_vector(7 downto 0);
CRAM_Wen : in std_logic;
en_wr_CSR : in std_logic;
CrCsrOffsetAddr : in std_logic_vector(18 downto 0);
VME_GA_oversampled : in std_logic_vector(5 downto 0);
locDataIn : in std_logic_vector(7 downto 0);
s_err_flag : in std_logic;
err_flag : in std_logic;
CR_data : out std_logic_vector(7 downto 0);
CRAM_data_o : out std_logic_vector(7 downto 0);
s_reset_flag : out std_logic;
reset_flag : out std_logic;
CSRdata : out std_logic_vector(7 downto 0);
Ader0 : out std_logic_vector(31 downto 0);
Ader1 : out std_logic_vector(31 downto 0);
......@@ -541,13 +560,13 @@ package vme64x_pack is
INT_Level : out std_logic_vector(7 downto 0);
INT_Vector : out std_logic_vector(7 downto 0)
);
END COMPONENT;
end component VME_CR_CSR_Space;
COMPONENT VME_Am_Match
PORT(
component VME_Am_Match is
port(
clk_i : in std_logic;
s_reset : in std_logic;
s_mainFSMreset : 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);
......@@ -575,31 +594,34 @@ package vme64x_pack is
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);
s_decode : in std_logic;
decode : in std_logic;
AmMatch : out std_logic_vector(7 downto 0)
);
END COMPONENT;
end component VME_Am_Match;
COMPONENT VME_Wb_master
PORT(
component VME_Wb_master is
generic(
g_width : integer := c_width;
g_addr_width : integer := c_addr_width
);
port(
s_memReq : in std_logic;
clk_i : in std_logic;
s_cardSel : in std_logic;
s_reset : in std_logic;
s_mainFSMreset : in std_logic;
s_BERRcondition : in std_logic;
s_sel : in std_logic_vector(7 downto 0);
s_beatCount : in std_logic_vector(8 downto 0);
s_locDataInSwap : in std_logic_vector(63 downto 0);
s_rel_locAddr : in std_logic_vector(63 downto 0);
s_RW : in std_logic;
cardSel : in std_logic;
reset : in std_logic;
mainFSMreset : in std_logic;
BERRcondition : in std_logic;
sel : in std_logic_vector(7 downto 0);
beatCount : in std_logic_vector(8 downto 0);
locDataInSwap : in std_logic_vector(63 downto 0);
rel_locAddr : in std_logic_vector(63 downto 0);
RW : in std_logic;
stall_i : in std_logic;
rty_i : in std_logic;
err_i : in std_logic;
wbData_i : in std_logic_vector(63 downto 0);
wbData_i : in std_logic_vector(g_width - 1 downto 0);
memAckWB_i : in std_logic;
s_locDataOut : out std_logic_vector(63 downto 0);
s_AckWithError : out std_logic;
locDataOut : out std_logic_vector(63 downto 0);
memAckWb : out std_logic;
err : out std_logic;
W32 : in std_logic;
......@@ -607,15 +629,15 @@ package vme64x_pack is
psize_o : out std_logic_vector(8 downto 0);
cyc_o : out std_logic;
memReq_o : out std_logic;
WBdata_o : out std_logic_vector(63 downto 0);
locAddr_o : out std_logic_vector(63 downto 0);
WbSel_o : out std_logic_vector(7 downto 0);
WBdata_o : out std_logic_vector(g_width - 1 downto 0);
locAddr_o : out std_logic_vector(g_addr_width - 1 downto 0);
WbSel_o : out std_logic_vector(f_div8(g_width) - 1 downto 0);
RW_o : out std_logic
);
END COMPONENT;
end component VME_Wb_master;
COMPONENT VME_Init
PORT(
component VME_Init is
port(
clk_i : in std_logic;
CRAddr : in std_logic_vector(18 downto 0);
CRdata_i : in std_logic_vector(7 downto 0);
......@@ -653,51 +675,58 @@ package vme64x_pack is
FUNC6_XAMCAP_o : out std_logic_vector(255 downto 0);
FUNC7_XAMCAP_o : out std_logic_vector(255 downto 0)
);
END COMPONENT;
end component VME_Init;
COMPONENT VME_swapper
PORT(
component 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)
);
END COMPONENT;
end component VME_swapper;
component Reg32bit is
port (
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;
sig_o : out std_logic := '0'
);
end component;
end component FlipFlopD;
component EdgeDetection is
port (
sig_i,clk_i : in std_logic;
sigEdge_o : out std_logic := '0'
);
end component;
end component EdgeDetection;
component FallingEdgeDetection is
port (
sig_i, clk_i : in std_logic;
FallEdge_o : out std_logic);
end component;
end component FallingEdgeDetection;
component RisEdgeDetection is
port (
sig_i, clk_i : in std_logic;
RisEdge_o : out std_logic);
end component;
end component RisEdgeDetection;
component DoubleSigInputSample is
port (
sig_i, clk_i : in std_logic;
sig_o : out std_logic);
end component;
end component DoubleSigInputSample;
component SigInputSample is
port (
sig_i, clk_i : in std_logic;
sig_o : out std_logic);
end component;
end component SigInputSample;
component DoubleRegInputSample is
generic(
......@@ -708,7 +737,7 @@ package vme64x_pack is
reg_o : out std_logic_vector(width-1 downto 0) := (others => '0');
clk_i : in std_logic
);
end component;
end component DoubleRegInputSample;
component RegInputSample is
generic(
......@@ -719,10 +748,22 @@ package vme64x_pack is
reg_o : out std_logic_vector(width-1 downto 0) := (others => '0');
clk_i : in std_logic
);
end component;
end component RegInputSample;
component SingleRegInputSample is
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) := (others => '0');
clk_i : in std_logic
);
end component SingleRegInputSample;
COMPONENT VME_IRQ_Controller
PORT(
component VME_IRQ_Controller is
port(
clk_i : in std_logic;
reset : in std_logic;
VME_IACKIN_n_i : in std_logic;
......@@ -741,26 +782,41 @@ package vme64x_pack is
VME_DATA_o : out std_logic_vector(31 downto 0);
VME_DATA_DIR_o : out std_logic
);
END COMPONENT;
end component VME_IRQ_Controller;
COMPONENT dpblockram
generic (dl : integer := 8; -- Length of the data word
al : integer := 19; -- Size of the addr map (10 = 1024 words)
nw : integer := 2**19); -- Number of words
PORT(
component VME_CRAM is
generic (dl : integer := 8;
al : integer := f_log2_size(c_CRAM_SIZE)
);
port(
clk : in std_logic;
we : in std_logic;
aw : in std_logic_vector(al - 1 downto 0);
ar : 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);
do : out std_logic_vector(dl - 1 downto 0)
dw : out std_logic_vector(dl - 1 downto 0)
);
END COMPONENT;
end component VME_CRAM;
end vme64x_pack;
package body vme64x_pack is
function f_div8 (width : integer) return integer is
begin
for I in 1 to 8 loop
if (8*I >= width) then
return(I);
end if;
end loop;
end function f_div8;
function f_log2_size (A : natural) return natural is
begin
for I in 1 to 64 loop -- Works for up to 64 bits
if (2**I >= A) then
return(I);
end if;
end loop;
return(63);
end function f_log2_size;
end vme64x_pack;
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