Commit c24c8fea authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

hdl: top level and simple testbench for SVEC (with 2 fine delays)

parent c993cca5
Please send any questions or opinions to:
Developers: rok.stefanic@cosylab.com, ziga.kroflic@cosylab.com
OHWR list: vme64x-core@ohwr.org
\ No newline at end of file
--==============================================================--
--Design Units : CTX1 Control and Statistics
--Size:
--Speed:
--File Name: MebRam.vhd
--
--Purpose: The dpblockram implements a synthetisable model of a
-- dual port RAM.
-- There are an input data and addr ports to allow the
-- writing at the reception of a GMT frame.
-- The output data and addr ports allow a simultanous
-- reading of the circular buffer by the user, at the
-- same time than it is beeing written.
--
-- The frame and the millisecond stamp are stored in the
-- same ram word. It is the task of the MEB block to
-- separate the frame data from the millisecond stamp data.
--
--Limitations:
--
--Errors:
--
--Libraries:
--
--Dependancies: It instantiates a synthetisable model of a DPRAM
-- See MebRam.vhd
--
--Author: Pablo Antonio Alvarez Sanchez
-- European Organisation for Nuclear Research
-- SL SPS/LHC -- Control -- Timing Division
-- CERN, Geneva, Switzerland, CH-1211
-- Building 864 Room 1 - A24
--
--Simulator: ModelSim XE 5.5e_p1
--==============================================================--
--Revision List
--Version Author Date Changes
--
--1.0 PAAS 30.09.2002 Added comments, tested with the
-- rest of the design
--==============================================================--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity dpblockram is
generic (dl : integer := 42; -- Length of the data word
al : integer := 10; -- Size of the addr map (10 = 1024 words)
nw : integer := 1024); -- Number of words
-- 'nw' has to be coherent with 'al'
port (clk : in std_logic; -- Global Clock
we : in std_logic; -- Write Enable
aw : in std_logic_vector(al - 1 downto 0); -- Write Address
ar : in std_logic_vector(al - 1 downto 0); -- Read Address
di : in std_logic_vector(dl - 1 downto 0); -- Data input
dw : out std_logic_vector(dl - 1 downto 0); -- Data write, normaly open
do : out std_logic_vector(dl - 1 downto 0)); -- Data output
end dpblockram;
-- DATA OUTPUT NOT REGISTERED!
--library synplify;
--use synplify.attributes.all;
architecture syn of dpblockram is
type ram_type is array (nw - 1 downto 0) of std_logic_vector (dl - 1 downto 0);
signal RAM : ram_type;
signal read_a : std_logic_vector(al - 1 downto 0);
signal read_ar : std_logic_vector(al - 1 downto 0);
--attribute syn_ramstyle of RAM : signal is "block_ram";
begin
process (clk)
begin
if (clk'event and clk = '1') then
if (we = '1') then
RAM(conv_integer(aw)) <= di;
end if;
read_a <= aw;
read_ar <= ar;
end if;
end process;
dw <= RAM(conv_integer(read_a));
do <= RAM(conv_integer(read_ar)); -- Notice that the Data Output is not registered
end syn;
-------------------------------------------------------------------------------
--
-- Title : IRQ_controller
-- Design : VME64xCore
-- Author : Ziga Kroflic
-- Company : Cosylab
--
-------------------------------------------------------------------------------
--
-- File : IRQ_controller.vhd
-- Generated : Thu Apr 1 08:48:48 2010
-- From : interface description file
-- By : Itf2Vhdl ver. 1.20
--
-------------------------------------------------------------------------------
--
-- Description :
--
-------------------------------------------------------------------------------
--{{ Section below this comment is automatically maintained
-- and may be overwritten
--{entity {IRQ_controller} architecture {RTL}}
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_unsigned.all;
entity IRQ_controller is
port(
clk_i : in std_logic;
reset_i : in std_logic;
VME_IRQ_n_o : out std_logic_vector(6 downto 0);
VME_IACKIN_n_i : in std_logic;
VME_IACKOUT_n_o : out std_logic;
VME_AS_n_i : in STD_LOGIC;
VME_DS_n_i : in STD_LOGIC_VECTOR(1 downto 0);
irqDTACK_o : out std_logic;
IACKinProgress_o: out std_logic;
IRQ_i: in std_logic;
locAddr_i: in std_logic_vector(3 downto 1);
IDtoData_o: out std_logic;
IRQlevelReg_i: in std_logic_vector(7 downto 0)
);
end IRQ_controller;
architecture RTL of IRQ_controller is
component RisEdgeDetection is
port (
sig_i, clk_i: in std_logic;
RisEdge_o: out std_logic );
end component;
component SigInputSample is
port (
sig_i, clk_i: in std_logic;
sig_o: out std_logic );
end component;
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;
signal VME_IACKIN_n_oversampled: std_logic;
signal VME_DS_n_oversampled : STD_LOGIC_VECTOR(1 downto 0);
signal s_reset: std_logic;
signal s_VME_IACKOUT: std_logic;
signal s_irqDTACK: std_logic; -- acknowledge of IACK cycle
signal s_applyIRQmask: std_logic; -- clears acknowlegded interrupt
signal s_IDtoData: std_logic; -- puts IRQ Status/ID register on data bus
signal s_IACKmatch: std_logic; -- signals that an active interrupt is being acknowledged
signal s_wbIRQrisingEdge: std_logic; -- rising edge detection on interrupt line
signal s_IRQenabled: std_logic; -- indicates that interrupts are enabled (IRQlevelReg has a valid level value)
signal s_IRQreg: std_logic; -- registers pending interrupt
type t_IRQstates is ( IDLE,
WAIT_FOR_DS,
CHECK_MATCH,
APPLY_MASK_AND_DATA,
PROPAGATE_IACK,
APPLY_DTACK
);
signal s_IRQstate: t_IRQstates;
begin
s_reset <= reset_i;
irqDTACK_o <= '0' when s_irqDTACK='0' else 'Z';
VME_IACKOUT_n_o <= '0' when s_VME_IACKOUT='0' else 'Z';
p_IRQcontrolFSM: process(clk_i)
begin
if rising_edge(clk_i) then
if s_reset='1' then
s_VME_IACKOUT <= '1';
s_irqDTACK <= '1';
s_applyIRQmask <= '0';
s_IDtoData <= '0';
IACKinProgress_o <= '0';
s_IRQstate <= IDLE;
else
case s_IRQstate is
when IDLE =>
s_VME_IACKOUT <= '1';
s_irqDTACK <= '1';
s_applyIRQmask <= '0';
s_IDtoData <= '0';
IACKinProgress_o <= '0';
if VME_IACKIN_n_oversampled='0' then
s_IRQstate <= WAIT_FOR_DS;
else
s_IRQstate <= IDLE;
end if;
when WAIT_FOR_DS =>
s_VME_IACKOUT <= '1';
s_irqDTACK <= '1';
s_applyIRQmask <= '0';
s_IDtoData <= '0';
IACKinProgress_o <= '0';
if VME_DS_n_oversampled/="11" then
s_IRQstate <= CHECK_MATCH;
else
s_IRQstate <= WAIT_FOR_DS;
end if;
when CHECK_MATCH =>
s_VME_IACKOUT <= '1';
s_irqDTACK <= '1';
s_applyIRQmask <= '0';
s_IDtoData <= '0';
IACKinProgress_o <= '0';
if s_IACKmatch='1' then
s_IRQstate <= APPLY_MASK_AND_DATA;
else
s_IRQstate <= PROPAGATE_IACK;
end if;
when APPLY_MASK_AND_DATA =>
s_VME_IACKOUT <= '1';
s_irqDTACK <= '1';
s_applyIRQmask <= '1';
s_IDtoData <= '1';
IACKinProgress_o <= '1';
s_IRQstate <= APPLY_DTACK;
when APPLY_DTACK =>
s_VME_IACKOUT <= '1';
s_irqDTACK <= '0';
s_applyIRQmask <= '0';
s_IDtoData <= '1';
IACKinProgress_o <= '1';
if VME_IACKIN_n_oversampled='1' then
s_IRQstate <= IDLE;
else
s_IRQstate <= APPLY_DTACK;
end if;
when PROPAGATE_IACK =>
s_VME_IACKOUT <= VME_IACKIN_n_oversampled;
s_irqDTACK <= '1';
s_applyIRQmask <= '0';
s_IDtoData <= '0';
IACKinProgress_o <= '0';
if VME_IACKIN_n_oversampled='1' then
s_IRQstate <= IDLE;
else
s_IRQstate <= PROPAGATE_IACK;
end if;
when OTHERS =>
s_VME_IACKOUT <= '1';
s_irqDTACK <= '1';
s_applyIRQmask <= '0';
s_IDtoData <= '0';
IACKinProgress_o <= '0';
s_IRQstate <= IDLE;
end case;
end if;
end if;
end process;
s_IACKmatch <= '1' when "00000"&locAddr_i = IRQlevelReg_i else '0';
s_IRQenabled <= '1' when IRQlevelReg_i < 8 and IRQlevelReg_i /= 0 else '0';
IDtoData_o <= s_IDtoData;
-- Setting and clearing pending interrupt request register
p_IRQregHandling: process(clk_i)
begin
if rising_edge(clk_i) then
if s_reset='1' then
s_IRQreg <= '0';
elsif s_applyIRQmask='1' then
s_IRQreg <= '0';
else
s_IRQreg <= s_wbIRQrisingEdge and s_IRQenabled;
end if;
end if;
end process;
-- Driving VME_IRQ lines
gen_IRQoutput: for i in 0 to 6 generate
VME_IRQ_n_o(i) <= '0' when s_IRQreg='1' and IRQlevelReg_i=(i+1) else 'Z';
end generate;
-- Signal input oversample & rising edge detection
IRQrisingEdge: RisEdgeDetection
port map (
sig_i => IRQ_i,
clk_i => clk_i,
RisEdge_o => s_wbIRQrisingEdge
);
IACKINinputSample: SigInputSample
port map(
sig_i => VME_IACKIN_n_i,
sig_o => VME_IACKIN_n_oversampled,
clk_i => clk_i
);
DSinputSample: RegInputSample
generic map(
width => 2
)
port map(
reg_i => VME_DS_n_i,
reg_o => VME_DS_n_oversampled,
clk_i => clk_i
);
end RTL;
files = [
"VME_bus.vhd",
"VME_CR_pack.vhd",
"wb_dma.vhd",
"VME_CSR_pack.vhd",
"VME_pack.vhd",
"SharedComps.vhd",
"DpBlockRam.vhd",
"TrueDpBlockRam.vhd",
"common_components.vhd",
"VME64xCore_NoIpTop.vhd" ];
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;
-- 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
--==============================================================--
--Design Units : CTX1 Control and Statistics
--Size:
--Speed:
--File Name: MebRam.vhd
--
--Purpose: The dpblockram implements a synthetisable model of a
-- dual port RAM.
-- There are an input data and addr ports to allow the
-- writing at the reception of a GMT frame.
-- The output data and addr ports allow a simultanous
-- reading of the circular buffer by the user, at the
-- same time than it is beeing written.
--
-- The frame and the millisecond stamp are stored in the
-- same ram word. It is the task of the MEB block to
-- separate the frame data from the millisecond stamp data.
--
--Limitations:
--
--Errors:
--
--Libraries:
--
--Dependancies: It instantiates a synthetisable model of a DPRAM
-- See MebRam.vhd
--
--Author: Pablo Antonio Alvarez Sanchez
-- European Organisation for Nuclear Research
-- SL SPS/LHC -- Control -- Timing Division
-- CERN, Geneva, Switzerland, CH-1211
-- Building 864 Room 1 - A24
--
--Simulator: ModelSim XE 5.5e_p1
--==============================================================--
--Revision List
--Version Author Date Changes
--
--1.0 PAAS 30.09.2002 Added comments, tested with the
-- rest of the design
--==============================================================--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity TrueDpblockram is
generic (dl : integer := 42; -- Length of the data word
al : integer := 10); -- Size of the addr map (10 = 1024 words)
-- 'nw' has to be coherent with 'al'
port (clk_a_i : in std_logic; -- Global Clock
we_a_i : in std_logic; -- Write Enable
a_a_i : in std_logic_vector(al - 1 downto 0); -- Write Address
di_a_i : in std_logic_vector(dl - 1 downto 0); -- Data input
do_a_o : out std_logic_vector(dl - 1 downto 0); -- Data write, normaly open
clk_b_i : in std_logic; -- Global Clock
we_b_i : in std_logic; -- Write Enable
a_b_i : in std_logic_vector(al - 1 downto 0); -- Write Address
di_b_i : in std_logic_vector(dl - 1 downto 0); -- Data input
do_b_o : out std_logic_vector(dl - 1 downto 0)); -- Data write, normaly open
end TrueDpblockram;
-- DATA OUTPUT NOT REGISTERED!
--library synplify;
--use synplify.attributes.all;
architecture syn of TrueDpblockram is
type t_ram is array (2**al-1 downto 0) of std_logic_vector (dl-1 downto 0);
shared variable ram: t_ram;
begin
process (clk_a_i)
begin
if (clk_a_i'event and clk_a_i = '1') then
-- if (<enableA> = '1') then
if (we_a_i = '1') then
ram(conv_integer(a_a_i)) := di_a_i;
end if;
do_a_o <= ram(conv_integer(a_a_i));
-- end if;
end if;
end process;
process (clk_b_i)
begin
if (clk_b_i'event and clk_b_i = '1') then
-- if (<enableB> = '1') then
if (we_b_i = '1') then
ram(conv_integer(a_b_i)) := di_b_i;
end if;
do_b_o <= ram(conv_integer(a_b_i));
end if;
-- end if;
end process;
end syn;
This diff is collapsed.
This diff is collapsed.
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;
use work.VME_pack.all;
package VME_CR_pack is
constant c_cr_array : t_cr_array(2**12 downto 0) :=
(
16#00# => (others => '0'),
-- Length of ROM
16#01# => x"01",
16#02# => x"00",
16#03# => x"00",
--Configuration ROM data acces width
16#04# => x"00",
--Configuration ROM data acces width
16#05# => x"01",
--Ascii "C"
16#06# => x"01",
--Ascii "R"
16#07# => x"43",
--Manufacturer's ID
16#08# => x"52",
16#09# => x"01",
16#0A# => x"02",
--board id
16#0B# => x"03",
16#0C# => x"03",