Commit 62b13b5e authored by Tom Levens's avatar Tom Levens

Clean up CR/CSR space

The CR/CSR space has been cleaned up and reworked. All decoding of the
addresses has been moved from VME_bus to VME_CR_CSR_Space to make the
code a bit more structured..

The option to have a user CR and CSR areas has been added. These are
external such that they can be implemented by the user.

The custom CSR registers (IRQ vector/level ...) have been moved to
VME_User_CSR.vhd. By default (in the xvme64x_core wrapper) this area is
mapped to 0x7FF33..7FF5F (in the reserved area) in order to maintain
compatibility with the previous version of the core. However, it can be
moved using generics to a non-reserved area for new applications. This
fixes Bug #1353.
Signed-off-by: Tom Levens's avatarTom Levens <tom.levens@cern.ch>
parent 781e4153
......@@ -6,6 +6,7 @@ files = [ "xvme64x_core.vhd",
"VME_Am_Match.vhd",
"VME_bus.vhd",
"VME_CR_CSR_Space.vhd",
"VME_User_CSR.vhd",
"VME_CRAM.vhd",
"VME_Funct_Match.vhd",
"VME_IRQ_Controller.vhd",
......
This diff is collapsed.
......@@ -9,7 +9,7 @@
-- author: Pablo Alvarez Sanchez <pablo.alvarez.sanchez@cern.ch>
-- Davide Pedretti <davide.pedretti@cern.ch>
--
-- description: RAM memory
-- description: CRAM memory
--
-- dependencies:
--
......@@ -38,32 +38,40 @@ use work.vme64x_pack.all;
entity VME_CRAM is
generic (
dl : integer;
al : integer
g_beg_cram : std_logic_vector(23 downto 0);
g_end_cram : std_logic_vector(23 downto 0)
);
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)
clk_i : in std_logic;
we_i : in std_logic;
addr_i : in std_logic_vector(18 downto 2);
data_i : in std_logic_vector( 7 downto 0);
data_o : out std_logic_vector( 7 downto 0)
);
end VME_CRAM;
architecture syn of VME_CRAM is
architecture rtl 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;
type t_cram is array (f_size(g_beg_cram, g_end_cram)-1 downto 0)
of std_logic_vector(7 downto 0);
signal s_cram : t_cram;
signal s_addr : unsigned(18 downto 2);
signal s_addr_1 : unsigned(18 downto 2);
begin
process (clk) begin
if rising_edge(clk) then
if (we = '1') then
CRAM(to_integer(unsigned(aw))) <= di;
s_addr <= unsigned(addr_i(18 downto 2));
process (clk_i) begin
if rising_edge(clk_i) then
if we_i = '1' then
s_cram(to_integer(s_addr)) <= data_i;
end if;
dw <= CRAM(to_integer(unsigned(aw)));
s_addr_1 <= s_addr;
end if;
end process;
end syn;
data_o <= s_cram(to_integer(s_addr_1));
end rtl;
This diff is collapsed.
--------------------------------------------------------------------------------
-- CERN (BE-CO-HT)
-- VME64x Core
-- http://www.ohwr.org/projects/vme64x-core
--------------------------------------------------------------------------------
--
-- unit name: VME_User_CSR (VME_User_CSR.vhd)
--
-- author: Pablo Alvarez Sanchez <pablo.alvarez.sanchez@cern.ch>
-- Davide Pedretti <davide.pedretti@cern.ch>
--
-- description:
--
-- This module implements the user CSR registers that were added to the
-- reserved area of the defined CSR in previous versions of this core.
--
-- To achieve the previous memory map layout, it is necessary to set the
-- following generics on the VME64xCore_Top:
--
-- g_beg_user_csr => x"07ff33",
-- g_end_user_csr => x"07ff5f",
--
-- However, for new designs it would be better to choose somewhere outside
-- the reserved area (from x"7fc00" to x"7ff5f"). For example:
--
-- g_beg_user_csr => x"07fbd3",
-- g_end_user_csr => x"07fbff",
--
-- The following registers are implemented:
-- _
-- IRQ_Vector --> 0x0002F |--> For the VME_IRQ_Controller
-- IRQ_level --> 0x0002B _|
--
-- Endian --> 0x00023 ----> For the VME_swapper
-- _
-- TIME0_ns --> 0x0001F |
-- TIME1_ns --> 0x0001B |
-- TIME2_ns --> 0x00017 |
-- TIME3_ns --> 0x00013 |--> To calculate the transfer rate
-- TIME4_ns --> 0x0000F | (not currently implemented)
-- BYTES0 --> 0x0000B |
-- BYTES1 --> 0x00007 _|
--
-- WB32bits --> 0x00003 ----> If bit 0 is '1' the WB data bus is 32b
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
--------------------------------------------------------------------------------
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your
-- option) any later version. This source is distributed in the hope that it
-- will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details. You should have
-- received a copy of the GNU Lesser General Public License along with this
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
--------------------------------------------------------------------------------
-- last changes: see log.
--------------------------------------------------------------------------------
-- TODO: -
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.vme64x_pack.all;
entity VME_User_CSR is
generic (
g_wb_data_width : integer
);
port (
clk_i : in std_logic;
reset_i : in std_logic;
addr_i : in std_logic_vector(18 downto 2);
data_i : in std_logic_vector( 7 downto 0);
data_o : out std_logic_vector( 7 downto 0);
we_i : in std_logic;
irq_vector_o : out std_logic_vector( 7 downto 0);
irq_level_o : out std_logic_vector( 7 downto 0);
endian_o : out std_logic_vector( 2 downto 0);
bytes_i : in std_logic_vector(15 downto 0);
time_i : in std_logic_vector(39 downto 0)
);
end VME_User_CSR;
architecture rtl of VME_User_CSR is
signal s_addr : unsigned(18 downto 2);
signal s_reg_irq_vector : std_logic_vector(7 downto 0);
signal s_reg_irq_level : std_logic_vector(7 downto 0);
signal s_reg_endian : std_logic_vector(7 downto 0);
signal s_reg_wb32bits : std_logic_vector(7 downto 0);
begin
s_addr <= unsigned(addr_i);
s_reg_wb32bits <= x"01" when g_wb_data_width = 32 else x"00";
-- Write
process (clk_i)
begin
if rising_edge(clk_i) then
if reset_i = '1' then
s_reg_irq_vector <= x"00";
s_reg_irq_level <= x"00";
s_reg_endian <= x"00";
else
if we_i = '1' then
case s_addr is
when c_addr_irq_vector(18 downto 2) => s_reg_irq_vector <= data_i;
when c_addr_irq_level(18 downto 2) => s_reg_irq_level <= data_i;
when c_addr_endian(18 downto 2) => s_reg_endian <= data_i;
when others => null;
end case;
end if;
end if;
end if;
end process;
irq_vector_o <= s_reg_irq_vector;
irq_level_o <= s_reg_irq_level;
endian_o <= s_reg_endian(2 downto 0);
-- Read
process (clk_i)
begin
if rising_edge(clk_i) then
if reset_i = '1' then
data_o <= x"00";
else
case s_addr is
when c_addr_irq_vector(18 downto 2) => data_o <= s_reg_irq_vector;
when c_addr_irq_level(18 downto 2) => data_o <= s_reg_irq_level;
when c_addr_endian(18 downto 2) => data_o <= s_reg_endian;
when c_addr_time0_ns(18 downto 2) => data_o <= time_i( 7 downto 0);
when c_addr_time1_ns(18 downto 2) => data_o <= time_i(15 downto 8);
when c_addr_time2_ns(18 downto 2) => data_o <= time_i(23 downto 16);
when c_addr_time3_ns(18 downto 2) => data_o <= time_i(31 downto 24);
when c_addr_time4_ns(18 downto 2) => data_o <= time_i(39 downto 32);
when c_addr_bytes0(18 downto 2) => data_o <= bytes_i( 7 downto 0);
when c_addr_bytes1(18 downto 2) => data_o <= bytes_i(15 downto 8);
when c_addr_wb32bits(18 downto 2) => data_o <= s_reg_wb32bits;
when others => data_o <= x"ff";
end case;
end if;
end if;
end process;
end rtl;
This diff is collapsed.
This diff is collapsed.
......@@ -39,7 +39,7 @@ entity xvme64x_core is
generic (
g_clock_period : integer := c_clk_period;
g_wb_data_width : integer := c_wishbone_data_width;
g_wb_addr_width : integer := c_wishbone_addr_width;
g_wb_addr_width : integer := c_wishbone_address_width;
-- CR/CSR
g_manufacturer_id : std_logic_vector(23 downto 0) := c_cern_id;
......@@ -52,11 +52,11 @@ entity xvme64x_core is
g_beg_user_cr : std_logic_vector(23 downto 0) := x"000000";
g_end_user_cr : std_logic_vector(23 downto 0) := x"000000";
g_beg_cram : std_logic_vector(23 downto 0) := x"001000";
g_beg_cram : std_logic_vector(23 downto 0) := x"001003";
g_end_cram : std_logic_vector(23 downto 0) := x"0013ff";
g_beg_user_csr : std_logic_vector(23 downto 0) := x"000000";
g_end_user_csr : std_logic_vector(23 downto 0) := x"000000";
g_beg_user_csr : std_logic_vector(23 downto 0) := x"07ff33";
g_end_user_csr : std_logic_vector(23 downto 0) := x"07ff5f";
g_beg_sn : std_logic_vector(23 downto 0) := x"000000";
g_end_sn : std_logic_vector(23 downto 0) := x"000000";
......@@ -142,11 +142,22 @@ end xvme64x_core;
architecture wrapper of xvme64x_core is
signal dat_out, dat_in : std_logic_vector(31 downto 0);
signal adr_out : std_logic_vector(63 downto 0);
signal dat_out,
dat_in : std_logic_vector(31 downto 0);
signal adr_out : std_logic_vector(31 downto 0);
signal irq_vector,
irq_level : std_logic_vector( 7 downto 0);
signal endian : std_logic_vector( 2 downto 0);
signal user_csr_addr : std_logic_vector(18 downto 2);
signal user_csr_data_i,
user_csr_data_o : std_logic_vector( 7 downto 0);
signal user_csr_we : std_logic;
signal rst : std_logic;
begin -- wrapper
rst <= not rst_n_i;
U_Wrapped_VME : VME64xCore_Top
generic map (
g_clock => g_clock_period,
......@@ -227,19 +238,31 @@ begin -- wrapper
VME_ADDR_DIR_o => VME_ADDR_DIR_o,
VME_ADDR_OE_N_o => VME_ADDR_OE_N_o,
DAT_i => dat_in,
DAT_o => dat_out,
ADR_o => adr_out,
CYC_o => master_o.cyc,
ERR_i => master_i.err,
RTY_i => master_i.rty,
SEL_o => open,
STB_o => master_o.stb,
ACK_i => master_i.ack,
WE_o => master_o.we,
STALL_i => master_i.stall,
IRQ_i => irq_i,
INT_ack_o => irq_ack_o
DAT_i => dat_in,
DAT_o => dat_out,
ADR_o => adr_out,
CYC_o => master_o.cyc,
ERR_i => master_i.err,
RTY_i => master_i.rty,
SEL_o => open,
STB_o => master_o.stb,
ACK_i => master_i.ack,
WE_o => master_o.we,
STALL_i => master_i.stall,
endian_i => endian,
user_csr_addr_o => user_csr_addr,
user_csr_data_i => user_csr_data_o,
user_csr_data_o => user_csr_data_i,
user_csr_we_o => user_csr_we,
user_cr_addr_o => open,
user_cr_data_i => x"00",
irq_i => irq_i,
irq_ack_o => irq_ack_o,
irq_vector_i => irq_vector,
irq_level_i => irq_level
);
master_o.dat <= dat_out(31 downto 0);
......@@ -247,6 +270,22 @@ begin -- wrapper
master_o.adr <= adr_out(29 downto 0) & "00";
dat_in <= master_i.dat;
-- VME_IRQ_n_o <= (others => '0');
U_User_CSR : VME_User_CSR
generic map (
g_wb_data_width => g_wb_data_width
)
port map (
clk_i => clk_i,
reset_i => rst,
addr_i => user_csr_addr,
data_i => user_csr_data_i,
data_o => user_csr_data_o,
we_i => user_csr_we,
irq_vector_o => irq_vector,
irq_level_o => irq_level,
endian_o => endian,
time_i => x"0000000000",
bytes_i => x"0000"
);
end wrapper;
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