Skip to content
Snippets Groups Projects
Commit 2cec3943 authored by Mathias Kreider's avatar Mathias Kreider
Browse files

cleanup

parent 4249ae74
Branches
Tags
No related merge requests found
------------------------------------------------------------
TimeQuest Timing Analyzer Summary
------------------------------------------------------------
Type : Slow 900mV 85C Model Setup 'clk_i'
Slack : -3.902
TNS : -3798.964
Type : Slow 900mV 85C Model Hold 'clk_i'
Slack : 0.315
TNS : 0.000
Type : Slow 900mV 85C Model Minimum Pulse Width 'clk_i'
Slack : -2.846
TNS : -2802.528
Type : Slow 900mV 0C Model Setup 'clk_i'
Slack : -3.821
TNS : -3679.196
Type : Slow 900mV 0C Model Hold 'clk_i'
Slack : 0.315
TNS : 0.000
Type : Slow 900mV 0C Model Minimum Pulse Width 'clk_i'
Slack : -2.846
TNS : -2800.185
Type : Fast 900mV 0C Model Setup 'clk_i'
Slack : -1.220
TNS : -951.719
Type : Fast 900mV 0C Model Hold 'clk_i'
Slack : 0.137
TNS : 0.000
Type : Fast 900mV 0C Model Minimum Pulse Width 'clk_i'
Slack : -2.846
TNS : -1170.141
------------------------------------------------------------
library IEEE;
--! Standard packages
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
library work;
use work.wishbone_pkg.all;
package wb_cores_pkg_gsi is
constant c_xwr_wb_timestamp_latch_sdwb : t_sdwb_device := (
wbd_begin => x"0000000000000000",
wbd_end => x"00000000000007ff",
sdwb_child => x"0000000000000000",
wbd_flags => x"01", -- big-endian, no-child, present
wbd_width => x"04", -- 8/16/32-bit port granularity
abi_ver_major => x"01",
abi_ver_minor => x"01",
abi_class => x"00000000", -- undocumented device
dev_vendor => x"00000651", -- GSI
dev_device => x"10051981",
dev_version => x"00000001",
dev_date => x"20120308",
description => "GSI_TM_LATCH ");
component wb_timestamp_latch
generic (
g_num_triggers : natural;
g_fifo_depth : natural);
port (
ref_clk_i : in std_logic;
sys_clk_i : in std_logic;
nRSt_i : in std_logic;
triggers_i : in std_logic_vector(g_num_triggers-1 downto 0);
tm_time_valid_i : in std_logic;
tm_utc_i : in std_logic_vector(39 downto 0);
tm_cycles_i : in std_logic_vector(27 downto 0);
pps_p_i : in std_logic;
wb_slave_i : in t_wishbone_slave_in;
wb_slave_o : out t_wishbone_slave_out);
end component;
end wb_cores_pkg_gsi;
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
library work;
use work.wishbone_pkg.all;
entity wb_ram is
port(
clk_i : in std_logic; --clock
nRST_i : in std_logic;
wb_slave_o : out t_wishbone_slave_out; --! EB Wishbone slave lines
wb_slave_i : in t_wishbone_slave_in
);
end entity wb_ram;
architecture behavioral of wb_ram is
constant c_ram_size_bytes : natural := 2048;
subtype t_mem8 IS std_logic_vector(7 DOWNTO 0);
TYPE t_memblock IS ARRAY(0 to c_ram_size_bytes/4-1) OF t_mem8;
signal ram_block0 : t_memblock;
signal ram_block1 : t_memblock;
signal ram_block2 : t_memblock;
signal ram_block3 : t_memblock;
signal address: integer RANGE 0 to c_ram_size_bytes/4-1;
signal address_check : unsigned(20 downto 0);
signal q: std_logic_vector (31 DOWNTO 0);
signal address_reg : integer RANGE 0 to c_ram_size_bytes/4-1;
signal address_check_reg : unsigned(20 downto 0);
signal ack_reg : std_logic;
signal sel_reg : std_logic_vector(3 downto 0);
signal data_reg: std_logic_vector (31 DOWNTO 0);
signal wr : std_logic;
signal rd : std_logic;
begin
address <= to_integer(unsigned(wb_slave_i.adr(10 downto 2)));
address_check <= unsigned(wb_slave_i.adr(31 downto 11));
wb_slave_o.rty <= '0';
wb_slave_o.stall <= '0';
wb_slave_o.int <= '0';
wb_slave_o.dat <= q;
PROCESS (clk_i)
BEGIN
IF (clk_i'event AND clk_i = '1') THEN
ack_reg <= wb_slave_i.cyc and wb_slave_i.stb;
if(address_check_reg = 0) then
wb_slave_o.ack <= ack_reg;
wb_slave_o.err <= '0';
else
wb_slave_o.ack <= '0';
wb_slave_o.err <= '1';
end if;
wr <= wb_slave_i.cyc and wb_slave_i.stb and wb_slave_i.we;
rd <= wb_slave_i.cyc and wb_slave_i.stb and not wb_slave_i.we;
address_reg <= address;
address_check_reg <= address_check;
data_reg <= wb_slave_i.dat;
sel_reg <= wb_slave_i.sel;
if(wr = '1') then
if(sel_reg(3) = '1') then
ram_block3(address_reg) <= data_reg(31 downto 24);
end if;
if(sel_reg(2) = '1') then
ram_block2(address_reg) <= data_reg(23 downto 16);
end if;
if(sel_reg(1) = '1') then
ram_block1(address_reg) <= data_reg(15 downto 8);
end if;
if(sel_reg(0) = '1') then
ram_block0(address_reg) <= data_reg(7 downto 0);
end if;
end if;
if(rd = '1') then
q <= ram_block3(address_reg)& ram_block2(address_reg) & ram_block1(address_reg) & ram_block0(address_reg);
end if;
END IF;
END PROCESS;
END behavioral;
\ No newline at end of file
--! @file wb_timestamp_latch.vhd
--! @brief Timestamp latch unit for WR core with WB b4 interface
--!
--! Copyright (C) 2011-2012 GSI Helmholtz Centre for Heavy Ion Research GmbH
--!
--! Register map:
--!----------------------------------------------------------------------------
--! 0x000 n..0 channel(n) timestamp(s) ready (ro)
--! 0x004 n..0 channel(n) FIFO clear (wo)
--! 0x008 n..0 channel(n) trigger armed status (ro)
--! 0x00C n..0 channel(n) trigger set armed (wo)
--! 0x010 n..0 channel(n) trigger clr armed (wo)
--! 0x014 n..0 channel(n) trigger edge status (ro)
--! 0x014 n..0 channel(n) trigger edge set pos (wo)
--! 0x014 n..0 channel(n) trigger edge set neg (wo)
--! 0x400 start of FIFO addresses
--!
--! FIFO 0 area is at 0x400, FIFO n is at 0x400 + n*0x020
--! Exemplary layout fo FIFO 0:
--! 0x400 pop (wo)
--! 0x404 fill count (ro)
--! 0x408 utc word0 (ro)
--! 0x40C utc word1 (ro)
--! 0x410 cycle word (ro)
--!----------------------------------------------------------------------------
--1
--! @author Mathias Kreider <m.kreider@gsi.de>
--!
--! @bug No know bugs.
--!
--------------------------------------------------------------------------------
--! This library 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 3 of the License, or (at your option) any later version.
--!
--! This library 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 library. If not, see <http://www.gnu.org/licenses/>.
---------------------------------------------------------------------------------
--! Standard library
library IEEE;
--! Standard packages
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
library work;
use work.wishbone_pkg.all;
use work.genram_pkg.all;
entity wb_timestamp_latch is
generic(g_num_triggers : natural := 1;
g_fifo_depth : natural := 10);
port (
ref_clk_i : in std_logic; -- tranceiver clock domain
sys_clk_i : in std_logic; -- local clock domain
nRSt_i : in std_logic;
triggers_i : in std_logic_vector(g_num_triggers-1 downto 0); -- trigger lines for latch
tm_time_valid_i : in std_logic; -- timestamp valid flag
tm_utc_i : in std_logic_vector(39 downto 0); -- UTC Timestamp
tm_cycles_i : in std_logic_vector(27 downto 0); -- refclock cycle count
pps_p_i : in std_logic; -- pps pulse, also signals reset of tm_cycles counter
wb_slave_i : in t_wishbone_slave_in; -- Wishbone slave interface (sys_clk domain)
wb_slave_o : out t_wishbone_slave_out
);
end wb_timestamp_latch;
architecture behavioral of wb_timestamp_latch is
component gc_sync_ffs
generic (
g_sync_edge : string);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
data_i : in std_logic;
synced_o : out std_logic;
npulse_o : out std_logic;
ppulse_o : out std_logic);
end component;
component generic_async_fifo
generic (
g_data_width : natural;
g_size : natural;
g_show_ahead : boolean := false;
-- Read-side flag selection
g_with_rd_empty : boolean := true; -- with empty flag
g_with_rd_full : boolean := false; -- with full flag
g_with_rd_almost_empty : boolean := false;
g_with_rd_almost_full : boolean := false;
g_with_rd_count : boolean := false; -- with words counter
-- Write-side flag selection
g_with_wr_empty : boolean := false;
g_with_wr_full : boolean := true;
g_with_wr_almost_empty : boolean := false;
g_with_wr_almost_full : boolean := false;
g_with_wr_count : boolean := false;
g_almost_empty_threshold : integer; -- threshold for almost empty flag
g_almost_full_threshold : integer); -- threshold for almost full flag
port (
rst_n_i : in std_logic := '1';
clk_wr_i : in std_logic;
d_i : in std_logic_vector(g_data_width-1 downto 0);
we_i : in std_logic;
wr_empty_o : out std_logic;
wr_full_o : out std_logic;
wr_almost_empty_o : out std_logic;
wr_almost_full_o : out std_logic;
wr_count_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
clk_rd_i : in std_logic;
q_o : out std_logic_vector(g_data_width-1 downto 0);
rd_i : in std_logic;
rd_empty_o : out std_logic;
rd_full_o : out std_logic;
rd_almost_empty_o : out std_logic;
rd_almost_full_o : out std_logic;
rd_count_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0));
end component;
-------------------------------------------------------------------------------
constant c_fifo_adr_offset : unsigned(11 downto 0) := x"400";
constant c_fifo_adr_map_end : unsigned(11 downto 0) := c_fifo_adr_offset+(g_num_triggers*8-1)*4;
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- type definitions
-------------------------------------------------------------------------------
-- stdlv with bit for every trigger channel
subtype channel is std_logic_vector (g_num_triggers-1 downto 0);
-- stdlv to hold utc + cycle counter
subtype t_timestamp is std_logic_vector(67 downto 0);
type t_tm_array is array (0 to g_num_triggers-1) of t_timestamp;
-- stdlv 32b wb bus word
subtype t_word is std_logic_vector(31 downto 0);
type t_word_array is array (0 to g_num_triggers-1) of t_word;
-- stdlv to hold read and write counts of fifos
subtype t_cnt is std_logic_vector(f_log2_size(g_fifo_depth)-1 downto 0);
type t_cnt_array is array (0 to g_num_triggers-1) of t_cnt;
-------------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- LATCH UNIT(s)
-----------------------------------------------------------------------------
-- trigger sync chain
signal triggers_synced : channel;
signal triggers_pos_edge_synced : channel;
signal triggers_neg_edge_synced : channel;
-- tm latch registers
signal tm_fifo_in : t_tm_array;
signal tm_fifo_out : t_tm_array;
signal tm_word0 : t_word_array;
signal tm_word1 : t_word_array;
signal tm_word2 : t_word_array;
-- fifo signals
signal nRst_fifo : channel;
signal rd : channel;
signal we : channel;
signal rd_empty : channel;
signal wr_empty : channel;
signal wr_full : channel;
signal rd_count : t_cnt_array;
signal wr_count : t_cnt_array;
-------------------------------------------------------------------------------
-- WB BUS INTERFACE
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- wb interface signals
signal address : unsigned(11 downto 0);
alias adr_hi : unsigned(4 downto 0) is address(9 downto 5);
alias adr_lo : unsigned(2 downto 0) is address(4 downto 2);
signal data : channel;
signal stall : std_logic;
-------------------------------------------------------------------------------
--wb registers
--fifo clear is asynchronous
signal fifo_clear : channel;
-- rd_empty signal is already in sys_clk domain
signal fifo_data_rdy : channel;
-- these control registers must be synced to ref_clk domain
signal trigger_active : channel;
signal trigger_edge : channel;
signal trigger_active_ref_clk : channel;
signal trigger_edge_ref_clk : channel;
-------------------------------------------------------------------------------
-- Bus Functions
-------------------------------------------------------------------------------
function pad_4_WB(reg : std_logic_vector) return std_logic_vector is
variable ret : std_logic_vector(31 downto 0);
begin
ret := std_logic_vector(to_unsigned(0, 32-reg'length)) & reg;
return ret;
end function pad_4_WB;
-----------------------------------------------------------------------------
begin -- behavioral
-------------------------------------------------------------------------------
-- BEGIN TRIGGER CHANNEL GENERATE
-------------------------------------------------------------------------------
trig_sync : for i in 0 to g_num_triggers-1 generate
nRst_fifo(i) <= nRst_i and not fifo_clear(i);
tm_fifo_in(i) <= (tm_utc_i & tm_cycles_i);
tm_word0(i) <= tm_fifo_out(i)(67 downto 36);
tm_word1(i) <= std_logic_vector(to_unsigned(0, 32-8)) & tm_fifo_out(i)(35 downto 28);
tm_word2(i) <= std_logic_vector(to_unsigned(0, 32-28)) & tm_fifo_out(i)(27 downto 0);
sync_trig_edge_reg : gc_sync_ffs
generic map (
g_sync_edge => "positive")
port map (
clk_i => ref_clk_i,
rst_n_i => nRst_i,
data_i => trigger_edge(i),
synced_o => trigger_edge_ref_clk(i),
npulse_o => open,
ppulse_o => open);
sync_trig_active_reg : gc_sync_ffs
generic map (
g_sync_edge => "positive")
port map (
clk_i => ref_clk_i,
rst_n_i => nRst_i,
data_i => trigger_active(i),
synced_o => trigger_active_ref_clk(i),
npulse_o => open,
ppulse_o => open);
sync_triggers : gc_sync_ffs
generic map (
g_sync_edge => "positive")
port map (
clk_i => ref_clk_i,
rst_n_i => nRst_i,
data_i => triggers_i(i),
synced_o => triggers_synced(i),
npulse_o => triggers_neg_edge_synced(i),
ppulse_o => triggers_pos_edge_synced(i));
generic_async_fifo_1 : generic_async_fifo
generic map (
g_data_width => t_timestamp'length, --utc + cycle count len
g_size => g_fifo_depth,
g_show_ahead => true,
g_with_rd_empty => true,
g_with_rd_full => false,
g_with_rd_almost_empty => false,
g_with_rd_almost_full => false,
g_with_rd_count => true,
g_with_wr_empty => true,
g_with_wr_full => true,
g_with_wr_almost_empty => false,
g_with_wr_almost_full => false,
g_with_wr_count => false,
g_almost_empty_threshold => 0,
g_almost_full_threshold => 0
)
port map (
rst_n_i => nRst_fifo(i),
clk_wr_i => ref_clk_i,
d_i => tm_fifo_in(i),
we_i => we(i),
wr_empty_o => wr_empty(i),
wr_full_o => wr_full(i),
wr_almost_empty_o => open,
wr_almost_full_o => open,
wr_count_o => open,
clk_rd_i => sys_clk_i,
q_o => tm_fifo_out(i),
rd_i => rd(i),
rd_empty_o => rd_empty(i),
rd_full_o => open,
rd_almost_empty_o => open,
rd_almost_full_o => open,
rd_count_o => rd_count(i));
latch : process (ref_clk_i)
begin -- process latch
if ref_clk_i'event and ref_clk_i = '1' then -- rising clock edge
if nRST_i = '0' then -- synchronous reset (active low)
we(i) <= '0';
else
---------------------------------------------------------------------
-- Latch timestamp if trigger is active and selected edge is detected
---------------------------------------------------------------------
we(i) <= '0';
if(trigger_active_ref_clk(i) = '1') then
if((trigger_edge_ref_clk(i) = '0' and triggers_neg_edge_synced(i) = '1')
or ((trigger_edge_ref_clk(i) = '1') and (triggers_pos_edge_synced(i) = '1'))) then
we(i) <= '1';
end if;
end if;
---------------------------------------------------------------------
end if;
end if;
end process latch;
end generate trig_sync;
-------------------------------------------------------------------------------
-- END TRIGGER CHANNEL GENERATE
-------------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- WB Interface
-----------------------------------------------------------------------------
-- show which fifos hold unread timestamps
fifo_data_rdy <= (not(rd_empty));
address <= unsigned(wb_slave_i.adr(11 downto 0));
data <= wb_slave_i.dat(g_num_triggers-1 downto 0);
wb_if : process (sys_clk_i)
variable i : natural range 0 to g_num_triggers-1 := 0;
begin -- process wb_if
if sys_clk_i'event and sys_clk_i = '1' then -- rising clock edge
if nRst_i = '0' then -- synchronous reset (active low)
trigger_active <= (others => '0');
trigger_edge <= (others => '0');
rd <= (others => '1');
else
-----------------------------------------------------------------------
fifo_clear <= (others => '0');
rd <= (others => '0');
wb_slave_o.ack <= '0';
wb_slave_o.err <= '0';
stall <= '0';
wb_slave_o.stall <= '0';
if(wb_slave_i.cyc = '1' and wb_slave_i.stb = '1' and stall = '0') then
if(address < c_fifo_adr_offset)then
if(wb_slave_i.we = '1') then
---------------------------------------------------------------------
-- Write standard config regs
---------------------------------------------------------------------
case address is
when x"000" => null;
when x"004" => fifo_clear <= data; wb_slave_o.ack <= '1'; -- clear fifo
-- trigger channel status (armed/inactive)
when x"008" => null;
when x"00C" => trigger_active <= trigger_active or data; wb_slave_o.ack <= '1'; --armed
when x"010" => trigger_active <= trigger_active and not data; wb_slave_o.ack <= '1'; --inactive
-- trigger channel edge select (pos/neg)
when x"014" => null;
when x"018" => trigger_edge <= trigger_edge or data; wb_slave_o.ack <= '1'; --pos
when x"01C" => trigger_edge <= trigger_edge and not data; wb_slave_o.ack <= '1'; --neg
when others => wb_slave_o.err <= '1';
end case;
else
-------------------------------------------------------------------
-- Read standard config regs
-------------------------------------------------------------------
case address is
when x"000" => wb_slave_o.dat <= pad_4_WB(fifo_data_rdy); wb_slave_o.ack <= '1';
when x"004" => null;
when x"008" => wb_slave_o.dat <= pad_4_WB(trigger_active); wb_slave_o.ack <= '1';
when x"00C" => null;
when x"010" => null;
when x"014" => wb_slave_o.dat <= pad_4_WB(trigger_edge); wb_slave_o.ack <= '1';
when x"018" => null;
when x"01C" => null;
when others => wb_slave_o.err <= '1';
end case;
end if;
else
-------------------------------------------------------------------
-- Counters and FIFOs
-------------------------------------------------------------------
if(address > c_fifo_adr_map_end) then
wb_slave_o.err <= '1';
else
i := to_integer(adr_hi);
case adr_lo is
when "000" => if(wb_slave_i.we = '1') then -- pop fifo
rd(i) <= '1';
wb_slave_o.ack <= '1';
wb_slave_o.stall <= '1';
stall <= '1';
else
wb_slave_o.err <= '1';
end if;
-- fifo fill count
when "001" => wb_slave_o.dat <= pad_4_WB(rd_count(i)); wb_slave_o.ack <= '1';
-- timestamp utc word 0
when "010" => wb_slave_o.dat <= tm_word0(i); wb_slave_o.ack <= '1';
-- timestamp utc word 1
when "011" => wb_slave_o.dat <= tm_word1(i); wb_slave_o.ack <= '1';
-- timestamp cycles word
when "100" => wb_slave_o.dat <= tm_word2(i); wb_slave_o.ack <= '1';
when others => wb_slave_o.err <= '1';
end case;
end if; -- if address < map_end
end if; -- if address > fifo_offset
end if; -- if cyc & stb & !stall
end if; -- if nrst
end if; -- if clock edge
end process wb_if;
end behavioral;
This diff is collapsed.
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