Commit e502cb54 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

wip

parent c864d026
......@@ -187,7 +187,7 @@ module acam_model
hit = t_stop1 - t_start + rmode_start_offset * 3;
if(g_verbose)$display("acam::hit1 %d", hit);
if(g_verbose)$display("acam::hit1 %d t_stop1 %d t_start %d", hit, t_stop1, t_start);
if(q_hit.num() == 0) begin
#(c_empty_flag_delay);
......
`define ADDR_FD_RSTR 7'h0
`define ADDR_FD_GCR 7'h4
`define ADDR_FD_RSTR 8'h0
`define ADDR_FD_IDR 8'h4
`define ADDR_FD_GCR 8'h8
`define FD_GCR_BYPASS_OFFSET 0
`define FD_GCR_BYPASS 32'h00000001
`define FD_GCR_INPUT_EN_OFFSET 1
`define FD_GCR_INPUT_EN 32'h00000002
`define FD_GCR_CLR_STAT_OFFSET 2
`define FD_GCR_CLR_STAT 32'h00000004
`define ADDR_FD_TAR 7'h8
`define FD_GCR_CSYNC_INT_OFFSET 2
`define FD_GCR_CSYNC_INT 32'h00000004
`define FD_GCR_CSYNC_WR_OFFSET 3
`define FD_GCR_CSYNC_WR 32'h00000008
`define FD_GCR_WR_READY_OFFSET 4
`define FD_GCR_WR_READY 32'h00000010
`define ADDR_FD_TAR 8'hc
`define FD_TAR_DATA_OFFSET 0
`define FD_TAR_DATA 32'h0fffffff
`define FD_TAR_ADDR_OFFSET 28
`define FD_TAR_ADDR 32'hf0000000
`define ADDR_FD_TDCSR 7'hc
`define ADDR_FD_TDCSR 8'h10
`define FD_TDCSR_WRITE_OFFSET 0
`define FD_TDCSR_WRITE 32'h00000001
`define FD_TDCSR_READ_OFFSET 1
......@@ -32,54 +37,156 @@
`define FD_TDCSR_STOP_DIS 32'h00000100
`define FD_TDCSR_STOP_EN_OFFSET 9
`define FD_TDCSR_STOP_EN 32'h00000200
`define ADDR_FD_DCR 7'h10
`define FD_DCR_DLY_SEL_OFFSET 0
`define FD_DCR_DLY_SEL 32'h0000000f
`define FD_DCR_DLY_VAL_OFFSET 4
`define FD_DCR_DLY_VAL 32'h00003ff0
`define ADDR_FD_GPSR 7'h14
`define FD_GPSR_CS_PLL_OFFSET 0
`define FD_GPSR_CS_PLL 32'h00000001
`define FD_GPSR_CS_GPIO_OFFSET 1
`define FD_GPSR_CS_GPIO 32'h00000002
`define FD_GPSR_SCLK_OFFSET 2
`define FD_GPSR_SCLK 32'h00000004
`define FD_GPSR_MOSI_OFFSET 3
`define FD_GPSR_MOSI 32'h00000008
`define ADDR_FD_GPCR 7'h18
`define FD_GPCR_CS_PLL_OFFSET 0
`define FD_GPCR_CS_PLL 32'h00000001
`define FD_GPCR_CS_GPIO_OFFSET 1
`define FD_GPCR_CS_GPIO 32'h00000002
`define FD_GPCR_SCLK_OFFSET 2
`define FD_GPCR_SCLK 32'h00000004
`define FD_GPCR_MOSI_OFFSET 3
`define FD_GPCR_MOSI 32'h00000008
`define ADDR_FD_GPRR 7'h1c
`define FD_GPRR_MISO_OFFSET 0
`define FD_GPRR_MISO 32'h00000001
`define ADDR_FD_IECRAW 7'h20
`define ADDR_FD_IECTAG 7'h24
`define ADDR_FD_IEPD 7'h28
`define ADDR_FD_PGCR 7'h2c
`define FD_PGCR_PERIOD_OFFSET 0
`define FD_PGCR_PERIOD 32'h7fffffff
`define FD_PGCR_ENABLE_OFFSET 31
`define FD_PGCR_ENABLE 32'h80000000
`define ADDR_FD_TSFIFO_R0 7'h30
`define FD_TSFIFO_R0_UTC_OFFSET 0
`define FD_TSFIFO_R0_UTC 32'hffffffff
`define ADDR_FD_TSFIFO_R1 7'h34
`define FD_TSFIFO_R1_COARSE_OFFSET 0
`define FD_TSFIFO_R1_COARSE 32'h0fffffff
`define ADDR_FD_TSFIFO_R2 7'h38
`define FD_TSFIFO_R2_FRAC_OFFSET 0
`define FD_TSFIFO_R2_FRAC 32'h007fffff
`define ADDR_FD_TSFIFO_R3 7'h3c
`define FD_TSFIFO_R3_FRAC_RAW_OFFSET 0
`define FD_TSFIFO_R3_FRAC_RAW 32'h007fffff
`define ADDR_FD_TSFIFO_CSR 7'h40
`define FD_TSFIFO_CSR_FULL_OFFSET 16
`define FD_TSFIFO_CSR_FULL 32'h00010000
`define FD_TSFIFO_CSR_EMPTY_OFFSET 17
`define FD_TSFIFO_CSR_EMPTY 32'h00020000
`define ADDR_FD_ADSFR 8'h14
`define ADDR_FD_ATMCR 8'h18
`define FD_ATMCR_C_THR_OFFSET 0
`define FD_ATMCR_C_THR 32'h0000000f
`define FD_ATMCR_F_THR_OFFSET 4
`define FD_ATMCR_F_THR 32'h07fffff0
`define ADDR_FD_ASOR 8'h1c
`define FD_ASOR_OFFSET_OFFSET 0
`define FD_ASOR_OFFSET 32'h007fffff
`define ADDR_FD_IECRAW 8'h20
`define ADDR_FD_IECTAG 8'h24
`define ADDR_FD_IEPD 8'h28
`define FD_IEPD_RST_STAT_OFFSET 0
`define FD_IEPD_RST_STAT 32'h00000001
`define FD_IEPD_PDELAY_OFFSET 1
`define FD_IEPD_PDELAY 32'h000001fe
`define ADDR_FD_RCRR 8'h2c
`define ADDR_FD_RCFR 8'h30
`define ADDR_FD_TSBCR 8'h34
`define FD_TSBCR_ENABLE_OFFSET 0
`define FD_TSBCR_ENABLE 32'h00000001
`define FD_TSBCR_PURGE_OFFSET 1
`define FD_TSBCR_PURGE 32'h00000002
`define FD_TSBCR_RST_SEQ_OFFSET 2
`define FD_TSBCR_RST_SEQ 32'h00000004
`define FD_TSBCR_FULL_OFFSET 3
`define FD_TSBCR_FULL 32'h00000008
`define FD_TSBCR_EMPTY_OFFSET 4
`define FD_TSBCR_EMPTY 32'h00000010
`define ADDR_FD_TSBR_U 8'h38
`define ADDR_FD_TSBR_C 8'h3c
`define ADDR_FD_TSBR_FID 8'h40
`define FD_TSBR_FID_FINE_OFFSET 0
`define FD_TSBR_FID_FINE 32'h00000fff
`define FD_TSBR_FID_SEQID_OFFSET 16
`define FD_TSBR_FID_SEQID 32'hffff0000
`define ADDR_FD_DCR1 8'h60
`define FD_DCR1_ENABLE_OFFSET 0
`define FD_DCR1_ENABLE 32'h00000001
`define FD_DCR1_MODE_OFFSET 1
`define FD_DCR1_MODE 32'h00000002
`define FD_DCR1_PG_ARM_OFFSET 2
`define FD_DCR1_PG_ARM 32'h00000004
`define FD_DCR1_PG_TRIG_OFFSET 3
`define FD_DCR1_PG_TRIG 32'h00000008
`define FD_DCR1_UPDATE_OFFSET 4
`define FD_DCR1_UPDATE 32'h00000010
`define FD_DCR1_UPD_DONE_OFFSET 5
`define FD_DCR1_UPD_DONE 32'h00000020
`define FD_DCR1_FORCE_CP_OFFSET 6
`define FD_DCR1_FORCE_CP 32'h00000040
`define FD_DCR1_POL_OFFSET 7
`define FD_DCR1_POL 32'h00000080
`define ADDR_FD_FRR1 8'h64
`define ADDR_FD_U_START1 8'h68
`define ADDR_FD_C_START1 8'h6c
`define ADDR_FD_F_START1 8'h70
`define ADDR_FD_U_END1 8'h74
`define ADDR_FD_C_END1 8'h78
`define ADDR_FD_F_END1 8'h7c
`define ADDR_FD_DCR2 8'h80
`define FD_DCR2_ENABLE_OFFSET 0
`define FD_DCR2_ENABLE 32'h00000001
`define FD_DCR2_MODE_OFFSET 1
`define FD_DCR2_MODE 32'h00000002
`define FD_DCR2_PG_ARM_OFFSET 2
`define FD_DCR2_PG_ARM 32'h00000004
`define FD_DCR2_PG_TRIG_OFFSET 3
`define FD_DCR2_PG_TRIG 32'h00000008
`define FD_DCR2_UPDATE_OFFSET 4
`define FD_DCR2_UPDATE 32'h00000010
`define FD_DCR2_UPD_DONE_OFFSET 5
`define FD_DCR2_UPD_DONE 32'h00000020
`define FD_DCR2_FORCE_CP_OFFSET 6
`define FD_DCR2_FORCE_CP 32'h00000040
`define FD_DCR2_POL_OFFSET 7
`define FD_DCR2_POL 32'h00000080
`define ADDR_FD_FRR2 8'h84
`define ADDR_FD_U_START2 8'h88
`define ADDR_FD_C_START2 8'h8c
`define ADDR_FD_F_START2 8'h90
`define ADDR_FD_U_END2 8'h94
`define ADDR_FD_C_END2 8'h98
`define ADDR_FD_F_END2 8'h9c
`define ADDR_FD_DCR3 8'ha0
`define FD_DCR3_ENABLE_OFFSET 0
`define FD_DCR3_ENABLE 32'h00000001
`define FD_DCR3_MODE_OFFSET 1
`define FD_DCR3_MODE 32'h00000002
`define FD_DCR3_PG_ARM_OFFSET 2
`define FD_DCR3_PG_ARM 32'h00000004
`define FD_DCR3_PG_TRIG_OFFSET 3
`define FD_DCR3_PG_TRIG 32'h00000008
`define FD_DCR3_UPDATE_OFFSET 4
`define FD_DCR3_UPDATE 32'h00000010
`define FD_DCR3_UPD_DONE_OFFSET 5
`define FD_DCR3_UPD_DONE 32'h00000020
`define FD_DCR3_FORCE_CP_OFFSET 6
`define FD_DCR3_FORCE_CP 32'h00000040
`define FD_DCR3_POL_OFFSET 7
`define FD_DCR3_POL 32'h00000080
`define ADDR_FD_FRR3 8'ha4
`define ADDR_FD_U_START3 8'ha8
`define ADDR_FD_C_START3 8'hac
`define ADDR_FD_F_START3 8'hb0
`define ADDR_FD_U_END3 8'hb4
`define ADDR_FD_C_END3 8'hb8
`define ADDR_FD_F_END3 8'hbc
`define ADDR_FD_DCR4 8'hc0
`define FD_DCR4_ENABLE_OFFSET 0
`define FD_DCR4_ENABLE 32'h00000001
`define FD_DCR4_MODE_OFFSET 1
`define FD_DCR4_MODE 32'h00000002
`define FD_DCR4_PG_ARM_OFFSET 2
`define FD_DCR4_PG_ARM 32'h00000004
`define FD_DCR4_PG_TRIG_OFFSET 3
`define FD_DCR4_PG_TRIG 32'h00000008
`define FD_DCR4_UPDATE_OFFSET 4
`define FD_DCR4_UPDATE 32'h00000010
`define FD_DCR4_UPD_DONE_OFFSET 5
`define FD_DCR4_UPD_DONE 32'h00000020
`define FD_DCR4_FORCE_CP_OFFSET 6
`define FD_DCR4_FORCE_CP 32'h00000040
`define FD_DCR4_POL_OFFSET 7
`define FD_DCR4_POL 32'h00000080
`define ADDR_FD_FRR4 8'hc4
`define ADDR_FD_U_START4 8'hc8
`define ADDR_FD_C_START4 8'hcc
`define ADDR_FD_F_START4 8'hd0
`define ADDR_FD_U_END4 8'hd4
`define ADDR_FD_C_END4 8'hd8
`define ADDR_FD_F_END4 8'hdc
`define ADDR_FD_EIC_IDR 8'he0
`define FD_EIC_IDR_TS_BUF_NOTEMPTY_OFFSET 0
`define FD_EIC_IDR_TS_BUF_NOTEMPTY 32'h00000001
`define ADDR_FD_EIC_IER 8'he4
`define FD_EIC_IER_TS_BUF_NOTEMPTY_OFFSET 0
`define FD_EIC_IER_TS_BUF_NOTEMPTY 32'h00000001
`define ADDR_FD_EIC_IMR 8'he8
`define FD_EIC_IMR_TS_BUF_NOTEMPTY_OFFSET 0
`define FD_EIC_IMR_TS_BUF_NOTEMPTY 32'h00000001
`define ADDR_FD_EIC_ISR 8'hec
`define FD_EIC_ISR_TS_BUF_NOTEMPTY_OFFSET 0
`define FD_EIC_ISR_TS_BUF_NOTEMPTY 32'h00000001
`define ADDR_FD_RAWFIFO_R0 8'hf0
`define FD_RAWFIFO_R0_FRAC_OFFSET 0
`define FD_RAWFIFO_R0_FRAC 32'h0fffffff
`define ADDR_FD_RAWFIFO_R1 8'hf4
`define FD_RAWFIFO_R1_COARSE_OFFSET 0
`define FD_RAWFIFO_R1_COARSE 32'h0fffffff
`define ADDR_FD_RAWFIFO_CSR 8'hf8
`define FD_RAWFIFO_CSR_EMPTY_OFFSET 17
`define FD_RAWFIFO_CSR_EMPTY 32'h00020000
`include "timestamp.svh"
module ideal_timestamper
(
input clk_ref_i,
......@@ -5,74 +7,78 @@ module ideal_timestamper
input enable_i,
input trig_a_i,
output reg [22:0] tag_frac_o,
output reg [27:0] tag_coarse_o,
output reg [31:0] tag_utc_o,
output tag_valid_p1_o,
output [27:0] cntr_coarse_o,
output [31:0] cntr_utc_o
input [31:0] csync_utc_i,
input [27:0] csync_coarse_i,
input csync_p1_i
);
parameter real g_frac_resolution = 80.9553ps/3.0;
parameter g_frac_range = 4096;
parameter g_coarse_range = 256;
const time c_frac_step = 8ns / g_frac_range;
reg [27:0] cntr_coarse;
reg [31:0] cntr_utc;
reg [22:0] cntr_frac;
reg [12:0] cntr_frac;
reg tag_valid_p1;
typedef struct {
reg [27:0] coarse;
reg [31:0] utc;
reg [22:0] frac;
} timestamp_t;
timestamp_t ts_queue[$] = '{};
Timestamp ts_queue[$];
always@(posedge clk_ref_i)
if(!rst_n_i)
begin
cntr_coarse <= 0;
cntr_utc <= 0;
cntr_frac <= 0;
tag_valid_p1 <= 0;
ts_queue = '{};
cntr_coarse <= 0;
cntr_utc <= 0;
cntr_frac <= 0;
tag_valid_p1 <= 0;
ts_queue = '{};
end
always@(posedge clk_ref_i)
cntr_frac <= 0;
cntr_frac <= 0;
always@(posedge clk_ref_i)
if(rst_n_i)
begin
if(cntr_coarse == 125000000 - 1) begin
cntr_coarse <= 0;
cntr_utc <= cntr_utc + 1;
if(!rst_n_i) begin
cntr_coarse <= 0;
cntr_utc <= 0;
end else begin
if(csync_p1_i)
begin
cntr_coarse <= csync_coarse_i+1;
cntr_utc <= csync_utc_i;
end else if(cntr_coarse == g_coarse_range) begin
cntr_coarse <= 1;
cntr_utc <= cntr_utc + 1;
end else if(cntr_coarse == g_coarse_range - 1) begin
cntr_coarse <= 0;
cntr_utc <= cntr_utc + 1;
end else
cntr_coarse <= cntr_coarse + 1;
cntr_coarse <= cntr_coarse + 1;
end
initial forever begin
#(g_frac_resolution) cntr_frac <= cntr_frac + 1;
end
initial forever #(c_frac_step) cntr_frac <= cntr_frac + 1;
always@(posedge trig_a_i) begin
if(enable_i)
begin
timestamp_t ts;
ts.frac = cntr_frac;
ts.coarse = cntr_coarse;
ts.utc = cntr_utc;
Timestamp ts;
ts = new (cntr_utc, cntr_coarse, cntr_frac);
ts_queue.push_back(ts);
end
end
function int poll();
return (ts_queue.size() > 0);
endfunction // poll
function Timestamp get();
return ts_queue.pop_front();
endfunction // get
/* -----\/----- EXCLUDED -----\/-----
always@(posedge clk_ref_i)
if(tag_valid_p1)
tag_valid_p1 <= 0;
......@@ -90,5 +96,6 @@ module ideal_timestamper
assign tag_valid_p1_o = tag_valid_p1;
assign cntr_coarse_o = cntr_coarse;
assign cntr_utc_o = cntr_utc;
-----/\----- EXCLUDED -----/\----- */
endmodule // ideal_timestamper
......@@ -19,7 +19,7 @@ module mc100ep195
always@(len)
if(len)
if(!len)
cur_dly <= delay;
always@(i)
......
......@@ -17,7 +17,7 @@ module random_pulse_gen
begin
real delta;
seed = $urandom(seed);
delta = $dist_uniform(seed, g_min_spacing + g_pulse_width, g_max_spacing + g_pulse_width);
delta = $dist_uniform(seed, g_min_spacing - g_pulse_width, g_max_spacing - g_pulse_width);
pulse_o = 1;
#(g_pulse_width);
pulse_o = 0;
......
`ifndef __TIMESTAMP_SVH
`define __TIMESTAMP_SVH
class Timestamp;
int utc, coarse, frac, coarse_range, seq_id;
function new(int _utc=0 ,int _coarse=0, int _frac=0,int _seq_id = 0, int _coarse_range = 256);
utc = _utc;
coarse = _coarse;
frac = _frac;
coarse_range = _coarse_range;
seq_id = _seq_id;
endfunction // new
function real flatten();
return real'(utc) * real'(coarse_range * 8) + real'(coarse) * 8.0 + (real'(frac)/4096.0 * 8.0);
endfunction // flatten
task unflatten(int x);
int t;
t =x;
frac = x % 4096;
x = x - frac;
x = x/4096;
coarse = x % 256;
x = x - coarse;
x = x/256;
utc = x;
$display("Unflat: %d %d %d %d", t, utc, coarse, frac);
endtask // unflatten
function Timestamp sub(Timestamp b);
endfunction
endclass
`endif // `ifndef __TIMESTAMP_SVH
files = ["fd_acam_timestamper.vhd",
"fd_cal_pulse_gen.vhd",
"fd_delay_line_driver.vhd",
"fd_wbgen2_pkg.vhd",
"fine_delay_core.vhd",
"fd_ring_buffer.vhd",
"fd_ts_adder.vhd",
"fd_ts_normalizer.vhd",
"fd_reset_generator.vhd",
"fd_csync_generator.vhd",
"fd_timestamper_stat_unit.vhd",
"fd_acam_timestamp_postprocessor.vhd",
"fd_delay_channel_driver.vhd",
"fd_delay_line_arbiter.vhd",
"fd_rearm_generator.vhd",
"fd_wishbone_slave.vhd",
"fine_delay_pkg.vhd",
"fine_delay_wb.vhd"]
"fine_delay_core.vhd"];
fetchto = "../ip_cores"
modules = {
"git" : [
"git@ohwr.org:hdl-core-lib/wr-cores.git",
"git@ohwr.org:hdl-core-lib/general-cores.git" ],
"svn" : [ "http://svn.ohwr.org/gn4124-core/branches/hdlmake-compliant/rtl" ]
}
"git" : [
"git@ohwr.org:hdl-core-lib/wr-cores.git",
"git@ohwr.org:hdl-core-lib/general-cores.git" ],
"svn" : [ "http://svn.ohwr.org/gn4124-core/branches/hdlmake-compliant/rtl" ]
};
-------------------------------------------------------------------------------
-- Title : ACAM TDX-GPX timestamp postprocessor
-- Project : Fine Delay Core (FmcDelay1ns4cha)
-------------------------------------------------------------------------------
-- File : fd_acam_timestamp_postprocessor.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN
-- Created : 2011-08-29
-- Last update: 2011-09-07
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Merges the coarse timestamp produced with the internal FPGA
-- counter with the fractional part obtained from the ACAM TDC, generating a final
-- UTC timestamp used for further processing.
-------------------------------------------------------------------------------
--
-- Copyright (c) 2011 CERN / BE-CO-HT
-- 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
--
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2011-08-29 1.0 twlostow Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.fd_wbgen2_pkg.all;
entity fd_acam_timestamp_postprocessor is
generic(
-- number of the bits in the fractional part
g_frac_bits : integer := 12);
port(
clk_ref_i : in std_logic;
rst_n_i : in std_logic;
-- Timestamp input, from the ACAM FSM
raw_valid_i : in std_logic;
raw_utc_i : in std_logic_vector(31 downto 0);
raw_coarse_i : in std_logic_vector(23 downto 0);
raw_frac_i : in std_logic_vector(22 downto 0);
---------------------------------------------------------------------------
-- Timestamp input, from the ACAM FS
---------------------------------------------------------------------------
raw_valid_i : in std_logic;
raw_utc_i : in std_logic_vector(31 downto 0);
-- "start number" (value of coarse counter, counting at every start pulse of the
-- TDC, i.e. 125 MHz / 16 = 7.8215 MHz)
raw_coarse_i : in std_logic_vector(23 downto 0);
-- raw fractional timestamp generated by ACAM
raw_frac_i : in std_logic_vector(22 downto 0);
-- coarse offset (in 125 MHz clock cycles) from the last ACAM's start pulse to the
-- input pulse (0..15)
raw_start_offset_i : in std_logic_vector(3 downto 0);
-- Offset between the actual timescale and the ACAM start signal generated
-- by the AD9516 PLL
-- Offset between the actual timescale and the ACAM fixed start signal generated
-- by the AD9516 PLL. Used to align the timestamps to the externally
-- provided time base (e.g. by White Rabbit).
acam_subcycle_offset_i : in std_logic_vector(4 downto 0);
---------------------------------------------------------------------------
-- Post-processed timestamp. WARNING! DE-NORMALIZED!
---------------------------------------------------------------------------
tag_valid_o : out std_logic;
tag_utc_o : out std_logic_vector(31 downto 0);
tag_coarse_o : out std_logic_vector(27 downto 0);
tag_frac_o : out std_logic_vector(g_frac_bits-1 downto 0);
regs_b : t_fd_registers
-- Wishbone regs
regs_i : in t_fd_out_registers
);
end fd_acam_timestamp_postprocessor;
architecture behavioral of fd_acam_timestamp_postprocessor is
-- number of the fractional bits to ignore in the rescaled ACAM's fractional
-- timestamp
constant c_SCALER_SHIFT : integer := 12;
signal pp_pipe : std_logic_vector(3 downto 0);
signal post_tag_coarse : unsigned(27 downto 0);
signal post_tag_frac : unsigned(g_frac_bits-1 downto 0);
signal post_tag_utc : unsigned(31 downto 0);
signal post_frac_multiplied : signed(c_SCALER_SHIFT + g_frac_bits + 8 downto 0);
signal post_frac_start_adj : signed(22 downto 0);
signal post_tag_coarse : unsigned(27 downto 0);
signal post_tag_frac : unsigned(g_frac_bits-1 downto 0);
signal post_tag_utc : unsigned(31 downto 0);
signal post_frac_multiplied : signed(c_SCALER_SHIFT + g_frac_bits + 8 downto 0);
signal post_frac_multiplied_d0 : signed(c_SCALER_SHIFT + g_frac_bits + 8 downto 0);
signal post_frac_start_adj : signed(22 downto 0);
begin -- behavioral
p_postprocess_tags : process(clk_ref_i)
begin
if rising_edge(clk_ref_i) then
......@@ -64,26 +124,31 @@ begin -- behavioral
pp_pipe(0) <= raw_valid_i;
post_frac_start_adj <= signed(raw_frac_i) - signed(regs_b.asor_offset_o);
post_frac_start_adj <= signed(raw_frac_i) - signed(regs_i.asor_offset_o);
post_tag_coarse(3 downto 0) <= (others => '0');
post_tag_utc <= unsigned(raw_utc_i);
-- pipeline stage 2:
-- - check for the "wraparound" condition and adjust the coarse start counter
-- - check for the "wraparound" condition and adjust the coarse start counter.
-- Wraparound occurs when the ACAM's hasn't yet accounted for the next start pulse
-- (resulting with a value of the fractional timestamp close to the upper
-- bound), but the FPGA counter had already "noticed" the next start. This
-- happens because of different routing delays and jitter.
pp_pipe(1) <= pp_pipe(0);
if (unsigned(raw_start_offset_i) <= unsigned(regs_b.atmcr_c_thr_o)) and (post_frac_start_adj > signed(regs_b.atmcr_f_thr_o)) then
if (unsigned(raw_start_offset_i) <= unsigned(regs_i.atmcr_c_thr_o)) and (post_frac_start_adj > signed(regs_i.atmcr_f_thr_o)) then
post_tag_coarse(post_tag_coarse'left downto 4) <= unsigned(raw_coarse_i) - 1;
else
post_tag_coarse(post_tag_coarse'left downto 4) <= unsigned(raw_coarse_i);
end if;
-- pipeline stage 3:
-- rescale the fractional part to our internal time base
-- rescale the fractional part to our internal time base
pp_pipe(2) <= pp_pipe(1);
post_frac_multiplied <= resize(signed(post_frac_start_adj) * signed(regs_b.adsfr_o), post_frac_multiplied'length);
pp_pipe(2) <= pp_pipe(1);
post_frac_multiplied <= resize(signed(post_frac_start_adj) * signed(regs_i.adsfr_o), post_frac_multiplied'length);
-- post_frac_multiplied_d0 <= post_frac_multiplied;
-- pipeline stage 4:
-- - split the rescaled fractional part into the (mod 4096) tag_frac_o and add
......@@ -94,7 +159,7 @@ begin -- behavioral
tag_utc_o <= std_logic_vector(post_tag_utc);
tag_coarse_o <= std_logic_vector(
signed(post_tag_coarse) -- index of start pulse (mod 16 = 0)
+ signed(acam_subcycle_offset_i) -- start-to-timescale offset
+ signed(acam_subcycle_offset_i) -- start-to-timescale offset
+ signed(post_frac_multiplied(post_frac_multiplied'left downto c_SCALER_SHIFT + g_frac_bits)));
-- extra coarse counts from ACAM's frac part after rescaling
......
This diff is collapsed.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity fd_cal_pulse_gen is
port(
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
pulse_o : out std_logic;
pgcr_enable_i : in std_logic;
pgcr_period_i : in std_logic_vector(30 downto 0)
);
end fd_cal_pulse_gen;
architecture behavioral of fd_cal_pulse_gen is
signal counter : unsigned(30 downto 0);
signal pulse_int : std_logic;
begin -- behavioral
process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' or pgcr_enable_i = '0' then
pulse_int <= '0';
counter <= to_unsigned(1, counter'length);
else
if(counter = unsigned(pgcr_period_i)) then
counter <= to_unsigned(1, counter'length);
pulse_int <= not pulse_int;
else
counter <= counter + 1;
end if;
pulse_o <= pulse_int;
end if;
end if;
end process;
end behavioral;
-------------------------------------------------------------------------------
-- Title : Counter Sync signal generator
-- Project : Fine Delay FMC (fmc-delay-1ns-4cha)
-------------------------------------------------------------------------------
-- File : fd_csync_generator.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN
-- Created : 2011-08-24
-- Last update: 2011-09-09
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Generates the internal time base used to synchronize the TDC
-- and the delayed pulse generators to an internal or WR-provided timescale.
-------------------------------------------------------------------------------