Commit 8dd5a97e authored by Evangelia Gousiou's avatar Evangelia Gousiou

all tests updated to latest vme core;

added internal reset that would be activated for few cycles after the reprogramming of the fpga
parent b55976a8
K 25
svn:wc:ra_dav:version-url
V 51
/vme64x-core/!svn/ver/190/trunk/hdl/vme64x-core/rtl
END
VME_bus.vhd
K 25
svn:wc:ra_dav:version-url
V 63
/vme64x-core/!svn/ver/189/trunk/hdl/vme64x-core/rtl/VME_bus.vhd
END
VME_Funct_Match.vhd
K 25
svn:wc:ra_dav:version-url
V 71
/vme64x-core/!svn/ver/189/trunk/hdl/vme64x-core/rtl/VME_Funct_Match.vhd
END
VME_IRQ_Controller.vhd
K 25
svn:wc:ra_dav:version-url
V 74
/vme64x-core/!svn/ver/189/trunk/hdl/vme64x-core/rtl/VME_IRQ_Controller.vhd
END
VME_CR_pack.vhd
K 25
svn:wc:ra_dav:version-url
V 67
/vme64x-core/!svn/ver/189/trunk/hdl/vme64x-core/rtl/VME_CR_pack.vhd
END
VME_Init.vhd
K 25
svn:wc:ra_dav:version-url
V 64
/vme64x-core/!svn/ver/189/trunk/hdl/vme64x-core/rtl/VME_Init.vhd
END
VME_Access_Decode.vhd
K 25
svn:wc:ra_dav:version-url
V 73
/vme64x-core/!svn/ver/189/trunk/hdl/vme64x-core/rtl/VME_Access_Decode.vhd
END
Manifest.py
K 25
svn:wc:ra_dav:version-url
V 63
/vme64x-core/!svn/ver/190/trunk/hdl/vme64x-core/rtl/Manifest.py
END
VME_SharedComps.vhd
K 25
svn:wc:ra_dav:version-url
V 71
/vme64x-core/!svn/ver/189/trunk/hdl/vme64x-core/rtl/VME_SharedComps.vhd
END
VME_Am_Match.vhd
K 25
svn:wc:ra_dav:version-url
V 68
/vme64x-core/!svn/ver/189/trunk/hdl/vme64x-core/rtl/VME_Am_Match.vhd
END
VME64xCore_Top.vhd
K 25
svn:wc:ra_dav:version-url
V 70
/vme64x-core/!svn/ver/189/trunk/hdl/vme64x-core/rtl/VME64xCore_Top.vhd
END
vme64x_pack.vhd
K 25
svn:wc:ra_dav:version-url
V 67
/vme64x-core/!svn/ver/189/trunk/hdl/vme64x-core/rtl/vme64x_pack.vhd
END
VME_swapper.vhd
K 25
svn:wc:ra_dav:version-url
V 67
/vme64x-core/!svn/ver/189/trunk/hdl/vme64x-core/rtl/VME_swapper.vhd
END
VME_CRAM.vhd
K 25
svn:wc:ra_dav:version-url
V 64
/vme64x-core/!svn/ver/189/trunk/hdl/vme64x-core/rtl/VME_CRAM.vhd
END
VME_Wb_master.vhd
K 25
svn:wc:ra_dav:version-url
V 69
/vme64x-core/!svn/ver/189/trunk/hdl/vme64x-core/rtl/VME_Wb_master.vhd
END
VME_CSR_pack.vhd
K 25
svn:wc:ra_dav:version-url
V 68
/vme64x-core/!svn/ver/164/trunk/hdl/vme64x-core/rtl/VME_CSR_pack.vhd
END
VME_CR_CSR_Space.vhd
K 25
svn:wc:ra_dav:version-url
V 72
/vme64x-core/!svn/ver/189/trunk/hdl/vme64x-core/rtl/VME_CR_CSR_Space.vhd
END
10
dir
193
http://svn.ohwr.org/vme64x-core/trunk/hdl/vme64x-core/rtl
http://svn.ohwr.org/vme64x-core
2012-11-21T17:45:28.032241Z
190
dpedrett
665b4545-5c6b-4c24-801b-41150b02b44b
VME_bus.vhd
file
2012-11-26T10:48:51.500192Z
29adec46b31a18dead39247d886e6157
2012-11-21T17:37:38.896694Z
189
dpedrett
has-props
70970
VME_Funct_Match.vhd
file
2012-11-26T10:48:51.500192Z
a079a37158f3b29e6902590457a99fe6
2012-11-21T17:37:38.896694Z
189
dpedrett
16428
VME_IRQ_Controller.vhd
file
2012-11-26T10:48:51.500192Z
cd6e6a5e4484114f70c97bb4cd978462
2012-11-21T17:37:38.896694Z
189
dpedrett
16870
VME_CR_pack.vhd
file
2012-11-26T10:48:51.500192Z
da1c5bf968940a988ccd2b521cfff939
2012-11-21T17:37:38.896694Z
189
dpedrett
has-props
19450
VME_Init.vhd
file
2012-11-26T10:48:51.500192Z
9ddfd69bacadf1d075668c9b5483253c
2012-11-21T17:37:38.896694Z
189
dpedrett
12887
VME_Access_Decode.vhd
file
2012-11-26T10:48:51.500192Z
d4b90a002f5e033f74d28fb8cca92100
2012-11-21T17:37:38.896694Z
189
dpedrett
17962
Manifest.py
file
2012-11-26T10:48:51.515817Z
577b13f5f1bec60770d8573edad9637c
2012-11-21T17:45:28.032241Z
190
dpedrett
458
VME_SharedComps.vhd
file
2012-11-26T10:48:51.515817Z
8a959af2ff9071f5ef0944bd6721db6f
2012-11-21T17:37:38.896694Z
189
dpedrett
has-props
7844
VME_Am_Match.vhd
file
2012-11-26T10:48:51.515817Z
9725d8b042eea4c37e9252e8847539c1
2012-11-21T17:37:38.896694Z
189
dpedrett
8939
VME64xCore_Top.vhd
file
2012-11-26T10:48:51.515817Z
a1501201ca3cd60f7a21fa55f4d79225
2012-11-21T17:37:38.896694Z
189
dpedrett
has-props
23885
CodeReview_2Nov2012
dir
vme64x_pack.vhd
file
2012-11-26T10:48:51.515817Z
2ad03c45d16eb7278cad34cc1c2d3213
2012-11-21T17:37:38.896694Z
189
dpedrett
51326
VME_swapper.vhd
file
2012-11-26T10:48:51.515817Z
475a0a59014eb399267a47ceafaab7c2
2012-11-21T17:37:38.896694Z
189
dpedrett
7189
VME_CRAM.vhd
file
2012-11-26T10:48:51.515817Z
92ce9b64e41565f5e84476f394ac38ae
2012-11-21T17:37:38.896694Z
189
dpedrett
has-props
3837
VME_Wb_master.vhd
file
2012-11-26T10:48:51.515817Z
057285373829b8b143c235309e892926
2012-11-21T17:37:38.896694Z
189
dpedrett
17561
VME_CSR_pack.vhd
file
2012-11-26T10:48:51.515817Z
1779157b263856655096a02a03da75d0
2012-11-02T10:53:52.853245Z
164
dpedrett
has-props
3751
VME_CR_CSR_Space.vhd
file
2012-11-26T10:48:51.531442Z
52b04724cda67fd8fc70c5f875be816f
2012-11-21T17:37:38.896694Z
189
dpedrett
23979
files = [ "VME64xCore_Top.vhd",
"vme64x_pack.vhd",
"VME_Access_Decode.vhd",
"VME_Am_Match.vhd",
"VME_bus.vhd",
"VME_CR_CSR_Space.vhd",
"VME_CR_pack.vhd",
"VME_CSR_pack.vhd",
"VME_CRAM.vhd",
"VME_Funct_Match.vhd",
"VME_Init.vhd",
"VME_IRQ_Controller.vhd",
"VME_SharedComps.vhd",
"VME_swapper.vhd",
"VME_Wb_master.vhd"]
--_____________________________________________________________________________|
-- VME TO WB INTERFACE |
-- |
-- CERN,BE/CO-HT |
--_____________________________________________________________________________|
-- File: VME64xCore_Top.vhd |
--_____________________________________________________________________________|
-- Description:
-- This core implements an interface to transfer data between the VMEbus and the WBbus.
-- This core is a Slave in the VME side and Master in the WB side.
-- The main blocks:
--
-- ________________________________________________________________
-- | VME64xCore_Top.vhd |
-- |__ ____________________ __________________ |
-- | | | | | | |
-- |S | | VME_bus.vhd | | | |
-- V |A | | | |VME_to_WB_FIFO.vhd| |
-- M |M | | | | |(not implemented) | |
-- E |P | | VME | WB | | | | W
-- |L | | slave | master | | | | B
-- B |I | | | | _______ | | |
-- U |N | | | | | CSR | | | | B
-- S |G | | | | |______ | |__________________| | U
-- | | | | | | _________________ | S
-- | | | | |CRAM | | | |
-- |__| | | |______ | | IRQ_Controller | |
-- | | | | | | | |
-- | | | | CR | | | |
-- | |____________________| |_______| |_________________| |
-- |________________________________________________________________|
-- This core complies with the VME64x specifications and allows "plug and play"
-- configuration of VME crates.
-- The base address is setted by the Geographical lines.
-- The base address can't be setted by hand with the switches on the board.
-- If the core is used in an old VME system without GA lines, the core should be provided of
-- a logic that detects if GA = "11111" and if it is the base address of the module
-- should be derived from the switches on the board.
-- All the VMEbus's asynchronous signals must be sampled 2 or 3 times to avoid
-- metastability problem.
-- All the output signals on the WB bus are registered.
-- The Input signals from the WB bus aren't registered indeed the WB is a synchronous protocol and
-- some registers in the WB side will introduce a delay that make impossible reproduce the
-- WB PIPELINED protocol.
-- The WB Slave application must work at the same frequency of this vme64x core.
-- The main component is the VME_bus on the left of the block diagram. Inside this component
-- you can find the main finite state machine that coordinates all the synchronisms.
-- The WB protocol is more faster than the VME protocol so to make independent
-- the two protocols a FIFO memory can be introduced.
-- The FIFO is necessary only during 2eSST access mode.
-- During the block transfer without FIFO the VME_bus accesses directly the Wb bus in
-- Single pipelined read/write mode. If this is the only Wb master this solution is
-- better than the solution with FIFO.
-- In this base version of the core the FIFO is not implemented indeed the 2e access modes
-- aren't supported yet.
-- A Configuration ROM/Control Status Register (CR/CSR) address space has been
-- introduced. The CR/CSR space can be accessed with the data transfer type
-- D08_3, D16_23, D32.
-- To access the CR/CSR space: AM = 0x2f --> this is A24 addressing type, SINGLE
-- transfer type. Base Address = Slot Number.
-- This interface is provided with an Interrupter. The IRQ Controller receives from
-- the Application (WB bus) an interrupt request and transfers this interrupt request
-- on the VMEbus. This component acts also during the Interrupt acknowledge cycle,
-- sending the status/ID to the Interrupt handler.
-- Inside each component is possible to read a more detailed description.
-- Access modes supported:
-- http://www.ohwr.org/projects/vme64x-core/repository/changes/trunk/
-- documentation/user_guides/VME_access_modes.pdf
--
--______________________________________________________________________________
--
-- References:
-- The VMEbus specification ANSI/IEEE STD1014-1987
-- The VME64std ANSI/VITA 1-1994
-- The VME64x ANSI/VITA 1.1-1997
--______________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--______________________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
-- This source file is free software; you can redistribute it and/or modify it under the terms of
-- the GNU Lesser General Public License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details.
-- You should have received a copy of the GNU Lesser General Public License along with this
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
---------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;
use work.vme64x_pack.all;
use work.VME_CR_pack.all;
--===========================================================================
-- Entity declaration
--===========================================================================
entity VME64xCore_Top is
generic(
-- clock period (ns)
g_clock : integer := c_clk_period; -- 100 MHz
--WB data width:
g_wb_data_width : integer := c_width; -- must be 32 or 64
--WB address width:
g_wb_addr_width : integer := c_addr_width; -- 64 or less
-- CRAM
g_cram_size : integer := c_CRAM_SIZE;
-- Board ID; each board shall have an unique ID. eg: SVEC_ID = 408.
-- loc: 0x33, 0x37, 0x3B, 0x3F CR space
g_BoardID : integer := c_SVEC_ID; -- 4 bytes: 0x00000198
-- Manufacturer ID: eg the CERN ID is 0x080030
-- loc: 0x27, 0x2B, 0x2F CR space
g_ManufacturerID : integer := c_CERN_ID; -- 3 bytes: 0x080030
-- Revision ID
-- loc: 0x43, 0x47, 0x4B, 0x4F CR space
g_RevisionID : integer := c_RevisionID; -- 4 bytes: 0x00000001
-- Program ID: this is the firmware ID
-- loc: 0x7f CR space
g_ProgramID : integer := 90 -- 1 byte : 0x5a
-- The default values can be found in the vme64x_pack
);
port(
clk_i : in std_logic;
-- for the IRQ_Generator and relative registers
reset_o : out std_logic; -- asserted when '1'
-- VME
VME_AS_n_i : in std_logic;
VME_RST_n_i : in std_logic; -- asserted when '0'
VME_WRITE_n_i : in std_logic;
VME_AM_i : in std_logic_vector(5 downto 0);
VME_DS_n_i : in std_logic_vector(1 downto 0);
VME_GA_i : in std_logic_vector(5 downto 0);
VME_BERR_o : out std_logic; -- [In the VME standard this line is asserted when low.
-- Here is asserted when high indeed the logic will be
-- inverted again in the VME transceivers on the board]*.
VME_DTACK_n_o : out std_logic;
VME_RETRY_n_o : out std_logic;
VME_LWORD_n_i : in std_logic;
VME_LWORD_n_o : out std_logic;
VME_ADDR_i : in std_logic_vector(31 downto 1);
VME_ADDR_o : out std_logic_vector(31 downto 1);
VME_DATA_i : in std_logic_vector(31 downto 0);
VME_DATA_o : out std_logic_vector(31 downto 0);
VME_IRQ_o : out std_logic_vector(6 downto 0); -- the same as []*
VME_IACKIN_n_i : in std_logic;
VME_IACK_n_i : in std_logic;
VME_IACKOUT_n_o : out std_logic;
-- VME buffers
VME_DTACK_OE_o : out std_logic;
VME_DATA_DIR_o : out std_logic;
VME_DATA_OE_N_o : out std_logic;
VME_ADDR_DIR_o : out std_logic;
VME_ADDR_OE_N_o : out std_logic;
VME_RETRY_OE_o : out std_logic;
-- WishBone
DAT_i : in std_logic_vector(g_wb_data_width - 1 downto 0);
DAT_o : out std_logic_vector(g_wb_data_width - 1 downto 0);
ADR_o : out std_logic_vector(g_wb_addr_width - 1 downto 0);
CYC_o : out std_logic;
ERR_i : in std_logic;
RTY_i : in std_logic;
SEL_o : out std_logic_vector(f_div8(g_wb_data_width) - 1 downto 0);
STB_o : out std_logic;
ACK_i : in std_logic;
WE_o : out std_logic;
STALL_i : in std_logic;
-- IRQ Generator
INT_ack_o : out std_logic; -- when the IRQ controller acknowledges the Interrupt
-- cycle it sends a pulse to the IRQ Generator
IRQ_i : in std_logic; -- Interrupt request; the IRQ Generator/your Wb application
-- sends a pulse to the IRQ Controller which asserts one of
-- the IRQ lines.
-- Added by Davide for debug:
debug : 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(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);
signal s_CRdata : std_logic_vector(7 downto 0);
signal s_RW : std_logic;
signal s_reset : std_logic;
signal s_IRQlevelReg : std_logic_vector(7 downto 0);
signal s_FIFOreset : std_logic;
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_fifo : std_logic;
signal s_VME_DTACK_VMEbus : std_logic;
signal s_VME_DTACK_IRQ : std_logic;
signal s_VME_DTACK_OE_VMEbus : std_logic;
signal s_VME_DTACK_OE_IRQ : std_logic;
signal s_VME_DATA_DIR_VMEbus : std_logic;
signal s_VME_DATA_DIR_IRQ : std_logic;
signal s_INT_Level : std_logic_vector(7 downto 0);
signal s_INT_Vector : std_logic_vector(7 downto 0);
signal s_VME_IRQ_n_o : std_logic_vector(6 downto 0);
signal s_reset_IRQ : std_logic;
signal s_CSRData_o : std_logic_vector(7 downto 0);
signal s_CSRData_i : std_logic_vector(7 downto 0);
signal s_CrCsrOffsetAddr : std_logic_vector(18 downto 0);
signal s_Ader0 : std_logic_vector(31 downto 0);
signal s_Ader1 : std_logic_vector(31 downto 0);
signal s_Ader2 : std_logic_vector(31 downto 0);
signal s_Ader3 : std_logic_vector(31 downto 0);
signal s_Ader4 : std_logic_vector(31 downto 0);
signal s_Ader5 : std_logic_vector(31 downto 0);
signal s_Ader6 : std_logic_vector(31 downto 0);
signal s_Ader7 : std_logic_vector(31 downto 0);
signal s_en_wr_CSR : std_logic;
signal s_err_flag : std_logic;
signal s_reset_flag : std_logic;
signal s_Sw_Reset : std_logic;
signal s_ModuleEnable : std_logic;
signal s_Endian : std_logic_vector(2 downto 0);
signal s_BAR : std_logic_vector(4 downto 0);
signal s_time : std_logic_vector(39 downto 0);
signal s_bytes : std_logic_vector(12 downto 0);
signal s_IRQ : std_logic;
-- Oversampled input signals
signal VME_RST_n_oversampled : std_logic;
signal VME_AS_n_oversampled : 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);
signal VME_DS_n_oversampled_1 : std_logic_vector(1 downto 0);
signal VME_GA_oversampled : std_logic_vector(5 downto 0);
signal VME_IACK_n_oversampled : std_logic;
signal VME_IACKIN_n_oversampled : std_logic;
signal s_reg_1 : std_logic_vector(1 downto 0);
signal s_reg_2 : std_logic_vector(1 downto 0);
--===========================================================================
-- Architecture begin
--===========================================================================
begin
---------------------METASTABILITY-----------------------------------------
-- Input oversampling & edge detection; oversampling the input data is necessary to avoid
-- metastability problems. With 3 samples the probability of metastability problem will
-- be very low but of course the transfer rate will be slow down a little.
GAinputSample : RegInputSample
generic map(
width => 6
)
port map(
reg_i => VME_GA_i,
reg_o => VME_GA_oversampled,
clk_i => clk_i
);
-- DSinputSample : RegInputSample
RegInputSample : process(clk_i)
begin
if rising_edge(clk_i) then
s_reg_1 <= VME_DS_n_i;
s_reg_2 <= s_reg_1;
VME_DS_n_oversampled <= s_reg_2;
end if;
end process;
-- to avoid timing problem during BLT and MBLT accesses
VME_DS_n_oversampled_1 <= s_reg_2;
WRITEinputSample : SigInputSample
port map(
sig_i => VME_WRITE_n_i,
sig_o => VME_WRITE_n_oversampled,
clk_i => clk_i
);
ASinputSample : SigInputSample
port map(
sig_i => VME_AS_n_i,
sig_o => VME_AS_n_oversampled,
clk_i => clk_i
);
RSTinputSample : SigInputSample
port map(
sig_i => VME_RST_n_i,
sig_o => VME_RST_n_oversampled,
clk_i => clk_i
);
IACKinputSample : SigInputSample
port map(
sig_i => VME_IACK_n_i,
sig_o => VME_IACK_n_oversampled,
clk_i => clk_i
);
IACKINinputSample : SigInputSample
port map(
sig_i => VME_IACKIN_n_i,
sig_o => VME_IACKIN_n_oversampled,
clk_i => clk_i
);
IrqrisingEdge : RisEdgeDetection
port map (
sig_i => IRQ_i,
clk_i => clk_i,
RisEdge_o => s_IRQ
);
Inst_VME_bus: VME_bus
generic map(
g_clock => g_clock,
g_wb_data_width => g_wb_data_width,
g_wb_addr_width => g_wb_addr_width,
g_cram_size => g_cram_size
)
port map(
clk_i => clk_i,
reset_o => s_reset, -- asserted when '1'
-- VME
VME_RST_n_i => VME_RST_n_oversampled,
VME_AS_n_i => VME_AS_n_oversampled,
VME_LWORD_n_o => VME_LWORD_n_o,
VME_LWORD_n_i => VME_LWORD_n_i,
VME_RETRY_n_o => VME_RETRY_n_o,
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_DS_ant_n_i => VME_DS_n_oversampled_1,
VME_DTACK_n_o => s_VME_DTACK_VMEbus,
VME_DTACK_OE_o => s_VME_DTACK_OE_VMEbus,
VME_BERR_o => VME_BERR_o,
VME_ADDR_i => VME_ADDR_i,
VME_ADDR_o => VME_ADDR_o,
VME_ADDR_DIR_o => VME_ADDR_DIR_o,
VME_ADDR_OE_N_o => VME_ADDR_OE_N_o,
VME_DATA_i => VME_DATA_i,
VME_DATA_o => s_VME_DATA_VMEbus,
VME_DATA_DIR_o => s_VME_DATA_DIR_VMEbus,
VME_DATA_OE_N_o => VME_DATA_OE_N_o,
VME_AM_i => VME_AM_i,
VME_IACK_n_i => VME_IACK_n_oversampled,
-- WB
memReq_o => STB_o,
memAckWB_i => ACK_i,
wbData_o => DAT_o,
wbData_i => DAT_i,
locAddr_o => ADR_o,
wbSel_o => SEL_o,
RW_o => s_RW,
cyc_o => CYC_o,
err_i => ERR_i,
rty_i => RTY_i,
stall_i => STALL_i,
-- CR/CSR signals
CRAMaddr_o => s_CRAMaddr,
CRAMdata_o => s_CRAMdataIn,
CRAMdata_i => s_CRAMdataOut,
CRAMwea_o => s_CRAMwea,
CRaddr_o => s_CRaddr,
CRdata_i => s_CRdata,
en_wr_CSR => s_en_wr_CSR,
CrCsrOffsetAddr => s_CrCsrOffsetAddr,
CSRData_o => s_CSRData_o,
CSRData_i => s_CSRData_i,
err_flag_o => s_err_flag,
reset_flag_i => s_reset_flag,
Ader0 => s_Ader0,
Ader1 => s_Ader1,
Ader2 => s_Ader2,
Ader3 => s_Ader3,
Ader4 => s_Ader4,
Ader5 => s_Ader5,
Ader6 => s_Ader6,
Ader7 => s_Ader7,
ModuleEnable => s_ModuleEnable,
Endian_i => s_Endian,
Sw_Reset => s_Sw_Reset,
BAR_i => s_BAR,
numBytes => s_bytes,
transfTime => s_time,
-- debug
leds => debug
);
---------------------------------------------------------------------------------
-- output
VME_IRQ_o <= not s_VME_IRQ_n_o; --The buffers will invert again the logic level
WE_o <= not s_RW;
reset_o <= s_reset;
INT_ack_o <= s_VME_DTACK_IRQ;
--------------------------------------------------------------------------------
--Multiplexer added on the output signal used by either VMEbus.vhd and the IRQ_controller.vhd
VME_DATA_o <= s_VME_DATA_VMEbus when VME_IACK_n_oversampled ='1' else
s_VME_DATA_IRQ;
VME_DTACK_n_o <= s_VME_DTACK_VMEbus when VME_IACK_n_oversampled ='1' else
s_VME_DTACK_IRQ;
VME_DTACK_OE_o <= s_VME_DTACK_OE_VMEbus when VME_IACK_n_oversampled ='1' else
s_VME_DTACK_OE_IRQ;
VME_DATA_DIR_o <= s_VME_DATA_DIR_VMEbus when VME_IACK_n_oversampled ='1' else
s_VME_DATA_DIR_IRQ;
--------------------------------------------------------------------------------
-- Interrupter
Inst_VME_IRQ_Controller: VME_IRQ_Controller port map(
clk_i => clk_i,
reset_n_i => s_reset_IRQ, -- asserted when low
VME_IACKIN_n_i => VME_IACKIN_n_oversampled,
VME_AS_n_i => VME_AS_n_oversampled,
VME_AS1_n_i => VME_AS_n_i,
VME_DS_n_i => VME_DS_n_oversampled,
VME_LWORD_n_i => VME_LWORD_n_i,
VME_ADDR_123_i => VME_ADDR_i(3 downto 1),
INT_Level_i => s_INT_Level,
INT_Vector_i => s_INT_Vector ,
INT_Req_i => s_IRQ,
VME_IRQ_n_o => s_VME_IRQ_n_o,
VME_IACKOUT_n_o => VME_IACKOUT_n_o,
VME_DTACK_n_o => s_VME_DTACK_IRQ,
VME_DTACK_OE_o => s_VME_DTACK_OE_IRQ,
VME_DATA_o => s_VME_DATA_IRQ,
VME_DATA_DIR_o => s_VME_DATA_DIR_IRQ
);
s_reset_IRQ <= not(s_reset);
--------------------------------------------------------------------------
--CR/CSR space
Inst_VME_CR_CSR_Space: VME_CR_CSR_Space
generic map(
g_cram_size => g_cram_size,
g_wb_data_width => g_wb_data_width,
g_CRspace => c_cr_array,
g_BoardID => g_BoardID,
g_ManufacturerID => g_ManufacturerID,
g_RevisionID => g_RevisionID,
g_ProgramID => g_ProgramID
)
port map(
clk_i => clk_i,
reset => s_reset,
CR_addr => s_CRaddr,
CR_data => s_CRdata,
CRAM_addr => s_CRAMaddr,
CRAM_data_o => s_CRAMdataOut,
CRAM_data_i => s_CRAMdataIn,
CRAM_Wen => s_CRAMwea,
en_wr_CSR => s_en_wr_CSR,
CrCsrOffsetAddr => s_CrCsrOffsetAddr,
VME_GA_oversampled => VME_GA_oversampled,
locDataIn => s_CSRData_o,
err_flag => s_err_flag,
reset_flag => s_reset_flag,
CSRdata => s_CSRData_i,
Ader0 => s_Ader0,
Ader1 => s_Ader1,
Ader2 => s_Ader2,
Ader3 => s_Ader3,
Ader4 => s_Ader4,
Ader5 => s_Ader5,
Ader6 => s_Ader6,
Ader7 => s_Ader7,
ModuleEnable => s_ModuleEnable,
Sw_Reset => s_Sw_Reset,
Endian_o => s_Endian,
BAR_o => s_BAR,
INT_Level => s_INT_Level,
numBytes => s_bytes,
transfTime => s_time,
INT_Vector => s_INT_Vector
);
end RTL;
--===========================================================================
-- Architecture end
--===========================================================================
\ No newline at end of file
--__________________________________________________________________________________
-- VME TO WB INTERFACE
--
-- CERN,BE/CO-HT
--_________________________________________________________________________________
-- File: VME_Access_Decode.vhd
--_________________________________________________________________________________
-- Description: This component checks if the board is addressed and if it is, allows
-- the access to CR/CSR space by asserting the Confaccess signal, or allows the access
-- to WB bus by asserting the CardSel signal.
--
-- 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 functions; only one at time can be selected. If one of
-- these functions is selected the CardSel signal is asserted (this is the responding Slave).
-- To access the Wb bus we need to decode the AM and the address lines; so as shown in
-- the block diagram the main components are two: VME_Funct_Match, VME_Am_Match.
-- ___________________________________________
-- | VME_Access_Decode.vhd |
-- | |
-- | ____________ ____________ |
-- | | | | | |
-- | | FUNCTION | | AM | |
-- | | | | | |
-- | | MATCH | | MATCH | |
-- | | | | | |
-- | | | | | |
-- | | | | | |
-- | | | | | |
-- | | | | | |
-- | |____________| |____________| |
-- | |
-- |___________________________________________|
-- Each function has one ADER, one ADEM, one AMCAP and one XAMCAP register.
-- The ADEM, AMCAP, XAMCAP are in the CR memory; the Master can't write these registers
-- The ADER registers are located in the CSR space so the VME master has to write
-- these registers properly after the initialization.
-- How to access:
-- ADER[31:0]
-- [31:8] --> compare bits (put here the base address)
-- [7:2] --> AM
-- [1] --> '0'
-- [0] --> XAM bit: '0'; '1' only for 2e access mode
-- If XAM is '1' it will be:
-- [31:10] --> compare bits (put here the base address)
-- [9:2] --> XAM
-- [1] --> '0'
-- [0] --> '1'
-- ADEM[31:0]
-- [31:8] --> mask bits
-- [7:4] --> "0000"
-- [3] --> '0' --> The ADER is programmable
-- [2] --> DFS
-- [1] --> '0'
-- [0] --> EFM : '0'
-- EFM = Extra Function Mask: if '1' the next ADEM (and so the next AMCAP, XAMCAP
-- and ADER) provides the upper bit's mask for a 64 bit decoder.
-- This bit is '1' during A64 and 2e access.
-- DFS = Dynamic Function Decoder: a '1' here means this function can be used
-- to decode different address length (eg. A16 or A24 or A32) so the mask bits
-- should be all '1'.
--
-- AMCAP[63:0]
-- 6 AM lines --> 2**6 = 64 different configurations
-- This register is 64 bits wide and each bit rappresents one AM configuration.
-- If the bit is '1' it means that the corresponding AM is supported by this function.
-- If the corresponding ADEM's DFS is 0, only the AMCAP's bits with the same address
-- width must be '1'.
-- If the corresponding ADEM's DFS is 1, one or more AMCAP's bits can be '1'
-- eg: "1011101100000000001000100000000100000000000000001011101100000000" this
-- function supports the following access mode:
-- A24_S, A24_BLT, A24_MBLT, A16_S, A32_S, A32_BLT, A32_MBLT supervisor and user
-- access
--
-- XAMCAP[255:0]
-- 8 XAM lines --> 2**8 = 256 different configurations
-- This register is 256 bits wide and each bit rappresents one XAM configuration.
-- If the bit is '1' it means that the corresponding XAM is supported
-- by this function.
-- This register is used during the decode phase if the XAM bit is asserted (1).
-- Before accessing the board the VME Master must write the ADER registers. Of course for
-- writing properly the ADER the VME Master needs to know the corresponding ADEM and check if
-- EFM or DFS bits are asserted. The VME Master can read also
-- the AMCAP and XAMCAP and check the access mode supported by each function.
--
-- eg.1 let's imagine that we want to access different storage device; we can assign
-- one base address and one function at each storage.
-- Now the VME Master has to write the base address of each storage in the corresponding
-- ADER's compare bits and after this operation each function decodes the access to
-- the corresponding storage.
-- eg.2 this example is relative to our application; the vme64x interface has to transfer
-- data from the VMEbus to WB bus and in this core we have only one WB master. We
-- can use the same base address for all the functions because we will access always
-- the same WB master, and use the different functions to access with different mode eg:
-- function0 --> A32_S, A32_BLT, A32_MBLT modes
-- function1 --> A24_S, A24_BLT, A24_MBLT modes
-- function2 --> A16 mode
-- function3 and function4 --> A64, A64_BLT, A64_MBLT
-- function5 and function6 --> 2eVME and 2eSST modes
-- Note that if the address is 64 bits wide we need of two ADER and two ADEM to decode the
-- address so we need two functions. (see also EFM bit definition)
-- Of course you can mix these two example and set up one system with more storage devices
-- each with its base address and to assign each storage more than one function to access it
-- with all the access modes.
-- It is also possible extend the number of the functions defining other ADEM, AMCAP, XAMCAP
-- and ADER in the User CR Space and User CSR Space (see the VME_CR_CSR_Space.vhd component)
-- respectively.
-- In the VME_Funct_Match.vhd and VME_Am_Match.vhd components you can find more details
-- about the decode process.
--
-- To access the board both the FunctMatch(i) and AmMatch(i) must be equal to one.
--________________________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--________________________________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your option)
-- any later version. This source is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
-- more details. You should have received a copy of the GNU Lesser General Public
-- License along with this source; if not, download it from
-- http://www.gnu.org/licenses/lgpl-2.1.html
-----------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.vme64x_pack.all;
--===========================================================================
-- Entity declaration
--===========================================================================
entity VME_Access_Decode is
Port (clk_i : in STD_LOGIC;
reset : in STD_LOGIC;
mainFSMreset : in STD_LOGIC;
decode : in STD_LOGIC;
ModuleEnable : in STD_LOGIC;
InitInProgress : in STD_LOGIC;
Addr : in STD_LOGIC_VECTOR (63 downto 0);
Ader0 : in STD_LOGIC_VECTOR (31 downto 0);
Ader1 : in STD_LOGIC_VECTOR (31 downto 0);
Ader2 : in STD_LOGIC_VECTOR (31 downto 0);
Ader3 : in STD_LOGIC_VECTOR (31 downto 0);
Ader4 : in STD_LOGIC_VECTOR (31 downto 0);
Ader5 : in STD_LOGIC_VECTOR (31 downto 0);
Ader6 : in STD_LOGIC_VECTOR (31 downto 0);
Ader7 : in STD_LOGIC_VECTOR (31 downto 0);
Adem0 : in STD_LOGIC_VECTOR (31 downto 0);
Adem1 : in STD_LOGIC_VECTOR (31 downto 0);
Adem2 : in STD_LOGIC_VECTOR (31 downto 0);
Adem3 : in STD_LOGIC_VECTOR (31 downto 0);
Adem4 : in STD_LOGIC_VECTOR (31 downto 0);
Adem5 : in STD_LOGIC_VECTOR (31 downto 0);
Adem6 : in STD_LOGIC_VECTOR (31 downto 0);
Adem7 : in STD_LOGIC_VECTOR (31 downto 0);
AmCap0 : in STD_LOGIC_VECTOR (63 downto 0);
AmCap1 : in STD_LOGIC_VECTOR (63 downto 0);
AmCap2 : in STD_LOGIC_VECTOR (63 downto 0);
AmCap3 : in STD_LOGIC_VECTOR (63 downto 0);
AmCap4 : in STD_LOGIC_VECTOR (63 downto 0);
AmCap5 : in STD_LOGIC_VECTOR (63 downto 0);
AmCap6 : in STD_LOGIC_VECTOR (63 downto 0);
AmCap7 : in STD_LOGIC_VECTOR (63 downto 0);
XAmCap0 : in STD_LOGIC_VECTOR (255 downto 0);
XAmCap1 : in STD_LOGIC_VECTOR (255 downto 0);
XAmCap2 : in STD_LOGIC_VECTOR (255 downto 0);
XAmCap3 : in STD_LOGIC_VECTOR (255 downto 0);
XAmCap4 : in STD_LOGIC_VECTOR (255 downto 0);
XAmCap5 : in STD_LOGIC_VECTOR (255 downto 0);
XAmCap6 : in STD_LOGIC_VECTOR (255 downto 0);
XAmCap7 : in STD_LOGIC_VECTOR (255 downto 0);
Am : in STD_LOGIC_VECTOR (5 downto 0);
XAm : in STD_LOGIC_VECTOR (7 downto 0);
BAR_i : in STD_LOGIC_VECTOR (4 downto 0);
AddrWidth : in STD_LOGIC_VECTOR (1 downto 0);
Funct_Sel : out STD_LOGIC_VECTOR (7 downto 0);
Base_Addr : out STD_LOGIC_VECTOR (63 downto 0);
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(
clk_i => clk_i,
reset => reset,
decode => decode,
mainFSMreset => mainFSMreset,
Addr => Addr,
AddrWidth => AddrWidth,
Ader0 => Ader0,
Ader1 => Ader1,
Ader2 => Ader2,
Ader3 => Ader3,
Ader4 => Ader4,
Ader5 => Ader5,
Ader6 => Ader6,
Ader7 => Ader7,
Adem0 => Adem0,
Adem1 => Adem1,
Adem2 => Adem2,
Adem3 => Adem3,
Adem4 => Adem4,
Adem5 => Adem5,
Adem6 => Adem6,
Adem7 => Adem7,
FunctMatch => s_Func_Match,
DFS_o => s_DFS,
Nx_Base_Addr => s_nx_base_addr
);
Inst_Am_Match: VME_Am_Match port map(
clk_i => clk_i,
reset => reset,
mainFSMreset => mainFSMreset,
Ader0 => Ader0,
Ader1 => Ader1,
Ader2 => Ader2,
Ader3 => Ader3,
Ader4 => Ader4,
Ader5 => Ader5,
Ader6 => Ader6,
Ader7 => Ader7,
AmCap0 => AmCap0,
AmCap1 => AmCap1,
AmCap2 => AmCap2,
AmCap3 => AmCap3,
AmCap4 => AmCap4,
AmCap5 => AmCap5,
AmCap6 => AmCap6,
AmCap7 => AmCap7,
XAmCap0 => XAmCap0,
XAmCap1 => XAmCap1,
XAmCap2 => XAmCap2,
XAmCap3 => XAmCap3,
XAmCap4 => XAmCap4,
XAmCap5 => XAmCap5,
XAmCap6 => XAmCap6,
XAmCap7 => XAmCap7,
Am => Am,
XAm => XAm,
DFS_i => s_DFS,
decode => decode,
AmMatch => s_Am_Match
);
-- Check if the WB application is addressed
process(clk_i)
begin
if rising_edge(clk_i) then
CardSel <= '0';
Base_Addr <= (others => '0');
if ModuleEnable = '1' and InitInProgress = '0' then
for I in 0 to 7 loop
if s_func_sel(i) = '1' then
CardSel <= '1';
Base_Addr <= s_nx_base_addr;
-- exit; in this case the exit statement is useless
end if;
end loop;
end if;
end if;
end process;
s_func_sel <= s_Func_Match and s_Am_Match;
-- Check if the CR/CSR space is addressed
Confaccess <= '1' when unsigned(BAR_i) = unsigned(Addr(23 downto 19)) and
Am = c_CR_CSR and InitInProgress = '0' else '0';
end Behavioral;
--===========================================================================
-- Architecture end
--===========================================================================
--_______________________________________________________________________________________
-- VME TO WB INTERFACE
--
-- CERN,BE/CO-HT
--______________________________________________________________________________________
-- File: VME_Am_Match.vhd
--______________________________________________________________________________________
-- Description: this component checks if the AM match.
-- If it is the correspondent AmMatch's bit is asserted. This condition is necessary but
-- not sufficient to select the function and access the board.
-- If DFS = '0' the function supports only access modes with the same address width;
-- 1 function --> only 1 address width;
-- with address width I mean A16, A24, A32 or A64.
-- is sufficient check the AMCAP; AmMatch(i) <= s_FUNC_AMCAP(i)(to_integer(unsigned(Am))).
-- If DFS = '1' the function supports access modes with different address widths so AmMatch(i)
-- is asserted only if ADER[7:2] = AM and s_FUNC_AMCAP(i)(to_integer(unsigned(Am)))='1'.
-- If ADER(i)'s XAM bit is asserted than AmMatch(i) is asserted only if AM = 0x20 and if the
-- XAMCAP(i)(to_integer(unsigned(XAm))) = '1' and if DFS = '1' also ADER[9:2] must be equal
-- to XAM[7:0] lines.
--______________________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--______________________________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your option)
-- any later version. This source is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
-- more details. You should have received a copy of the GNU Lesser General Public
-- License along with this source; if not, download it from
-- http://www.gnu.org/licenses/lgpl-2.1.html
----------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.vme64x_pack.all;
--===========================================================================
-- Entity declaration
--===========================================================================
entity VME_Am_Match is
Port ( clk_i : in std_logic;
reset : in std_logic;
mainFSMreset : in std_logic;
Ader0 : in std_logic_vector (31 downto 0);
Ader1 : in std_logic_vector (31 downto 0);
Ader2 : in std_logic_vector (31 downto 0);
Ader3 : in std_logic_vector (31 downto 0);
Ader4 : in std_logic_vector (31 downto 0);
Ader5 : in std_logic_vector (31 downto 0);
Ader6 : in std_logic_vector (31 downto 0);
Ader7 : in std_logic_vector (31 downto 0);
AmCap0 : in std_logic_vector (63 downto 0);
AmCap1 : in std_logic_vector (63 downto 0);
AmCap2 : in std_logic_vector (63 downto 0);
AmCap3 : in std_logic_vector (63 downto 0);
AmCap4 : in std_logic_vector (63 downto 0);
AmCap5 : in std_logic_vector (63 downto 0);
AmCap6 : in std_logic_vector (63 downto 0);
AmCap7 : in std_logic_vector (63 downto 0);
XAmCap0 : in std_logic_vector (255 downto 0);
XAmCap1 : in std_logic_vector (255 downto 0);
XAmCap2 : in std_logic_vector (255 downto 0);
XAmCap3 : in std_logic_vector (255 downto 0);
XAmCap4 : in std_logic_vector (255 downto 0);
XAmCap5 : in std_logic_vector (255 downto 0);
XAmCap6 : in std_logic_vector (255 downto 0);
XAmCap7 : in std_logic_vector (255 downto 0);
Am : in std_logic_vector (5 downto 0);
XAm : in std_logic_vector (7 downto 0);
DFS_i : in std_logic_vector (7 downto 0);
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;
signal s_FUNC_XAMCAP : t_FUNC_256b_array;
signal s_amcap_match : std_logic_vector(7 downto 0);
signal s_xamcap_match : std_logic_vector(7 downto 0);
--===========================================================================
-- Architecture begin
--===========================================================================
begin
s_FUNC_ADER(0) <= unsigned(Ader0);
s_FUNC_ADER(1) <= unsigned(Ader1);
s_FUNC_ADER(2) <= unsigned(Ader2);
s_FUNC_ADER(3) <= unsigned(Ader3);
s_FUNC_ADER(4) <= unsigned(Ader4);
s_FUNC_ADER(5) <= unsigned(Ader5);
s_FUNC_ADER(6) <= unsigned(Ader6);
s_FUNC_ADER(7) <= unsigned(Ader7);
s_FUNC_AMCAP(0) <= unsigned(AmCap0);
s_FUNC_AMCAP(1) <= unsigned(AmCap1);
s_FUNC_AMCAP(2) <= unsigned(AmCap2);
s_FUNC_AMCAP(3) <= unsigned(AmCap3);
s_FUNC_AMCAP(4) <= unsigned(AmCap4);
s_FUNC_AMCAP(5) <= unsigned(AmCap5);
s_FUNC_AMCAP(6) <= unsigned(AmCap6);
s_FUNC_AMCAP(7) <= unsigned(AmCap7);
s_FUNC_XAMCAP(0) <= unsigned(XAmCap0);
s_FUNC_XAMCAP(1) <= unsigned(XAmCap1);
s_FUNC_XAMCAP(2) <= unsigned(XAmCap2);
s_FUNC_XAMCAP(3) <= unsigned(XAmCap3);
s_FUNC_XAMCAP(4) <= unsigned(XAmCap4);
s_FUNC_XAMCAP(5) <= unsigned(XAmCap5);
s_FUNC_XAMCAP(6) <= unsigned(XAmCap6);
s_FUNC_XAMCAP(7) <= unsigned(XAmCap7);
p_AMmatch : process(clk_i)
begin
if rising_edge(clk_i) then
if mainFSMreset = '1' or reset = '1' then
AmMatch <= (others => '0');
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
if unsigned(s_FUNC_ADER(i)(7 downto 2)) = unsigned(Am) then
AmMatch(i) <= s_amcap_match(i);
else
AmMatch(i) <= '0';
end if;
else
if (unsigned(XAm) = unsigned(s_FUNC_ADER(i)(9 downto 2))) then
AmMatch(i) <= s_xamcap_match(i) and s_amcap_match(i);
else
AmMatch(i) <= '0';
end if;
end if;
else
if s_FUNC_ADER(i)(XAM_MODE) = '1' then
AmMatch(i) <= s_xamcap_match(i) and s_amcap_match(i);
else
AmMatch(i) <= s_amcap_match(i);
end if;
end if;
end loop;
end if;
end if;
end process;
------------------------------------------------------
-- Check if the AM is in the AMCAP register
process(s_FUNC_AMCAP, Am)
begin
s_amcap_match <= (others => '0');
for i in 0 to 7 loop
s_amcap_match(i) <= s_FUNC_AMCAP(i)(to_integer(unsigned(Am)));
end loop;
end process;
-------------------------------------------------------
-- Check if the XAM is in the XAMCAP register
process(s_FUNC_XAMCAP, XAm)
begin
s_xamcap_match <= (others => '0');
for i in 0 to 7 loop
s_xamcap_match(i) <= s_FUNC_XAMCAP(i)(to_integer(unsigned(XAm)));
end loop;
end process;
------------------------------------------------------
end Behavioral;
--===========================================================================
-- Architecture end
--===========================================================================
--______________________________________________________________________________|
-- VME TO WB INTERFACE |
-- |
-- CERN,BE/CO-HT |
--______________________________________________________________________________|
-- File: VME_CRAM.vhd |
--______________________________________________________________________________|
-- Description: RAM memory
--______________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--______________________________________________________________________________
-- 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
--===========================================================================
--________________________________________________________________________________________________
-- VME TO WB INTERFACE
--
-- CERN,BE/CO-HT
--________________________________________________________________________________________________
-- File: VME_CR_CSR_Space.vhd
--________________________________________________________________________________________________
-- Description:
-- Please note that only every fourth location in the CR/CSR space is used so it is possible write
-- the CSR/CRAM selecting the data transfer mode D08_Byte3, D16_Byte23, D32. If other data transfer
-- modes are selected the write operation will not be successful.
-- If the Master access the board for a reading operation with data transfer type different than
-- D08_Byte3, D16_Byte23, D32 the data that will be read is 0.
-- width = 1 byte
-- /---------------------------------/
-- _________________________________
-- | |0x7ffff
-- | |
-- | Defined and Reserved CSR |
-- | |
-- | Table 10-13 "Defined Control |
-- | Status register Assignments" |
-- | ANSI/VITA 1.1-1997 |
-- | VME64 Extensions |
-- |_________________________________|0x7fc00
-- | |0x013ff
-- | |
-- | |
-- | CRAM |
-- | |
-- | |
-- | |
-- | |
-- |_________________________________|0x1000
-- | |0xfff
-- | |
-- | Defined and reserved CR |
-- | |
-- | Table 10-12 "Defined |
-- | Configuration ROM Assignments" |
-- | ANSI/VITA 1.1-1997 |
-- | VME64 Extensions |
-- | |
-- |_________________________________| 0x00
--
-- If the size of the register is bigger than 1 byte, (eg: ADER is 4 bytes) these bytes are
-- stored in the BIG_ENDIAN ORDER.
-- User CR and User CSR are not implemented.
-- In addition to the registers of the table 10-13 in the CSR space you can find:
-- _
-- IRQ_Vector --> 0x7FF5F |--> for the Interrupter
-- IRQ_level --> 0x7FF5B _|
--
-- Endian --> 0x7FF53 --> for the swapper
--
-- WB32bits --> 0x7FF33 --> if the bit 0 is '1' it means that the WB data bus is 32 bit
-- _
-- TIME0_ns --> 0x7FF4f |
-- TIME1_ns --> 0x7FF4b |
-- TIME2_ns --> 0x7FF47 |
-- TIME3_ns --> 0x7FF43 | --> to calculate the transfer rate
-- TIME4_ns --> 0x7FF3f |
-- BYTES0 --> 0x7FF3b |
-- BYTES1 --> 0x7FF37 _|
--
-- CRAM memory Added. How to use the CRAM: (1KB)
-- 1) The Master read the CRAM_OWNER Register location 0x7fff3; if 0 the CRAM is free
-- 2) The Master write his ID in the CRAM_OWNER Register location 0x7fff3
-- 3) If the Master can read his ID in the CRAM_OWNER Register it means that it
-- is the owner of the CRAM.
-- If other Masters write their ID in the CRAM_OWNER Register when it contains a non-zero
-- value, the write operation will not be successful --> this allows the first
-- Master that writes a non-zero value to acquire ownership.
-- 4) When a Master has the ownership of the CRAM the Bit Set Register's bit 2,
-- location 0x7fffb, should be setted.
-- 5) The Master can release the ownership by writing '1' in the bit 2 to the Bit Set
-- Register location 0x7fffb.
-- Other flags:
-- Module Enable --> Bit Set Register's bit 4 location 0x7fffb
-- If this bit is '0' the slave module's address decoder is not enable and
-- the Wb bus can't be accessed.
-- Error flag --> Bit Set Register's bit 3 location 0x7fffb
-- When the Slave asserts the BERR* line should asserts also this bit.
-- CRAM_OWNER flag --> Bit Set Register's bit 2 location 0x7fffb
-- The Master can clear these flags by writing '1' in the corresponding bits to the Bit Clr Register
-- location 0x7fff7.
--
-- Software reset --> Bit Set Register's bit 7 location 0x7fffb
-- This bit acts as software reset, indeed if the Master writes '1' here,
-- the module will be resetted and reinitializated.
-- The reset condition is temporary because during the initialization the default
-- configuration is uploaded again, so the Master don't need to remove the
-- module from reset mode by writing '1' in the bit 7 to the Bit Clr Register.
--
--______________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--______________________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
-- This source file is free software; you can redistribute it and/or modify it under the terms of
-- the GNU Lesser General Public License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details.
-- You should have received a copy of the GNU Lesser General Public License along with this
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
---------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
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;
g_wb_data_width : integer := c_width;
g_CRspace : t_cr_array := c_cr_array;
g_BoardID : integer := c_SVEC_ID;
g_ManufacturerID : integer := c_CERN_ID; -- 0x00080030
g_RevisionID : integer := c_RevisionID; -- 0x00000001
g_ProgramID : integer := 96 -- 0x00000060
);
Port ( -- VMEbus.vhd signals
clk_i : 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 (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;
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);
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);
-- VMEbus.vhd DECODER signals
Ader0 : out std_logic_vector(31 downto 0);
Ader1 : out std_logic_vector(31 downto 0);
Ader2 : out std_logic_vector(31 downto 0);
Ader3 : out std_logic_vector(31 downto 0);
Ader4 : out std_logic_vector(31 downto 0);
Ader5 : out std_logic_vector(31 downto 0);
Ader6 : out std_logic_vector(31 downto 0);
Ader7 : out std_logic_vector(31 downto 0);
ModuleEnable : out std_logic;
Sw_Reset : out std_logic;
Endian_o : out std_logic_vector(2 downto 0);
BAR_o : out std_logic_vector(4 downto 0);
-- IRQ_controller signals
INT_Level : out std_logic_vector(7 downto 0);
INT_Vector : out std_logic_vector(7 downto 0)
);
end VME_CR_CSR_Space;
--===========================================================================
-- Architecture declaration
--===========================================================================
architecture Behavioral of VME_CR_CSR_Space is
signal s_CSRarray : t_CSRarray; -- Array of CSR registers
signal s_bar_written : std_logic;
signal s_CSRdata : unsigned(7 downto 0);
signal s_FUNC_ADER : t_FUNC_32b_array;
signal s_CR_Space : t_cr_array(2**12 downto 0);
signal s_CrCsrOffsetAddr : unsigned(18 downto 0);
signal s_locDataIn : unsigned(7 downto 0);
signal s_CrCsrOffsetAderIndex : unsigned(18 downto 0);
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 even the BAR register
-- is set to 0x00 and the following flag is asserted; the board will not answer if the
-- master accesses its CR/CSR space and we can see a time out error in the VME bus.
s_BARerror <= not(s_BAR_o(4) or s_BAR_o(3)or s_BAR_o(2) or s_BAR_o(1) or s_BAR_o(0));
--------------------------------------------------------------------------------
s_CR_Space <= f_set_CR_space(g_BoardID, g_CRspace, g_ManufacturerID, g_RevisionID, g_ProgramID);
-- CR
process(clk_i)
begin
if rising_edge(clk_i) then
CR_data <= s_CR_Space(to_integer(unsigned(CR_addr))); -- c_cr_array(to_integer(unsigned(CR_addr)));
end if;
end process;
--------------------------------------------------------------------------------
-- CSR Write
s_locDataIn <= unsigned(locDataIn);
s_CrCsrOffsetAderIndex <= s_CrCsrOffsetAddr -
(c_FUNC0_ADER_3_addr(18 downto 0) srl 2) + FUNC0_ADER_3;
p_CSR_Write : process(clk_i)
begin
if rising_edge(clk_i) then
if reset = '1' then
s_CSRarray(BAR) <= (others => '0');
s_bar_written <= '0';
for i in 254 downto WB32bits loop -- Initialization of the CSR memory
s_CSRarray(i) <= c_csr_array(i);
end loop;
elsif s_bar_written = '0' and s_odd_parity = '1' then
-- initialization of BAR reg to access the CR/CSR space
s_CSRarray(BAR)(7 downto 3) <= unsigned(not VME_GA_oversampled(4 downto 0));
s_CSRarray(BAR)(2 downto 0) <= "000";
s_bar_written <= '1';
elsif s_odd_parity = '0' then
s_CSRarray(BAR) <= (others => '0');
elsif (en_wr_CSR = '1') then
case to_integer(s_CrCsrOffsetAddr) is
when to_integer("00" & c_BAR_addr(18 downto 2)) =>
s_CSRarray(BAR) <= s_locDataIn(7 downto 0);
s_bar_written <= '1';
when to_integer("00" & c_BIT_SET_REG_addr(18 downto 2)) =>
for i in 0 to 7 loop
s_CSRarray(BIT_SET_CLR_REG)(i) <= s_locDataIn(i);
end loop;
when to_integer("00" & c_BIT_CLR_REG_addr(18 downto 2)) =>
for i in 0 to 7 loop
if s_locDataIn(i) = '1' and i = 2 then
s_CSRarray(BIT_SET_CLR_REG)(i) <= '0';
s_CSRarray(CRAM_OWNER) <= x"00";
elsif s_locDataIn(i) = '1' and i = 3 then
reset_flag <= '1';
else
if s_locDataIn(i) = '1' then
s_CSRarray(BIT_SET_CLR_REG)(i) <= '0';
end if;
end if;
end loop;
when to_integer("00" & c_CRAM_OWNER_addr(18 downto 2)) =>
if s_CSRarray(CRAM_OWNER) = x"00" and s_locDataIn(7 downto 0) /= x"00" then
-- Write register give ownership only if register value is 0
s_CSRarray(CRAM_OWNER) <= s_locDataIn(7 downto 0);
s_CSRarray(BIT_SET_CLR_REG)(2) <= '1';
end if;
when to_integer("00" & c_USR_BIT_SET_REG_addr(18 downto 2)) =>
s_CSRarray(USR_BIT_SET_CLR_REG) <= s_locDataIn(7 downto 0);
when to_integer("00" & c_USR_BIT_CLR_REG_addr(18 downto 2)) =>
for i in 0 to 7 loop
if s_locDataIn(i) = '1' then
s_CSRarray(USR_BIT_SET_CLR_REG)(i) <= '0';
end if;
end loop;
when to_integer("00" & c_FUNC0_ADER_3_addr(18 downto 2)) to
to_integer("00" & c_FUNC7_ADER_0_addr(18 downto 2)) =>
s_CSRarray(to_integer(s_CrCsrOffsetAderIndex)) <= s_locDataIn(7 downto 0);
when to_integer("00" & c_IRQ_Vector_addr(18 downto 2)) =>
s_CSRarray(IRQ_Vector) <= s_locDataIn(7 downto 0);
when to_integer("00" & c_IRQ_level_addr(18 downto 2)) =>
s_CSRarray(IRQ_level) <= s_locDataIn(7 downto 0);
when to_integer("00" & c_Endian_addr(18 downto 2)) =>
s_CSRarray(Endian) <= s_locDataIn(7 downto 0);
when others => null;
end case;
else
if g_wb_data_width = 32 then
s_CSRarray(WB32bits) <= x"01";
else
s_CSRarray(WB32bits) <= 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));
s_CSRarray(TIME1_ns) <= unsigned(transfTime(15 downto 8));
s_CSRarray(TIME2_ns) <= unsigned(transfTime(23 downto 16));
s_CSRarray(TIME3_ns) <= unsigned(transfTime(31 downto 24));
s_CSRarray(TIME4_ns) <= unsigned(transfTime(39 downto 32));
end if;
end if;
end process;
------------------------------------------------------------------------------------------------------------------------------------
--CSR Read
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) & 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) & err_flag & s_CSRarray(BIT_SET_CLR_REG)(2 downto 0);
when "00" & c_CRAM_OWNER_addr(18 downto 2) => s_CSRdata <= s_CSRarray(CRAM_OWNER);
when "00" & c_USR_BIT_SET_REG_addr(18 downto 2) => s_CSRdata <= s_CSRarray(
USR_BIT_SET_CLR_REG);
when "00" & c_USR_BIT_CLR_REG_addr(18 downto 2) => s_CSRdata <= s_CSRarray(
USR_BIT_SET_CLR_REG);
when "00" & c_FUNC7_ADER_0_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC7_ADER_0);
when "00" & c_FUNC7_ADER_1_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC7_ADER_1);
when "00" & c_FUNC7_ADER_2_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC7_ADER_2);
when "00" & c_FUNC7_ADER_3_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC7_ADER_3);
when "00" & c_FUNC6_ADER_0_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC6_ADER_0);
when "00" & c_FUNC6_ADER_1_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC6_ADER_1);
when "00" & c_FUNC6_ADER_2_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC6_ADER_2);
when "00" & c_FUNC6_ADER_3_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC6_ADER_3);
when "00" & c_FUNC5_ADER_0_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC5_ADER_0);
when "00" & c_FUNC5_ADER_1_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC5_ADER_1);
when "00" & c_FUNC5_ADER_2_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC5_ADER_2);
when "00" & c_FUNC5_ADER_3_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC5_ADER_3);
when "00" & c_FUNC4_ADER_0_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC4_ADER_0);
when "00" & c_FUNC4_ADER_1_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC4_ADER_1);
when "00" & c_FUNC4_ADER_2_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC4_ADER_2);
when "00" & c_FUNC4_ADER_3_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC4_ADER_3);
when "00" & c_FUNC3_ADER_0_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC3_ADER_0);
when "00" & c_FUNC3_ADER_1_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC3_ADER_1);
when "00" & c_FUNC3_ADER_3_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC3_ADER_3);
when "00" & c_FUNC2_ADER_0_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC2_ADER_0);
when "00" & c_FUNC2_ADER_1_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC2_ADER_1);
when "00" & c_FUNC2_ADER_2_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC2_ADER_2);
when "00" & c_FUNC2_ADER_3_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC2_ADER_3);
when "00" & c_FUNC1_ADER_0_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC1_ADER_0);
when "00" & c_FUNC1_ADER_1_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC1_ADER_1);
when "00" & c_FUNC1_ADER_2_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC1_ADER_2);
when "00" & c_FUNC1_ADER_3_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC1_ADER_3);
when "00" & c_FUNC0_ADER_0_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC0_ADER_0);
when "00" & c_FUNC0_ADER_1_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC0_ADER_1);
when "00" & c_FUNC0_ADER_2_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC0_ADER_2);
when "00" & c_FUNC0_ADER_3_addr(18 downto 2) => s_CSRdata <= s_CSRarray(FUNC0_ADER_3);
when "00" & c_IRQ_Vector_addr (18 downto 2) => s_CSRdata <= s_CSRarray(IRQ_Vector);
when "00" & c_IRQ_level_addr(18 downto 2) => s_CSRdata <= s_CSRarray(IRQ_level);
when "00" & c_Endian_addr(18 downto 2) => s_CSRdata <= s_CSRarray(Endian);
when "00" & c_TIME0_ns_addr(18 downto 2) => s_CSRdata <= s_CSRarray(TIME0_ns);
when "00" & c_TIME1_ns_addr(18 downto 2) => s_CSRdata <= s_CSRarray(TIME1_ns);
when "00" & c_TIME2_ns_addr(18 downto 2) => s_CSRdata <= s_CSRarray(TIME2_ns);
when "00" & c_TIME3_ns_addr(18 downto 2) => s_CSRdata <= s_CSRarray(TIME3_ns);
when "00" & c_TIME4_ns_addr(18 downto 2) => s_CSRdata <= s_CSRarray(TIME4_ns);
when "00" & c_BYTES0_addr(18 downto 2) => s_CSRdata <= s_CSRarray(BYTES0);
when "00" & c_BYTES1_addr(18 downto 2) => s_CSRdata <= s_CSRarray(BYTES1);
when "00" & c_WB32bits_addr(18 downto 2) => s_CSRdata <= s_CSRarray(WB32bits);
when others => s_CSRdata <= (others => '0');
end case;
end process;
INT_Level <= std_logic_vector(s_CSRarray(IRQ_level));
INT_Vector <= std_logic_vector(s_CSRarray(IRQ_Vector));
CSRdata <= std_logic_vector(s_CSRdata);
s_CrCsrOffsetAddr <= unsigned(CrCsrOffsetAddr);
-- Generate a vector of 8 array (unsigned 32 bits).
GADER_1 : for i in 0 to 7 generate
GADER_2 : for h in 0 to 3 generate
s_FUNC_ADER(i)(8*(4-h)-1 downto 8*(3-h)) <= s_CSRarray(FUNC0_ADER_3+(h+i*4));
end generate GADER_2;
end generate GADER_1;
-- to the decoder
Ader0 <= std_logic_vector(s_FUNC_ADER(0));
Ader1 <= std_logic_vector(s_FUNC_ADER(1));
Ader2 <= std_logic_vector(s_FUNC_ADER(2));
Ader3 <= std_logic_vector(s_FUNC_ADER(3));
Ader4 <= std_logic_vector(s_FUNC_ADER(4));
Ader5 <= std_logic_vector(s_FUNC_ADER(5));
Ader6 <= std_logic_vector(s_FUNC_ADER(6));
Ader7 <= std_logic_vector(s_FUNC_ADER(7));
ModuleEnable <= s_CSRarray(BIT_SET_CLR_REG)(4);
Endian_o <= std_logic_vector(s_CSRarray(Endian)(2 downto 0));
Sw_Reset <= s_CSRarray(BIT_SET_CLR_REG)(7);
BAR_o <= s_BAR_o;
s_BAR_o <= std_logic_vector(s_CSRarray(BAR)(7 downto 3));
---------------------------------------------------------------------------------------------------------------
-- CRAM:
CRAM_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
--===========================================================================
--_______________________________________________________________________________________
-- VME TO WB INTERFACE
--
-- CERN,BE/CO-HT
--______________________________________________________________________________________
-- File: VME_CR_pack.vhd
--______________________________________________________________________________________
-- Description: ROM memory (CR space)
--______________________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 06/2012
-- Version v0.02
--______________________________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your option)
-- any later version. This source is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
-- more details. You should have received a copy of the GNU Lesser General Public
-- License along with this source; if not, download it from
-- http://www.gnu.org/licenses/lgpl-2.1.html
---------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;
use work.vme64x_pack.all;
package VME_CR_pack is
-- type t_cr_array is array (natural range <>) of std_logic_vector(7 downto 0);
constant c_amcap : std_logic_vector(63 downto 0) :=
"1111111100000000001100100000000000000000000100001111111100001011";
constant c_amcap0 : std_logic_vector(63 downto 0) :=
"0000000000000000000000000000000000000000000000001011101100000000"; --A32
-- "1011101100000000001000100000000100000000000000001011101100000000";
constant c_amcapMBLT : std_logic_vector(63 downto 0) :=
"0000000000000000000000000000000000000000000000000000000100000000";
constant c_amcap1 : std_logic_vector(63 downto 0) :=
"1011101100000000000000000000000000000000000000000000000000000000"; --A24
constant c_amcap2 : std_logic_vector(63 downto 0) :=
"0000000000000000001000100000000000000000000000000000000000000000"; --A16
constant c_amcapA64 : std_logic_vector(63 downto 0) :=
"0000000000000000000000000000000000000000000000000000000000001011"; --for modalities A64, A64_BLT, A64_MBLT
constant c_amcap2e : std_logic_vector(63 downto 0) :=
"0000000000000000000000000000000100000000000000000000000000000000"; -- for modalities TWO_edge
constant c_xamcap0 : std_logic_vector(255 downto 0) :=
(others => '0');
constant c_xamcap2 : std_logic_vector(255 downto 0) :=
x"0000000000000000000000000000000000000000000000000000000000060006";
constant c_amb : t_cr_array(0 to 7) :=(
c_amcap(7 downto 0), c_amcap(15 downto 8),
c_amcap(23 downto 16), c_amcap(31 downto 24),
c_amcap(39 downto 32), c_amcap(47 downto 40),
c_amcap(55 downto 48), c_amcap(63 downto 56));
constant c_amb0 : t_cr_array(0 to 7) :=(
c_amcap0(7 downto 0), c_amcap0(15 downto 8),
c_amcap0(23 downto 16), c_amcap0(31 downto 24),
c_amcap0(39 downto 32), c_amcap0(47 downto 40),
c_amcap0(55 downto 48), c_amcap0(63 downto 56));
constant c_amb1 : t_cr_array(0 to 7) :=(
c_amcap1(7 downto 0), c_amcap1(15 downto 8),
c_amcap1(23 downto 16), c_amcap1(31 downto 24),
c_amcap1(39 downto 32), c_amcap1(47 downto 40),
c_amcap1(55 downto 48), c_amcap1(63 downto 56));
constant c_amb2 : t_cr_array(0 to 7) :=(
c_amcap2(7 downto 0), c_amcap2(15 downto 8),
c_amcap2(23 downto 16), c_amcap2(31 downto 24),
c_amcap2(39 downto 32), c_amcap2(47 downto 40),
c_amcap2(55 downto 48), c_amcap2(63 downto 56));
constant c_amb2e : t_cr_array(0 to 7) :=(
c_amcap2e(7 downto 0), c_amcap2e(15 downto 8),
c_amcap2e(23 downto 16), c_amcap2e(31 downto 24),
c_amcap2e(39 downto 32), c_amcap2e(47 downto 40),
c_amcap2e(55 downto 48), c_amcap2e(63 downto 56));
constant c_amb64 : t_cr_array(0 to 7) :=(
c_amcapA64(7 downto 0), c_amcapA64(15 downto 8),
c_amcapA64(23 downto 16), c_amcapA64(31 downto 24),
c_amcapA64(39 downto 32), c_amcapA64(47 downto 40),
c_amcapA64(55 downto 48), c_amcapA64(63 downto 56));
constant c_xam0 : t_cr_array(0 to 31) :=(
c_xamcap0(7 downto 0), c_xamcap0(15 downto 8), c_xamcap0(23 downto 16),
c_xamcap0(31 downto 24), c_xamcap0(39 downto 32), c_xamcap0(47 downto 40),
c_xamcap0(55 downto 48), c_xamcap0(63 downto 56), c_xamcap0(71 downto 64),
c_xamcap0(79 downto 72), c_xamcap0(87 downto 80), c_xamcap0(95 downto 88),
c_xamcap0(103 downto 96), c_xamcap0(111 downto 104), c_xamcap0(119 downto 112),
c_xamcap0(127 downto 120), c_xamcap0(135 downto 128), c_xamcap0(143 downto 136),
c_xamcap0(151 downto 144), c_xamcap0(159 downto 152), c_xamcap0(167 downto 160),
c_xamcap0(175 downto 168), c_xamcap0(183 downto 176), c_xamcap0(191 downto 184),
c_xamcap0(199 downto 192), c_xamcap0(207 downto 200), c_xamcap0(215 downto 208),
c_xamcap0(223 downto 216), c_xamcap0(231 downto 224), c_xamcap0(239 downto 232),
c_xamcap0(247 downto 240), c_xamcap0(255 downto 248));
constant c_xam2 : t_cr_array(0 to 31) :=(
c_xamcap2(7 downto 0), c_xamcap2(15 downto 8), c_xamcap2(23 downto 16),
c_xamcap2(31 downto 24), c_xamcap2(39 downto 32), c_xamcap2(47 downto 40),
c_xamcap2(55 downto 48), c_xamcap2(63 downto 56), c_xamcap2(71 downto 64),
c_xamcap2(79 downto 72), c_xamcap2(87 downto 80), c_xamcap2(95 downto 88),
c_xamcap2(103 downto 96), c_xamcap2(111 downto 104), c_xamcap2(119 downto 112),
c_xamcap2(127 downto 120), c_xamcap2(135 downto 128), c_xamcap2(143 downto 136),
c_xamcap2(151 downto 144), c_xamcap2(159 downto 152), c_xamcap2(167 downto 160),
c_xamcap2(175 downto 168), c_xamcap2(183 downto 176), c_xamcap2(191 downto 184),
c_xamcap2(199 downto 192), c_xamcap2(207 downto 200), c_xamcap2(215 downto 208),
c_xamcap2(223 downto 216), c_xamcap2(231 downto 224), c_xamcap2(239 downto 232),
c_xamcap2(247 downto 240), c_xamcap2(255 downto 248));
constant c_cr_array : t_cr_array(2**12 downto 0) :=
(
16#00# => (others => '0'),
-- Length of ROM
16#01# => x"00",
16#02# => x"10",
16#03# => x"00",
--Configuration ROM data acces width
16#04# => x"84", --D32, D16, D08
--CSR data acces width
16#05# => x"84", --D32, D16, D08
--CR/CSR Space Specification ID
16#06# => x"01",
--Ascii "C"
16#07# => x"43",
--Ascii "R"
16#08# => x"52",
--Manufacturer's ID -- for CERN: 0x080030
16#09# => x"08",
16#0A# => x"00",
16#0B# => x"30",
--board id -- eg: SVEC ID = 0x000198
16#0C# => x"03",
16#0D# => x"04",
16#0E# => x"04",
16#0F# => x"03",
--Rev id
16#10# => x"00",
16#11# => x"00",
16#12# => x"00",
16#13# => x"02",
--Point to ascii null terminatied
16#14# => x"00",
16#15# => x"00",
16#16# => x"00",
--Program Id code
16#1F# => x"5a",
--Offset to BEG_USER_CR
16#20# => x"00",
16#21# => x"00",
16#22# => x"00",
--Offset to END_USER_CR
16#23# => x"00",
16#24# => x"00",
16#25# => x"00",
--Offset to BEG_CRAM
16#26# => x"00",
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
16#2C# => x"00",
16#2D# => x"00",
16#2E# => x"00", -- 0x7fbf0 and NOT 0x7fbf3 because is possible access with D32 mode
--Offset to END_USER_CSR
16#2F# => x"00",
16#30# => x"00",
16#31# => x"00",
--CRAM_ACCESS_WIDTH
16#3f# => x"84", --D32, D16, D08
--Function data access width
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
16#48# => c_amb0(7), -- Fun 0 for A32 S, A32 BLT, A32 MBLT
16#49# => c_amb0(6), -- Fun 0
16#4A# => c_amb0(5), -- Fun 0
16#4B# => c_amb0(4), -- Fun 0
16#4C# => c_amb0(3), -- Fun 0
16#4D# => c_amb0(2), -- Fun 0
16#4E# => c_amb0(1), -- Fun 0
16#4F# => c_amb0(0), -- Fun 0
16#50# => c_amb1(7), -- Fun 1 for A24 S, A24 BLT, A24 MBLT
16#51# => c_amb1(6), -- Fun 1
16#52# => c_amb1(5), -- Fun 1
16#53# => c_amb1(4), -- Fun 1
16#54# => c_amb1(3), -- Fun 1
16#55# => c_amb1(2), -- Fun 1
16#56# => c_amb1(1), -- Fun 1
16#57# => c_amb1(0), -- Fun 1
16#58# => c_amb2(7), -- Fun 2 for A16
16#59# => c_amb2(6), -- Fun 2
16#5A# => c_amb2(5), -- Fun 2
16#5B# => c_amb2(4), -- Fun 2
16#5C# => c_amb2(3), -- Fun 2
16#5D# => c_amb2(2), -- Fun 2
16#5E# => c_amb2(1), -- Fun 2
16#5F# => c_amb2(0), -- Fun 2
16#60# => c_amb64(7), -- Fun 3 -- for A64 S, A64 BLT, A64 MBLT
16#61# => c_amb64(6), -- Fun 3
16#62# => c_amb64(5), -- Fun 3
16#63# => c_amb64(4), -- Fun 3
16#64# => c_amb64(3), -- Fun 3
16#65# => c_amb64(2), -- Fun 3
16#66# => c_amb64(1), -- Fun 3
16#67# => c_amb64(0), -- Fun 3
16#68# => x"00", -- Fun 3_b -- These are not used because the FUNC 3 decode
16#69# => x"00", -- Fun 3_b -- the access mode: A64 --> 2 ADER, 2 ADEM
16#6A# => x"00", -- Fun 3_b
16#6B# => x"00", -- Fun 3_b
16#6C# => x"00", -- Fun 3_b
16#6D# => x"00", -- Fun 3_b
16#6E# => x"00", -- Fun 3_b
16#6F# => x"00", -- Fun 3_b
16#70# => c_amb2e(7), -- Fun 4
16#71# => c_amb2e(6), -- Fun 4
16#72# => c_amb2e(5), -- Fun 4
16#73# => c_amb2e(4), -- Fun 4
16#74# => c_amb2e(3), -- Fun 4
16#75# => c_amb2e(2), -- Fun 4
16#76# => c_amb2e(1), -- Fun 4
16#77# => c_amb2e(0), -- Fun 4
16#78# => x"00", -- Fun 4_b
16#79# => x"00", -- Fun 4_b
16#7A# => x"00", -- Fun 4_b
16#7B# => x"00", -- Fun 4_b
16#7C# => x"00", -- Fun 4_b
16#7D# => x"00", -- Fun 4_b
16#7E# => x"00", -- Fun 4_b
16#7F# => x"00", -- Fun 4_b
--Xamcap
16#88# => c_xam0(31), -- Fun 0 XAMCAP MSB
16#89# => c_xam0(30),
16#8A# => c_xam0(29),
16#8B# => c_xam0(28),
16#8C# => c_xam0(27),
16#8D# => c_xam0(26),
16#8E# => c_xam0(25),
16#8F# => c_xam0(24),
16#90# => c_xam0(23),
16#91# => c_xam0(22),
16#92# => c_xam0(21),
16#93# => c_xam0(20),
16#94# => c_xam0(19),
16#95# => c_xam0(18),
16#96# => c_xam0(17),
16#97# => c_xam0(16),
16#98# => c_xam0(15),
16#99# => c_xam0(14),
16#9A# => c_xam0(13),
16#9B# => c_xam0(12),
16#9C# => c_xam0(11),
16#9D# => c_xam0(10),
16#9E# => c_xam0(9),
16#9F# => c_xam0(8),
16#A0# => c_xam0(7),
16#A1# => c_xam0(6),
16#A2# => c_xam0(5),
16#A3# => c_xam0(4),
16#A4# => c_xam0(3),
16#A5# => c_xam0(2),
16#A6# => c_xam0(1),
16#A7# => c_xam0(0),
16#A8# => c_xam0(31), -- Fun 1 XAMCAP MSB
16#A9# => c_xam0(30),
16#AA# => c_xam0(29),
16#AB# => c_xam0(28),
16#AC# => c_xam0(27),
16#AD# => c_xam0(26),
16#AE# => c_xam0(25),
16#AF# => c_xam0(24),
16#B0# => c_xam0(23),
16#B1# => c_xam0(22),
16#B2# => c_xam0(21),
16#B3# => c_xam0(20),
16#B4# => c_xam0(19),
16#B5# => c_xam0(18),
16#B6# => c_xam0(17),
16#B7# => c_xam0(16),
16#B8# => c_xam0(15),
16#B9# => c_xam0(14),
16#BA# => c_xam0(13),
16#BB# => c_xam0(12),
16#BC# => c_xam0(11),
16#BD# => c_xam0(10),
16#BE# => c_xam0(9),
16#BF# => c_xam0(8),
16#C0# => c_xam0(7),
16#C1# => c_xam0(6),
16#C2# => c_xam0(5),
16#C3# => c_xam0(4),
16#C4# => c_xam0(3),
16#C5# => c_xam0(2),
16#C6# => c_xam0(1),
16#C7# => c_xam0(0),
16#C8# => c_xam0(31), -- Fun 2 XAMCAP MSB
16#C9# => c_xam0(30),
16#CA# => c_xam0(29),
16#CB# => c_xam0(28),
16#CC# => c_xam0(27),
16#CD# => c_xam0(26),
16#CE# => c_xam0(25),
16#CF# => c_xam0(24),
16#D0# => c_xam0(23),
16#D1# => c_xam0(22),
16#D2# => c_xam0(21),
16#D3# => c_xam0(20),
16#D4# => c_xam0(19),
16#D5# => c_xam0(18),
16#D6# => c_xam0(17),
16#D7# => c_xam0(16),
16#D8# => c_xam0(15),
16#D9# => c_xam0(14),
16#DA# => c_xam0(13),
16#DB# => c_xam0(12),
16#DC# => c_xam0(11),
16#DD# => c_xam0(10),
16#DE# => c_xam0(9),
16#DF# => c_xam0(8),
16#E0# => c_xam0(7),
16#E1# => c_xam0(6),
16#E2# => c_xam0(5),
16#E3# => c_xam0(4),
16#E4# => c_xam0(3),
16#E5# => c_xam0(2),
16#E6# => c_xam0(1),
16#E7# => c_xam0(0),
16#E8# => c_xam0(31), -- Fun 3 XAMCAP MSB
16#E9# => c_xam0(30),
16#EA# => c_xam0(29),
16#EB# => c_xam0(28),
16#EC# => c_xam0(27),
16#ED# => c_xam0(26),
16#EE# => c_xam0(25),
16#EF# => c_xam0(24),
16#F0# => c_xam0(23),
16#F1# => c_xam0(22),
16#F2# => c_xam0(21),
16#F3# => c_xam0(20),
16#F4# => c_xam0(19),
16#F5# => c_xam0(18),
16#F6# => c_xam0(17),
16#F7# => c_xam0(16),
16#F8# => c_xam0(15),
16#F9# => c_xam0(14),
16#FA# => c_xam0(13),
16#FB# => c_xam0(12),
16#FC# => c_xam0(11),
16#FD# => c_xam0(10),
16#FE# => c_xam0(9),
16#FF# => c_xam0(8),
16#100# => c_xam0(7),
16#101# => c_xam0(6),
16#102# => c_xam0(5),
16#103# => c_xam0(4),
16#104# => c_xam0(3),
16#105# => c_xam0(2),
16#106# => c_xam0(1),
16#107# => c_xam0(0),
16#108# => c_xam0(31), -- Fun 3_b XAMCAP MSB
16#109# => c_xam0(30),
16#10A# => c_xam0(29),
16#10B# => c_xam0(28),
16#10C# => c_xam0(27),
16#10D# => c_xam0(26),
16#10E# => c_xam0(25),
16#10F# => c_xam0(24),
16#110# => c_xam0(23),
16#111# => c_xam0(22),
16#112# => c_xam0(21),
16#113# => c_xam0(20),
16#114# => c_xam0(19),
16#115# => c_xam0(18),
16#116# => c_xam0(17),
16#117# => c_xam0(16),
16#118# => c_xam0(15),
16#119# => c_xam0(14),
16#11A# => c_xam0(13),
16#11B# => c_xam0(12),
16#11C# => c_xam0(11),
16#11D# => c_xam0(10),
16#11E# => c_xam0(9),
16#11F# => c_xam0(8),
16#120# => c_xam0(7),
16#121# => c_xam0(6),
16#122# => c_xam0(5),
16#123# => c_xam0(4),
16#124# => c_xam0(3),
16#125# => c_xam0(2),
16#126# => c_xam0(1),
16#127# => c_xam0(0),
16#128# => c_xam2(31), -- Fun 4 XAMCAP MSB
16#129# => c_xam2(30),
16#12A# => c_xam2(29),
16#12B# => c_xam2(28),
16#12C# => c_xam2(27),
16#12D# => c_xam2(26),
16#12E# => c_xam2(25),
16#12F# => c_xam2(24),
16#130# => c_xam2(23),
16#131# => c_xam2(22),
16#132# => c_xam2(21),
16#133# => c_xam2(20),
16#134# => c_xam2(19),
16#135# => c_xam2(18),
16#136# => c_xam2(17),
16#137# => c_xam2(16),
16#138# => c_xam2(15),
16#139# => c_xam2(14),
16#13A# => c_xam2(13),
16#13B# => c_xam2(12),
16#13C# => c_xam2(11),
16#13D# => c_xam2(10),
16#13E# => c_xam2(9),
16#13F# => c_xam2(8),
16#140# => c_xam2(7),
16#141# => c_xam2(6),
16#142# => c_xam2(5),
16#143# => c_xam2(4),
16#144# => c_xam2(3),
16#145# => c_xam2(2),
16#146# => c_xam2(1),
16#147# => c_xam2(0),
16#148# => c_xam0(31), -- Fun 4_b XAMCAP MSB
16#149# => c_xam0(30),
16#14A# => c_xam0(29),
16#14B# => c_xam0(28),
16#14C# => c_xam0(27),
16#14D# => c_xam0(26),
16#14E# => c_xam0(25),
16#14F# => c_xam0(24),
16#150# => c_xam0(23),
16#151# => c_xam0(22),
16#152# => c_xam0(21),
16#153# => c_xam0(20),
16#154# => c_xam0(19),
16#155# => c_xam0(18),
16#156# => c_xam0(17),
16#157# => c_xam0(16),
16#158# => c_xam0(15),
16#159# => c_xam0(14),
16#15A# => c_xam0(13),
16#15B# => c_xam0(12),
16#15C# => c_xam0(11),
16#15D# => c_xam0(10),
16#15E# => c_xam0(9),
16#15F# => c_xam0(8),
16#160# => c_xam0(7),
16#161# => c_xam0(6),
16#162# => c_xam0(5),
16#163# => c_xam0(4),
16#164# => c_xam0(3),
16#165# => c_xam0(2),
16#166# => c_xam0(1),
16#167# => c_xam0(0),
16#168# => c_xam0(31), -- Fun 5 XAMCAP MSB
16#169# => c_xam0(30),
16#16A# => c_xam0(29),
16#16B# => c_xam0(28),
16#16C# => c_xam0(27),
16#16D# => c_xam0(26),
16#16E# => c_xam0(25),
16#16F# => c_xam0(24),
16#170# => c_xam0(23),
16#171# => c_xam0(22),
16#172# => c_xam0(21),
16#173# => c_xam0(20),
16#174# => c_xam0(19),
16#175# => c_xam0(18),
16#176# => c_xam0(17),
16#177# => c_xam0(16),
16#178# => c_xam0(15),
16#179# => c_xam0(14),
16#17A# => c_xam0(13),
16#17B# => c_xam0(12),
16#17C# => c_xam0(11),
16#17D# => c_xam0(10),
16#17E# => c_xam0(9),
16#17F# => c_xam0(8),
16#180# => c_xam0(7),
16#181# => c_xam0(6),
16#182# => c_xam0(5),
16#183# => c_xam0(4),
16#184# => c_xam0(3),
16#185# => c_xam0(2),
16#186# => c_xam0(1),
16#187# => c_xam0(0),
--...
--16#C6# => x"00", -- Fun 0 XAMCAP LSB
--16#C7# => x"01", -- Fun 0 XAMCAP LSB
--......
-- Address Decoder Mask ADEM
16#188# => x"f0", -- Fun 0
16#189# => x"00", -- Fun 0
16#18A# => x"00", -- Fun 0
16#18B# => x"00", -- Fun 0 --DFS = '0'
16#18c# => x"00", -- Fun 1
16#18d# => x"f0", -- Fun 1
16#18e# => x"00", -- Fun 1
16#18f# => x"00", -- Fun 1 --DFS = '0'
16#190# => x"00", -- Fun 2
16#191# => x"00", -- Fun 2
16#192# => x"f0", -- Fun 2
16#193# => x"00", -- Fun 2 --DFS = '0'
16#194# => x"00", -- Fun 3
16#195# => x"00", -- Fun 3
16#196# => x"00", -- Fun 3
16#197# => x"01", -- Fun 3
16#198# => x"ff", -- Fun 4 (used for decoding FUNC3)
16#199# => x"00", -- Fun 4 (used for decoding FUNC3)
16#19a# => x"00", -- Fun 4 (used for decoding FUNC3)
16#19b# => x"00", -- Fun 4 (used for decoding FUNC3)
16#19c# => x"ff", -- Fun 5
16#19d# => x"00", -- Fun 5
16#19e# => x"00", -- Fun 5
16#19f# => x"01", -- Fun 5
16#1a0# => x"00", -- Fun 6
16#1a1# => x"00", -- Fun 6
16#1a2# => x"00", -- Fun 6
16#1a3# => x"00", -- Fun 6
others => (others => '0'));
end VME_CR_pack;
--________________________________________________________________________________________________
-- VME TO WB INTERFACE
--
-- CERN,BE/CO-HT
--________________________________________________________________________________________________
-- File: VME_CSR_pack.vhd
--________________________________________________________________________________________________
-- Description: This file defines the default configuration of the CSR space after power-up or
-- software reset.
--______________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 06/2012
-- Version v0.02
--______________________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your option)
-- any later version. This source is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
-- more details. You should have received a copy of the GNU Lesser General Public
-- License along with this source; if not, download it from
-- http://www.gnu.org/licenses/lgpl-2.1.html
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;
use work.vme64x_pack.all;
package VME_CSR_pack is
constant c_csr_array : t_CSRarray :=
(
BAR => x"00", --CR/CSR BAR
BIT_SET_CLR_REG => x"00", --Bit set register -- 0x10=module enable
USR_BIT_SET_CLR_REG => x"00", --Bit clear register
CRAM_OWNER => x"00", --CRAM_OWNER
FUNC0_ADER_0 =>x"00", --A32_S "24"
FUNC0_ADER_1 =>x"00", -- "00"
FUNC0_ADER_2 =>x"00", -- "00"
FUNC0_ADER_3 =>x"00", -- "c0"
FUNC1_ADER_0 =>x"00", --A24_S "e4"
FUNC1_ADER_1 =>x"00", -- "00"
FUNC1_ADER_2 =>x"00", -- "c0"
FUNC1_ADER_3 =>x"00", -- "00"
FUNC2_ADER_0 =>x"00", --A16_S "a4"
FUNC2_ADER_1 =>x"00", -- "c0"
FUNC2_ADER_2 =>x"00", -- "00"
FUNC2_ADER_3 =>x"00", -- "00"
FUNC3_ADER_0 =>x"00", --A64_S "04"
FUNC3_ADER_1 =>x"00",
FUNC3_ADER_2 =>x"00",
FUNC3_ADER_3 =>x"00",
FUNC4_ADER_0 =>x"00", --used for decoding the FUNC3
FUNC4_ADER_1 =>x"00", --used for decoding the FUNC3
FUNC4_ADER_2 =>x"00", --used for decoding the FUNC3
FUNC4_ADER_3 =>x"00", --used for decoding the FUNC3 "c0"
FUNC5_ADER_0 =>x"00",
FUNC5_ADER_1 =>x"00",
FUNC5_ADER_2 =>x"00",
FUNC5_ADER_3 =>x"00",
FUNC6_ADER_0 =>x"00",
FUNC6_ADER_1 =>x"00",
FUNC6_ADER_2 =>x"00",
FUNC6_ADER_3 =>x"00",
IRQ_Vector =>x"00", --"00" because each Slot has a different IRQ Vector
-- and the VME Master should set this value
IRQ_level =>x"02",
WB32bits =>x"01", -- 32 bit WB of default
others => (others => '0'));
end VME_CSR_pack;
--_________________________________________________________________________________________
-- VME TO WB INTERFACE
--
-- CERN,BE/CO-HT
--_________________________________________________________________________________________
-- File: VME_Funct_Match.vhd
--_________________________________________________________________________________________
-- Description: this component compares the Address with the ADER using the mask bits and
-- if the base address match it asserts the corresponding bit in the FunctMatch vector and it
-- latches the base address that will be subtracted to the Address before accessing the WB bus.
-- FunctMatch /= 0 is necessary but not sufficient to select one function and to access the board,
-- indeed also the AM has to be checked (VME_AM_Match.vhd component).
-- For better understanding how this component works here is one example:
-- base address = 0xc0
-- access mode: A32_S --> AM = 0x09
-- The Master writes the ADERi = 0xc0000024
-- ADEMi = 0xffffff04 --> DFS = '1' --> all the mask bits are '1'!!
-- The Master wants to access the location 0x08: Address= 0xc0000008
-- For i = 0 to 7 check:
-- Check if the ADEMi is compatible with the AM selected: ADEMi[31:8] /= 0
-- Address[31:8] and ADEMi[31:8] ADERi[31:8] and ADEMi[31:8]
-- | |
-- 0xc00000 0xc00000
-- | _______ |
-- |________________| = ? |_______________|
-- |_______|
-- No | |yes
-- FunctMatch(i) <= '0'_____| |______FunctMatch(i) <= '1'
-- Now with the same ADEMi the master accesses with A16 mode:
-- base address = 0xc0
-- access mode: A16_S --> AM = 0x29
-- The Master writes the ADERi = 0x0000c0a4
-- The Master wants to access the location 0x08: Address= 0x0000c008
-- For i = 0 to 7 check:
-- Check if the ADEMi is compatible with the AM selected: ADEMi[15:8] /= 0
-- Address[31:8] and ADEMi[31:8] ADERi[31:8] and ADEMi[31:8]
-- | |
-- 0x0000c0 0x0000c0
-- | _______ |
-- |________________| = ? |_______________|
-- |_______|
-- No | |yes
-- FunctMatch(i) <= '0'_____| |______FunctMatch(i) <= '1'
--
-- DFS = '1' --> 1 function --> multiple access modes
-- The Master accesses with different modes only changing the ADER registers if the
-- DFS bit is asserted but:
-- It is easy to see that if DFS = '1' we can only address 256 bytes, indeed eg:
-- base address = 0xc0
-- access mode: A32_S --> AM = 0x09
-- The Master write the ADERi = 0xc0000024
-- The Master wants to access the location 0x4008: Address= 0xc0004008
-- For i = 0 to 7 check:
-- Check if the ADEMi is compatible with the AM selected: ADEMi[31:8] /= 0
-- Address[31:8] and ADEMi[31:8] ADERi[31:8] and ADEMi[31:8]
-- | |
-- 0xc00040 0xc00000
-- | _______ |
-- |________________| = ? |_______________|
-- |_______|
-- No | |yes
-- FunctMatch(i) <= '0'_____| |______FunctMatch(i) <= '1'
-- The Master can't access!!
-- Without DFS asserted:
-- base address = 0xc0
-- access mode: A32_S --> AM = 0x09
-- The Master write the ADERi = 0xc0000024
-- ADEMi = 0xff000000 --> DFS = '0'
-- The Master wants to access the location 0x4008: Address= 0xc0004008
-- For i = 0 to 7 check:
-- Check if the ADEMi is compatible with the AM selected: ADEM[31:8] /= 0
-- Address[31:8] and ADEMi[31:8] ADERi[31:8] and ADEMi[31:8]
-- | |
-- 0xc00000 0xc00000
-- | _______ |
-- |________________| = ? |_______________|
-- |_______|
-- No | |yes
-- FunctMatch(i) <= '0'_____| |______FunctMatch(i) <= '1'
-- The Master can access!
-- base address = 0xc0
-- access mode: A16_S --> AM = 0x29
-- The Master writes the ADERi = 0x0000c0a4
-- ADEMi = 0xff000000 --> DFS = '0' -- The Master can't change the CR space!!
-- The Master wants to access the location 0x08: Address= 0x0000c008
-- For i = 0 to 7 check:
-- Check if the ADEMi is compatible with the AM selected:
-- ADEM[15:8] = 0 --> FunctMatch(i) <= '0'
-- The Master can't access! this mask is not compatible with A16
--
-- DFS = '0' --> 1 function --> only the access modes with the same
-- address width !!
-- Is it possible initialize all the ADER to 0 ?
-- Yes, it is. Indeed now suppose that we are in this situation:
-- ADERi = 0x00000000
-- ADEMi = 0x0000ff00 --> DFS = '0'
-- A VME Master takes the ownership of the VMEbus for accessing another board:
-- base address = 0xc0
-- access mode: A32_S --> AM = 0x09
-- The Master wants to access the location 0x0008: Address= 0xc0000008
-- For i = 0 to 7 check:
-- Check if the ADEMi is compatible with the AM selected: ADEMi[31:8] /= 0
-- Address[31:8] and ADEMi[31:8] ADERi[31:8] and ADEMi[31:8]
-- | |
-- 0x000000 0x000000
-- | _______ |
-- |________________| = ? |_______________|
-- |_______|
-- No | |yes
-- FunctMatch(i) <= '0'_____| |______FunctMatch(i) <= '1'
-- FunctMatch(i) is asserted but our Slave will not be the responding Slave, indeed
-- the AmMatch(i) is zero becouse the Master is accessing with A32_S and if DFS is 0
-- the AMCAPi register has only the A16 or A16_SUP bits asserted!
-- If DFS is '1' AmMatch(i) is zero becouse ADER[7:2] is 0 (see VME_Am_Match.vhd) and
-- also FunctMatch(i) is 0 because ADEMi should has all the mask bits '1'.
--
-- An example about A64 access mode:
-- base address = 0xc0
-- access mode: A64_S --> AM = 0x01
-- ADEM(i) = 0x00000001 --> EFM = '1' and DFS = '0'
-- ADEM(i+1) = 0xff000000
-- ADEM64(i) = ADEM(i+1) & ADEM(i)
-- AMCAP(i) = "0000000000000000000000000000000000000000000000000000000000000010";
-- AMCAP(i+1) <= (others => '0')
-- ADER(i) = 0x00000004
-- ADER(i+1) = 0xc0000000
-- ADER64(i) = ADER(i+1) & ADER(i)
-- s_isprev_func64(i+1) --> '1' --> don't check if the function i + 1 is selected
-- because the next ADER and ADEM are used to decode the function i.
-- 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]
-- | |
-- 0xc0000000000000 0xc0000000000000
-- | _______ |
-- |________________| = ? |_______________|
-- |_______|
-- No | |yes
-- FunctMatch(i) <= '0'_____| |______FunctMatch(i) <= '1'
--
-- For the 2e modes it is the same, it changes only the ADER(i)'s XAM bit that must
-- be '1'.
--______________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--______________________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your option)
-- any later version. This source is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
-- more details. You should have received a copy of the GNU Lesser General Public
-- License along with this source; if not, download it from
-- http://www.gnu.org/licenses/lgpl-2.1.html
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.vme64x_pack.all;
--===========================================================================
-- Entity declaration
--===========================================================================
entity VME_Funct_Match is
Port ( clk_i : 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);
Ader1 : in std_logic_vector(31 downto 0);
Ader2 : in std_logic_vector(31 downto 0);
Ader3 : in std_logic_vector(31 downto 0);
Ader4 : in std_logic_vector(31 downto 0);
Ader5 : in std_logic_vector(31 downto 0);
Ader6 : in std_logic_vector(31 downto 0);
Ader7 : in std_logic_vector(31 downto 0);
Adem0 : in std_logic_vector(31 downto 0);
Adem1 : in std_logic_vector(31 downto 0);
Adem2 : in std_logic_vector(31 downto 0);
Adem3 : in std_logic_vector(31 downto 0);
Adem4 : in std_logic_vector(31 downto 0);
Adem5 : in std_logic_vector(31 downto 0);
Adem6 : in std_logic_vector(31 downto 0);
Adem7 : in std_logic_vector(31 downto 0);
FunctMatch : out std_logic_vector(7 downto 0);
DFS_o : out std_logic_vector(7 downto 0);
Nx_Base_Addr : out std_logic_vector(63 downto 0)
);
end VME_Funct_Match;
--===========================================================================
-- Architecture declaration
--===========================================================================
architecture Behavioral of VME_Funct_Match is
signal s_FUNC_ADER, s_FUNC_ADEM : t_FUNC_32b_array;
signal s_FUNC_ADER_64, s_FUNC_ADEM_64: t_FUNC_64b_array;
signal s_isprev_func64 : std_logic_vector(7 downto 0);
signal s_locAddr : unsigned(63 downto 0);
--===========================================================================
-- Architecture begin
--===========================================================================
begin
s_locAddr <= unsigned(Addr);
p_functMatch : process(clk_i)
begin
if rising_edge(clk_i) then
if mainFSMreset = '1' or reset = '1' then
FunctMatch <= (others => '0');
Nx_Base_Addr <= (others => '0');
elsif decode = '1' then
for i in FunctMatch'range loop
case AddrWidth is
when "11" =>
if (s_FUNC_ADEM(i)(0) = '1') and (s_isprev_func64(i) = '0') and
(s_FUNC_ADEM_64(i)(63 downto 10) /= 0) then
if (s_FUNC_ADER_64(i)(63 downto 10) and s_FUNC_ADEM_64(i)(63 downto 10)) =
((s_locAddr(63 downto 10)) and s_FUNC_ADEM_64(i)(63 downto 10)) then
FunctMatch(i) <= '1';
Nx_Base_Addr(63 downto 10) <= std_logic_vector(s_FUNC_ADER_64(i)(63 downto 10));
Nx_Base_Addr(9 downto 0) <= (others => '0');
end if;
end if;
when "10" =>
if (s_FUNC_ADEM(i)(31 downto 8) /=0) and (s_isprev_func64(i) = '0') then
if (s_FUNC_ADER(i)(31 downto 8) and s_FUNC_ADEM(i)(31 downto 8)) =
((s_locAddr(31 downto 8)) and s_FUNC_ADEM(i)(31 downto 8)) then
FunctMatch(i) <= '1';
Nx_Base_Addr(31 downto 8) <= std_logic_vector(s_FUNC_ADER(i)(31 downto 8));
Nx_Base_Addr(63 downto 32) <= (others => '0');
Nx_Base_Addr(7 downto 0) <= (others => '0');
end if;
end if;
when "01" =>
if (s_FUNC_ADEM(i)(23 downto 8) /=0) and (s_isprev_func64(i) = '0') then
if (s_FUNC_ADER(i)(23 downto 8) and s_FUNC_ADEM(i)(23 downto 8)) =
((s_locAddr(23 downto 8)) and s_FUNC_ADEM(i)(23 downto 8)) then
FunctMatch(i) <= '1';
Nx_Base_Addr(23 downto 8) <= std_logic_vector(s_FUNC_ADER(i)(23 downto 8));
Nx_Base_Addr(63 downto 24) <= (others => '0');
Nx_Base_Addr(7 downto 0) <= (others => '0');
end if;
end if;
when "00" =>
if (s_FUNC_ADEM(i)(15 downto 8) /=0) and (s_isprev_func64(i) = '0') then
if (s_FUNC_ADER(i)(15 downto 8) and s_FUNC_ADEM(i)(15 downto 8)) =
((s_locAddr(15 downto 8)) and s_FUNC_ADEM(i)(15 downto 8)) then
FunctMatch(i) <= '1';
Nx_Base_Addr(15 downto 8) <= std_logic_vector(s_FUNC_ADER(i)(15 downto 8));
Nx_Base_Addr(63 downto 16) <= (others => '0');
Nx_Base_Addr(7 downto 0) <= (others => '0');
end if;
end if;
when others =>
end case;
end loop;
end if;
end if;
end process;
------------------------------------------------------
s_FUNC_ADER(0) <= unsigned(Ader0);
s_FUNC_ADER(1) <= unsigned(Ader1);
s_FUNC_ADER(2) <= unsigned(Ader2);
s_FUNC_ADER(3) <= unsigned(Ader3);
s_FUNC_ADER(4) <= unsigned(Ader4);
s_FUNC_ADER(5) <= unsigned(Ader5);
s_FUNC_ADER(6) <= unsigned(Ader6);
s_FUNC_ADER(7) <= unsigned(Ader7);
s_FUNC_ADEM(0) <= unsigned(Adem0);
s_FUNC_ADEM(1) <= unsigned(Adem1);
s_FUNC_ADEM(2) <= unsigned(Adem2);
s_FUNC_ADEM(3) <= unsigned(Adem3);
s_FUNC_ADEM(4) <= unsigned(Adem4);
s_FUNC_ADEM(5) <= unsigned(Adem5);
s_FUNC_ADEM(6) <= unsigned(Adem6);
s_FUNC_ADEM(7) <= unsigned(Adem7);
GDFS : for i in 0 to 7 generate
DFS_o(i) <= s_FUNC_ADEM(i)(DFS);
end generate GDFS;
GADER_64 : for i in 0 to 6 generate
s_FUNC_ADER_64(i) <= s_FUNC_ADER(i+1)&s_FUNC_ADER(i);
end generate GADER_64;
s_FUNC_ADER_64(7) <= (others => '0');
GADEM_64 : for i in 0 to 6 generate
s_FUNC_ADEM_64(i) <= s_FUNC_ADEM(i+1)&s_FUNC_ADEM(i);
s_isprev_func64(i+1) <= s_FUNC_ADEM(i)(0);
end generate GADEM_64;
s_isprev_func64(0) <= '0';
s_FUNC_ADEM_64(7) <= (others => '0');
end Behavioral;
--===========================================================================
-- Architecture end
--===========================================================================
--_________________________________________________________________________________________
-- VME TO WB INTERFACE
--
-- CERN,BE/CO-HT
--_________________________________________________________________________________________
-- File: VME_IRQ_Controller.vhd
--_________________________________________________________________________________________
-- Description:
-- This block acts as Interrupter. Phases of an interrupt cycle:
-- 1) The Interrupt Controller receives an interrupt request by the WB bus;
-- this request is a pulse on the INT_Req input
-- 2) The Interrupt Controller asserts ('0') one of the 7 VME_IRQ lines; --> request of a service.
-- The Interrupt priority is specificated by the Master writing the INT_Level register
-- in the CR/CSR space
-- 3) The Interrupter Controller wait for the falling edge on the VME_IACKIN line.
-- 4) When detects VME_IACKIN_n_i = '0' and the Interrupt Handler initiates the Interrupt
-- cycle by asserting AS,the Interrupt Controller check if it is the responding interrupter.
-- Indeed before responding to an interrupt acknowledge cycle the interrupter shall have
-- an interrupt request pending, shall check if the level of that request match the level
-- indicated on the address lines A1, A2 and A3,the data transfer width during the interrupt
-- acknowledge cycle should be equal or greater than the size the it can respond with, and
-- it shall receive a falling edge on its IACKIN*.
-- 5) If it is the responding interrupter should send the source/ID on the VME_DATA lines
-- (in our case the source/ID is the INT_Vector that the Master can write in the corresponding
-- register in the CR/CSR space) and it terminates the interrupt cycle with an acknowledge before
-- releasing the IRQ lines. If it isn't the responding interrupter, it should pass a falling edge on
-- down the daisy-chain so other interrupters can respond.
--
-- All the output signals are registered
-- To implement the 5 phases before mentioned the follow FSM has been implemented:
-- __________
-- |--| IACKOUT2 |<-|
-- | |__________| |
-- | |
-- | _________ | _________ _________ _________
-- |-->| IDLE |--->| IRQ |-->| WAIT_AS |-->| WAIT_DS |---------------->|
-- |_________| |_________| |_________| |_________| |
-- | | |
-- | | _________ _________ |
-- | |---------<------------| IACKOUT1| <--| CHECK |<----|
-- | |_________| |_________|
-- | __________ __________ |
-- |--<-----------------| DTACK |<--| DATA_OUT |---<----|
-- |__________| |__________|
--
-- The interrupter wait the IACKIN falling edge in the IRQ state, so if the interrupter
-- don't have interrupt pending for sure it will not respond because it is in IDLE.
-- If the slave module does not have an interrupt pending (IDLE state) and it receives
-- a falling edge on the IACKIN, it shall pass the falling edge through the daisy chain.
-- To obtain this the IACKOUT2 state has been added.
-- Time constraint:
--
-- Time constraint n° 35:
-- Clk _____ _____ _____ _____ _____ _____
-- _____| |_____| |_____| |_____| |_____| |_____| |_____
-- VME_AS1_n_i ____________________________________________________________________
-- ________|
-- VME_AS_n_i ___________________________________
-- _________________________________________|
-- s_AS_RisingEdge ___________
-- _____________________________________________________| |___________
-- s_IACKOUT ____________________________________________________________________
-- ________|
-- VME_IACKOUT_o ____________________________________________________________________
-- ________|
--
-- _________________________________________________________________ __________
-- IACKOUT 1/2 \/ IDLE/IRQ
-- -----------------------------------------------------------------/\----------
--
-- To respect the time constraint indicated with the number 35 fig. 55 pag. 183 in the
-- "VMEbus Specification" ANSI/IEEE STD1014-1987, is necessary to generate the VME_AS1_n_i
-- signal which is the AS signal not sampled, and assign this signal to the s_IACKOUT
-- signal when the fsm is in the IACKOUTx state.
--
-- The LWORD* input is not used now, since this is a D08(O) Interrupter (see Table 31
-- page 157 VMEbus specification).
-- Since this is a D08 interrupter we do not need to monitor the LWORD* and DS1* lines
-- and the Vector (1 byte) is outputted in the D00-D07 data lines.
--____________________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--_____________________________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your option)
-- any later version. This source is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
-- more details. You should have received a copy of the GNU Lesser General Public
-- License along with this source; if not, download it from
-- http://www.gnu.org/licenses/lgpl-2.1.html
---------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
use work.vme64x_pack.all;
--===========================================================================
-- Entity declaration
--===========================================================================
entity VME_IRQ_Controller is
Port ( clk_i : in std_logic;
reset_n_i : in std_logic;
VME_IACKIN_n_i : in std_logic;
VME_AS_n_i : in std_logic;
VME_AS1_n_i : in std_logic; -- this is the AS* not triple sampled
VME_DS_n_i : in std_logic_vector (1 downto 0);
VME_LWORD_n_i : in std_logic;
VME_ADDR_123_i : in std_logic_vector (2 downto 0);
INT_Level_i : in std_logic_vector (7 downto 0);
INT_Vector_i : in std_logic_vector (7 downto 0);
INT_Req_i : in std_logic;
VME_IRQ_n_o : out std_logic_vector (6 downto 0);
VME_IACKOUT_n_o : out std_logic;
VME_DTACK_n_o : out std_logic;
VME_DTACK_OE_o : out std_logic;
VME_DATA_o : out std_logic_vector (31 downto 0);
VME_DATA_DIR_o : out std_logic);
end VME_IRQ_Controller;
--===========================================================================
-- Architecture declaration
--===========================================================================
architecture Behavioral of VME_IRQ_Controller is
--input signals
signal s_INT_Req_sample : std_logic;
--output signals
signal s_DTACK_OE_o : std_logic;
signal s_enable : std_logic;
signal s_IRQ : std_logic_vector(6 downto 0);
signal s_Data : std_logic_vector(31 downto 0);
--
signal s_AS_FallingEdge : std_logic;
signal s_AS_RisingEdge : std_logic;
type t_MainFSM is (IDLE, IRQ, WAIT_AS, WAIT_DS, LATCH_DS, CHECK, DATA_OUT, DTACK,IACKOUT1,IACKOUT2);
signal s_currs, s_nexts : t_MainFSM;
signal s_ack_int : std_logic;
signal s_VME_ADDR_123_latched : std_logic_vector(2 downto 0);
signal s_VME_DS_latched : std_logic_vector(1 downto 0);
signal s_ADDRmatch : std_logic;
signal s_FSM_IRQ : t_FSM_IRQ;
--===========================================================================
-- Architecture begin
--===========================================================================
begin
-- Input sampling and edge detection
ASrisingEdge : RisEdgeDetection
port map (
sig_i => VME_AS_n_i,
clk_i => clk_i,
RisEdge_o => s_AS_RisingEdge
);
ASfallingEdge : FallingEdgeDetection
port map (
sig_i => VME_AS_n_i,
clk_i => clk_i,
FallEdge_o => s_AS_FallingEdge
);
INT_ReqinputSample : process(clk_i)
begin
if rising_edge(clk_i) then
if s_enable = '1' then
s_INT_Req_sample <= INT_Req_i;
end if;
end if;
end process;
--Output registers:
DTACKOutputSample : process(clk_i)
begin
if rising_edge(clk_i) then
VME_DTACK_n_o <= s_FSM_IRQ.s_DTACK;
end if;
end process;
DataDirOutputSample : process(clk_i)
begin
if rising_edge(clk_i) then
VME_DATA_DIR_o <= s_FSM_IRQ.s_DataDir;
end if;
end process;
DTACKOEOutputSample : process(clk_i)
begin
if rising_edge(clk_i) then
s_DTACK_OE_o <= s_FSM_IRQ.s_DTACK_OE;
end if;
end process;
process(clk_i)
begin
if rising_edge(clk_i) then
if s_FSM_IRQ.s_resetIRQ = '1' then
VME_IRQ_n_o <= (others => '1');
elsif s_FSM_IRQ.s_enableIRQ = '1' then
VME_IRQ_n_o <= s_IRQ;
end if;
end if;
end process;
process(clk_i)
begin
if rising_edge(clk_i) then
VME_DATA_o <= s_Data;
end if;
end process;
-- Update current state
process(clk_i)
begin
if rising_edge(clk_i) then
if reset_n_i = '0' then
s_currs <= IDLE;
else
s_currs <= s_nexts;
end if;
end if;
end process;
-- Update next state
process(s_currs,s_INT_Req_sample,VME_AS_n_i,VME_DS_n_i,s_ack_int,VME_IACKIN_n_i,s_AS_RisingEdge)
begin
case s_currs is
when IDLE =>
if s_INT_Req_sample = '1' and VME_IACKIN_n_i = '1' then
s_nexts <= IRQ;
elsif VME_IACKIN_n_i = '0' then
s_nexts <= IACKOUT2;
else
s_nexts <= IDLE;
end if;
when IRQ =>
if VME_IACKIN_n_i = '0' then -- Each Interrupter who is driving an interrupt request line
-- low waits for a falling edge on IACKIN input -->
-- the IRQ_Controller have to detect a falling edge on the IACKIN.
s_nexts <= WAIT_AS;
else
s_nexts <= IRQ;
end if;
when WAIT_AS =>
if VME_AS_n_i = '0' then -- NOT USE FALLING EDGE HERE!
s_nexts <= WAIT_DS;
else
s_nexts <= WAIT_AS;
end if;
when WAIT_DS =>
if VME_DS_n_i /= "11" then
s_nexts <= CHECK;
else
s_nexts <= WAIT_DS;
end if;
-- when LATCH_DS => -- this state is necessary only for D16 ans D32 Interrupters
-- s_nexts <= CHECK;
-- If the interrupter is D16 or D32 add a generic number of LATCH_DS state like in the VME_bus component.
when CHECK =>
if s_ack_int = '1' then
s_nexts <= DATA_OUT; -- The Interrupter send the INT_Vector
else
s_nexts <= IACKOUT1; -- the Interrupter must pass a falling edge on the IACKOUT output
end if;
when IACKOUT1 =>
if s_AS_RisingEdge = '1' then
s_nexts <= IRQ;
else
s_nexts <= IACKOUT1;
end if;
when DATA_OUT=>
s_nexts <= DTACK;
when IACKOUT2 =>
if s_AS_RisingEdge = '1' then
s_nexts <= IDLE;
else
s_nexts <= IACKOUT2;
end if;
when DTACK=>
if s_AS_RisingEdge = '1' then
s_nexts <= IDLE;
else
s_nexts <= DTACK;
end if;
when others => null;
end case;
end process;
-- Update Outputs
-- Mealy FSM
process(s_currs,VME_AS1_n_i)
begin
s_FSM_IRQ <= c_FSM_IRQ;
case s_currs is
when IDLE =>
s_FSM_IRQ <= c_FSM_IRQ;
when IRQ =>
s_FSM_IRQ <= c_FSM_IRQ;
s_FSM_IRQ.s_enableIRQ <= '1';
s_FSM_IRQ.s_resetIRQ <= '0';
when WAIT_AS =>
s_FSM_IRQ <= c_FSM_IRQ;
s_FSM_IRQ.s_resetIRQ <= '0';
when WAIT_DS =>
s_FSM_IRQ <= c_FSM_IRQ;
s_FSM_IRQ.s_resetIRQ <= '0';
-- when LATCH_DS =>
-- s_IACKOUT <= '1';
-- s_DataDir <= '0';
-- s_DTACK <= '1';
-- s_enableIRQ <= '0';
-- s_resetIRQ <= '0';
-- s_DSlatch <= '1';
-- s_DTACK_OE <= '0';
when CHECK =>
s_FSM_IRQ <= c_FSM_IRQ;
s_FSM_IRQ.s_resetIRQ <= '0';
when IACKOUT1 =>
s_FSM_IRQ <= c_FSM_IRQ;
s_FSM_IRQ.s_resetIRQ <= '0';
s_FSM_IRQ.s_IACKOUT <= VME_AS1_n_i;
when IACKOUT2 =>
s_FSM_IRQ <= c_FSM_IRQ;
s_FSM_IRQ.s_resetIRQ <= '0';
s_FSM_IRQ.s_IACKOUT <= VME_AS1_n_i;
when DATA_OUT=>
s_FSM_IRQ <= c_FSM_IRQ;
s_FSM_IRQ.s_DataDir <= '1';
s_FSM_IRQ.s_resetIRQ <= '0';
s_FSM_IRQ.s_DTACK_OE <= '1';
when DTACK=>
s_FSM_IRQ <= c_FSM_IRQ;
s_FSM_IRQ.s_DataDir <= '1';
s_FSM_IRQ.s_DTACK <= '0';
s_FSM_IRQ.s_DTACK_OE <= '1';
when others => null;
end case;
end process;
-- This process provides the IRQ vector
process(INT_Level_i)
begin
case (INT_Level_i) is
when "00000001" => s_IRQ <= "1111110";
when "00000010" => s_IRQ <= "1111101";
when "00000011" => s_IRQ <= "1111011";
when "00000100" => s_IRQ <= "1110111";
when "00000101" => s_IRQ <= "1101111";
when "00000110" => s_IRQ <= "1011111";
when "00000111" => s_IRQ <= "0111111";
when others => s_IRQ <= "1111111";
end case;
end process;
-- This process sampling the address lines on AS falling edge
process(clk_i)
begin
if rising_edge(clk_i) then
if reset_n_i = '0' then
s_VME_ADDR_123_latched <= (others => '0');
elsif s_AS_FallingEdge = '1' then
s_VME_ADDR_123_latched <= VME_ADDR_123_i;
end if;
end if;
end process;
-- Data strobo latch
process(clk_i)
begin
if rising_edge(clk_i) then
if reset_n_i = '0' then
s_VME_DS_latched <= (others => '0');
elsif s_FSM_IRQ.s_DSlatch = '1' then
s_VME_DS_latched <= VME_DS_n_i;
end if;
end if;
end process;
--This process check the A01 A02 A03:
process(clk_i)
begin
if rising_edge(clk_i) then
if reset_n_i = '0' then
s_ADDRmatch <= '0';
elsif unsigned(INT_Level_i) = unsigned(s_VME_ADDR_123_latched) then
s_ADDRmatch <= '1';
else
s_ADDRmatch <= '0';
end if;
end if;
end process;
s_ack_int <= s_ADDRmatch; --D08 Interrupter
-- s_ack_int <= (not(s_VME_DS_latched(1))) and s_ADDRmatch and (not(VME_LWORD_n_i))
-- for a D32 Interrupter
s_Data <= x"000000" & INT_Vector_i;
s_enable <= (not s_INT_Req_sample) or ((not s_FSM_IRQ.s_DTACK) and (s_AS_RisingEdge));
-- the INT_Vector is in the D0:D7 lines (byte3 in big endian order)
VME_DTACK_OE_o <= s_DTACK_OE_o;
VME_IACKOUT_n_o <= s_FSM_IRQ.s_IACKOUT;
end Behavioral;
--===========================================================================
-- Architecture end
--===========================================================================
--_______________________________________________________________________________________
-- VME TO WB INTERFACE
--
-- CERN,BE/CO-HT
--________________________________________________________________________________________
-- File: VME_Init.vhd
--________________________________________________________________________________________
-- Description: Read important CR data (like FUNC_ADEMs etc.) and store it locally
-- This important CR data will be used in the decoder.
--________________________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--________________________________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your option)
-- any later version. This source is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
-- more details. You should have received a copy of the GNU Lesser General Public
-- License along with this source; if not, download it from
-- http://www.gnu.org/licenses/lgpl-2.1.html
------------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.vme64x_pack.all;
--===========================================================================
-- Entity declaration
--===========================================================================
entity VME_Init is
Port ( clk_i : in std_logic;
RSTedge_i : in std_logic;
CRAddr_i : in std_logic_vector (18 downto 0);
CRdata_i : in std_logic_vector (7 downto 0);
InitReadCount_o : out std_logic_vector (8 downto 0);
InitInProgress_o : out std_logic;
BEG_USR_CR_o : out std_logic_vector (23 downto 0);
END_USR_CR_o : out std_logic_vector (23 downto 0);
BEG_USR_CSR_o : out std_logic_vector (23 downto 0);
END_USR_CSR_o : out std_logic_vector (23 downto 0);
BEG_CRAM_o : out std_logic_vector (23 downto 0);
END_CRAM_o : out std_logic_vector (23 downto 0);
FUNC0_ADEM_o : out std_logic_vector (31 downto 0);
FUNC1_ADEM_o : out std_logic_vector (31 downto 0);
FUNC2_ADEM_o : out std_logic_vector (31 downto 0);
FUNC3_ADEM_o : out std_logic_vector (31 downto 0);
FUNC4_ADEM_o : out std_logic_vector (31 downto 0);
FUNC5_ADEM_o : out std_logic_vector (31 downto 0);
FUNC6_ADEM_o : out std_logic_vector (31 downto 0);
FUNC7_ADEM_o : out std_logic_vector (31 downto 0);
FUNC0_AMCAP_o : out std_logic_vector (63 downto 0);
FUNC1_AMCAP_o : out std_logic_vector (63 downto 0);
FUNC2_AMCAP_o : out std_logic_vector (63 downto 0);
FUNC3_AMCAP_o : out std_logic_vector (63 downto 0);
FUNC4_AMCAP_o : out std_logic_vector (63 downto 0);
FUNC5_AMCAP_o : out std_logic_vector (63 downto 0);
FUNC6_AMCAP_o : out std_logic_vector (63 downto 0);
FUNC7_AMCAP_o : out std_logic_vector (63 downto 0);
FUNC0_XAMCAP_o : out std_logic_vector (255 downto 0);
FUNC1_XAMCAP_o : out std_logic_vector (255 downto 0);
FUNC2_XAMCAP_o : out std_logic_vector (255 downto 0);
FUNC3_XAMCAP_o : out std_logic_vector (255 downto 0);
FUNC4_XAMCAP_o : out std_logic_vector (255 downto 0);
FUNC5_XAMCAP_o : out std_logic_vector (255 downto 0);
FUNC6_XAMCAP_o : out std_logic_vector (255 downto 0);
FUNC7_XAMCAP_o : out std_logic_vector (255 downto 0));
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
signal s_initInProgress : std_logic;
signal s_CRadd_offset : unsigned(18 downto 0);
signal s_CRaddr_base : unsigned(18 downto 0);
signal s_CRaddr : unsigned(18 downto 0);
signal s_latchCRdataPos : std_logic_vector(BEG_USER_CR to FUNC_ADEM);
-- CR image registers
signal s_FUNC_ADEM : t_FUNC_32b_array;
signal s_FUNC_AMCAP : t_FUNC_64b_array;
signal s_FUNC_XAMCAP : t_FUNC_256b_array;
signal s_BEG_USER_CSR : unsigned(23 downto 0);
signal s_END_USER_CSR : unsigned(23 downto 0);
signal s_BEG_USER_CR : unsigned(23 downto 0);
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_o <= std_logic_vector(s_initReadCounter);
s_CRaddr <= unsigned(CRAddr_i);
p_coreInit : process(clk_i)
begin
if rising_edge(clk_i) then
if RSTedge_i = '1' then
s_initState <= IDLE;
s_initReadCounter <= to_unsigned(0, s_initReadCounter'length);
s_latchCRdata <= '0';
else
case s_initState is
when IDLE =>
s_initReadCounter <= to_unsigned(0, s_initReadCounter'length);
s_latchCRdata <= '0';
s_initState <= SET_ADDR;
when SET_ADDR =>
s_initReadCounter <= s_initReadCounter+1;
s_latchCRdata <= '0';
s_initState <= GET_DATA;
when GET_DATA =>
s_initReadCounter <= s_initReadCounter;
s_latchCRdata <= '1';
if s_initInProgress = '1' then
s_initState <= SET_ADDR;
else
s_initState <= END_INIT;
end if;
when END_INIT => -- will wait in this state until reset
s_initReadCounter <= s_initReadCounter;
s_latchCRdata <= '0';
s_initState <= END_INIT;
when others =>
s_initState <= IDLE;
s_initReadCounter <= to_unsigned(0, s_initReadCounter'length);
s_latchCRdata <= '0';
end case;
end if;
end if;
end process;
s_initInProgress <= '1' when (s_initReadCounter <= (424)) else '0';
InitInProgress_o <= s_initInProgress;
s_CRadd_offset <= s_CRaddr - s_CRaddr_base;
process(s_latchCRdata, s_initReadCounter)
begin
s_latchCRdataPos <= (others => '0');
s_CRaddr_base <= (others => '0');
for I in c_CRinitAddr'range loop
if (s_initReadCounter >= c_CRinitAddr(I).add) and
(s_initReadCounter <= (c_CRinitAddr(I).add+(c_CRinitAddr(I).len-1))) then
s_CRaddr_base <= to_unsigned(c_CRinitAddr(I).add, s_CRaddr_base'length);
s_latchCRdataPos(I) <= s_latchCRdata;
exit;
end if;
end loop;
end process;
process(clk_i)
begin
if rising_edge(clk_i) then
for I in 0 to 2 loop
if (s_latchCRdataPos(BEG_USER_CR) = '1') and (unsigned(s_CRadd_offset) = I) then
s_BEG_USER_CR(((3-I)*8 - 1) downto (2-I)*8) <= unsigned(CRdata_i);
end if;
if s_latchCRdataPos(END_USER_CR) = '1' and (unsigned(s_CRadd_offset) = I) then
s_END_USER_CR(((3-I)*8 - 1) downto (2-I)*8) <= unsigned(CRdata_i);
end if;
if (s_latchCRdataPos(BEG_USER_CSR) = '1') and (unsigned(s_CRadd_offset) = I) then
s_BEG_USER_CSR(((3-I)*8 - 1) downto (2-I)*8) <= unsigned(CRdata_i);
end if;
if (s_latchCRdataPos(END_USER_CSR) = '1') and (unsigned(s_CRadd_offset) = I) then
s_END_USER_CSR(((3-I)*8 - 1) downto (2-I)*8) <= unsigned(CRdata_i);
end if;
if (s_latchCRdataPos(BEG_CRAM) = '1') and (unsigned(s_CRadd_offset) = I) then
s_BEG_CRAM(((3-I)*8 - 1) downto (2-I)*8) <= unsigned(CRdata_i);
end if;
if (s_latchCRdataPos(END_CRAM) = '1') and (unsigned(s_CRadd_offset) = I) then
s_END_CRAM(((3-I)*8 - 1) downto (2-I)*8) <= unsigned(CRdata_i);
end if;
end loop;
for I in 0 to 7 loop
if (s_latchCRdataPos(FUNC_AMCAP) = '1') and (unsigned(s_CRadd_offset(5 downto 3)) = I) then
for H in 0 to 7 loop
if (unsigned(s_CRadd_offset(2 downto 0)) = H) then
s_FUNC_AMCAP(I)(((8-h)*8 - 1) downto (7-h)*8) <= unsigned(CRdata_i);
end if;
end loop;
end if;
if (s_latchCRdataPos(FUNC_ADEM) = '1') and (unsigned(s_CRadd_offset(5 downto 2)) = I) then
for H in 0 to 3 loop
if (unsigned(s_CRadd_offset(1 downto 0)) = H) then
s_FUNC_ADEM(I)(((4-h)*8 - 1) downto (3-h)*8) <= unsigned(CRdata_i);
end if;
end loop;
end if;
if (s_latchCRdataPos(FUNC_XAMCAP) = '1') and (unsigned(s_CRadd_offset(7 downto 5)) = I) then
for H in 0 to 31 loop
if (unsigned(s_CRadd_offset(4 downto 0)) = H) then
s_FUNC_XAMCAP(I)(((32-h)*8 - 1) downto (31-h)*8) <= unsigned(CRdata_i);
end if;
end loop;
end if;
end loop;
end if;
end process;
BEG_USR_CR_o <= std_logic_vector(s_BEG_USER_CR);
END_USR_CR_o <= std_logic_vector(s_END_USER_CR);
BEG_USR_CSR_o <= std_logic_vector(s_BEG_USER_CSR);
END_USR_CSR_o <= std_logic_vector(s_END_USER_CSR);
BEG_CRAM_o <= std_logic_vector(s_BEG_CRAM);
END_CRAM_o <= std_logic_vector(s_END_CRAM);
FUNC0_ADEM_o <= std_logic_vector(s_FUNC_ADEM(0));
FUNC1_ADEM_o <= std_logic_vector(s_FUNC_ADEM(1));
FUNC2_ADEM_o <= std_logic_vector(s_FUNC_ADEM(2));
FUNC3_ADEM_o <= std_logic_vector(s_FUNC_ADEM(3));
FUNC4_ADEM_o <= std_logic_vector(s_FUNC_ADEM(4));
FUNC5_ADEM_o <= std_logic_vector(s_FUNC_ADEM(5));
FUNC6_ADEM_o <= std_logic_vector(s_FUNC_ADEM(6));
FUNC7_ADEM_o <= std_logic_vector(s_FUNC_ADEM(7));
FUNC0_AMCAP_o <= std_logic_vector(s_FUNC_AMCAP(0));
FUNC1_AMCAP_o <= std_logic_vector(s_FUNC_AMCAP(1));
FUNC2_AMCAP_o <= std_logic_vector(s_FUNC_AMCAP(2));
FUNC3_AMCAP_o <= std_logic_vector(s_FUNC_AMCAP(3));
FUNC4_AMCAP_o <= std_logic_vector(s_FUNC_AMCAP(4));
FUNC5_AMCAP_o <= std_logic_vector(s_FUNC_AMCAP(5));
FUNC6_AMCAP_o <= std_logic_vector(s_FUNC_AMCAP(6));
FUNC7_AMCAP_o <= std_logic_vector(s_FUNC_AMCAP(7));
FUNC0_XAMCAP_o <= std_logic_vector(s_FUNC_XAMCAP(0));
FUNC1_XAMCAP_o <= std_logic_vector(s_FUNC_XAMCAP(1));
FUNC2_XAMCAP_o <= std_logic_vector(s_FUNC_XAMCAP(2));
FUNC3_XAMCAP_o <= std_logic_vector(s_FUNC_XAMCAP(3));
FUNC4_XAMCAP_o <= std_logic_vector(s_FUNC_XAMCAP(4));
FUNC5_XAMCAP_o <= std_logic_vector(s_FUNC_XAMCAP(5));
FUNC6_XAMCAP_o <= std_logic_vector(s_FUNC_XAMCAP(6));
FUNC7_XAMCAP_o <= std_logic_vector(s_FUNC_XAMCAP(7));
end Behavioral;
--===========================================================================
-- Architecture end
--===========================================================================
--_______________________________________________________________________________________
-- VME TO WB INTERFACE
--
-- CERN,BE/CO-HT
--_______________________________________________________________________________________
-- File: VME_SharedComps.vhd
--_______________________________________________________________________________________
-- Description: This component implements the rising and falling edge detection and the
-- tripple and double sample entities
--_______________________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--_______________________________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your option)
-- any later version. This source is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
-- more details. You should have received a copy of the GNU Lesser General Public
-- License along with this source; if not, download it from
-- http://www.gnu.org/licenses/lgpl-2.1.html
----------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
-- tripple sample sig_i signals to avoid metastable states
entity SigInputSample is
port (
sig_i, clk_i: in std_logic;
sig_o: out std_logic );
end SigInputSample;
architecture RTL of SigInputSample is
signal s_1: std_logic;
signal s_2: std_logic;
begin
process(clk_i)
begin
if rising_edge(clk_i) then
s_1 <= sig_i;
s_2 <= s_1;
sig_o <= s_2;
end if;
end process;
end RTL;
-- ***************************************************
library IEEE;
use IEEE.STD_LOGIC_1164.all;
-- double sample sig_i signals to avoid metastable states
entity DoubleSigInputSample is
port (
sig_i, clk_i: in std_logic;
sig_o: out std_logic );
end DoubleSigInputSample;
architecture RTL of DoubleSigInputSample is
signal s_1: std_logic;
-- signal s_2: std_logic;
begin
process(clk_i)
begin
if rising_edge(clk_i) then
s_1 <= sig_i;
sig_o <= s_1;
end if;
end process;
end RTL;
--***************************************************
library IEEE;
use IEEE.STD_LOGIC_1164.all;
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;
use IEEE.STD_LOGIC_1164.all;
entity FlipFlopD is
port (
reset, sig_i, clk_i, enable: in std_logic;
sig_o: out std_logic );
end FlipFlopD;
architecture RTL of FlipFlopD is
-- signal s_1: std_logic;
-- signal s_2: std_logic;
begin
process(clk_i)
begin
if rising_edge(clk_i) then
if reset = '1' then
sig_o <= '0';
elsif enable = '1' then
sig_o <= sig_i;
--sig_o <= s_1;
end if;
end if;
end process;
end RTL;
--Register 32 bits
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity 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 Reg32bit;
architecture RTL of Reg32bit is
--signal s_reg : std_logic_vector(31 downto 0);
begin
process(clk_i)
begin
if rising_edge(clk_i) then
if reset = '0' then
do <= (others => '0');
--s_reg <= (others => '0');
elsif enable = '1' then
do <= di;
--s_reg <= di;
end if;
end if;
--do <= s_reg;
end process;
end RTL;
--
library IEEE;
use IEEE.STD_LOGIC_1164.all;
-- detect rising edge
entity RisEdgeDetection is
port (
sig_i, clk_i: in std_logic;
RisEdge_o: out std_logic );
end RisEdgeDetection;
architecture RTL of RisEdgeDetection is
signal s_1: std_logic;
begin
process(clk_i)
begin
if rising_edge(clk_i) then
s_1 <= sig_i;
if s_1 = '0' and sig_i = '1' then
RisEdge_o <= '1';
else
RisEdge_o <= '0';
end if;
end if;
end process;
end RTL;
-- ***************************************************
library IEEE;
use IEEE.STD_LOGIC_1164.all;
-- detect falling edge
entity FallingEdgeDetection is
port (
sig_i, clk_i: in std_logic;
FallEdge_o: out std_logic );
end FallingEdgeDetection;
architecture RTL of FallingEdgeDetection is
signal s_1: std_logic;
begin
process(clk_i)
begin
if rising_edge(clk_i) then
s_1 <= sig_i;
if s_1 = '1' and sig_i = '0' then
FallEdge_o <= '1';
else
FallEdge_o <= '0';
end if;
end if;
end process;
end RTL;
-- ***************************************************
library IEEE;
use IEEE.STD_LOGIC_1164.all;
-- give pulse (sigEdge_o) at rising and falling edge
entity EdgeDetection is
port (
sig_i,
clk_i: in std_logic;
sigEdge_o: out std_logic
);
end EdgeDetection;
architecture RTL of EdgeDetection is
signal s_1: std_logic;
begin
process(clk_i)
begin
if rising_edge(clk_i) then
s_1 <= sig_i;
if (s_1 = '0' and sig_i = '1') or (s_1 = '1' and sig_i = '0') then
sigEdge_o <= '1';
else
sigEdge_o <= '0';
end if;
end if;
end process;
end RTL;
-- ***************************************************
library IEEE;
use IEEE.STD_LOGIC_1164.all;
-- triple sample input register reg_i to avoid metastable states
-- and catching of transition values
entity RegInputSample 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 RegInputSample;
architecture RTL of RegInputSample is
signal reg_1, reg_2: std_logic_vector(width-1 downto 0);
begin
process(clk_i)
begin
if rising_edge(clk_i) then
reg_1 <= reg_i;
reg_2 <= reg_1;
reg_o <= reg_2;
end if;
end process;
end RTL;
-- ***************************************************
library IEEE;
use IEEE.STD_LOGIC_1164.all;
-- triple sample input register reg_i to avoid metastable states
-- and catching of transition values
entity DoubleRegInputSample 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 DoubleRegInputSample;
architecture RTL of DoubleRegInputSample is
signal reg_1, reg_2: std_logic_vector(width-1 downto 0);
begin
process(clk_i)
begin
if rising_edge(clk_i) then
reg_1 <= reg_i;
reg_o <= reg_1;
end if;
end process;
end RTL;
\ No newline at end of file
--___________________________________________________________________________________
-- VME TO WB INTERFACE
--
-- CERN,BE/CO-HT
--___________________________________________________________________________________
-- File: VME_Wb_master.vhd
--___________________________________________________________________________________
-- Description:
-- This component implements the WB master side in the vme64x core.
-- Work mode:
-- PIPELINED
-- SINGLE READ/WRITE
--
-- The WB bus can be 64 bit wide or 32 bit wide and the data organization is BIG ENDIAN
-- --> the most significant byte is carried in the lower position of the bus.
-- Eg:
-- _______________________________________________________________________
-- | Byte(0)| Byte(1)| Byte(2)| Byte(3)| Byte(4)| Byte(5)| Byte(6)| Byte(7)|
-- |________|________|________|________|________|________|________|________|
-- D[63:56] D[55:48] D[47:40] D[39:32] D[31:24] D[23:16] D[15:8] D[7:0]
--
-- eg of timing diagram with synchronous WB Slave:
--
-- Clk _____ _____ _____ _____ _____ _____ _____
-- _____| |_____| |_____| |_____| |_____| |_____| |_____|
-- cyc_o ____________________________________________________________
-- _____| |________________
-- stb_o ________________________________________________
-- _____| |____________________________
-- __________________________________________
-- stall_i |________________________________________
-- ack_i ___________
-- ______________________________________________________| |________________
--
-- The ack_i can be asserted with some Tclk of delay, not immediately.
-- This component implements the correct shift of the data in input/output from/to WB bus
--
--______________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--______________________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your option)
-- any later version. This source is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
-- more details. You should have received a copy of the GNU Lesser General Public
-- License along with this source; if not, download it from
-- http://www.gnu.org/licenses/lgpl-2.1.html
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
use work.vme64x_pack.all;
--===========================================================================
-- Entity declaration
--===========================================================================
entity VME_Wb_master is
generic(g_wb_data_width : integer := c_width;
g_wb_addr_width : integer := c_addr_width
);
Port ( memReq_i : in std_logic;
clk_i : in std_logic;
cardSel_i : in std_logic;
reset_i : in std_logic;
BERRcondition_i : in std_logic;
sel_i : in std_logic_vector(7 downto 0);
locDataInSwap_i : in std_logic_vector(63 downto 0);
locDataOut_o : out std_logic_vector(63 downto 0);
rel_locAddr_i : in std_logic_vector(63 downto 0);
memAckWb_o : out std_logic;
err_o : out std_logic;
rty_o : out std_logic;
RW_i : in std_logic;
stall_i : in std_logic;
rty_i : in std_logic;
err_i : in std_logic;
cyc_o : out std_logic;
memReq_o : out std_logic;
WBdata_o : out std_logic_vector(g_wb_data_width - 1 downto 0);
wbData_i : in std_logic_vector(g_wb_data_width - 1 downto 0);
locAddr_o : out std_logic_vector(g_wb_addr_width - 1 downto 0);
memAckWB_i : in std_logic;
WbSel_o : out std_logic_vector(f_div8(g_wb_data_width) - 1 downto 0);
RW_o : out std_logic);
end VME_Wb_master;
--===========================================================================
-- Architecture declaration
--===========================================================================
architecture Behavioral of VME_Wb_master is
signal s_shift_dx : std_logic;
signal s_cyc : std_logic;
signal s_AckWithError : std_logic;
signal s_wbData_i : std_logic_vector(63 downto 0);
signal s_select : std_logic_vector(8 downto 0);
signal s_DATi_sample : std_logic_vector(g_wb_data_width - 1 downto 0);
--===========================================================================
-- Architecture begin
--===========================================================================
begin
s_select <= cardSel_i & sel_i;
s_wbData_i <= std_logic_vector(resize(unsigned(s_DATi_sample),s_wbData_i'length));
-- stb handler
process(clk_i)
begin
if rising_edge(clk_i) then
if reset_i = '1' or (stall_i = '0' and s_cyc = '1') then
memReq_o <= '0';
elsif memReq_i = '1' and cardSel_i = '1' and BERRcondition_i = '0' then
memReq_o <= '1';
end if;
end if;
end process;
-- cyc_o handler
process(clk_i)
begin
if rising_edge(clk_i) then
if reset_i = '1' or memAckWB_i = '1' then
s_cyc <= '0';
elsif memReq_i = '1' and cardSel_i = '1' and BERRcondition_i = '0' then
s_cyc <= '1';
end if;
end if;
end process;
cyc_o <= s_cyc;
process(clk_i)
begin
if rising_edge(clk_i) then
RW_o <= RW_i;
s_AckWithError <=(memReq_i and cardSel_i and BERRcondition_i);
end if;
end process;
-- shift data and address for WB data bus 64 bits
gen64: if (g_wb_data_width = 64) generate
process(clk_i)
begin
if rising_edge(clk_i) then
locAddr_o <= std_logic_vector(resize(unsigned(rel_locAddr_i) srl 3,g_wb_addr_width));
end if;
end process;
process(clk_i)
begin
if rising_edge(clk_i) then
case sel_i is
when "10000000" => WBdata_o <= std_logic_vector(unsigned(locDataInSwap_i) sll 56);
when "01000000" => WBdata_o <= std_logic_vector(unsigned(locDataInSwap_i) sll 48);
when "00100000" => WBdata_o <= std_logic_vector(unsigned(locDataInSwap_i) sll 40);
when "00010000" => WBdata_o <= std_logic_vector(unsigned(locDataInSwap_i) sll 32);
when "00001000" => WBdata_o <= std_logic_vector(unsigned(locDataInSwap_i) sll 24);
when "00000100" => WBdata_o <= std_logic_vector(unsigned(locDataInSwap_i) sll 16);
when "00000010" => WBdata_o <= std_logic_vector(unsigned(locDataInSwap_i) sll 8);
when "11000000" => WBdata_o <= std_logic_vector(unsigned(locDataInSwap_i) sll 48);
when "00110000" => WBdata_o <= std_logic_vector(unsigned(locDataInSwap_i) sll 32);
when "00001100" => WBdata_o <= std_logic_vector(unsigned(locDataInSwap_i) sll 16);
when "11110000" => WBdata_o <= std_logic_vector(unsigned(locDataInSwap_i) sll 32);
when "00001111" => WBdata_o <= locDataInSwap_i;
when "00000001" => WBdata_o <= locDataInSwap_i;
when "00000011" => WBdata_o <= locDataInSwap_i;
when "11111111" => WBdata_o <= locDataInSwap_i;
when others => null;
end case;
WbSel_o <= std_logic_vector(sel_i);
end if;
end process;
process (s_select,s_wbData_i)
begin
case s_select is
when "100000010" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(15 downto 0)) srl 8, locDataOut_o'length));
when "100000100" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(23 downto 0)) srl 16,locDataOut_o'length));
when "100001000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)) srl 24,locDataOut_o'length));
when "100010000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(39 downto 0)) srl 32,locDataOut_o'length));
when "100100000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(47 downto 0)) srl 40,locDataOut_o'length));
when "101000000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(55 downto 0)) srl 48,locDataOut_o'length));
when "110000000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i) srl 56,locDataOut_o'length));
when "100001100" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)) srl 16,locDataOut_o'length));
when "100110000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(47 downto 0)) srl 32,locDataOut_o'length));
when "111000000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i) srl 48,locDataOut_o'length));
when "100000001" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(7 downto 0)), locDataOut_o'length));
when "100000011" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(15 downto 0)), locDataOut_o'length));
when "100001111" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)), locDataOut_o'length));
when "111110000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i) srl 32, locDataOut_o'length));
when "111111111" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i),locDataOut_o'length));
when others => locDataOut_o <= (others => '0');
end case;
end process;
end generate gen64;
-- shift data and address for WB data bus 32 bits
gen32: if (g_wb_data_width = 32) generate
process(clk_i)
begin
if rising_edge(clk_i) then
locAddr_o <= std_logic_vector(resize(unsigned(rel_locAddr_i) srl 2,g_wb_addr_width));
end if;
end process;
process(sel_i)
begin
if sel_i = "10000000" or sel_i = "01000000" or sel_i = "00100000" or sel_i = "00010000"
or sel_i = "11000000" or sel_i = "00110000" or sel_i = "11110000" then
s_shift_dx <= '1';
else
s_shift_dx <= '0';
end if;
end process;
process(clk_i)
begin
if rising_edge(clk_i) then
case sel_i is
when "10000000" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i) sll 24,g_wb_data_width));
when "01000000" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i) sll 16,g_wb_data_width));
when "00100000" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i) sll 8,g_wb_data_width));
when "00010000" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i),g_wb_data_width));
when "00001000" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i) sll 24,g_wb_data_width));
when "00000100" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i) sll 16,g_wb_data_width));
when "00000010" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i) sll 8,g_wb_data_width));
when "11000000" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i) sll 16,g_wb_data_width));
when "00110000" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i),g_wb_data_width));
when "00001100" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i) sll 16,g_wb_data_width));
when "11110000" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i),g_wb_data_width));
when "00001111" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i),g_wb_data_width));
when "00000001" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i),g_wb_data_width));
when "00000011" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i),g_wb_data_width));
when "11111111" => WBdata_o <= std_logic_vector(resize(unsigned(locDataInSwap_i),g_wb_data_width));
when others => null;
end case;
if s_shift_dx = '1' then
WbSel_o <= sel_i(7 downto 4);
else
WbSel_o <= sel_i(3 downto 0);
end if;
end if;
end process;
process (s_select,s_wbData_i)
begin
case s_select is
when "100000010" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(15 downto 0)) srl 8, locDataOut_o'length));
when "100000100" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(23 downto 0)) srl 16,locDataOut_o'length));
when "100001000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)) srl 24,locDataOut_o'length));
when "100010000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(7 downto 0)),locDataOut_o'length));
when "100100000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(15 downto 0)) srl 8,locDataOut_o'length));
when "101000000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(23 downto 0)) srl 16,locDataOut_o'length));
when "110000000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)) srl 24,locDataOut_o'length));
when "100001100" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)) srl 16,locDataOut_o'length));
when "100110000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(15 downto 0)),locDataOut_o'length));
when "111000000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)) srl 16,locDataOut_o'length));
when "100000001" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(7 downto 0)), locDataOut_o'length));
when "100000011" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(15 downto 0)), locDataOut_o'length));
when "100001111" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)), locDataOut_o'length));
when "111110000" => locDataOut_o <= std_logic_vector(
resize(unsigned(s_wbData_i(31 downto 0)), locDataOut_o'length));
when others => locDataOut_o <= (others => '0');
end case;
end process;
end generate gen32;
err_o <= err_i;
rty_o <= rty_i;
memAckWb_o <= memAckWB_i or s_AckWithError or rty_i;
------------------------------------------------------------------------
-- This process registers the WB data input; this is a warranty that this
-- data will be stable during all the time the VME_bus component needs to
-- transfers its to the VME bus.
process(clk_i)
begin
if rising_edge(clk_i) then
if memAckWB_i = '1' then
s_DATi_sample <= wbData_i;
end if;
end if;
end process;
------------------------------------------------------------------------
end Behavioral;
--===========================================================================
-- Architecture end
--===========================================================================
--______________________________________________________________________________|
-- VME TO WB INTERFACE |
-- |
-- CERN,BE/CO-HT |
--______________________________________________________________________________|
-- File: VME_bus.vhd |
--______________________________________________________________________________|
-- Description: |
-- This block acts as interface between the VMEbus and the CR/CSR space or WBbus.
-- |
-- _____________VME_bus________________ |
-- | _______ | |
-- | ______ | M | | |
-- | | A D | | A F | ____| |
-- | | C E | | I S | | W | |
-- | | C C | | N M | | B | |
-- VME | | E O | | | | | |
-- BUS | | S D | |_______| | M | |
-- | | S E | | A | |
-- | |______| | S | |
-- | ______ ___________ | T | |
-- | | I | | OTHER || E | |
-- | | N | | DATA & || R | |
-- | | I | | ADDR ||____| |
-- | | T | | PROCESS | | |
-- | |______| |___________| | |
-- |____________________________________| |
-- |
-- The INIT component performs the initialization of the core after the power-up|
-- or reset. |
-- The Access decode component decodes the address to check if the board is the |
-- responding Slave. This component is of fundamental importance, indeed only |
-- one Slave can answer to the Master! |
-- In the right side you can see the WB Master who implements the Wb Pipelined |
-- single read/write protocol.
--
-- led 0 <-- error flag
-- led 1 <-- last access: CR/CSR
-- led 2 <-- last access: WB SINGLE access
-- led 3 <-- last access: WB BLT access
-- led 4 <-- last access: WB MBLT access
-- led 5 <-- WB data bus 32 bits
-- led 6 <-- Module enable
-- led 7 <-- flashing
-- Each VME board plugged in a slot acts as a VME slave module and it has only
-- one CR/CSR space (conforming with the specification) so only one FPGA at time
-- must drive the output lines on the VME bus; only one FPGA at time can carry
-- the vme64x core or other similar VME slave core.
-- Inside each component is possible read a more detailed description. |
--______________________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--______________________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your option)
-- any later version. This source is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
-- more details. You should have received a copy of the GNU Lesser General Public
-- License along with this source; if not, download it from
-- http://www.gnu.org/licenses/lgpl-2.1.html
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;
use work.vme64x_pack.all;
--===========================================================================
-- Entity declaration
--===========================================================================
entity VME_bus is
generic(g_clock : integer := c_clk_period;
g_wb_data_width : integer := c_width;
g_wb_addr_width : integer := c_addr_width;
g_cram_size : integer := c_CRAM_SIZE
);
port(
clk_i : in std_logic;
reset_o : out std_logic; -- to the Interrupt Generator and IRQ controller
-- VME signals
VME_RST_n_i : in std_logic;
VME_AS_n_i : in std_logic;
VME_LWORD_n_o : out std_logic;
VME_LWORD_n_i : in std_logic;
VME_RETRY_n_o : out std_logic;
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_DS_ant_n_i : in std_logic_vector(1 downto 0);
VME_DTACK_n_o : out std_logic;
VME_DTACK_OE_o : out std_logic;
VME_BERR_o : out std_logic;
VME_ADDR_i : in std_logic_vector(31 downto 1);
VME_ADDR_o : out std_logic_vector(31 downto 1);
VME_ADDR_DIR_o : out std_logic;
VME_ADDR_OE_N_o : out std_logic;
VME_DATA_i : in std_logic_vector(31 downto 0);
VME_DATA_o : out std_logic_vector(31 downto 0);
VME_DATA_DIR_o : out std_logic;
VME_DATA_OE_N_o : out std_logic;
VME_AM_i : in std_logic_vector(5 downto 0);
VME_IACK_n_i : in std_logic; -- USE VME_IACK_n_i and NOT VME_IACKIN_n_i !!!!
-- because VME_IACKIN_n_i is delayed the more you
-- are away from Slots 0
-- WB signals
memReq_o : out std_logic;
memAckWB_i : in std_logic;
wbData_o : out std_logic_vector(g_wb_data_width - 1 downto 0);
wbData_i : in std_logic_vector(g_wb_data_width - 1 downto 0);
locAddr_o : out std_logic_vector(g_wb_addr_width - 1 downto 0);
wbSel_o : out std_logic_vector(f_div8(g_wb_data_width) - 1 downto 0);
RW_o : out std_logic;
cyc_o : out std_logic;
err_i : in std_logic;
rty_i : in std_logic;
stall_i : in std_logic;
--CR/CSR space signals:
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;
CRaddr_o : out std_logic_vector(11 downto 0);
CRdata_i : in std_logic_vector(7 downto 0);
en_wr_CSR : out std_logic;
CrCsrOffsetAddr : out std_logic_vector(18 downto 0);
CSRData_o : out std_logic_vector(7 downto 0);
CSRData_i : in std_logic_vector(7 downto 0);
err_flag_o : out std_logic;
reset_flag_i : in std_logic;
Ader0 : in std_logic_vector(31 downto 0);
Ader1 : in std_logic_vector(31 downto 0);
Ader2 : in std_logic_vector(31 downto 0);
Ader3 : in std_logic_vector(31 downto 0);
Ader4 : in std_logic_vector(31 downto 0);
Ader5 : in std_logic_vector(31 downto 0);
Ader6 : in std_logic_vector(31 downto 0);
Ader7 : in std_logic_vector(31 downto 0);
ModuleEnable : in std_logic;
Endian_i : in std_logic_vector(2 downto 0);
Sw_Reset : in std_logic;
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
leds : out std_logic_vector(7 downto 0)
);
end VME_bus;
--===========================================================================
-- Architecture declaration
--===========================================================================
architecture RTL of VME_bus is
signal s_reset : std_logic;
-- Input signals
signal s_VMEaddrInput : unsigned(31 downto 1);
signal s_VMEdataInput : unsigned(31 downto 0);
signal s_LWORDinput : std_logic;
-- External buffer signals
signal s_dtackOE : std_logic;
signal s_dataDir : std_logic;
signal s_dataOE : std_logic;
signal s_addrDir : std_logic;
signal s_addrOE : std_logic;
-- Local data & address
signal s_locDataIn : unsigned(63 downto 0);
signal s_locDataOut : unsigned(63 downto 0);
signal s_locData : unsigned(63 downto 0); -- Local data
signal s_locAddr, s_rel_locAddr : unsigned(63 downto 0); -- Local address
signal s_locAddr2e : unsigned(63 downto 0); -- for 2e transfers
signal s_locAddrBeforeOffset : unsigned(63 downto 0);
signal s_phase1addr : unsigned(63 downto 0); -- for 2e transfers
signal s_phase2addr : unsigned(63 downto 0); --
signal s_phase3addr : unsigned(63 downto 0); --
signal s_addrOffset : unsigned(17 downto 0); -- block transfers|
signal s_CrCsrOffsetAddr : unsigned(18 downto 0); -- CR/CSR address
signal s_DataShift : unsigned(5 downto 0);
signal s_2eLatchAddr : std_logic_vector(1 downto 0); -- for 2e transfers
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
signal s_DSlatched : std_logic_vector(1 downto 0); -- Stores DS
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_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);
signal s_addrWidth1 : 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
signal s_VMEaddrLatch : std_logic; -- pulse on VME_AS_n_i f.edge
signal s_DSlatch : std_logic; -- Stores data strobes
signal s_incrementAddr : std_logic; -- Increments local address
signal s_blockTransferLimit : std_logic; -- Block transfer limit
signal s_mainFSMreset : std_logic; -- Resets main FSM on AS r. edge
signal s_dataPhase : std_logic; -- for A64 and multipl. transf.
signal s_transferActive : std_logic; -- active VME transfer
-- signal s_retry : std_logic; -- RETRY signal
signal s_retry_out : std_logic;
signal s_berr : std_logic; -- BERR signal
signal s_berr_1 : std_logic; --
signal s_berr_2 : std_logic; --
-- Access decode signals
signal s_confAccess : std_logic; -- Asserted when CR or CSR is addressed
signal s_cardSel : std_logic; -- Asserted when WB memory is addressed
-- WishBone signals
signal s_sel : unsigned(7 downto 0); -- SEL WB signal
signal s_nx_sel : std_logic_vector(7 downto 0);
signal s_RW : std_logic; -- RW WB signal
-- CR/CSR related signals
signal s_CRaddressed : std_logic; -- CR is addressed
signal s_CRAMaddressed : std_logic; -- CRAM is addressed
signal s_CSRaddressed : std_logic; -- CSR space is addressed
signal s_CSRdata : unsigned(7 downto 0); -- CSR data write/read
signal s_CRdataIn : std_logic_vector(7 downto 0); -- CR data bus
signal s_CRAMdataIn : std_logic_vector(7 downto 0); -- CRAM data bus
signal s_FUNC_ADEM : t_FUNC_32b_array_std;
signal s_FUNC_AMCAP : t_FUNC_64b_array_std;
signal s_FUNC_XAMCAP : t_FUNC_256b_array_std;
-- CR image registers
signal s_BEG_USER_CSR : std_logic_vector(23 downto 0);
signal s_END_USER_CSR : std_logic_vector(23 downto 0);
signal s_BEG_USER_CR : std_logic_vector(23 downto 0);
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
signal s_initReadCounter1 : std_logic_vector(8 downto 0);
signal s_CRaddr : unsigned(18 downto 0);
signal s_is_d64 : std_logic;
signal s_base_addr : unsigned(63 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_VMEdata64In : unsigned(63 downto 0);
signal s_counter : unsigned(25 downto 0);
signal s_countcyc : unsigned(9 downto 0);
signal s_BERR_out : std_logic;
signal s_errorflag : std_logic;
signal s_resetflag : std_logic;
signal s_led1 : std_logic;
signal s_led2 : std_logic;
signal s_led3 : std_logic;
signal s_led4 : std_logic;
signal s_led5 : 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:
signal s_countertime : unsigned(39 downto 0);
signal s_time : std_logic_vector(39 downto 0);
signal s_counterbytes : unsigned(12 downto 0);
signal s_bytes : std_logic_vector(12 downto 0);
signal s_datawidth : unsigned(3 downto 0);
--
signal s_wbMaster_rst : std_logic;
signal s_num_latchDS : integer;
--===========================================================================
-- Architecture begin
--===========================================================================
begin
-- calculate the number of LATCH DS states necessary to match the timing
-- rule 2.39 page 113 VMEbus specification ANSI/IEEE STD1014-1987.
s_num_latchDS <= f_latchDS(g_clock);
---------
s_is_d64 <= '1' when s_sel= "11111111" else '0'; --used to drive the VME_ADDR_DIR_o
---------
s_RW <= VME_WRITE_n_i;
s_reset <= not(VME_RST_n_i) or s_sw_reset; -- hw and sw reset
reset_o <= s_reset; -- Asserted when high
-------------------------------------------------------------------------
-- These output signals are connected to the buffers on the board
-- SN74VMEH22501A Function table:
-- OEn | DIR | OUTPUT OEAB | OEBYn | OUTPUT
-- H | X | Z L | H | Z
-- L | H | A to B H | H | A to B
-- L | L | B to A L | L | B to Y
-- H | L |A to B, B to Y |
VME_DATA_DIR_o <= s_dataDir;
VME_DATA_OE_N_o <= s_dataOE;
VME_ADDR_DIR_o <= s_addrDir;
VME_ADDR_OE_N_o <= s_addrOE;
VME_DTACK_OE_o <= s_dtackOE; -- |
-- VME DTACK:
VME_DTACK_n_o <= s_mainDTACK;
--------------------------ACCESS MODE DECODERS----------------------------
-- Type of data transfer decoder
-- VME64 ANSI/VITA 1-1994...Table 2-2 "Signal levels during data transfers"
-- A2 is used to select the D64 type (D64 --> MBLT and 2edge cycles)
-- VME DATA --> BIG ENDIAN
s_typeOfDataTransferSelect <= s_DSlatched & s_VMEaddrLatched(1) &
s_LWORDlatched & s_VMEaddrLatched(2);
-- These 5 bits are not sufficient to descriminate the D32 and D64 data
-- transfer type; indeed the D32 access with A2 = '0' (eg 0x010)
-- fall within D64 access --> The data transfer type have to be evaluated
-- jointly with the address type.
-- Bytes position on VMEbus:
-- A24-A31 | A16-A23 | A08-A15 | A00-A07 | D24-D31 | D16-D23 | D08-D15 | D00-D07
-- | | | | | | BYTE(0) |
-- | | | | | | | BYTE(1)
-- | | | | | | BYTE(2) |
-- | | | | | | | BYTE(3)
-- | | | | | | BYTE(0) | BYTE(1)
-- | | | | | | BYTE(2) | BYTE(3)
-- | | | | BYTE(0)| BYTE(1) | BYTE(2) | BYTE(3)
-- BYTE(0)| BYTE(1) | BYTE(2) | BYTE(3) | BYTE(4)| BYTE(5) | BYTE(6) | BYTE(7)
with s_typeOfDataTransferSelect select
s_typeOfDataTransfer <= D08_0 when "01010",
D08_0 when "01011",
D08_1 when "10010",
D08_1 when "10011",
D08_2 when "01110",
D08_2 when "01111",
D08_3 when "10110",
D08_3 when "10111",
D16_01 when "00010",
D16_01 when "00011",
D16_23 when "00110",
D16_23 when "00111",
D32 when "00001",
D64 when "00000",
TypeError when others;
with s_typeOfDataTransferSelect select
s_DataShift <= b"001000" when "01010",
b"001000" when "01011",
b"001000" when "01110",
b"001000" when "01111",
b"000000" when others;
-- Address modifier decoder
-- Either the supervisor or user access modes are supported
s_addressingTypeSelect <= s_AMlatched;
with s_addressingTypeSelect select
s_addressingType <= A24 when c_A24_S_sup,
A24 when c_A24_S,
A24_BLT when c_A24_BLT,
A24_BLT when c_A24_BLT_sup,
A24_MBLT when c_A24_MBLT,
A24_MBLT when c_A24_MBLT_sup,
CR_CSR when c_CR_CSR,
A16 when c_A16,
A16 when c_A16_sup,
A32 when c_A32,
A32 when c_A32_sup,
A32_BLT when c_A32_BLT,
A32_BLT when c_A32_BLT_sup,
A32_MBLT when c_A32_MBLT,
A32_MBLT when c_A32_MBLT_sup,
A64 when c_A64,
A64_BLT when c_A64_BLT,
A64_MBLT when c_A64_MBLT,
TWOedge when c_TWOedge,
AM_Error when others;
-- 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;
process(clk_i)
begin
if rising_edge(clk_i) then
s_addrWidth <= s_addrWidth1;
end if;
end process;
-- To implement the A32 2eVME and A32 2eSST accesses the following logic
-- must be changed:
with s_addressingType select
s_addrWidth1 <= "00" when A16,
"01" when A24,
"01" when A24_BLT,
"01" when A24_MBLT,
"01" when CR_CSR,
"10" when A32,
"10" when A32_BLT,
"10" when A32_MBLT,
"11" when others;
-------------------------------------MAIN FSM--------------------------------|
s_memReq <= s_FSM.s_memReq;
s_decode <= s_FSM.s_decode;
s_dtackOE <= s_FSM.s_dtackOE;
s_mainDTACK <= s_FSM.s_mainDTACK;
s_dataDir <= s_FSM.s_dataDir;
s_dataOE <= s_FSM.s_dataOE;
s_addrDir <= s_FSM.s_addrDir;
s_addrOE <= s_FSM.s_addrOE;
s_DSlatch <= s_FSM.s_DSlatch;
s_incrementAddr <= s_FSM.s_incrementAddr;
s_dataPhase <= s_FSM.s_dataPhase;
s_dataToOutput <= s_FSM.s_dataToOutput;
s_dataToAddrBus <= s_FSM.s_dataToAddrBus;
s_transferActive <= s_FSM.s_transferActive;
s_2eLatchAddr <= s_FSM.s_2eLatchAddr;
s_retry_out <= s_FSM.s_retry;
s_berr <= s_FSM.s_berr;
s_BERR_out <= s_FSM.s_BERR_out;
p_VMEmainFSM : process(clk_i)
begin
if rising_edge(clk_i) then
if s_reset = '1' or s_mainFSMreset = '1' then -- FSM resetted after power up,
-- software reset, manually reset,
-- on rising edge of AS.
s_FSM <= c_FSM_default;
s_mainFSMstate <= IDLE;
else
case s_mainFSMstate is
when IDLE =>
s_FSM <= c_FSM_default;
-- During the Interrupt ack cycle the Slave can't be accessed
-- 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 falling edge --> go in DECODE_ACCESS
else
s_mainFSMstate <= IDLE;
end if;
when DECODE_ACCESS =>
-- check if this slave board is addressed and if it is, check the access mode
s_FSM <= c_FSM_default;
s_FSM.s_decode <= '1';
s_FSM.s_DSlatch <= '1';
-- uncomment for using 2e modes:
-- if s_addressingType = TWOedge then -- start 2e transfer
-- s_mainFSMstate <= WAIT_FOR_DS_2e;
if s_confAccess = '1' or (s_cardSel = '1') then
--confAccess = '1' it means CR/CSR space addressed
--s_cardSel = '1' it means WB application addressed
s_mainFSMstate <= WAIT_FOR_DS;
else
s_mainFSMstate <= DECODE_ACCESS;
-- another board will answer; wait here the rising edge on VME_AS_i
end if;
when WAIT_FOR_DS => -- wait until DS /= "11"
s_FSM <= c_FSM_default;
s_FSM.s_dtackOE <= '1';
s_FSM.s_addrDir <= (s_is_d64) and VME_WRITE_n_i;
s_FSM.s_DSlatch <= '1';
s_FSM.s_dataPhase <= s_dataPhase;
s_FSM.s_transferActive <= '1';
if VME_DS_n_i /= "11" then
s_mainFSMstate <= LATCH_DS1;
else
s_mainFSMstate <= WAIT_FOR_DS;
end if;
when LATCH_DS1 =>
-- this state is necessary indeed the VME master can assert the
-- DS lines not at the same time
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;
s_FSM.s_transferActive <= '1';
if s_num_latchDS = 1 then
s_mainFSMstate <= CHECK_TRANSFER_TYPE;
else
s_mainFSMstate <= LATCH_DS2;
end if;
when LATCH_DS2 =>
-- this state is necessary indeed the VME master can assert the
-- DS lines not at the same time
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;
s_FSM.s_transferActive <= '1';
if s_num_latchDS = 2 then
s_mainFSMstate <= CHECK_TRANSFER_TYPE;
else
s_mainFSMstate <= LATCH_DS3;
end if;
when LATCH_DS3 =>
-- this state is necessary indeed the VME master can assert the
-- DS lines not at the same time
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;
s_FSM.s_transferActive <= '1';
if s_num_latchDS = 3 then
s_mainFSMstate <= CHECK_TRANSFER_TYPE;
else
s_mainFSMstate <= LATCH_DS4;
end if;
when LATCH_DS4 =>
-- this state is necessary indeed the VME master can assert the
-- DS lines not at the same time
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;
s_FSM.s_transferActive <= '1';
s_mainFSMstate <= CHECK_TRANSFER_TYPE;
when CHECK_TRANSFER_TYPE =>
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_dataPhase <= s_dataPhase;
s_FSM.s_transferActive <= '1';
if (s_transferType = SINGLE or s_transferType = BLT) and s_addrWidth /= "11" then
s_mainFSMstate <= MEMORY_REQ;
s_FSM.s_memReq <= '1';
elsif (s_transferType = MBLT or s_addrWidth = "11") and s_dataPhase = '0' then
s_mainFSMstate <= DTACK_LOW;
elsif (s_transferType = MBLT or s_addrWidth = "11") and s_dataPhase = '1' then
s_mainFSMstate <= MEMORY_REQ;
s_FSM.s_memReq <= '1';
end if;
when MEMORY_REQ =>
-- To request the memory CR/CSR or WB memory it is sufficient to
-- generate a pulse on s_memReq signal
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_dataPhase <= s_dataPhase;
s_FSM.s_transferActive <= '1';
if s_memAck = '1' and s_RW = '0' then
s_mainFSMstate <= DTACK_LOW;
elsif s_memAck = '1' and s_RW = '1' then
if s_transferType = MBLT then
s_FSM.s_dataToAddrBus <= '1';
else
s_FSM.s_dataToOutput <= '1';
end if;
s_mainFSMstate <= DATA_TO_BUS;
else
s_mainFSMstate <= MEMORY_REQ;
end if;
when DATA_TO_BUS =>
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_dataPhase <= s_dataPhase;
s_FSM.s_transferActive <= '1';
s_FSM.s_dataToAddrBus <= s_dataToAddrBus;
s_FSM.s_dataToOutput <= s_dataToOutput;
s_mainFSMstate <= DTACK_LOW;
when DTACK_LOW =>
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_dataPhase <= s_dataPhase;
s_FSM.s_transferActive <= '1';
if s_BERRcondition = '0' and s_rty1 = '0' then
s_FSM.s_mainDTACK <= '0';
elsif s_BERRcondition = '0' and s_rty1 = '1' then
s_FSM.s_retry <= '1';
else
s_FSM.s_BERR_out <= '1';
end if;
if VME_DS_n_i = "11" then
s_mainFSMstate <= DECIDE_NEXT_CYCLE;
s_FSM.s_dataDir <= '0';
else
s_mainFSMstate <= DTACK_LOW;
end if;
when DECIDE_NEXT_CYCLE =>
s_FSM <= c_FSM_default;
s_FSM.s_dtackOE <= '1';
s_FSM.s_addrDir <= (s_is_d64) and VME_WRITE_n_i;
s_FSM.s_dataPhase <= s_dataPhase;
s_FSM.s_transferActive <= '1';
if (s_transferType = SINGLE and s_addrWidth /= "11") or
(s_transferType = SINGLE and s_addrWidth = "11" and s_dataPhase = '1') then
s_mainFSMstate <= WAIT_FOR_DS;
elsif (s_transferType = BLT and s_addrWidth /= "11") or
(s_transferType = BLT and s_addrWidth = "11" and s_dataPhase = '1') or
(s_transferType = MBLT and s_dataPhase = '1') then
s_mainFSMstate <= INCREMENT_ADDR;
elsif (s_transferType = MBLT or s_addrWidth = "11")and s_dataPhase = '0' then
s_mainFSMstate <= SET_DATA_PHASE;
else s_mainFSMstate <= DECIDE_NEXT_CYCLE;
end if;
when INCREMENT_ADDR =>
s_FSM <= c_FSM_default;
s_FSM.s_dtackOE <= '1';
s_FSM.s_addrDir <= (s_is_d64) and VME_WRITE_n_i;
s_FSM.s_dataPhase <= s_dataPhase;
s_FSM.s_transferActive <= '1';
s_FSM.s_incrementAddr <= '1';
s_mainFSMstate <= WAIT_FOR_DS;
when SET_DATA_PHASE =>
s_FSM <= c_FSM_default;
s_FSM.s_dtackOE <= '1';
s_FSM.s_addrDir <= (s_is_d64) and VME_WRITE_n_i;
s_FSM.s_dataPhase <= '1';
s_FSM.s_transferActive <= '1';
s_mainFSMstate <= WAIT_FOR_DS;
when others =>
s_FSM <= c_FSM_default;
s_mainFSMstate <= IDLE;
end case;
end if;
end if;
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
if s_retry_out = '1' then
VME_RETRY_n_o <= '0';
VME_RETRY_OE_o <= '1';
else
VME_RETRY_n_o <= '1';
VME_RETRY_OE_o <= '0';
end if;
end if;
end process;
-- BERR driver
-- The slave asserts the Error line during the Decode access phase when an error
-- condition is detected and the s_BERRcondition is asserted.
-- When the FSM is in the DTACK_LOW state one of the VME_DTACK and VME_BERR lines
-- is asserted.
-- The VME_BERR line can not be asserted by the slave at anytime, but only during
-- the DTACK_LOW state; this to avoid that one temporary error condition
-- during the decode access phase causes an undesired assertion of VME_BERR line.
p_BERRdriver: process(clk_i)
begin
if rising_edge(clk_i) then
-- 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
else
VME_BERR_o <= '0';
end if;
end if;
end process;
-- When the VME_BERR line is asserted this process asserts the error flag; This flag
-- acts as the BERR flag --> BIT SET REGISTER's bit 3 in the CSR space
FlagError: process(clk_i)
begin
if rising_edge (clk_i) then
if s_resetflag = '1' or s_reset = '1' then
s_errorflag <= '0';
elsif (s_BERR_out = '1') then
s_errorflag <= '1';
end if;
end if;
end process;
-- This process detects an error condition and assert the s_BERRcondition signal
-- A transfer cycle is terminated with assertion of this signal if the VME64x
-- slave does not recognize the data or addressing type used in the transfer cycle,
-- if a Master attempts to access in BLT mode with D08 or D16, if the master attempts
-- to access in MBLT mode and the WB data bus is 32 bits, or if the read only memory
-- is addressed during a write only cycle!
process(clk_i)
begin
if rising_edge(clk_i) then
if s_reset = '1' then s_BERRcondition <= '0';
elsif (s_CRAMaddressed = '1' and s_CRaddressed = '1') or (s_CRAMaddressed = '1' and
s_CSRaddressed = '1') or (s_CRaddressed = '1' and s_confAccess = '1' and s_RW = '0')
or (s_CSRaddressed = '1' and s_CRaddressed = '1') or ((s_transferType = error or
s_wberr1 = '1') and s_transferActive='1') or (s_typeOfDataTransfer = TypeError) or
(s_addressingType = AM_Error) or s_blockTransferLimit = '1' or
(s_transferType = BLT and (not(s_typeOfDataTransfer = D32 or
s_typeOfDataTransfer = D64))) or (s_transferType = MBLT and
s_typeOfDataTransfer /= D64) or (s_is_d64 = '1' and g_wb_data_width = 32) then
s_BERRcondition <= '1';
else
s_BERRcondition <= '0';
end if;
end if;
end process;
-- generate the error condition if block transfer overflows the limit
-- BLT --> block transfer limit = 256 bytes (rule 2.12a VME64 std ANSI/VITA 1-1994)
-- MBLT --> block transfer limit = 2048 bytes (rule 2.78 VME64 std ANSI/VITA 1-1994)
with s_transferType select
s_blockTransferLimit <= s_addrOffset(8) when BLT,
s_addrOffset(11) when MBLT,
'0' when others;
-- wb err handler
process(clk_i)
begin
if rising_edge(clk_i) then
if s_mainFSMreset = '1' or s_reset = '1' then
s_wberr1 <= '0';
elsif s_err = '1' then
s_wberr1 <= '1';
end if;
end if;
end process;
-- wb retry handler
process(clk_i)
begin
if rising_edge(clk_i) then
if s_mainFSMreset = '1' or s_reset = '1' then
s_rty1 <= '0';
elsif s_rty = '1' then
s_rty1 <= '1';
end if;
end if;
end process;
---------------------------------------------------------------------|
--These two mux are inserted to provide the MBLT access mode
p_ADDRmux : process(clk_i)
begin
if rising_edge(clk_i) then
if s_dataToAddrBus = '1' then
VME_ADDR_o <= s_locDataSwap(63 downto 33);
VME_LWORD_n_o <= s_locDataSwap(32);
end if;
end if;
end process;
p_DATAmux : process(clk_i)
begin
if rising_edge(clk_i) then
if s_dataToAddrBus = '1' or s_dataToOutput = '1' then
if s_addressingType = CR_CSR then
VME_DATA_o <= std_logic_vector(s_locData(31 downto 0));
else
VME_DATA_o <= s_locDataSwap(31 downto 0);
end if;
end if;
end if;
end process;
---------------------ADDRESS_HANDLER_PROCESS------------------------|
--Local address & AM & 2e address phase latching
s_VMEaddrInput <= unsigned(VME_ADDR_i);
s_LWORDinput <= VME_LWORD_n_i;
s_VMEdataInput <= unsigned(VME_DATA_i);
p_addrLatching : process(clk_i)
begin
if rising_edge(clk_i) then
if s_reset = '1' then
s_VMEaddrLatched <= (others => '0');
s_LWORDlatched <= '0';
s_AMlatched <= (others => '0');
else
if s_VMEaddrLatch = '1' then -- Latching on falling edge of VME_AS_n_i
s_VMEaddrLatched <= s_VMEdataInput & s_VMEaddrInput;
s_LWORDlatched <= s_LWORDinput;
s_AMlatched <= VME_AM_i;
else
s_VMEaddrLatched <= s_VMEaddrLatched;
s_LWORDlatched <= s_LWORDlatched;
s_AMlatched <= s_AMlatched;
end if;
end if;
end if;
end process;
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 in the VME_WB_master to address the WB memory
process(clk_i)
begin
if rising_edge(clk_i) then
if s_addressingType = TWOedge then
s_rel_locAddr <= s_locAddr2e + s_addrOffset-s_base_addr;
s_locAddr <= s_locAddr2e;
elsif s_addressingType = CR_CSR then
s_locAddr <= s_locAddrBeforeOffset;
else
s_rel_locAddr <= s_locAddrBeforeOffset + s_addrOffset-s_base_addr;
s_locAddr <= s_locAddrBeforeOffset;
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
-- the vme64x core increments the address every cycle
p_addrIncrementing : process(clk_i)
begin
if rising_edge(clk_i) then
if s_reset = '1' or s_mainFSMreset = '1' then
s_addrOffset <= (others => '0');
elsif s_incrementAddr = '1' then
if s_addressingType = TWOedge then
s_addrOffset <= s_addrOffset + 8; -- the TWOedge access is D64
else
if s_typeOfDataTransfer = D08_0 or s_typeOfDataTransfer = D08_1 or
s_typeOfDataTransfer = D08_2 or s_typeOfDataTransfer = D08_3 then
s_addrOffset <= s_addrOffset + 1;
elsif s_typeOfDataTransfer = D16_01 or s_typeOfDataTransfer = D16_23 then
s_addrOffset <= s_addrOffset + 2;
elsif s_typeOfDataTransfer = D64 then
if s_transferType = MBLT then
s_addrOffset <= s_addrOffset + 8;
else
s_addrOffset <= s_addrOffset + 4; --BLT D32
end if;
elsif s_typeOfDataTransfer = D32 then --BLT D32
s_addrOffset <= s_addrOffset + 4;
else
s_addrOffset <= s_addrOffset;
end if;
end if;
else
s_addrOffset <= s_addrOffset;
end if;
end if;
end process;
s_CrCsrOffsetAddr <= "00"&s_locAddr(18 downto 2) when s_mainFSMreset = '0' else
(others => '0');
s_CRaddr <= (s_CrCsrOffsetAddr) when s_initInProgress = '0' else
(resize(s_initReadCounter, s_CRaddr'length));
CRaddr_o <= std_logic_vector(s_CRaddr(11 downto 0));
CRAMaddr_o <= std_logic_vector(resize(s_CrCsrOffsetAddr - unsigned(s_BEG_CRAM(18 downto 0)),
f_log2_size(g_cram_size)));
--------------------DATA HANDLER PROCESS---------------------------- |
-- Data strobe latching
p_DSlatching : process(clk_i)
begin
if rising_edge(clk_i) then
if s_DSlatch = '1' then
s_DSlatched <= VME_DS_ant_n_i;
end if;
end if;
end process;
s_VMEdata64In(63 downto 33) <= s_VMEaddrInput(31 downto 1);
s_VMEdata64In(32) <= (s_LWORDinput);
s_VMEdata64In(31 downto 0) <= s_VMEdataInput(31 downto 0);
-- This process aligns the VME data input in the lsb
process(clk_i)
begin
if rising_edge(clk_i) then
s_locDataIn <= unsigned(s_VMEdata64In) srl to_integer(unsigned(s_DataShift));
end if;
end process;
CSRData_o <= std_logic_vector(s_locDataIn(7 downto 0));
process(clk_i)
begin
if rising_edge(clk_i) then
CRAMdata_o <= std_logic_vector(s_locDataIn(7 downto 0));
if (s_confAccess = '1' and s_CRAMaddressed = '1' and s_memReq = '1' and
s_RW = '0' and (s_typeOfDataTransfer = D08_3 or s_typeOfDataTransfer = D32 or
s_typeOfDataTransfer = D16_23 or (s_typeOfDataTransfer = D64 and
s_transferType /= MBLT))) then
CRAMwea_o <= '1';
else
CRAMwea_o <= '0';
end if;
end if;
end process;
--swap the data during read or write operation
--sel= 000 --> No swap
--sel= 001 --> Swap Byte eg: 01234567 become 10325476
--sel= 010 --> Swap Word eg: 01234567 become 23016745
--sel= 011 --> Swap Word+ Swap Byte eg: 01234567 become 32107654
--sel= 100 --> Swap DWord + Swap Word+ Swap Byte eg: 01234567 become 76543210
swapper_write: VME_swapper port map(
d_i => std_logic_vector(s_locDataIn),
sel => Endian_i,
d_o => s_locDataInSwap
);
swapper_read: VME_swapper port map(
d_i => std_logic_vector(s_locData),
sel => Endian_i,
d_o => s_locDataSwap
);
-- data from WB or CR/CSR to VME bus
s_CRCSRtype <= '1' when (s_typeOfDataTransfer = D08_3 or s_typeOfDataTransfer = D32 or
s_typeOfDataTransfer = D16_23 or (s_typeOfDataTransfer = D64 and
s_transferType /= MBLT)) else
'0';
process(clk_i)
begin
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);
---------------------MEMORY MAPPING--------------------------------
-- WB bus width = 64-bits
-- Granularity = byte
-- WB bus --> BIG ENDIAN
p_memoryMapping : process(clk_i)
begin
if rising_edge(clk_i) then
if s_transferType = TWOe then
s_nx_sel <= "11111111";
else
case s_typeOfDataTransfer is
when D08_0 =>
if s_rel_locAddr(2) = '0' then
s_nx_sel <= "10000000";
else
s_nx_sel <= "00001000";
end if;
when D08_1 =>
if s_rel_locAddr(2) = '0' then
s_nx_sel <= "01000000";
else
s_nx_sel <= "00000100";
end if;
when D08_2 =>
if s_rel_locAddr(2) = '0' then
s_nx_sel <= "00100000";
else
s_nx_sel <= "00000010";
end if;
when D08_3 =>
if s_rel_locAddr(2) = '0' then
s_nx_sel <= "00010000";
else
s_nx_sel <= "00000001";
end if;
when D16_01 =>
if s_rel_locAddr(2) = '0' then
s_nx_sel <= "11000000";
else
s_nx_sel <= "00001100";
end if;
when D16_23 =>
if s_rel_locAddr(2) = '0' then
s_nx_sel <= "00110000";
else
s_nx_sel <= "00000011";
end if;
when D64 =>
case s_transferType is
when MBLT => -- D64 |
s_nx_sel <= "11111111";
when others => -- D32 BLT or SINGLE
if s_rel_locAddr(2) = '0' then
s_nx_sel <= "11110000";
else
s_nx_sel <= "00001111";
end if;
end case;
when D32 =>
if s_rel_locAddr(2) = '1' then
s_nx_sel <= "00001111";
else
s_nx_sel <= "11110000";
end if;
when others =>
s_nx_sel <= "00000000";
end case;
end if;
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.
s_wbMaster_rst <= s_reset or s_mainFSMreset;
Inst_Wb_master: VME_Wb_master
generic map(
g_wb_data_width => g_wb_data_width,
g_wb_addr_width => g_wb_addr_width
)
port map(
memReq_i => s_memReq,
clk_i => clk_i,
cardSel_i => s_cardSel,
reset_i => s_wbMaster_rst,
BERRcondition_i => s_BERRcondition,
sel_i => std_logic_vector(s_sel),
locDataInSwap_i => s_locDataInSwap,
locDataOut_o => s_locDataOutWb,
rel_locAddr_i => std_logic_vector(s_rel_locAddr),
memAckWb_o => s_AckWb,
err_o => s_err,
rty_o => s_rty,
RW_i => s_RW,
stall_i => stall_i,
rty_i => rty_i,
err_i => err_i,
cyc_o => cyc_o,
memReq_o => memReq_o,
WBdata_o => wbData_o,
wbData_i => wbData_i,
locAddr_o => locAddr_o,
memAckWB_i => memAckWB_i,
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 signal is asserted
-- If the Wb memory is addressed the CardSel signal is asserted.
Inst_Access_Decode: VME_Access_Decode port map(
clk_i => clk_i,
reset => s_reset,
mainFSMreset => s_mainFSMreset,
decode => s_decode,
ModuleEnable => ModuleEnable,
InitInProgress => s_initInProgress,
Addr => std_logic_vector(s_locAddr),
Ader0 => Ader0,
Ader1 => Ader1,
Ader2 => Ader2,
Ader3 => Ader3,
Ader4 => Ader4,
Ader5 => Ader5,
Ader6 => Ader6,
Ader7 => Ader7,
Adem0 => s_FUNC_ADEM(0),
Adem1 => s_FUNC_ADEM(1),
Adem2 => s_FUNC_ADEM(2),
Adem3 => s_FUNC_ADEM(3),
Adem4 => s_FUNC_ADEM(4),
Adem5 => s_FUNC_ADEM(5),
Adem6 => s_FUNC_ADEM(6),
Adem7 => s_FUNC_ADEM(7),
AmCap0 => s_FUNC_AMCAP(0),
AmCap1 => s_FUNC_AMCAP(1),
AmCap2 => s_FUNC_AMCAP(2),
AmCap3 => s_FUNC_AMCAP(3),
AmCap4 => s_FUNC_AMCAP(4),
AmCap5 => s_FUNC_AMCAP(5),
AmCap6 => s_FUNC_AMCAP(6),
AmCap7 => s_FUNC_AMCAP(7),
XAmCap0 => s_FUNC_XAMCAP(0),
XAmCap1 => s_FUNC_XAMCAP(1),
XAmCap2 => s_FUNC_XAMCAP(2),
XAmCap3 => s_FUNC_XAMCAP(3),
XAmCap4 => s_FUNC_XAMCAP(4),
XAmCap5 => s_FUNC_XAMCAP(5),
XAmCap6 => s_FUNC_XAMCAP(6),
XAmCap7 => s_FUNC_XAMCAP(7),
Am => s_AMlatched,
XAm => std_logic_vector(s_XAM),
BAR_i => BAR_i,
AddrWidth => s_addrWidth,
Funct_Sel => s_func_sel,
Base_Addr => s_nx_base_addr,
Confaccess => s_confAccess,
CardSel => s_cardSel
);
s_base_addr <= unsigned(s_nx_base_addr);
-- CR/CSR addressing
-- Please note that the location of the user defined CR and CSR regions as well as the CRAM
-- region are programmable. If these regions are overlapped the vme64x core asserts the BERR* line
s_CSRaddressed <= '1' when (s_locAddr(18 downto 0) <= x"7FFFF" and
s_locAddr(18 downto 0) >= x"7FC00") xor
(s_locAddr(18 downto 0) >= unsigned(s_BEG_USER_CSR(18 downto 0)) and
s_locAddr(18 downto 0) <= unsigned(s_END_USER_CSR(18 downto 0)) and
unsigned(s_BEG_USER_CSR) < unsigned(s_END_USER_CSR)) else '0';
s_CRaddressed <= '1' when (s_locAddr(18 downto 0) <= x"00FFF" and
s_locAddr(18 downto 0) >= x"00000") xor
(s_locAddr(18 downto 0) >= unsigned(s_BEG_USER_CR(18 downto 0)) and
s_locAddr(18 downto 0) <= unsigned(s_END_USER_CR(18 downto 0)) and
unsigned(s_BEG_USER_CR) < unsigned(s_END_USER_CR)) else '0';
s_CRAMaddressed <= '1' when (s_locAddr(18 downto 0) >= unsigned(s_BEG_CRAM(18 downto 0)) and
s_locAddr(18 downto 0) <= unsigned(s_END_CRAM(18 downto 0)) and
unsigned(s_BEG_CRAM) < unsigned(s_END_CRAM)) else '0';
--------------------------ACKNOWLEDGE---------------------------------------|
--s_memAck should be asserted also if an error condition is detected.
process(clk_i)
begin
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)
begin
if rising_edge(clk_i) then
if s_reset = '1' then
s_memAckCSR <= '0';
else
if s_memReq = '1' and s_confAccess = '1' then
s_memAckCSR <= '1';
else
s_memAckCSR <= '0';
end if;
end if;
end if;
end process;
-----------------------CR/CSR IN/OUT----------------------------------------|
en_wr_CSR <= '1' when ((s_typeOfDataTransfer = D08_3 or s_typeOfDataTransfer = D32 or
s_typeOfDataTransfer = D16_23 or (s_typeOfDataTransfer = D64 and
s_transferType /= MBLT)) and s_memReq = '1' and
s_confAccess = '1' and s_RW = '0') else '0';
CrCsrOffsetAddr <= std_logic_vector(s_CrCsrOffsetAddr);
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
if s_mainFSMreset = '1' then
s_sw_reset <= Sw_Reset;
else
s_sw_reset <= '0';
end if;
end if;
end process;
-- 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 s_reset = '1' or s_mainFSMreset = '1' then
s_countertime <= (others => '0');
elsif VME_AS_n_i = '0' then
s_countertime <= s_countertime + to_unsigned(g_clock,40);
end if;
end if;
end process;
process(clk_i)
begin
if rising_edge(clk_i) then
if (s_mainFSMreset = '1' and s_cardSel = '1') or s_reset = '1' then
s_time <= std_logic_vector(s_countertime + 30);
end if;
end if;
end process;
process(clk_i)
begin
if rising_edge(clk_i) 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;
end if;
end if;
end process;
process(clk_i)
begin
if rising_edge(clk_i) then
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 (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(
clk_i => clk_i,
RSTedge_i => s_RSTedge,
CRAddr_i => std_logic_vector(s_CRaddr),
CRdata_i => CRdata_i,
InitReadCount_o => s_initReadCounter1,
InitInProgress_o => s_initInProgress,
BEG_USR_CR_o => s_BEG_USER_CR,
END_USR_CR_o => s_END_USER_CR,
BEG_USR_CSR_o => s_BEG_USER_CSR,
END_USR_CSR_o => s_END_USER_CSR,
BEG_CRAM_o => s_BEG_CRAM,
END_CRAM_o => s_END_CRAM,
FUNC0_ADEM_o => s_FUNC_ADEM(0),
FUNC1_ADEM_o => s_FUNC_ADEM(1),
FUNC2_ADEM_o => s_FUNC_ADEM(2),
FUNC3_ADEM_o => s_FUNC_ADEM(3),
FUNC4_ADEM_o => s_FUNC_ADEM(4),
FUNC5_ADEM_o => s_FUNC_ADEM(5),
FUNC6_ADEM_o => s_FUNC_ADEM(6),
FUNC7_ADEM_o => s_FUNC_ADEM(7),
FUNC0_AMCAP_o => s_FUNC_AMCAP(0),
FUNC1_AMCAP_o => s_FUNC_AMCAP(1),
FUNC2_AMCAP_o => s_FUNC_AMCAP(2),
FUNC3_AMCAP_o => s_FUNC_AMCAP(3),
FUNC4_AMCAP_o => s_FUNC_AMCAP(4),
FUNC5_AMCAP_o => s_FUNC_AMCAP(5),
FUNC6_AMCAP_o => s_FUNC_AMCAP(6),
FUNC7_AMCAP_o => s_FUNC_AMCAP(7),
FUNC0_XAMCAP_o => s_FUNC_XAMCAP(0),
FUNC1_XAMCAP_o => s_FUNC_XAMCAP(1),
FUNC2_XAMCAP_o => s_FUNC_XAMCAP(2),
FUNC3_XAMCAP_o => s_FUNC_XAMCAP(3),
FUNC4_XAMCAP_o => s_FUNC_XAMCAP(4),
FUNC5_XAMCAP_o => s_FUNC_XAMCAP(5),
FUNC6_XAMCAP_o => s_FUNC_XAMCAP(6),
FUNC7_XAMCAP_o => s_FUNC_XAMCAP(7)
);
------------------EDGE DETECTION and SAMPLING-----------------------------------------
ASfallingEdge : FallingEdgeDetection
port map (
sig_i => VME_AS_n_i,
clk_i => clk_i,
FallEdge_o => s_VMEaddrLatch
);
RSTrisingEdge : RisEdgeDetection
port map (
sig_i => s_reset,
clk_i => clk_i,
RisEdge_o => s_RSTedge
);
ASrisingEdge : RisEdgeDetection
port map (
sig_i => VME_AS_n_i,
clk_i => clk_i,
RisEdge_o => s_mainFSMreset
);
CRinputSample : DoubleRegInputSample
generic map(
width => 8
)
port map(
reg_i => CRdata_i,
reg_o => s_CRdataIn,
clk_i => clk_i
);
CRAMinputSample : SingleRegInputSample
generic map(
width => 8
)
port map(
reg_i => CRAMdata_i,
reg_o => s_CRAMdataIn,
clk_i => clk_i
);
------------------------------LEDS------------------------------------------------|
-- Debug
process(clk_i)
begin
if rising_edge(clk_i) then
if s_reset = '1' then
s_led5 <= '1';
elsif g_wb_data_width = 32 then
s_led5 <= '0';
end if;
end if;
end process;
leds(6) <= not ModuleEnable;
leds(2) <= '1';
leds(7) <= s_counter(25);
leds(5) <= s_led5;
leds(4) <= not s_errorflag;
leds(1) <= '1';
leds(3) <= '1';
leds(0) <= '1';
-------------------------------------------------------------------------------------------
-- This process implements a simple 26 bit counter. If the bitstream file has been downloaded
-- correctly and the clock is working properly you can see a led flash on the board.
process(clk_i)
begin
if rising_edge(clk_i) then
if VME_RST_n_i = '0' then
s_counter <= (others => '0');
else
s_counter <= s_counter + 1;
end if;
end if;
end process;
end RTL;
--===========================================================================
-- Architecture end
--===========================================================================
\ No newline at end of file
--______________________________________________________________________________
-- VME TO WB INTERFACE
--
-- CERN,BE/CO-HT
--______________________________________________________________________________
-- File: VME_swapper.vhd
--______________________________________________________________________________
-- Description:
--sel= 00 --> No swap
--sel= 01 --> Swap Byte eg: 01234567 became 10325476
--sel= 10 --> Swap Word eg: 01234567 became 23016745
--sel= 11 --> Swap Word+ Swap Byte eg: 01234567 became 32107654
--______________________________________________________________________________
-- Authors:
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--______________________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your option)
-- any later version. This source is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
-- more details. You should have received a copy of the GNU Lesser General Public
-- License along with this source; if not, download it from
-- http://www.gnu.org/licenses/lgpl-2.1.html
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--===========================================================================
-- Entity declaration
--===========================================================================
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);
signal Byte2_i : std_logic_vector(7 downto 0);
signal Byte3_i : std_logic_vector(7 downto 0);
signal Byte4_i : std_logic_vector(7 downto 0);
signal Byte5_i : std_logic_vector(7 downto 0);
signal Byte6_i : std_logic_vector(7 downto 0);
signal Byte7_i : std_logic_vector(7 downto 0);
signal Byte0_o : std_logic_vector(7 downto 0);
signal Byte1_o : std_logic_vector(7 downto 0);
signal Byte2_o : std_logic_vector(7 downto 0);
signal Byte3_o : std_logic_vector(7 downto 0);
signal Byte4_o : std_logic_vector(7 downto 0);
signal Byte5_o : std_logic_vector(7 downto 0);
signal Byte6_o : std_logic_vector(7 downto 0);
signal Byte7_o : std_logic_vector(7 downto 0);
--===========================================================================
-- Architecture begin
--===========================================================================
begin
process (sel,Byte0_i,Byte1_i,Byte2_i,Byte3_i,Byte7_i)
begin
case sel is
when "000" => Byte0_o <= Byte0_i;
when "001" => Byte0_o <= Byte1_i;
when "010" => Byte0_o <= Byte2_i;
when "011" => Byte0_o <= Byte3_i;
when "100" => Byte0_o <= Byte7_i;
when others => Byte0_o <= Byte0_i;
end case;
end process;
process (sel,Byte0_i,Byte1_i,Byte2_i,Byte3_i,Byte6_i)
begin
case sel is
when "000" => Byte1_o <= Byte1_i;
when "001" => Byte1_o <= Byte0_i;
when "010" => Byte1_o <= Byte3_i;
when "011" => Byte1_o <= Byte2_i;
when "100" => Byte1_o <= Byte6_i;
when others => Byte1_o <= Byte1_i;
end case;
end process;
process (sel,Byte0_i,Byte1_i,Byte2_i,Byte3_i,Byte5_i)
begin
case sel is
when "000" => Byte2_o <= Byte2_i;
when "001" => Byte2_o <= Byte3_i;
when "010" => Byte2_o <= Byte0_i;
when "011" => Byte2_o <= Byte1_i;
when "100" => Byte2_o <= Byte5_i;
when others => Byte2_o <= Byte2_i;
end case;
end process;
process (sel,Byte0_i,Byte1_i,Byte2_i,Byte3_i,Byte4_i)
begin
case sel is
when "000" => Byte3_o <= Byte3_i;
when "001" => Byte3_o <= Byte2_i;
when "010" => Byte3_o <= Byte1_i;
when "011" => Byte3_o <= Byte0_i;
when "100" => Byte3_o <= Byte4_i;
when others => Byte3_o <= Byte3_i;
end case;
end process;
process (sel,Byte4_i,Byte5_i,Byte6_i,Byte7_i,Byte3_i)
begin
case sel is
when "000" => Byte4_o <= Byte4_i;
when "001" => Byte4_o <= Byte5_i;
when "010" => Byte4_o <= Byte6_i;
when "011" => Byte4_o <= Byte7_i;
when "100" => Byte4_o <= Byte3_i;
when others => Byte4_o <= Byte4_i;
end case;
end process;
process (sel,Byte4_i,Byte5_i,Byte6_i,Byte7_i,Byte2_i)
begin
case sel is
when "000" => Byte5_o <= Byte5_i;
when "001" => Byte5_o <= Byte4_i;
when "010" => Byte5_o <= Byte7_i;
when "011" => Byte5_o <= Byte6_i;
when "100" => Byte5_o <= Byte2_i;
when others => Byte5_o <= Byte5_i;
end case;
end process;
process (sel,Byte4_i,Byte5_i,Byte6_i,Byte7_i,Byte1_i)
begin
case sel is
when "000" => Byte6_o <= Byte6_i;
when "001" => Byte6_o <= Byte7_i;
when "010" => Byte6_o <= Byte4_i;
when "011" => Byte6_o <= Byte5_i;
when "100" => Byte6_o <= Byte1_i;
when others => Byte6_o <= Byte6_i;
end case;
end process;
process (sel,Byte4_i,Byte5_i,Byte6_i,Byte7_i,Byte0_i)
begin
case sel is
when "000" => Byte7_o <= Byte7_i;
when "001" => Byte7_o <= Byte6_i;
when "010" => Byte7_o <= Byte5_i;
when "011" => Byte7_o <= Byte4_i;
when "100" => Byte7_o <= Byte0_i;
when others => Byte7_o <= Byte7_i;
end case;
end process;
Byte0_i <= d_i(7 downto 0);
Byte1_i <= d_i(15 downto 8);
Byte2_i <= d_i(23 downto 16);
Byte3_i <= d_i(31 downto 24);
Byte4_i <= d_i(39 downto 32);
Byte5_i <= d_i(47 downto 40);
Byte6_i <= d_i(55 downto 48);
Byte7_i <= d_i(63 downto 56);
d_o(7 downto 0) <= Byte0_o;
d_o(15 downto 8) <= Byte1_o;
d_o(23 downto 16) <= Byte2_o;
d_o(31 downto 24) <= Byte3_o;
d_o(39 downto 32) <= Byte4_o;
d_o(47 downto 40) <= Byte5_o;
d_o(55 downto 48) <= Byte6_o;
d_o(63 downto 56) <= Byte7_o;
end Behavioral;
--===========================================================================
-- Architecture end
--===========================================================================
--______________________________________________________________________
-- VME TO WB INTERFACE
--
-- CERN,BE/CO-HT
--______________________________________________________________________
-- File: vme64x_pack.vhd
--______________________________________________________________________
-- Authors:
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Davide Pedretti (Davide.Pedretti@cern.ch)
-- Date 11/2012
-- Version v0.03
--_______________________________________________________________________
-- GNU LESSER GENERAL PUBLIC LICENSE
-- ------------------------------------
-- Copyright (c) 2009 - 2011 CERN
-- This source file is free software; you can redistribute it and/or modify it under the terms of
-- the GNU Lesser General Public License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details.
-- You should have received a copy of the GNU Lesser General Public License along with this
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
---------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;
--use work.VME_CR_pack.all;
package vme64x_pack is
--__________________________________________________________________________________
-- Records:
type t_rom_cell is
record
add : integer;
len : integer;
end record;
type t_cr_add_table is array (natural range <>) of t_rom_cell;
type t_FSM is
record
s_memReq : std_logic;
s_decode : std_logic;
s_dtackOE : std_logic;
s_mainDTACK : std_logic;
s_dataDir : std_logic;
s_dataOE : std_logic;
s_addrDir : std_logic;
s_addrOE : std_logic;
s_DSlatch : std_logic;
s_incrementAddr : std_logic;
s_dataPhase : std_logic;
s_dataToOutput : std_logic;
s_dataToAddrBus : std_logic;
s_transferActive : std_logic;
s_2eLatchAddr : std_logic_vector(1 downto 0);
s_retry : std_logic;
s_berr : std_logic;
s_BERR_out : std_logic;
end record;
type t_FSM_IRQ is
record
s_IACKOUT : std_logic;
s_DataDir : std_logic;
s_DTACK : std_logic;
s_enableIRQ : std_logic;
s_resetIRQ : std_logic;
s_DSlatch : std_logic;
s_DTACK_OE : std_logic;
end record;
--_______________________________________________________________________________
-- Constants:
--WB data width:
constant c_width : integer := 64; --must be 32 or 64!
--CRAM size in the CR/CSR space (bytes):
constant c_CRAM_SIZE : integer := 1024;
-- remember to set properly the "END_CRAM" register in the CR space
-- WB addr width:
constant c_addr_width : integer := 9;
--
constant DFS : integer := 2; -- for accessing at the ADEM's bit 2
constant XAM_MODE : integer := 0; -- for accessing at the ADER's bit 0
-- Tclk in ns used to calculate the data transfer rate
constant c_clk_period : integer := 10; --c_CLK_PERIOD : std_logic_vector(19 downto 0) := "00000000000000001010";
-- add here the default boards ID:
constant c_SVEC_ID : integer := 408; -- 0x00000198
constant c_CERN_ID : integer := 524336; -- 0x080030
constant c_RevisionID : integer := 1; -- 0x00000001
--BoardID positions:
constant c_BOARD_ID_p1 : integer := 12;
constant c_BOARD_ID_p2 : integer := 13;
constant c_BOARD_ID_p3 : integer := 14;
constant c_BOARD_ID_p4 : integer := 15;
--ManufacturerID positions:
constant c_Manuf_ID_p1 : integer := 9;
constant c_Manuf_ID_p2 : integer := 10;
constant c_Manuf_ID_p3 : integer := 11;
--RevisionID positions:
constant c_Rev_ID_p1 : integer := 16;
constant c_Rev_ID_p2 : integer := 17;
constant c_Rev_ID_p3 : integer := 18;
constant c_Rev_ID_p4 : integer := 19;
--ProgramID positions:
constant c_Prog_ID_p : integer := 31;
-- AM table.
-- References:
-- Table 2-3 "Address Modifier Codes" pages 21/22 VME64std ANSI/VITA 1-1994
-- Table 2.4 "Extended Address Modifier Code" page 12 2eSST ANSI/VITA 1.5-2003(R2009)
constant c_A24_S_sup : std_logic_vector(5 downto 0) := "111101"; -- hex code 0x3d
constant c_A24_S : std_logic_vector(5 downto 0) := "111001"; -- hex code 0x39
constant c_A24_BLT : std_logic_vector(5 downto 0) := "111011"; -- hex code 0x3b
constant c_A24_BLT_sup : std_logic_vector(5 downto 0) := "111111"; -- hex code 0x3f
constant c_A24_MBLT : std_logic_vector(5 downto 0) := "111000"; -- hex code 0x38
constant c_A24_MBLT_sup : std_logic_vector(5 downto 0) := "111100"; -- hex code 0x3c
constant c_A24_LCK : std_logic_vector(5 downto 0) := "110010"; -- hex code 0x32
constant c_CR_CSR : std_logic_vector(5 downto 0) := "101111"; -- hex code 0x2f
constant c_A16 : std_logic_vector(5 downto 0) := "101001"; -- hex code 0x29
constant c_A16_sup : std_logic_vector(5 downto 0) := "101101"; -- hex code 0x2d
constant c_A16_LCK : std_logic_vector(5 downto 0) := "101100"; -- hex code 0x2c
constant c_A32 : std_logic_vector(5 downto 0) := "001001"; -- hex code 0x09
constant c_A32_sup : std_logic_vector(5 downto 0) := "001101"; -- hex code 0x0d
constant c_A32_BLT : std_logic_vector(5 downto 0) := "001011"; -- hex code 0x0b
constant c_A32_BLT_sup : std_logic_vector(5 downto 0) := "001111"; -- hex code 0x0f
constant c_A32_MBLT : std_logic_vector(5 downto 0) := "001000"; -- hex code 0x08
constant c_A32_MBLT_sup : std_logic_vector(5 downto 0) := "001100"; -- hex code 0x0c
constant c_A32_LCK : std_logic_vector(5 downto 0) := "000101"; -- hex code 0x05
constant c_A64 : std_logic_vector(5 downto 0) := "000001"; -- hex code 0x01
constant c_A64_BLT : std_logic_vector(5 downto 0) := "000011"; -- hex code 0x03
constant c_A64_MBLT : std_logic_vector(5 downto 0) := "000000"; -- hex code 0x00
constant c_A64_LCK : std_logic_vector(5 downto 0) := "000100"; -- hex code 0x04
constant c_TWOedge : std_logic_vector(5 downto 0) := "100000"; -- hex code 0x20
constant c_A32_2eVME : std_logic_vector(7 downto 0) := "00000001"; -- hex code 0x21
constant c_A64_2eVME : std_logic_vector(7 downto 0) := "00000010"; -- hex code 0x22
constant c_A32_2eSST : std_logic_vector(7 downto 0) := "00010001"; -- hex code 0x11
constant c_A64_2eSST : std_logic_vector(7 downto 0) := "00010010"; -- hex code 0x12
--CSR array's index:
constant BAR : integer := 255;
constant BIT_SET_CLR_REG : integer := 254;
constant USR_BIT_SET_CLR_REG : integer := 253;
constant CRAM_OWNER : integer := 252;
constant FUNC7_ADER_0 : integer := 251;
constant FUNC7_ADER_1 : integer := FUNC7_ADER_0 - 1;
constant FUNC7_ADER_2 : integer := FUNC7_ADER_0 - 2;
constant FUNC7_ADER_3 : integer := FUNC7_ADER_0 - 3;
constant FUNC6_ADER_0 : integer := FUNC7_ADER_0 - 4;
constant FUNC6_ADER_1 : integer := FUNC7_ADER_0 - 5;
constant FUNC6_ADER_2 : integer := FUNC7_ADER_0 - 6;
constant FUNC6_ADER_3 : integer := FUNC7_ADER_0 - 7;
constant FUNC5_ADER_0 : integer := FUNC7_ADER_0 - 8;
constant FUNC5_ADER_1 : integer := FUNC7_ADER_0 - 9;
constant FUNC5_ADER_2 : integer := FUNC7_ADER_0 - 10;
constant FUNC5_ADER_3 : integer := FUNC7_ADER_0 - 11;
constant FUNC4_ADER_0 : integer := FUNC7_ADER_0 - 12;
constant FUNC4_ADER_1 : integer := FUNC7_ADER_0 - 13;
constant FUNC4_ADER_2 : integer := FUNC7_ADER_0 - 14;
constant FUNC4_ADER_3 : integer := FUNC7_ADER_0 - 15;
constant FUNC3_ADER_0 : integer := FUNC7_ADER_0 - 16;
constant FUNC3_ADER_1 : integer := FUNC7_ADER_0 - 17;
constant FUNC3_ADER_2 : integer := FUNC7_ADER_0 - 18;
constant FUNC3_ADER_3 : integer := FUNC7_ADER_0 - 19;
constant FUNC2_ADER_0 : integer := FUNC7_ADER_0 - 20;
constant FUNC2_ADER_1 : integer := FUNC7_ADER_0 - 21;
constant FUNC2_ADER_2 : integer := FUNC7_ADER_0 - 22;
constant FUNC2_ADER_3 : integer := FUNC7_ADER_0 - 23;
constant FUNC1_ADER_0 : integer := FUNC7_ADER_0 - 24;
constant FUNC1_ADER_1 : integer := FUNC7_ADER_0 - 25;
constant FUNC1_ADER_2 : integer := FUNC7_ADER_0 - 26;
constant FUNC1_ADER_3 : integer := FUNC7_ADER_0 - 27;
constant FUNC0_ADER_0 : integer := FUNC7_ADER_0 - 28;
constant FUNC0_ADER_1 : integer := FUNC7_ADER_0 - 29;
constant FUNC0_ADER_2 : integer := FUNC7_ADER_0 - 30;
constant FUNC0_ADER_3 : integer := FUNC7_ADER_0 - 31;
constant IRQ_Vector : integer := FUNC0_ADER_3 -1;
constant IRQ_level : integer := FUNC0_ADER_3 -2;
constant TIME0_ns : integer := FUNC0_ADER_3 -5;
constant TIME1_ns : integer := FUNC0_ADER_3 -6;
constant TIME2_ns : integer := FUNC0_ADER_3 -7;
constant TIME3_ns : integer := FUNC0_ADER_3 -8;
constant TIME4_ns : integer := FUNC0_ADER_3 -9;
constant BYTES0 : integer := FUNC0_ADER_3 -10;
constant BYTES1 : integer := FUNC0_ADER_3 -11;
constant WB32bits : integer := FUNC0_ADER_3 -12;
constant Endian : integer := FUNC0_ADER_3 -4;
-- Initialization CR:
constant BEG_USER_CR : integer := 1;
constant END_USER_CR : integer := 2;
constant BEG_CRAM : integer := 3;
constant END_CRAM : integer := 4;
constant BEG_USER_CSR : integer := 5;
constant END_USER_CSR : integer := 6;
constant FUNC_AMCAP : integer := 7;
constant FUNC_XAMCAP : integer := 8;
constant FUNC_ADEM : integer := 9;
constant c_CRinitAddr : t_cr_add_table(BEG_USER_CR to FUNC_ADEM) := (
BEG_USER_CR => (add => 16#020#, len => 3),
END_USER_CR => (add => 16#023#, len => 3),
BEG_CRAM => (add => 16#26#, len => 3),
END_CRAM => (add => 16#29#, len => 3),
BEG_USER_CSR => (add => 16#02C#, len => 3),
END_USER_CSR => (add => 16#02F#, len => 3),
FUNC_AMCAP => (add => 16#048#, len => 64),
FUNC_XAMCAP => (add => 16#088#, len => 256),
FUNC_ADEM => (add => 16#188#, len => 32));
-- Main Finite State machine signals default:
-- When the S_FPGA detects the magic sequency, it erases the A_FPGA so
-- I don't need to drive the s_dtackOE, s_dataOE, s_addrOE, s_addrDir, s_dataDir
-- to 'Z' in the default configuration.
-- If the S_FPGA will be provided to a core who drive these lines without erase the
-- A_FPGA the above mentioned lines should be changed to 'Z' !!!
constant c_FSM_default : t_FSM :=(
s_memReq => '0',
s_decode => '0',
s_dtackOE => '0',
s_mainDTACK => '1',
s_dataDir => '0',
s_dataOE => '0',
s_addrDir => '0', -- during IACK cycle the ADDR lines are input
s_addrOE => '0',
s_DSlatch => '0',
s_incrementAddr => '0',
s_dataPhase => '0',
s_dataToOutput => '0',
s_dataToAddrBus => '0',
s_transferActive => '0',
s_2eLatchAddr => "00",
s_retry => '0',
s_berr => '0',
s_BERR_out => '0'
);
constant c_FSM_IRQ : t_FSM_IRQ :=(
s_IACKOUT => '1',
s_DataDir => '0',
s_DTACK => '1',
s_enableIRQ => '0',
s_resetIRQ => '1',
s_DSlatch => '0',
s_DTACK_OE => '0'
);
-- CSR address:
constant c_BAR_addr : unsigned(19 downto 0) := x"7FFFF"; -- VME64x defined CSR
constant c_BIT_SET_REG_addr : unsigned(19 downto 0) := x"7FFFB";
constant c_BIT_CLR_REG_addr : unsigned(19 downto 0) := x"7FFF7";
constant c_CRAM_OWNER_addr : unsigned(19 downto 0) := x"7FFF3";
constant c_USR_BIT_SET_REG_addr : unsigned(19 downto 0) := x"7FFEF";
constant c_USR_BIT_CLR_REG_addr : unsigned(19 downto 0) := x"7FFEB";
constant c_FUNC7_ADER_0_addr : unsigned(19 downto 0) := x"7FFDF";
constant c_FUNC7_ADER_1_addr : unsigned(19 downto 0) := x"7FFDB";
constant c_FUNC7_ADER_2_addr : unsigned(19 downto 0) := x"7FFD7";
constant c_FUNC7_ADER_3_addr : unsigned(19 downto 0) := x"7FFD3";
constant c_FUNC6_ADER_0_addr : unsigned(19 downto 0) := x"7FFCF";
constant c_FUNC6_ADER_1_addr : unsigned(19 downto 0) := x"7FFCB";
constant c_FUNC6_ADER_2_addr : unsigned(19 downto 0) := x"7FFC7";
constant c_FUNC6_ADER_3_addr : unsigned(19 downto 0) := x"7FFC3";
constant c_FUNC5_ADER_0_addr : unsigned(19 downto 0) := x"7FFBF";
constant c_FUNC5_ADER_1_addr : unsigned(19 downto 0) := x"7FFBB";
constant c_FUNC5_ADER_2_addr : unsigned(19 downto 0) := x"7FFB7";
constant c_FUNC5_ADER_3_addr : unsigned(19 downto 0) := x"7FFB3";
constant c_FUNC4_ADER_0_addr : unsigned(19 downto 0) := x"7FFAF";
constant c_FUNC4_ADER_1_addr : unsigned(19 downto 0) := x"7FFAB";
constant c_FUNC4_ADER_2_addr : unsigned(19 downto 0) := x"7FFA7";
constant c_FUNC4_ADER_3_addr : unsigned(19 downto 0) := x"7FFA3";
constant c_FUNC3_ADER_0_addr : unsigned(19 downto 0) := x"7FF9F";
constant c_FUNC3_ADER_1_addr : unsigned(19 downto 0) := x"7FF9B";
constant c_FUNC3_ADER_2_addr : unsigned(19 downto 0) := x"7FF97";
constant c_FUNC3_ADER_3_addr : unsigned(19 downto 0) := x"7FF93";
constant c_FUNC2_ADER_0_addr : unsigned(19 downto 0) := x"7FF8F";
constant c_FUNC2_ADER_1_addr : unsigned(19 downto 0) := x"7FF8B";
constant c_FUNC2_ADER_2_addr : unsigned(19 downto 0) := x"7FF87";
constant c_FUNC2_ADER_3_addr : unsigned(19 downto 0) := x"7FF83";
constant c_FUNC1_ADER_0_addr : unsigned(19 downto 0) := x"7FF7F";
constant c_FUNC1_ADER_1_addr : unsigned(19 downto 0) := x"7FF7B";
constant c_FUNC1_ADER_2_addr : unsigned(19 downto 0) := x"7FF77";
constant c_FUNC1_ADER_3_addr : unsigned(19 downto 0) := x"7FF73";
constant c_FUNC0_ADER_0_addr : unsigned(19 downto 0) := x"7FF6F";
constant c_FUNC0_ADER_1_addr : unsigned(19 downto 0) := x"7FF6B";
constant c_FUNC0_ADER_2_addr : unsigned(19 downto 0) := x"7FF67";
constant c_FUNC0_ADER_3_addr : unsigned(19 downto 0) := x"7FF63"; -- VME64x defined CSR
constant c_IRQ_Vector_addr : unsigned(19 downto 0) := x"7FF5F"; -- VME64x reserved CSR
constant c_IRQ_level_addr : unsigned(19 downto 0) := x"7FF5B"; -- VME64x reserved CSR
constant c_TIME0_ns_addr : unsigned(19 downto 0) := x"7FF4f"; -- VME64x reserved CSR
constant c_TIME1_ns_addr : unsigned(19 downto 0) := x"7FF4b";
constant c_TIME2_ns_addr : unsigned(19 downto 0) := x"7FF47";
constant c_TIME3_ns_addr : unsigned(19 downto 0) := x"7FF43";
constant c_TIME4_ns_addr : unsigned(19 downto 0) := x"7FF3f";
constant c_BYTES0_addr : unsigned(19 downto 0) := x"7FF3b";
constant c_BYTES1_addr : unsigned(19 downto 0) := x"7FF37";
constant c_WB32bits_addr : unsigned(19 downto 0) := x"7FF33";
constant c_Endian_addr : unsigned(19 downto 0) := x"7FF53"; -- VME64x reserved CSR
--___________________________________________________________________________________________
-- TYPE:
type t_typeOfDataTransfer is ( D08_0,
D08_1,
D08_2,
D08_3,
D16_01,
D16_23,
D32,
D64,
TypeError
);
type t_addressingType is ( A24,
A24_BLT,
A24_MBLT,
CR_CSR,
A16,
A32,
A32_BLT,
A32_MBLT,
A64,
A64_BLT,
A64_MBLT,
TWOedge,
AM_Error
);
type t_transferType is ( SINGLE,
BLT,
MBLT,
TWOe,
error
);
type t_XAMtype is ( A32_2eVME,
A64_2eVME,
A32_2eSST,
A64_2eSST,
A32_2eSSTb,
A64_2eSSTb,
XAM_error
);
type t_2eType is ( TWOe_VME,
TWOe_SST
);
type t_mainFSMstates is ( IDLE,
DECODE_ACCESS,
WAIT_FOR_DS,
LATCH_DS1,
LATCH_DS2,
LATCH_DS3,
LATCH_DS4,
CHECK_TRANSFER_TYPE,
MEMORY_REQ,
DATA_TO_BUS,
DTACK_LOW,
DECIDE_NEXT_CYCLE,
INCREMENT_ADDR,
SET_DATA_PHASE
-- uncomment for using 2e modes:
-- WAIT_FOR_DS_2e,
-- ADDR_PHASE_1,
-- ADDR_PHASE_2,
-- ADDR_PHASE_3,
-- DECODE_ACCESS_2e,
-- DTACK_PHASE_1,
-- DTACK_PHASE_2,
-- DTACK_PHASE_3,
-- TWOeVME_WRITE,
-- TWOeVME_READ,
-- TWOeVME_MREQ_RD,
-- WAIT_WR_1,
-- WAIT_WR_2,
-- WAIT_WB_ACK_WR,
-- WAIT_WB_ACK_RD,
-- TWOeVME_TOGGLE_WR,
-- TWOeVME_TOGGLE_RD,
-- TWOe_FIFO_WRITE,
-- TWOe_TOGGLE_DTACK,
-- TWOeVME_INCR_ADDR,
-- TWOe_WAIT_FOR_DS1,
-- TWOe_FIFO_WAIT_READ,
-- TWOe_FIFO_READ,
-- TWOe_CHECK_BEAT,
-- TWOe_RELEASE_DTACK,
-- TWOe_END_1,
-- TWOe_END_2
);
type t_initState is ( IDLE,
SET_ADDR,
GET_DATA,
END_INIT
);
type t_FUNC_32b_array is array (0 to 7) of unsigned(31 downto 0); -- ADER register array
type t_FUNC_64b_array is array (0 to 7) of unsigned(63 downto 0); -- AMCAP register array
type t_FUNC_256b_array is array (0 to 7) of unsigned(255 downto 0); -- XAMCAP register array
type t_FUNC_32b_array_std is array (0 to 7) of std_logic_vector(31 downto 0); -- ADER register array
type t_FUNC_64b_array_std is array (0 to 7) of std_logic_vector(63 downto 0); -- AMCAP register array
type t_FUNC_256b_array_std is array (0 to 7) of std_logic_vector(255 downto 0); -- XAMCAP register array
type t_CSRarray is array(BAR downto WB32bits) of unsigned(7 downto 0);
type t_cr_array is array (natural range <>) of std_logic_vector(7 downto 0);
-- functions
function f_div8 (width : integer) return integer;
function f_log2_size (A : natural) return natural;
function f_set_CR_space (BoardID : integer; cr_default : t_cr_array;
ManufacturerID : integer; RevisionID : integer; ProgramID : integer) return t_cr_array;
function f_latchDS (clk_period : integer) return integer;
--_____________________________________________________________________________________________________
--COMPONENTS:
component VME_bus is
generic( g_clock : integer := c_clk_period;
g_wb_data_width : integer := c_width;
g_wb_addr_width : integer := c_addr_width;
g_cram_size : integer := c_CRAM_SIZE
);
port(
clk_i : in std_logic;
VME_RST_n_i : in std_logic;
VME_AS_n_i : in std_logic;
VME_LWORD_n_i : in std_logic;
VME_WRITE_n_i : in std_logic;
VME_DS_n_i : in std_logic_vector(1 downto 0);
VME_DS_ant_n_i : in std_logic_vector(1 downto 0);
VME_ADDR_i : in std_logic_vector(31 downto 1);
VME_DATA_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(g_wb_data_width - 1 downto 0);
err_i : in std_logic;
rty_i : in std_logic;
stall_i : in std_logic;
CRAMdata_i : in std_logic_vector(7 downto 0);
CRdata_i : in std_logic_vector(7 downto 0);
CSRData_i : in std_logic_vector(7 downto 0);
reset_flag_i : in std_logic;
Ader0 : in std_logic_vector(31 downto 0);
Ader1 : in std_logic_vector(31 downto 0);
Ader2 : in std_logic_vector(31 downto 0);
Ader3 : in std_logic_vector(31 downto 0);
Ader4 : in std_logic_vector(31 downto 0);
Ader5 : in std_logic_vector(31 downto 0);
Ader6 : in std_logic_vector(31 downto 0);
Ader7 : in std_logic_vector(31 downto 0);
ModuleEnable : in std_logic;
Endian_i : in std_logic_vector(2 downto 0);
Sw_Reset : in std_logic;
BAR_i : in std_logic_vector(4 downto 0);
reset_o : out std_logic;
VME_LWORD_n_o : out std_logic;
VME_RETRY_n_o : out std_logic;
VME_RETRY_OE_o : out std_logic;
VME_DTACK_n_o : out std_logic;
VME_DTACK_OE_o : out std_logic;
VME_BERR_o : out std_logic;
VME_ADDR_o : out std_logic_vector(31 downto 1);
VME_ADDR_DIR_o : out std_logic;
VME_ADDR_OE_N_o : out std_logic;
VME_DATA_o : out std_logic_vector(31 downto 0);
VME_DATA_DIR_o : out std_logic;
VME_DATA_OE_N_o : out std_logic;
memReq_o : out std_logic;
wbData_o : out std_logic_vector(g_wb_data_width - 1 downto 0);
locAddr_o : out std_logic_vector(g_wb_addr_width - 1 downto 0);
wbSel_o : out std_logic_vector(f_div8(g_wb_data_width) - 1 downto 0);
RW_o : out std_logic;
cyc_o : out std_logic;
CRAMaddr_o : out std_logic_vector(f_log2_size(g_cram_size)-1 downto 0);
CRAMdata_o : out std_logic_vector(7 downto 0);
CRAMwea_o : out std_logic;
CRaddr_o : out std_logic_vector(11 downto 0);
en_wr_CSR : out std_logic;
CrCsrOffsetAddr : out std_logic_vector(18 downto 0);
CSRData_o : out std_logic_vector(7 downto 0);
err_flag_o : out std_logic;
numBytes : out std_logic_vector(12 downto 0);
transfTime : out std_logic_vector(39 downto 0);
leds : out std_logic_vector(7 downto 0)
);
end component VME_bus;
component VME_Access_Decode is
port (
clk_i : in std_logic;
reset : in std_logic;
mainFSMreset : in std_logic;
decode : in std_logic;
ModuleEnable : in std_logic;
InitInProgress : in std_logic;
Addr : in std_logic_vector(63 downto 0);
Ader0 : in std_logic_vector(31 downto 0);
Ader1 : in std_logic_vector(31 downto 0);
Ader2 : in std_logic_vector(31 downto 0);
Ader3 : in std_logic_vector(31 downto 0);
Ader4 : in std_logic_vector(31 downto 0);
Ader5 : in std_logic_vector(31 downto 0);
Ader6 : in std_logic_vector(31 downto 0);
Ader7 : in std_logic_vector(31 downto 0);
Adem0 : in std_logic_vector(31 downto 0);
Adem1 : in std_logic_vector(31 downto 0);
Adem2 : in std_logic_vector(31 downto 0);
Adem3 : in std_logic_vector(31 downto 0);
Adem4 : in std_logic_vector(31 downto 0);
Adem5 : in std_logic_vector(31 downto 0);
Adem6 : in std_logic_vector(31 downto 0);
Adem7 : in std_logic_vector(31 downto 0);
AmCap0 : in std_logic_vector(63 downto 0);
AmCap1 : in std_logic_vector(63 downto 0);
AmCap2 : in std_logic_vector(63 downto 0);
AmCap3 : in std_logic_vector(63 downto 0);
AmCap4 : in std_logic_vector(63 downto 0);
AmCap5 : in std_logic_vector(63 downto 0);
AmCap6 : in std_logic_vector(63 downto 0);
AmCap7 : in std_logic_vector(63 downto 0);
XAmCap0 : in std_logic_vector(255 downto 0);
XAmCap1 : in std_logic_vector(255 downto 0);
XAmCap2 : in std_logic_vector(255 downto 0);
XAmCap3 : in std_logic_vector(255 downto 0);
XAmCap4 : in std_logic_vector(255 downto 0);
XAmCap5 : in std_logic_vector(255 downto 0);
XAmCap6 : in std_logic_vector(255 downto 0);
XAmCap7 : in std_logic_vector(255 downto 0);
Am : in std_logic_vector(5 downto 0);
XAm : in std_logic_vector(7 downto 0);
BAR_i : in std_logic_vector(4 downto 0);
AddrWidth : in std_logic_vector(1 downto 0);
Funct_Sel : out std_logic_vector(7 downto 0);
Base_Addr : out std_logic_vector(63 downto 0);
Confaccess : out std_logic;
CardSel : out std_logic
);
end component VME_Access_Decode;
component VME_Funct_Match is
port(
clk_i : 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);
Ader1 : in std_logic_vector(31 downto 0);
Ader2 : in std_logic_vector(31 downto 0);
Ader3 : in std_logic_vector(31 downto 0);
Ader4 : in std_logic_vector(31 downto 0);
Ader5 : in std_logic_vector(31 downto 0);
Ader6 : in std_logic_vector(31 downto 0);
Ader7 : in std_logic_vector(31 downto 0);
Adem0 : in std_logic_vector(31 downto 0);
Adem1 : in std_logic_vector(31 downto 0);
Adem2 : in std_logic_vector(31 downto 0);
Adem3 : in std_logic_vector(31 downto 0);
Adem4 : in std_logic_vector(31 downto 0);
Adem5 : in std_logic_vector(31 downto 0);
Adem6 : in std_logic_vector(31 downto 0);
Adem7 : in std_logic_vector(31 downto 0);
FunctMatch : out std_logic_vector(7 downto 0);
DFS_o : out std_logic_vector(7 downto 0);
Nx_Base_Addr : out std_logic_vector(63 downto 0)
);
end component VME_Funct_Match;
component VME_CR_CSR_Space is
generic(
g_cram_size : integer := c_CRAM_SIZE;
g_wb_data_width : integer := c_width;
g_CRspace : t_cr_array; -- := c_cr_array;
g_BoardID : integer := c_SVEC_ID;
g_ManufacturerID : integer := c_CERN_ID;
g_RevisionID : integer := c_RevisionID;
g_ProgramID : integer := 96
);
port(
clk_i : in std_logic;
reset : in std_logic;
CR_addr : in std_logic_vector(11 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);
err_flag : in std_logic;
CR_data : out std_logic_vector(7 downto 0);
CRAM_data_o : out std_logic_vector(7 downto 0);
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);
Ader2 : out std_logic_vector(31 downto 0);
Ader3 : out std_logic_vector(31 downto 0);
Ader4 : out std_logic_vector(31 downto 0);
Ader5 : out std_logic_vector(31 downto 0);
Ader6 : out std_logic_vector(31 downto 0);
Ader7 : out std_logic_vector(31 downto 0);
ModuleEnable : out std_logic;
Sw_Reset : out std_logic;
numBytes : in std_logic_vector(12 downto 0);
transfTime : in std_logic_vector(39 downto 0);
Endian_o : out std_logic_vector(2 downto 0);
BAR_o : out std_logic_vector(4 downto 0);
INT_Level : out std_logic_vector(7 downto 0);
INT_Vector : out std_logic_vector(7 downto 0)
);
end component VME_CR_CSR_Space;
component VME_Am_Match is
port(
clk_i : in std_logic;
reset : in std_logic;
mainFSMreset : in std_logic;
Ader0 : in std_logic_vector(31 downto 0);
Ader1 : in std_logic_vector(31 downto 0);
Ader2 : in std_logic_vector(31 downto 0);
Ader3 : in std_logic_vector(31 downto 0);
Ader4 : in std_logic_vector(31 downto 0);
Ader5 : in std_logic_vector(31 downto 0);
Ader6 : in std_logic_vector(31 downto 0);
Ader7 : in std_logic_vector(31 downto 0);
AmCap0 : in std_logic_vector(63 downto 0);
AmCap1 : in std_logic_vector(63 downto 0);
AmCap2 : in std_logic_vector(63 downto 0);
AmCap3 : in std_logic_vector(63 downto 0);
AmCap4 : in std_logic_vector(63 downto 0);
AmCap5 : in std_logic_vector(63 downto 0);
AmCap6 : in std_logic_vector(63 downto 0);
AmCap7 : in std_logic_vector(63 downto 0);
XAmCap0 : in std_logic_vector(255 downto 0);
XAmCap1 : in std_logic_vector(255 downto 0);
XAmCap2 : in std_logic_vector(255 downto 0);
XAmCap3 : in std_logic_vector(255 downto 0);
XAmCap4 : in std_logic_vector(255 downto 0);
XAmCap5 : in std_logic_vector(255 downto 0);
XAmCap6 : in std_logic_vector(255 downto 0);
XAmCap7 : in std_logic_vector(255 downto 0);
Am : in std_logic_vector(5 downto 0);
XAm : in std_logic_vector(7 downto 0);
DFS_i : in std_logic_vector(7 downto 0);
decode : in std_logic;
AmMatch : out std_logic_vector(7 downto 0)
);
end component VME_Am_Match;
component VME_Wb_master is
generic(
g_wb_data_width : integer := c_width;
g_wb_addr_width : integer := c_addr_width
);
port(
memReq_i : in std_logic;
clk_i : in std_logic;
cardSel_i : in std_logic;
reset_i : in std_logic;
BERRcondition_i : in std_logic;
sel_i : in std_logic_vector(7 downto 0);
locDataInSwap_i : in std_logic_vector(63 downto 0);
rel_locAddr_i : in std_logic_vector(63 downto 0);
RW_i : in std_logic;
stall_i : in std_logic;
rty_i : in std_logic;
err_i : in std_logic;
wbData_i : in std_logic_vector(g_wb_data_width - 1 downto 0);
memAckWB_i : in std_logic;
locDataOut_o : out std_logic_vector(63 downto 0);
memAckWb_o : out std_logic;
err_o : out std_logic;
rty_o : out std_logic;
cyc_o : out std_logic;
memReq_o : out std_logic;
WBdata_o : out std_logic_vector(g_wb_data_width - 1 downto 0);
locAddr_o : out std_logic_vector(g_wb_addr_width - 1 downto 0);
WbSel_o : out std_logic_vector(f_div8(g_wb_data_width) - 1 downto 0);
RW_o : out std_logic
);
end component VME_Wb_master;
component VME_Init is
port(
clk_i : in std_logic;
CRAddr_i : in std_logic_vector(18 downto 0);
CRdata_i : in std_logic_vector(7 downto 0);
RSTedge_i : in std_logic;
InitReadCount_o : out std_logic_vector(8 downto 0);
InitInProgress_o : out std_logic;
BEG_USR_CR_o : out std_logic_vector(23 downto 0);
END_USR_CR_o : out std_logic_vector(23 downto 0);
BEG_USR_CSR_o : out std_logic_vector(23 downto 0);
END_USR_CSR_o : out std_logic_vector(23 downto 0);
BEG_CRAM_o : out std_logic_vector(23 downto 0);
END_CRAM_o : out std_logic_vector(23 downto 0);
FUNC0_ADEM_o : out std_logic_vector(31 downto 0);
FUNC1_ADEM_o : out std_logic_vector(31 downto 0);
FUNC2_ADEM_o : out std_logic_vector(31 downto 0);
FUNC3_ADEM_o : out std_logic_vector(31 downto 0);
FUNC4_ADEM_o : out std_logic_vector(31 downto 0);
FUNC5_ADEM_o : out std_logic_vector(31 downto 0);
FUNC6_ADEM_o : out std_logic_vector(31 downto 0);
FUNC7_ADEM_o : out std_logic_vector(31 downto 0);
FUNC0_AMCAP_o : out std_logic_vector(63 downto 0);
FUNC1_AMCAP_o : out std_logic_vector(63 downto 0);
FUNC2_AMCAP_o : out std_logic_vector(63 downto 0);
FUNC3_AMCAP_o : out std_logic_vector(63 downto 0);
FUNC4_AMCAP_o : out std_logic_vector(63 downto 0);
FUNC5_AMCAP_o : out std_logic_vector(63 downto 0);
FUNC6_AMCAP_o : out std_logic_vector(63 downto 0);
FUNC7_AMCAP_o : out std_logic_vector(63 downto 0);
FUNC0_XAMCAP_o : out std_logic_vector(255 downto 0);
FUNC1_XAMCAP_o : out std_logic_vector(255 downto 0);
FUNC2_XAMCAP_o : out std_logic_vector(255 downto 0);
FUNC3_XAMCAP_o : out std_logic_vector(255 downto 0);
FUNC4_XAMCAP_o : out std_logic_vector(255 downto 0);
FUNC5_XAMCAP_o : out std_logic_vector(255 downto 0);
FUNC6_XAMCAP_o : out std_logic_vector(255 downto 0);
FUNC7_XAMCAP_o : out std_logic_vector(255 downto 0)
);
end component VME_Init;
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 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 FlipFlopD;
component EdgeDetection is
port (
sig_i,clk_i : in std_logic;
sigEdge_o : out std_logic := '0'
);
end component EdgeDetection;
component FallingEdgeDetection is
port (
sig_i, clk_i : in std_logic;
FallEdge_o : out std_logic);
end component FallingEdgeDetection;
component RisEdgeDetection is
port (
sig_i, clk_i : in std_logic;
RisEdge_o : out std_logic);
end component RisEdgeDetection;
component DoubleSigInputSample is
port (
sig_i, clk_i : in std_logic;
sig_o : out std_logic);
end component DoubleSigInputSample;
component SigInputSample is
port (
sig_i, clk_i : in std_logic;
sig_o : out std_logic);
end component SigInputSample;
component DoubleRegInputSample 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 DoubleRegInputSample;
component RegInputSample 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 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 is
port(
clk_i : in std_logic;
reset_n_i : in std_logic;
VME_IACKIN_n_i : in std_logic;
VME_AS_n_i : in std_logic;
VME_AS1_n_i : in std_logic;
VME_DS_n_i : in std_logic_vector(1 downto 0);
VME_LWORD_n_i : in std_logic;
VME_ADDR_123_i : in std_logic_vector(2 downto 0);
INT_Level_i : in std_logic_vector(7 downto 0);
INT_Vector_i : in std_logic_vector(7 downto 0);
INT_Req_i : in std_logic;
VME_IRQ_n_o : out std_logic_vector(6 downto 0);
VME_IACKOUT_n_o : out std_logic;
VME_DTACK_n_o : out std_logic;
VME_DTACK_OE_o : out std_logic;
VME_DATA_o : out std_logic_vector(31 downto 0);
VME_DATA_DIR_o : out std_logic
);
end component VME_IRQ_Controller;
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);
di : in std_logic_vector(dl - 1 downto 0);
dw : out std_logic_vector(dl - 1 downto 0)
);
end component VME_CRAM;
end vme64x_pack;
package body vme64x_pack is
function f_div8 (width : integer) return integer is
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;
function f_set_CR_space(BoardID : integer; cr_default : t_cr_array;
ManufacturerID : integer; RevisionID : integer;
ProgramID : integer) return t_cr_array is
variable v_CR_space : t_cr_array(2**12 downto 0);
variable v_BoardID : std_logic_vector(31 downto 0);
variable v_ManufacturerID : std_logic_vector(23 downto 0);
variable v_RevisionID : std_logic_vector(31 downto 0);
variable v_ProgramID : std_logic_vector(7 downto 0);
begin
v_BoardID := std_logic_vector(to_unsigned(BoardID,32));
v_ManufacturerID := std_logic_vector(to_unsigned(ManufacturerID,24));
v_RevisionID := std_logic_vector(to_unsigned(RevisionID,32));
v_ProgramID := std_logic_vector(to_unsigned(ProgramID,8));
for i in cr_default'range loop
case i is
when c_BOARD_ID_p1 => v_CR_space(i) := v_BoardID(31 downto 24);
when c_BOARD_ID_p2 => v_CR_space(i) := v_BoardID(23 downto 16);
when c_BOARD_ID_p3 => v_CR_space(i) := v_BoardID(15 downto 8);
when c_BOARD_ID_p4 => v_CR_space(i) := v_BoardID(7 downto 0);
when c_Manuf_ID_p1 => v_CR_space(i) := v_ManufacturerID(23 downto 16);
when c_Manuf_ID_p2 => v_CR_space(i) := v_ManufacturerID(15 downto 8);
when c_Manuf_ID_p3 => v_CR_space(i) := v_ManufacturerID(7 downto 0);
when c_Rev_ID_p1 => v_CR_space(i) := v_RevisionID(31 downto 24);
when c_Rev_ID_p2 => v_CR_space(i) := v_RevisionID(23 downto 16);
when c_Rev_ID_p3 => v_CR_space(i) := v_RevisionID(15 downto 8);
when c_Rev_ID_p4 => v_CR_space(i) := v_RevisionID(7 downto 0);
when c_Prog_ID_p => v_CR_space(i) := v_ProgramID(7 downto 0);
when others => v_CR_space(i) := cr_default(i);
end case;
-- if i = c_BOARD_ID_p1 then
-- v_CR_space(i) := v_BoardID(31 downto 24);
-- elsif i = c_BOARD_ID_p2 then
-- v_CR_space(i) := v_BoardID(23 downto 16);
-- elsif i = c_BOARD_ID_p3 then
-- v_CR_space(i) := v_BoardID(15 downto 8);
-- elsif i = c_BOARD_ID_p4 then
-- v_CR_space(i) := v_BoardID(7 downto 0);
-- elsif i = c_Manuf_ID_p1 then
-- v_CR_space(i) := v_ManufacturerID(23 downto 16);
-- elsif i = c_Manuf_ID_p2 then
-- v_CR_space(i) := v_ManufacturerID(15 downto 8);
-- elsif i = c_Manuf_ID_p3 then
-- v_CR_space(i) := v_ManufacturerID(7 downto 0);
-- elsif i = c_Rev_ID_p1 then
-- v_CR_space(i) := v_RevisionID(31 downto 24);
-- elsif i = c_Rev_ID_p2 then
-- v_CR_space(i) := v_RevisionID(23 downto 16);
-- elsif i = c_Rev_ID_p3 then
-- v_CR_space(i) := v_RevisionID(15 downto 8);
-- elsif i = c_Rev_ID_p4 then
-- v_CR_space(i) := v_RevisionID(7 downto 0);
-- elsif i = c_Prog_ID_p then
-- v_CR_space(i) := v_ProgramID(7 downto 0);
-- else
-- v_CR_space(i) := cr_default(i);
-- end if;
end loop;
return(v_CR_space);
end function f_set_CR_space;
function f_latchDS(clk_period : integer) return integer is
begin
for I in 1 to 4 loop
if (clk_period * I >= 20) then -- 20 is the max time between the assertion
-- of the DS lines.
return(I);
end if;
end loop;
return(4); -- works for up to 200 MHz
end function f_latchDS;
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