Commit 91806588 authored by egousiou's avatar egousiou

added sdb;

added carrier_csr;
restructuring with creation of fmc_tdc_core;
data_formatting unit debugged marginal cases of timestamps

git-svn-id: http://svn.ohwr.org/fmc-tdc@91 85dfdc96-de2c-444c-878d-45b388be74a9
parent e77637ed
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for Carrier control and status registers
---------------------------------------------------------------------------------------
-- File : ../rtl/carrier_csr.vhd
-- Author : auto-generated by wbgen2 from carrier_csr.wb
-- Created : Mon Mar 11 17:11:09 2013
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE carrier_csr.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity carrier_csr is
port (
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(1 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
-- Port for std_logic_vector field: 'PCB revision' in reg: 'Carrier type and PCB version'
carrier_csr_carrier_pcb_rev_i : in std_logic_vector(3 downto 0);
-- Port for std_logic_vector field: 'Reserved register' in reg: 'Carrier type and PCB version'
carrier_csr_carrier_reserved_i : in std_logic_vector(11 downto 0);
-- Port for std_logic_vector field: 'Carrier type' in reg: 'Carrier type and PCB version'
carrier_csr_carrier_type_i : in std_logic_vector(15 downto 0);
-- Port for BIT field: 'FMC presence' in reg: 'Status'
carrier_csr_stat_fmc_pres_i : in std_logic;
-- Port for BIT field: 'GN4142 core P2L PLL status' in reg: 'Status'
carrier_csr_stat_p2l_pll_lck_i : in std_logic;
-- Port for BIT field: 'System clock PLL status' in reg: 'Status'
carrier_csr_stat_sys_pll_lck_i : in std_logic;
-- Port for BIT field: 'DDR3 calibration status' in reg: 'Status'
carrier_csr_stat_ddr3_cal_done_i : in std_logic;
-- Port for std_logic_vector field: 'Reserved' in reg: 'Status'
carrier_csr_stat_reserved_i : in std_logic_vector(27 downto 0);
-- Port for BIT field: 'Green LED' in reg: 'Control'
carrier_csr_ctrl_led_green_o : out std_logic;
-- Port for BIT field: 'Red LED' in reg: 'Control'
carrier_csr_ctrl_led_red_o : out std_logic;
-- Port for BIT field: 'DAC clear' in reg: 'Control'
carrier_csr_ctrl_dac_clr_n_o : out std_logic;
-- Port for std_logic_vector field: 'Reserved' in reg: 'Control'
carrier_csr_ctrl_reserved_o : out std_logic_vector(28 downto 0)
);
end carrier_csr;
architecture syn of carrier_csr is
signal carrier_csr_ctrl_led_green_int : std_logic ;
signal carrier_csr_ctrl_led_red_int : std_logic ;
signal carrier_csr_ctrl_dac_clr_n_int : std_logic ;
signal carrier_csr_ctrl_reserved_int : std_logic_vector(28 downto 0);
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(1 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal bus_clock_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments. For (foreseen) compatibility with other bus standards.
wrdata_reg <= wb_data_i;
bwsel_reg <= wb_sel_i;
bus_clock_int <= wb_clk_i;
rd_int <= wb_cyc_i and (wb_stb_i and (not wb_we_i));
wr_int <= wb_cyc_i and (wb_stb_i and wb_we_i);
allones <= (others => '1');
allzeros <= (others => '0');
--
-- Main register bank access process.
process (bus_clock_int, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
carrier_csr_ctrl_led_green_int <= '0';
carrier_csr_ctrl_led_red_int <= '0';
carrier_csr_ctrl_dac_clr_n_int <= '0';
carrier_csr_ctrl_reserved_int <= "00000000000000000000000000000";
elsif rising_edge(bus_clock_int) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
ack_in_progress <= '0';
else
end if;
else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
case rwaddr_reg(1 downto 0) is
when "00" =>
if (wb_we_i = '1') then
else
rddata_reg(3 downto 0) <= carrier_csr_carrier_pcb_rev_i;
rddata_reg(15 downto 4) <= carrier_csr_carrier_reserved_i;
rddata_reg(31 downto 16) <= carrier_csr_carrier_type_i;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "01" =>
if (wb_we_i = '1') then
rddata_reg(0) <= 'X';
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
else
rddata_reg(0) <= carrier_csr_stat_fmc_pres_i;
rddata_reg(1) <= carrier_csr_stat_p2l_pll_lck_i;
rddata_reg(2) <= carrier_csr_stat_sys_pll_lck_i;
rddata_reg(3) <= carrier_csr_stat_ddr3_cal_done_i;
rddata_reg(31 downto 4) <= carrier_csr_stat_reserved_i;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "10" =>
if (wb_we_i = '1') then
rddata_reg(0) <= 'X';
carrier_csr_ctrl_led_green_int <= wrdata_reg(0);
rddata_reg(1) <= 'X';
carrier_csr_ctrl_led_red_int <= wrdata_reg(1);
rddata_reg(2) <= 'X';
carrier_csr_ctrl_dac_clr_n_int <= wrdata_reg(2);
carrier_csr_ctrl_reserved_int <= wrdata_reg(31 downto 3);
else
rddata_reg(0) <= carrier_csr_ctrl_led_green_int;
rddata_reg(1) <= carrier_csr_ctrl_led_red_int;
rddata_reg(2) <= carrier_csr_ctrl_dac_clr_n_int;
rddata_reg(31 downto 3) <= carrier_csr_ctrl_reserved_int;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
end if;
end if;
end process;
-- Drive the data output bus
wb_data_o <= rddata_reg;
-- PCB revision
-- Reserved register
-- Carrier type
-- FMC presence
-- GN4142 core P2L PLL status
-- System clock PLL status
-- DDR3 calibration status
-- Reserved
-- Green LED
carrier_csr_ctrl_led_green_o <= carrier_csr_ctrl_led_green_int;
-- Red LED
carrier_csr_ctrl_led_red_o <= carrier_csr_ctrl_led_red_int;
-- DAC clear
carrier_csr_ctrl_dac_clr_n_o <= carrier_csr_ctrl_dac_clr_n_int;
-- Reserved
carrier_csr_ctrl_reserved_o <= carrier_csr_ctrl_reserved_int;
rwaddr_reg <= wb_addr_i;
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0);
end syn;
--_________________________________________________________________________________________________
-- |
-- |TDC core| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- sdb_meta_pkg |
-- |
---------------------------------------------------------------------------------------------------
-- File sdb_meta_pkg.vhd |
-- |
-- Description Sdb meta-information for the FMC TDC design for SPEC. |
-- |
-- Authors Matthieu Cattin (matthieu.cattin@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 04/2013 |
-- Version v1 |
-- |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- 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 |
---------------------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;
package sdb_meta_pkg is
------------------------------------------------------------------------------
-- Meta-information sdb records
------------------------------------------------------------------------------
-- Top module repository url
constant c_SDB_REPO_URL : t_sdb_repo_url := (
-- url (string, 63 char)
repo_url => "http://svn.ohwr.org/fmc-tdc/hdl/spec/ ");
-- Synthesis informations
constant c_SDB_SYNTHESIS : t_sdb_synthesis := (
-- Top module name (string, 16 char)
syn_module_name => "spec_top_fmc_tdc",
-- Commit ID (hex string, 128-bit = 32 char)
-- git log -1 --format="%H" | cut -c1-320
syn_commit_id => x"00000000",
-- Synthesis tool name (string, 8 char)
syn_tool_name => "SynpliDP",
-- Synthesis tool version (bcd encoded, 32-bit)
syn_tool_version => x"00201203",
-- Synthesis date (bcd encoded, 32-bit)
syn_date => x"20130410",
-- Synthesised by (string, 15 char)
syn_username => "egousiou ");
-- Integration record
constant c_SDB_INTEGRATION : t_sdb_integration := (
product => (
vendor_id => x"000000000000CE42", -- CERN
device_id => x"47c786a2", -- echo "spec_fmc-adc-100m14b4cha" | md5sum | cut -c1-8
version => x"00010001", -- bcd encoded, [31:16] = major, [15:0] = minor
date => x"20130410", -- yyyymmdd
name => "spec_fmctdc1ns5cha "));
end sdb_meta_pkg;
package body sdb_meta_pkg is
end sdb_meta_pkg;
\ No newline at end of file
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;
entity sdb_rom is
generic(
g_layout : t_sdb_record_array;
g_bus_end : unsigned(63 downto 0));
port(
clk_sys_i : in std_logic;
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out);
end sdb_rom;
architecture rtl of sdb_rom is
alias c_layout : t_sdb_record_array(g_layout'length downto 1) is g_layout;
-- The ROM must describe all slaves, the crossbar itself and the optional information records
constant c_used_entries : natural := c_layout'length + 1;
constant c_rom_entries : natural := 2**f_ceil_log2(c_used_entries); -- next power of 2
constant c_sdb_words : natural := c_sdb_device_length / c_wishbone_data_width;
constant c_rom_words : natural := c_rom_entries * c_sdb_words;
constant c_rom_depth : natural := f_ceil_log2(c_rom_words);
constant c_rom_lowbits : natural := f_ceil_log2(c_wishbone_data_width / 8);
type t_rom is array(c_rom_words-1 downto 0) of t_wishbone_data;
function f_build_rom
return t_rom
is
variable res : t_rom := (others => (others => '0'));
variable sdb_device : std_logic_vector(c_sdb_device_length-1 downto 0) := (others => '0');
variable sdb_component : t_sdb_component;
begin
sdb_device(511 downto 480) := x"5344422D" ; -- sdb_magic
sdb_device(479 downto 464) := std_logic_vector(to_unsigned(c_used_entries, 16)); -- sdb_records
sdb_device(463 downto 456) := x"01"; -- sdb_version
sdb_device(455 downto 448) := x"00"; -- sdb_bus_type = sdb_wishbone
sdb_device( 7 downto 0) := x"00"; -- record_type = sdb_interconnect
sdb_component.addr_first := (others => '0');
sdb_component.addr_last := std_logic_vector(g_bus_end);
sdb_component.product.vendor_id := x"0000000000000651"; -- GSI
sdb_component.product.device_id := x"e6a542c9";
sdb_component.product.version := x"00000002";
sdb_component.product.date := x"20120511";
sdb_component.product.name := "WB4-Crossbar-GSI ";
sdb_device(447 downto 8) := f_sdb_embed_component(sdb_component, (others => '0'));
for i in 0 to c_sdb_words-1 loop
res(c_sdb_words-1-i) :=
sdb_device((i+1)*c_wishbone_data_width-1 downto i*c_wishbone_data_width);
end loop;
for slave in 1 to c_used_entries-1 loop
sdb_device(511 downto 0) := c_layout(slave);
for i in 0 to c_sdb_words-1 loop
res((slave+1)*c_sdb_words-1-i) :=
sdb_device((i+1)*c_wishbone_data_width-1 downto i*c_wishbone_data_width);
end loop;
end loop;
return res;
end f_build_rom;
signal rom : t_rom := f_build_rom;
signal adr_reg : unsigned(c_rom_depth-1 downto 0);
begin
-- Simple ROM; ignore we/sel/dat
slave_o.err <= '0';
slave_o.rty <= '0';
slave_o.stall <= '0';
slave_o.int <= '0'; -- Tom sucks! This should not be here.
slave_o.dat <= rom(to_integer(adr_reg));
slave_clk : process(clk_sys_i)
begin
if (rising_edge(clk_sys_i)) then
adr_reg <= unsigned(slave_i.adr(c_rom_depth+c_rom_lowbits-1 downto c_rom_lowbits));
slave_o.ack <= slave_i.cyc and slave_i.stb;
end if;
end process;
end rtl;
This diff is collapsed.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;
entity xwb_sdb_crossbar is
generic(
g_num_masters : natural := 1;
g_num_slaves : natural := 1;
g_registered : boolean := false;
g_wraparound : boolean := true;
g_layout : t_sdb_record_array;
g_sdb_addr : t_wishbone_address);
port(
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
-- Master connections (INTERCON is a slave)
slave_i : in t_wishbone_slave_in_array(g_num_masters-1 downto 0);
slave_o : out t_wishbone_slave_out_array(g_num_masters-1 downto 0);
-- Slave connections (INTERCON is a master)
master_i : in t_wishbone_master_in_array(g_num_slaves-1 downto 0);
master_o : out t_wishbone_master_out_array(g_num_slaves-1 downto 0));
end xwb_sdb_crossbar;
architecture rtl of xwb_sdb_crossbar is
alias c_layout : t_sdb_record_array(g_layout'length-1 downto 0) is g_layout;
-- Pretty print device name
function f_trim(s : string) return string is
variable cut : natural;
begin
byte : for i in s'length downto 1 loop
cut := i;
exit byte when s(i) /= ' ';
end loop;
return s(1 to cut);
end f_trim;
-- Step 1. Place the SDB ROM on the bus
-- How much space does the ROM need?
constant c_used_entries : natural := c_layout'length + 1;
constant c_rom_entries : natural := 2**f_ceil_log2(c_used_entries); -- next power of 2
constant c_sdb_bytes : natural := c_sdb_device_length / 8;
constant c_rom_bytes : natural := c_rom_entries * c_sdb_bytes;
-- Step 2. Find the size of the bus
function f_bus_end return unsigned is
variable result : unsigned(63 downto 0);
variable sdb_component : t_sdb_component;
constant zero : t_wishbone_address := (others => '0');
begin
-- The SDB block must be aligned
assert (g_sdb_addr and std_logic_vector(to_unsigned(c_rom_bytes - 1, c_wishbone_address_width))) = zero
report "SDB address is not aligned (" & f_bits2string(g_sdb_addr) & "). This is not supported by the crossbar."
severity Failure;
if not g_wraparound then
result := (others => '0');
for i in 0 to c_wishbone_address_width-1 loop
result(i) := '1';
end loop;
else
-- The ROM will be an addressed slave as well
result := (others => '0');
result(c_wishbone_address_width-1 downto 0) := unsigned(g_sdb_addr);
result := result + to_unsigned(c_rom_bytes, 64) - 1;
for i in c_layout'range loop
if c_layout(i)(7) /= '1' then -- Ignore meta-information
sdb_component := f_sdb_extract_component(c_layout(i)(447 downto 8));
if unsigned(sdb_component.addr_last) > result then
result := unsigned(sdb_component.addr_last);
end if;
end if;
end loop;
-- round result up to a power of two -1
for i in 62 downto 0 loop
result(i) := result(i) or result(i+1);
end loop;
end if;
return result;
end f_bus_end;
constant c_bus_end : unsigned(63 downto 0) := f_bus_end;
-- Step 3. Map device address begin values
function f_addresses return t_wishbone_address_array is
variable result : t_wishbone_address_array(g_num_slaves-1 downto 0);
variable sdb_component : t_sdb_component;
variable extend : unsigned(63 downto 0) := (others => '0');
begin
for i in c_layout'range loop
if c_layout(i)(7) /= '1' then -- Ignore meta-information
sdb_component := f_sdb_extract_component(c_layout(i)(447 downto 8));
result(i) := sdb_component.addr_first(c_wishbone_address_width-1 downto 0);
-- Range must be valid
assert unsigned(sdb_component.addr_first) <= unsigned(sdb_component.addr_last)
report "Wishbone slave device #" & Integer'image(i) & " (" & f_trim(sdb_component.product.name) & ") sdb_component.addr_first (" & f_bits2string(sdb_component.addr_first) & ") must precede sdb_component.addr_last address (" & f_bits2string(sdb_component.addr_last) & ")."
severity Failure;
-- Address must fit
extend(c_wishbone_address_width-1 downto 0) := unsigned(result(i));
assert unsigned(sdb_component.addr_first) = extend
report "Wishbone slave device #" & Integer'image(i) & " (" & f_trim(sdb_component.product.name) & ") sdb_component.addr_first (" & f_bits2string(sdb_component.addr_first) & " does not fit in t_wishbone_address."
severity Failure;
end if;
end loop;
return result;
end f_addresses;
-- Step 3. Map device address end values
function f_masks return t_wishbone_address_array is
variable result : t_wishbone_address_array(g_num_slaves-1 downto 0);
variable sdb_component : t_sdb_component;
variable size : unsigned(63 downto 0);
constant zero : unsigned(63 downto 0) := (others => '0');
begin
for i in c_layout'range loop
if c_layout(i)(7) /= '1' then -- Ignore meta-information
sdb_component := f_sdb_extract_component(c_layout(i)(447 downto 8));
size := unsigned(sdb_component.addr_last) - unsigned(sdb_component.addr_first);
-- size must be of the form 000000...00001111...1
assert (size and (size + to_unsigned(1, 64))) = zero
report "Wishbone slave device #" & Integer'image(i) & " (" & f_trim(sdb_component.product.name) & ") has an address range that is not a power of 2 minus one (" & f_bits2string(std_logic_vector(size)) & "). This is not supported by the crossbar."
severity Warning;
-- fix the size up to the form 000...0001111...11
for j in c_wishbone_address_width-2 downto 0 loop
size(j) := size(j) or size(j+1);
end loop;
-- the base address must be aligned to the size
assert (unsigned(sdb_component.addr_first) and size) = zero
report "Wishbone slave device #" & Integer'image(i) & " (" & f_trim(sdb_component.product.name) & ") sdb_component.addr_first (" & f_bits2string(sdb_component.addr_first) & ") is not aligned. This is not supported by the crossbar."
severity Failure;
size := c_bus_end - size;
result(i) := std_logic_vector(size(c_wishbone_address_width-1 downto 0));
end if;
end loop;
return result;
end f_masks;
constant c_rom_mask : unsigned(63 downto 0) :=
c_bus_end - to_unsigned(c_rom_bytes-1, 64);
constant c_sdb_mask : t_wishbone_address :=
std_logic_vector(c_rom_mask(c_wishbone_address_width-1 downto 0));
constant c_address : t_wishbone_address_array(g_num_slaves downto 0) :=
g_sdb_addr & f_addresses;
constant c_mask : t_wishbone_address_array(g_num_slaves downto 0) :=
c_sdb_mask & f_masks;
signal master_i_1 : t_wishbone_master_in_array(g_num_slaves downto 0);
signal master_o_1 : t_wishbone_master_out_array(g_num_slaves downto 0);
begin
master_i_1(g_num_slaves-1 downto 0) <= master_i;
master_o <= master_o_1(g_num_slaves-1 downto 0);
rom : sdb_rom
generic map(
g_layout => c_layout,
g_bus_end => c_bus_end)
port map(
clk_sys_i => clk_sys_i,
slave_i => master_o_1(g_num_slaves),
slave_o => master_i_1(g_num_slaves));
crossbar : xwb_crossbar
generic map(
g_num_masters => g_num_masters,
g_num_slaves => g_num_slaves + 1,
g_registered => g_registered,
g_address => c_address,
g_mask => c_mask)
port map(
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
slave_i => slave_i,
slave_o => slave_o,
master_i => master_i_1,
master_o => master_o_1);
end rtl;
This diff is collapsed.
......@@ -202,7 +202,7 @@ begin
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when RD_START =>
-----------------------------------------------
ack <= '0';
ack <= '0';
cs_extend <= '1';
rd_extend <= '1';
wr_extend <= '0';
......@@ -215,7 +215,7 @@ begin
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when RD_FETCH =>
-----------------------------------------------
ack <= '0';
ack <= '0';
cs_extend <= '1';
rd_extend <= '1';
wr_extend <= '0';
......@@ -228,7 +228,7 @@ begin
when RD_ACK =>
-----------------------------------------------
ack <= '1';
ack <= '1';
cs_extend <= '0';
rd_extend <= '0';
wr_extend <= '0';
......@@ -240,7 +240,7 @@ begin
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when WR_START =>
-----------------------------------------------
ack <= '0';
ack <= '0';
cs_extend <= '1';
rd_extend <= '0';
wr_extend <= '1';
......@@ -253,7 +253,7 @@ begin
when WR_PUSH =>
-----------------------------------------------
ack <= '0';
ack <= '0';
cs_extend <= '0';
rd_extend <= '0';
wr_extend <= '0';
......@@ -266,7 +266,7 @@ begin
when WR_ACK =>
-----------------------------------------------
ack <= '1';
ack <= '1';
cs_extend <= '0';
rd_extend <= '0';
wr_extend <= '0';
......@@ -278,7 +278,7 @@ begin
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when others =>
-----------------------------------------------
ack <= '0';
ack <= '0';
cs_extend <= '0';
rd_extend <= '0';
wr_extend <= '0';
......
......@@ -81,14 +81,12 @@ entity acam_timecontrol_interface is
-- OUTPUTS
-- Signals to the ACAM chip
start_dis_o : out std_logic;
start_from_fpga_o : out std_logic;
stop_dis_o : out std_logic;
-- Signals to the
acam_errflag_r_edge_p_o : out std_logic; -- ACAM ErrFlag rising edge
acam_errflag_f_edge_p_o : out std_logic; -- ACAM ErrFlag falling edge
acam_intflag_f_edge_p_o : out std_logic);-- ACAM IntFlag falling edge
acam_errflag_r_edge_p_o : out std_logic; -- ACAM ErrFlag rising edge
acam_errflag_f_edge_p_o : out std_logic; -- ACAM ErrFlag falling edge
acam_intflag_f_edge_p_o : out std_logic);-- ACAM IntFlag falling edge
end acam_timecontrol_interface;
......@@ -251,10 +249,6 @@ begin
start_trig_edge <= start_trig_r(1) and not(start_trig_r(0));
-- outputs
stop_dis_o <= '0';
start_dis_o <= '0';
end architecture rtl;
--=================================================================================================
......
......@@ -27,7 +27,7 @@
-- 05/2011 v0.1 GP First version |
-- 04/2012 v0.2 EG Added DFFs to the pll_sdi_o, pll_cs_o outputs |
-- Changed completely the internal reset generation; now it depends |
-- on the pll_status activation |
-- on the pll_status activation |
-- General revamping, comments added, signals renamed |
-- 05/2012 v0.3 EG Added logic for DAC configuration |
-- |
......@@ -75,9 +75,9 @@ entity clks_rsts_manager is
(spec_clk_i : in std_logic; -- 20 MHz OSC on SPEC board
-- Clock signals from the PLL
acam_refclk_p_i : in std_logic; -- 31.25 MHz differential clock generated by the PLL, clock of ACAM
acam_refclk_n_i : in std_logic; -- 31.25 MHz clock generated by the PLL, clock of ACAM
tdc_clk_p_i : in std_logic; -- 125 MHz clock generated by the PLL, clock of all other TDC core logic
acam_refclk_p_i : in std_logic; -- 31.25 MHz differential clock generated by the mezzanine PLL, clock of ACAM
acam_refclk_n_i : in std_logic; -- 31.25 MHz differential clock generated by the mezzanine PLL, clock of ACAM
tdc_clk_p_i : in std_logic; -- 125 MHz clock generated by the mezzanine PLL, clock of all other TDC core logic
tdc_clk_n_i : in std_logic;
-- Other signals from the PLL
......@@ -104,7 +104,8 @@ entity clks_rsts_manager is
pll_sclk_o : out std_logic; -- SPI clock
-- Signal to the one_hz_gen and acam_timecontrol_interface units
acam_refclk_r_edge_p_o : out std_logic; -- pulse upon acam_refclk_p_i rising edge
acam_refclk_o : out std_logic; -- 31.25 MHz reference clock for ACAM chip
acam_refclk_r_edge_p_o : out std_logic; -- pulse upon acam_refclk rising edge
-- Signals to the leds_manager unit
gnum_rst_o : out std_logic; -- GENUM reset synched with 20 MHz clock
......@@ -246,8 +247,8 @@ begin
---------------------------------------------------------------------------------------------------
tdc_clk125_ibuf : IBUFDS
generic map
(DIFF_TERM => false, -- Differential Termination
IBUF_LOW_PWR => true, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards
(DIFF_TERM => true, -- Differential Termination
IBUF_LOW_PWR => false, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards
IOSTANDARD => "DEFAULT")
port map
(O => tdc_clk_buf, -- Buffer output
......@@ -276,22 +277,6 @@ begin
-- -- -- -- -- -- -- --
spec_clk_o <= spec_clk;
---------------------------------------------------------------------------------------------------
acam_refclk31M25_ibuf : IBUFDS
generic map
(DIFF_TERM => false, -- Differential Termination
IBUF_LOW_PWR => true, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards
IOSTANDARD => "DEFAULT")
port map
(O => acam_refclk,
I => acam_refclk_p_i, -- Diff_p buffer input (connect directly to top-level port)
IB => acam_refclk_n_i);-- Diff_n buffer input (connect directly to top-level port)
--acam_refclk31M25_gbuf : BUFG
--port map
-- (O => acam_refclk,
-- I => acam_refclk_buf);
---------------------------------------------------------------------------------------------------
-- General Internal Reset --
......@@ -365,8 +350,27 @@ begin
---------------------------------------------------------------------------------------------------
-- ACAM Reference Clock Synchronizer --
-- ACAM Reference Clock --
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
acam_refclk31M25_ibuf : IBUFDS
generic map
(DIFF_TERM => true, -- Differential Termination
IBUF_LOW_PWR => false, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards
IOSTANDARD => "DEFAULT")
port map
(O => acam_refclk,
I => acam_refclk_p_i, -- Diff_p buffer input (connect directly to top-level port)
IB => acam_refclk_n_i);-- Diff_n buffer input (connect directly to top-level port)
--acam_refclk31M25_gbuf : BUFG
--port map
--(O => acam_refclk,
--I => acam_refclk_buf);
---------------------------------------------------------------------------------------------------
acam_refclk_synchronizer: process (tdc_clk)
begin
if rising_edge (tdc_clk) then
......@@ -377,9 +381,9 @@ begin
end if;
end if;
end process;
-- -- -- -- -- -- -- --
-- -- -- -- -- --
acam_refclk_r_edge_p_o <= (not acam_refclk_synch(2)) and acam_refclk_synch(1);
acam_refclk_o <= acam_refclk;
---------------------------------------------------------------------------------------------------
......
......@@ -202,7 +202,7 @@ begin
acam_we <= '0';
-----------------------------------------------
if activate_acq_p_i = '1' then -- activation of timestamps aquisition
if activate_acq_p_i = '1' then -- activation of timestamps aquisition
nxt_engine_st <= ACTIVE;
elsif acam_wr_config_p_i = '1' then
......@@ -272,7 +272,7 @@ begin
-- ef check ^
-- It is first checked if iFIFO1 is not empty, and if so a timestamp is retreived from it.
-- Then iFIFO2 is checked and if it not empty a timestamp is retreived from it.
-- Then iFIFO2 is checked and if it is not empty a timestamp is retreived from it.
-- The alternation between the two FIFOs takes place until they are both empty.
-- The retreival of a timestamp from any of the FIFOs takes place
......
This diff is collapsed.
This diff is collapsed.
......@@ -152,7 +152,7 @@ begin
nxt_irq_st <= IDLE;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when TSTAMP_AND_TIME_COUNTING =>
-----------------------------------------------
irq_tstamp_p_o <= '0';
......@@ -164,7 +164,7 @@ begin
-----------------------------------------------
if deactivate_acq_p_i = '1' then
nxt_irq_st <= IDLE;
elsif tstamps_c >= ZERO and tstamps_c >= irq_tstamp_threshold_i(8 downto 0) then
elsif tstamps_c > ZERO and tstamps_c >= irq_tstamp_threshold_i(8 downto 0) then -- not >= ZERO!!
nxt_irq_st <= RAISE_IRQ_TSTAMP;
elsif time_c >= irq_time_threshold_i and tstamps_c > ZERO then
nxt_irq_st <= RAISE_IRQ_TIME;
......@@ -219,6 +219,7 @@ begin
end process;
---------------------------------------------------------------------------------------------------
-- TIMESTAMPS COUNTER --
---------------------------------------------------------------------------------------------------
......@@ -238,6 +239,8 @@ begin
-------------------------------------------
tstamps_c_incr_en <= tstamps_c_en and tstamp_wr_p_i;
---------------------------------------------------------------------------------------------------
-- TIME COUNTER --
---------------------------------------------------------------------------------------------------
......
......@@ -22,17 +22,18 @@
-- | O O | 5, 6 |
-- |______| |
-- |
-- And further down 2 LEDs on the front panel of the SPEC carrier board: |
-- ______ |
-- | O O | 1, 2 |
-- |______| |
-- |
-- TDC LED 1 orange: division of the 125 MHz clock; one hz pulses |
-- TDC LED 2 orange: Channel 1 terminatio enable |
-- TDC LED 3 orange: Channel 2 terminatio enable |
-- TDC LED 4 orange: Channel 3 terminatio enable |
-- TDC LED 5 orange: Channel 4 terminatio enable |
-- TDC LED 6 orange: Channel 5 terminatio enable |
-- |
-- And further down 2 LEDs on the front panel of the SPEC carrier board: |
-- ______ |
-- | O O | 1, 2 |
-- |______| |
-- |
-- SPEC LED 1 green : PLL status (DLD) |
-- SPEC LED 2 red : division of the 20 MHz clock |
-- |
......
This diff is collapsed.
......@@ -29,17 +29,17 @@
-- each bit represents 81.03 ps |
-- |
-- In I-Mode the Acam chip provides unlimited measuring range with internal start |
-- retriggers. Acam is programmed to retrigger every (16*acam_clk) = (64*clk_i) ticks|
-- (the StartTimer in Acam Reg 4 is set to 15), it counts the number of retriggers |
-- after a Start pulse and upon the arrival of a Stop pulse it sends this number |
-- in the "Start#" field of the timestamp. Unfortunately Acam's counter of the |
-- retriggers has only 8 bits and can count up to 256 retriggers. Within one second |
-- (our UTC time) there can be up to 1,953,125 retriggers, which is >> 256 and |
-- actually corresponds to 7629 overflows of the Acam counter. Therefore there is the|
-- need to follow Acam and keep track of the overflows. The Acam Interrupt flag |
-- (IrFlag pin 59) has been set to follow the highest bit of the Start# (through the |
-- Acam Reg 12 bit 26) and like this we manage to count retriggers synchronously to |
-- Acam itself. |
-- retriggers. Acam is programmed to retrigger every (16*acam_clk_period) = |
-- (64*clk_i_period) = 512 ns; the StartTimer in Acam Reg 4 is set to 15. It counts |
-- the number of retriggers after a Start pulse and upon the arrival of a Stop pulse |
-- and it sends this number in the "Start#" field of the timestamp. |
-- Unfortunately Acam's counter of the retriggers has only 8 bits and can count up |
-- to 256 retriggers. Within one second (our UTC time) there can be up to |
-- 1,953,125 retriggers, which is >> 256 and actually corresponds to 7629 overflows |
-- of the Acam counter. Therefore there is the need to follow Acam and keep track of |
-- the overflows. The Acam Interrupt flag (IrFlag pin 59) has been set to follow the |
-- highest bit of the Start# (through the Acam Reg 12 bit 26) and like this we |
-- manage to count retriggers synchronously to Acam itself. |
-- For simplification, in the following figure we assume that two Stop signals arrive|
-- after less than 256 Acam internal retriggers. Therefore in the timestamps that |
-- Acam will give the Start# field will represent the exact amount of retriggers |
......
This diff is collapsed.
This diff is collapsed.
--------------------------------------------------------------------------------
-- --
-- CERN BE-CO-HT GN4124 core for PCIe FMC carrier --
-- http://www.ohwr.org/projects/gn4124-core --
--------------------------------------------------------------------------------
--
-- unit name: wishbone address decoder
--
-- author: Matthieu Cattin (matthieu.cattin@cern.ch)
--
-- date: 02-08-2011
--
-- version: 0.1
--
-- description: Provides a simple wishbone address decoder.
-- Splits the memory windows into equal parts.
--
-- 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:
--------------------------------------------------------------------------------
-- TODO:
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.gn4124_core_pkg.all;
entity wb_addr_decoder is
generic
(
g_WINDOW_SIZE : integer := 18; -- Number of bits to address periph on the board (32-bit word address)
g_WB_SLAVES_NB : integer := 2
);
port
(
---------------------------------------------------------
-- GN4124 core clock and reset
clk_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- wishbone master interface
wbm_adr_i : in std_logic_vector(31 downto 0); -- Address
wbm_dat_i : in std_logic_vector(31 downto 0); -- Data out
wbm_sel_i : in std_logic_vector(3 downto 0); -- Byte select
wbm_stb_i : in std_logic; -- Strobe
wbm_we_i : in std_logic; -- Write
wbm_cyc_i : in std_logic; -- Cycle
wbm_dat_o : out std_logic_vector(31 downto 0); -- Data in
wbm_ack_o : out std_logic; -- Acknowledge
wbm_stall_o : out std_logic; -- Stall
---------------------------------------------------------
-- wishbone slaves interface
wb_adr_o : out std_logic_vector(31 downto 0); -- Address
wb_dat_o : out std_logic_vector(31 downto 0); -- Data out
wb_sel_o : out std_logic_vector(3 downto 0); -- Byte select
wb_stb_o : out std_logic; -- Strobe
wb_we_o : out std_logic; -- Write
wb_cyc_o : out std_logic_vector(g_WB_SLAVES_NB-1 downto 0); -- Cycle
wb_dat_i : in std_logic_vector((32*g_WB_SLAVES_NB)-1 downto 0); -- Data in
wb_ack_i : in std_logic_vector(g_WB_SLAVES_NB-1 downto 0); -- Acknowledge
wb_stall_i : in std_logic_vector(g_WB_SLAVES_NB-1 downto 0) -- Stall
);
end wb_addr_decoder;
architecture behaviour of wb_addr_decoder is
-----------------------------------------------------------------------------
-- Constants declaration
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Signals declaration
-----------------------------------------------------------------------------
-- Wishbone
signal s_wb_periph_addr : std_logic_vector(log2_ceil(g_WB_SLAVES_NB)-1 downto 0);
signal wb_periph_addr : std_logic_vector(log2_ceil(g_WB_SLAVES_NB)-1 downto 0);
signal s_wb_periph_select : std_logic_vector((2**s_wb_periph_addr'length)-1 downto 0);
signal s_wb_ack_muxed : std_logic;
signal wb_ack_t : std_logic;
signal s_wb_dat_i_muxed : std_logic_vector(31 downto 0);
signal s_wb_cyc_demuxed : std_logic_vector(g_WB_SLAVES_NB-1 downto 0);
signal wb_adr_t : std_logic_vector(g_WINDOW_SIZE-log2_ceil(g_WB_SLAVES_NB)-1 downto 0);
begin
------------------------------------------------------------------------------
-- Wishbone master address decoding
------------------------------------------------------------------------------
-- Take the first N bits of the address to select the active wb peripheral
-- g_WINDOW_SIZE represents 32-bit word address window
s_wb_periph_addr <= wbm_adr_i(g_WINDOW_SIZE-1 downto g_WINDOW_SIZE-log2_ceil(g_WB_SLAVES_NB));
-----------------------------------------------------------------------------
-- One-hot decode function, s_wb_periph_select <= onehot_decode(s_wb_periph_addr);
-----------------------------------------------------------------------------
onehot_decode : process(s_wb_periph_addr)
variable v_onehot : std_logic_vector((2**s_wb_periph_addr'length)-1 downto 0);
variable v_index : integer range 0 to (2**s_wb_periph_addr'length)-1;
begin
v_onehot := (others => '0');
v_index := 0;
for i in s_wb_periph_addr'range loop
if (s_wb_periph_addr(i) = '1') then
v_index := 2*v_index+1;
else
v_index := 2*v_index;
end if;
end loop;
v_onehot(v_index) := '1';
s_wb_periph_select <= v_onehot;
end process onehot_decode;
-- Register multiplexed ack and data + periph address
p_wb_in_regs : process (clk_i, rst_n_i)
begin
if (rst_n_i = c_RST_ACTIVE) then
wb_periph_addr <= (others => '0');
wbm_dat_o <= (others => '0');
wb_ack_t <= '0';
elsif rising_edge(clk_i) then
wb_periph_addr <= s_wb_periph_addr;
wbm_dat_o <= s_wb_dat_i_muxed;
wb_ack_t <= s_wb_ack_muxed;
end if;
end process p_wb_in_regs;
wbm_ack_o <= wb_ack_t;
-- Select ack line of the active peripheral
p_ack_mux : process (wb_ack_i, wb_periph_addr)
begin
if (to_integer(unsigned(wb_periph_addr)) < g_WB_SLAVES_NB) then
s_wb_ack_muxed <= wb_ack_i(to_integer(unsigned(wb_periph_addr)));
else
s_wb_ack_muxed <= '0';
end if;
end process p_ack_mux;
-- Select stall line of the active peripheral
p_stall_mux : process (wb_stall_i, s_wb_periph_addr)
begin
if (to_integer(unsigned(s_wb_periph_addr)) < g_WB_SLAVES_NB) then
wbm_stall_o <= wb_stall_i(to_integer(unsigned(s_wb_periph_addr)));
else
wbm_stall_o <= '0';
end if;
end process p_stall_mux;
-- Select input data of the active peripheral
p_din_mux : process (wb_dat_i, wb_periph_addr)
begin
if (to_integer(unsigned(wb_periph_addr)) < g_WB_SLAVES_NB) then
s_wb_dat_i_muxed <=
wb_dat_i(31+(32*to_integer(unsigned(wb_periph_addr))) downto 32*to_integer(unsigned(wb_periph_addr)));
else
s_wb_dat_i_muxed <= (others => 'X');
end if;
end process p_din_mux;
-- Assert the cyc line of the selected peripheral
gen_cyc_demux : for i in 0 to g_WB_SLAVES_NB-1 generate
s_wb_cyc_demuxed(i) <= wbm_cyc_i and s_wb_periph_select(i) and not(wb_ack_t);
end generate gen_cyc_demux;
-- Slaves wishbone bus outputs
wb_dat_o <= wbm_dat_i;
wb_stb_o <= wbm_stb_i;
wb_we_o <= wbm_we_i;
wb_sel_o <= wbm_sel_i;
wb_cyc_o <= s_wb_cyc_demuxed;
-- extend address bus to 32-bit
wb_adr_t <= wbm_adr_i(g_WINDOW_SIZE-log2_ceil(g_WB_SLAVES_NB)-1 downto 0);
wb_adr_o(wb_adr_t'left downto 0) <= wb_adr_t;
wb_adr_o(31 downto wb_adr_t'left+1) <= (others => '0');
end behaviour;
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