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,
......@@ -6,32 +8,22 @@ module ideal_timestamper
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)
......@@ -47,32 +39,46 @@ module ideal_timestamper
cntr_frac <= 0;
always@(posedge clk_ref_i)
if(rst_n_i)
if(!rst_n_i) begin
cntr_coarse <= 0;
cntr_utc <= 0;
end else begin
if(csync_p1_i)
begin
if(cntr_coarse == 125000000 - 1) 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;
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" ]
}
};
-------------------------------------------------------------------------------
-- 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
---------------------------------------------------------------------------
-- 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);
......@@ -44,11 +102,13 @@ architecture behavioral of fd_acam_timestamp_postprocessor is
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,16 +124,20 @@ 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);
......@@ -83,7 +147,8 @@ begin -- behavioral
-- 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);
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
......
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.
-------------------------------------------------------------------------------
-- Copyright (c) 2011 CERN / BE-CO-HT
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2011-08-24 1.0 twlostow Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
......@@ -7,27 +29,32 @@ use work.fd_wbgen2_pkg.all;
entity fd_csync_generator is
generic (
g_coarse_range : integer;
g_frac_bits : integer);
-- coarse counter range (0..g_coarse_range-1)
g_coarse_range : integer);
port(
clk_ref_i : in std_logic;
rst_n_i : in std_logic;
-- White Rabbit Counter sync input
-- when HI, wr_utc_i and wr_coarse_i contain a valid time value and
-- clk_ref_i is in-phase with the remote WR master
wr_time_valid_i : in std_logic;
wr_utc_i : in std_logic_vector(31 downto 0);
wr_coarse_i : in std_logic_vector(27 downto 0);
-- CSYNC Output
-- Counter sync output. HI Pulse = load internal counter with values from
-- csync_utc_o and csync_coarse_o.
csync_p1_o : out std_logic;
csync_utc_o : out std_logic_vector(31 downto 0);
csync_coarse_o : out std_logic_vector(27 downto 0);
regs_b : inout t_fd_registers);
-- Wishbone regs
regs_i : in t_fd_out_registers;
regs_o : out t_fd_in_registers);
end fd_csync_generator;
architecture behavioral of fd_csync_generator is
constant c_ADDER_PIPELINE_DELAY : integer := 4;
......@@ -64,8 +91,6 @@ architecture behavioral of fd_csync_generator is
begin -- behavioral
regs_b <= c_fd_registers_init_value;
U_Timescale_Adjust : fd_ts_adder
generic map (
g_frac_bits => 2,
......@@ -87,7 +112,7 @@ begin -- behavioral
q_coarse_o => csync_coarse_o,
q_frac_o => open);
regs_b.gcr_wr_ready_i <= wr_time_valid_i;
regs_o.gcr_wr_ready_i <= wr_time_valid_i;
process(clk_ref_i)
begin
......@@ -96,21 +121,21 @@ begin -- behavioral
coarse <= (others => '0');
utc <= (others => '0');
else
if(regs_b.gcr_csync_wr_o = '1' and wr_time_valid_i = '1') then
if(regs_i.gcr_csync_wr_o = '1' and wr_time_valid_i = '1') then
utc <= unsigned(wr_utc_i);
coarse <= unsigned(wr_coarse_i) + 1;
csync_int <= '1';
elsif(coarse = g_coarse_range) then -- unlike, but may happen after WR csync
coarse <= to_unsigned(1, coarse'length);
utc <= utc + 1;
csync_int <= regs_b.gcr_csync_int_o;
csync_int <= regs_i.gcr_csync_int_o;
elsif(coarse = g_coarse_range-1) then
coarse <= (others => '0');
utc <= utc + 1;
csync_int <= regs_b.gcr_csync_int_o;
csync_int <= regs_i.gcr_csync_int_o;
else
coarse <= coarse + 1;
csync_int <= regs_b.gcr_csync_int_o;
csync_int <= regs_i.gcr_csync_int_o;
end if;
end if;
end if;
......
This diff is collapsed.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity fd_delay_line_arbiter is
port (
clk_ref_i : in std_logic;
rst_n_i : in std_logic;
load_i : in std_logic_vector(3 downto 0);
done_o : out std_logic_vector(3 downto 0);
delay_val0_i : in std_logic_vector(9 downto 0);
delay_val1_i : in std_logic_vector(9 downto 0);
delay_val2_i : in std_logic_vector(9 downto 0);
delay_val3_i : in std_logic_vector(9 downto 0);
delay_val_o : out std_logic_vector(9 downto 0);
delay_len_o : out std_logic_vector(3 downto 0)
);
end fd_delay_line_arbiter;
architecture behavioral of fd_delay_line_arbiter is
signal arb_sreg : std_logic_vector(4*2 - 1 downto 0);
type t_dly_array is array (integer range <>) of std_logic_vector(9 downto 0);
signal done_reg : std_logic_vector(3 downto 0);
signal delay_vec : t_dly_array(0 to 3);
signal delay_len_reg : std_logic_vector(3 downto 0);
signal delay_val_reg : std_logic_vector(9 downto 0);
begin -- behavioral
delay_vec(0) <= delay_val0_i;
delay_vec(1) <= delay_val1_i;
delay_vec(2) <= delay_val2_i;
delay_vec(3) <= delay_val3_i;
p_arbitrate : process(clk_ref_i)
begin
if rising_edge(clk_ref_i) then
if rst_n_i = '0' then
delay_len_reg <= (others => '1');
delay_val_reg <= (others => '0');
-- done_reg <= (others => '0');
arb_sreg <= std_logic_vector(to_unsigned(1, arb_sreg'length));
else
arb_sreg <= arb_sreg(arb_sreg'left-1 downto 0) & arb_sreg(arb_sreg'left);
for i in 0 to 3 loop
if(arb_sreg(2*i) = '1' and load_i(i) = '1') then
delay_val_reg <= delay_vec(i);
delay_len_reg(i) <= '0';
end if;
if(arb_sreg(2*i+1) = '1' and load_i(i) = '1') then
delay_val_reg <= delay_vec(i);
delay_len_reg(i) <= '1';
end if;
end loop; -- i in 0 to 3
-- done_o <= done_reg;
delay_len_o <= delay_len_reg;
delay_val_o <= delay_val_reg;
end if;
end if;
end process;
gen_done: for i in 0 to 3 generate
done_o(i) <= arb_sreg(2*i+1) and load_i(i);
end generate gen_done;
end behavioral;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.fine_delay_pkg.all;
entity delay_line_driver is
port(
clk_ref_i : in std_logic;
rst_n_i : in std_logic;
-- time base synchronization
csync_time_i : in t_fd_timestamp;
csync_p1_i : in std_logic;
ch_start_i : in t_fd_timestamp_array;
ch_length_i : in t_fd_timestamp_array;
ch_load_p1_i : in std_logic_vector(c_fd_num_outputs-1 downto 0);
ch_polarity_i : in std_logic_vector(c_fd_num_outputs-1 downto 0);
ch_ready_o : out std_logic_vector(c_fd_num_outputs-1 downto 0);
delay_bus_o : out std_logic_vector(9 downto 0);
delay_len_o : out std_logic_vector(c_fd_num_outputs-1 downto 0);
delay_pulse_o : out std_logic_vector(c_fd_num_outputs-1 downto 0)
);
end delay_line_driver;
architecture behavioral of delay_line_driver is
signal t : t_fd_timestamp;
type t_adjustment_fsm_state is(A_IDLE, A_FIX_START, A_FIX_END, A_WAIT_ARM);
type t_channel is record
t_start: t_fd_timestamp;
t_stop: t_fd_timestamp;
t_length: t_fd_timestamp;
adj_state: t_adjustment_fsm_state;
armed: std_logic;
dly_adjusted: std_logic;
done: std_logic;
issued_start: std_logic;
end record;
type t_channel_array is array(0 to c_fd_num_outputs-1) of t_channel;
signal C : t_channel_array;
begin -- behavioral
p_timebase_counter : process(clk_ref_i)
begin
if rising_edge(clk_ref_i) then
if rst_n_i = '0' then
t.secs <= (others => '0');
t.cycles <= (others => '0');
t.fine <= (others => '0');
else
if(csync_p1_i = '1') then
t <= csync_time_i;
elsif(t.cycles = c_fd_refclk_freq - 1) then
t.secs <= t.secs + 1;
t.cycles <= (others => '0');
else
t.cycles <= t.cycles + 1;
end if;
end if;
end if;
end process;
gen_channels : for i in 0 to c_fd_num_outputs-1 generate
p_load_adjust_start_stop : process(clk_ref_i)
begin
if rising_edge(clk_ref_i) then
if rst_n_i = '0' then
C(i).t_start.cycles <= (others => '0');
C(i).t_start.secs <= (others => '0');
C(i).t_start.fine <= (others => '0');
C(i).armed <= '0';
else
case C(i).adj_state is
when A_IDLE =>
if ch_load_p1_i(i) = '1' then
C(i).t_start.fine <= ch_start_i(i).fine;
C(i).t_start.cycles <= ch_start_i(i).cycles - 2; -- 2 cycles in advance
C(i).t_start.secs <= ch_start_i(i).secs;
C(i).t_length <= ch_length_i(i);
C(i).armed <= '1';
C(i).adj_state <= A_FIX_START;
end if;
when A_FIX_START =>
-- calculate the end-of-pulse timestamp
C(i).t_stop.fine <= C(i).t_start.fine + C(i).t_length.fine;
C(i).t_stop.cycles <= C(i).t_start.cycles + C(i).t_length.cycles;
C(i).t_stop.secs <= C(i).t_start.secs + C(i).t_length.secs;
-- unwind start-of-pulse timestamp
if(C(i).t_start.cycles(27) = '1') then
C(i).t_start.secs <= C(i).t_start.secs + 1;
C(i).t_start.cycles <= C(i).t_start.cycles + c_fd_refclk_freq;
end if;
when others => null;
end case;
end if;
end if;
end process;
end generate gen_channels;
end behavioral;
library ieee;
use ieee.std_logic_1164.all;
use work.fd_wbgen2_pkg.all;
entity fd_gpio is
port (
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
-- chip select for VCTCXO DAC
spi_cs_dac_n_o : out std_logic;
-- chip select for AD9516 PLL
spi_cs_pll_n_o : out std_logic;
-- chip select for MCP23S17 GPIO
spi_cs_gpio_n_o : out std_logic;
-- these are obvious
spi_sclk_o : out std_logic;
spi_mosi_o : out std_logic;
spi_miso_i : in std_logic;
regs_b : inout t_fd_registers
);
end fd_gpio;
architecture rtl of fd_gpio is
begin -- rtl
regs_b <= c_fd_registers_init_value;
p_gpio_loads : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if (rst_n_i = '0') then
spi_cs_dac_n_o <= '1';
spi_cs_pll_n_o <= '1';
spi_cs_gpio_n_o <= '1';
spi_sclk_o <= '0';
spi_mosi_o <= '0';
regs_b.gprr_miso_i <= '0';
else
if(regs_b.gpsr_cs_pll_wr_o = '1' and regs_b.gpsr_cs_pll_o = '1') then
spi_cs_pll_n_o <= '1';
elsif (regs_b.gpcr_cs_pll_wr_o = '1' and regs_b.gpcr_cs_pll_o = '1') then
spi_cs_pll_n_o <= '0';
end if;
if(regs_b.gpsr_cs_gpio_wr_o = '1' and regs_b.gpsr_cs_gpio_o = '1') then
spi_cs_gpio_n_o <= '1';
elsif (regs_b.gpcr_cs_gpio_wr_o = '1' and regs_b.gpcr_cs_gpio_o = '1') then
spi_cs_gpio_n_o <= '0';
end if;
if(regs_b.gpsr_mosi_wr_o = '1' and regs_b.gpsr_mosi_o = '1') then
spi_mosi_o <= '1';
elsif (regs_b.gpcr_mosi_wr_o = '1' and regs_b.gpcr_mosi_o = '1') then
spi_mosi_o <= '0';
end if;
if(regs_b.gpsr_sclk_wr_o = '1' and regs_b.gpsr_sclk_o = '1') then
spi_sclk_o <= '1';
elsif (regs_b.gpcr_sclk_wr_o = '1' and regs_b.gpcr_sclk_o = '1') then
spi_sclk_o <= '0';
end if;
regs_b.gprr_miso_i <= spi_miso_i;
end if;
end if;
end process;
end rtl;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity fd_rearm_generator is
port (
clk_ref_i : in std_logic;
rst_n_i : in std_logic;
tag_valid_i : in std_logic;
rearm_i : in std_logic_vector(3 downto 0);
dcr_enable_i : in std_logic_vector(3 downto 0);
dcr_mode_i : in std_logic_vector(3 downto 0);
rearm_p1_o : out std_logic
);
end fd_rearm_generator;
architecture behavioral of fd_rearm_generator is
signal rearm_ch : std_logic_vector(3 downto 0);
begin -- behavioral
p_rearm : process(clk_ref_i)
begin
if rising_edge(clk_ref_i) then
if rst_n_i = '0' then
rearm_ch <= (others => '0');
rearm_p1_o <= '0';
else
if(rearm_ch = "1111") then
rearm_ch <= (others => '0');
rearm_p1_o <= '1';
elsif(tag_valid_i = '1')then
for i in 0 to 3 loop
rearm_ch(i) <= (not dcr_enable_i(i)) or dcr_mode_i(i);
end loop; -- i
rearm_p1_o <= '0';
else
rearm_p1_o <= '0';
for i in 0 to 3 loop
if(dcr_enable_i(i) = '1' and rearm_i(i) = '1') then
rearm_ch(i) <= '1';
end if;
end loop; -- i
end if;
end if;
end if;
end process;
end behavioral;
......@@ -13,7 +13,7 @@ entity fd_reset_generator is
rst_n_sys_o : out std_logic;
rst_n_ref_o : out std_logic;
regs_b : inout t_fd_registers);
regs_i : in t_fd_out_registers);
end fd_reset_generator;
......@@ -29,15 +29,13 @@ architecture behavioral of fd_reset_generator is
begin -- behavioral
regs_b <= c_fd_registers_init_value;
p_soft_reset : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if(rst_n_i = '0') then
rstn_host_sysclk <= '0';
else
if(regs_b.rstr_wr_o = '1' and regs_b.rstr_o = c_RSTR_TRIGGER_VALUE) then
if(regs_i.rstr_wr_o = '1' and regs_i.rstr_o = c_RSTR_TRIGGER_VALUE) then
rstn_host_sysclk <= '0';
else
rstn_host_sysclk <= '1';
......
......@@ -27,7 +27,9 @@ entity fd_ring_buffer is
advance_rbuf_i : in std_logic;
buf_irq_o : out std_logic;
regs_b : inout t_fd_registers
regs_i : in t_fd_out_registers;
regs_o : out t_fd_in_registers
);
......@@ -88,12 +90,11 @@ architecture behavioral of fd_ring_buffer is
begin -- behavioral
regs_b <= c_fd_registers_init_value;
p_count_seq_id : process(clk_ref_i)
begin
if rising_edge(clk_ref_i) then
if rst_n_ref_i = '0' or regs_b.tsbcr_rst_seq_o = '1' then
if rst_n_ref_i = '0' or regs_i.tsbcr_rst_seq_o = '1' then
cur_seq_id <= (others => '0');
elsif(tag_valid_i = '1') then
cur_seq_id <= cur_seq_id + 1;
......@@ -152,28 +153,27 @@ begin -- behavioral
buf_full <= '1' when (buf_wr_ptr + 1 = buf_rd_ptr) else '0';
buf_empty <= '1' when (buf_wr_ptr = buf_rd_ptr) else '0';
buf_write <= regs_b.tsbcr_enable_o and fifo_read_d0;
buf_write <= regs_i.tsbcr_enable_o and fifo_read_d0;
buf_ram_out <= f_unpack_timestamp(buf_rd_data);
buf_irq_o <= not buf_empty;
-- drive WB registers
regs_b.tsbcr_empty_i <= buf_empty;
regs_b.tsbcr_full_i <= buf_full;
regs_o.tsbcr_empty_i <= buf_empty;
regs_o.tsbcr_full_i <= buf_full;
p_buffer_control : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_sys_i = '0' or regs_b.tsbcr_purge_o = '1' then
if rst_n_sys_i = '0' or regs_i.tsbcr_purge_o = '1' then
buf_rd_ptr <= (others => '0');
buf_wr_ptr <= (others => '0');
buf_write <= '0';
fifo_read_d0 <= '0';
else
fifo_read_d0 <= fifo_read;
update_regs <= advance_rbuf_i and not (buf_write and buf_full);
--update_regs <= advance_rbuf_i and not (buf_write and buf_full);
if(buf_write = '1') then
buf_wr_ptr <= buf_wr_ptr + 1;
......@@ -183,16 +183,17 @@ begin -- behavioral
buf_rd_ptr <= buf_rd_ptr + 1;
end if;
if(update_regs = '1') then
regs_b.tsbr_u_i <= buf_ram_out.utc;
regs_b.tsbr_c_i <= buf_ram_out.coarse;
regs_b.tsbr_fid_fine_i <= buf_ram_out.frac;
regs_b.tsbr_fid_seqid_i <= buf_ram_out.seq_id;
end if;
----if(update_regs = '1') then
----end if;
end if;
end if;
end process;
regs_o.tsbr_u_i <= buf_ram_out.utc;
regs_o.tsbr_c_i <= buf_ram_out.coarse;
regs_o.tsbr_fid_fine_i <= buf_ram_out.frac;
regs_o.tsbr_fid_seqid_i <= buf_ram_out.seq_id;
end behavioral;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.fd_wbgen2_pkg.all;
use work.gencores_pkg.all;
entity fd_spi_master is
port (
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
-- chip select for VCTCXO DAC
spi_cs_dac_n_o : out std_logic;
-- chip select for AD9516 PLL
spi_cs_pll_n_o : out std_logic;
-- chip select for MCP23S17 GPIO
spi_cs_gpio_n_o : out std_logic;
-- these are obvious
spi_sclk_o : out std_logic;
spi_mosi_o : out std_logic;
spi_miso_i : in std_logic;
regs_i : in t_fd_out_registers;
regs_o : out t_fd_in_registers
);
end fd_spi_master;
architecture behavioral of fd_spi_master is
signal busy : std_logic;
signal divider : unsigned(11 downto 0);
signal dataSh : std_logic_vector(23 downto 0);
signal bitCounter : std_logic_vector(25 downto 0);
signal endSendingData : std_logic;
signal sendingData : std_logic;
signal iDacClk : std_logic;
signal iValidValue : std_logic;
signal divider_muxed : std_logic;
signal cs_sel_dac : std_logic;
signal cs_sel_gpio : std_logic;
signal cs_sel_pll : std_logic;
signal data_in_reg : std_logic_vector(23 downto 0);
signal data_out_reg : std_logic_vector(23 downto 0);
begin -- rtl
divider_muxed <= divider(1); -- sclk = clk_i/64
iValidValue <= regs_i.scr_start_o;
process(clk_sys_i, rst_n_i)
begin
if rising_edge(clk_sys_i) then
if (rst_n_i = '0') then
data_in_reg <= (others => '0');
elsif(regs_i.scr_data_load_o = '1') then
data_in_reg <= regs_i.scr_data_o;
end if;
end if;
end process;
process(clk_sys_i, rst_n_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
sendingData <= '0';
else
if iValidValue = '1' and sendingData = '0' then
sendingData <= '1';
elsif endSendingData = '1' then
sendingData <= '0';
end if;
end if;
end if;
end process;
process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if iValidValue = '1' then
divider <= (others => '0');
elsif sendingData = '1' then
if(divider_muxed = '1') then
divider <= (others => '0');
else
divider <= divider + 1;
end if;
elsif endSendingData = '1' then
divider <= (others => '0');
end if;
end if;
end process;
process(clk_sys_i, rst_n_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
iDacClk <= '1'; -- 0
else
if iValidValue = '1' then
iDacClk <= '1'; -- 0
elsif divider_muxed = '1' then
iDacClk <= not(iDacClk);
elsif endSendingData = '1' then
iDacClk <= '1'; -- 0
end if;
end if;
end if;
end process;
process(clk_sys_i, rst_n_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
dataSh <= (others => '0');
else
if iValidValue = '1' and sendingData = '0' then
cs_sel_dac <= regs_i.scr_sel_dac_o;
cs_sel_gpio <= regs_i.scr_sel_gpio_o;
cs_sel_pll <= regs_i.scr_sel_pll_o;
dataSh <= data_in_reg;
elsif sendingData = '1' and divider_muxed = '1' and iDacClk = '0' then
dataSh(0) <= spi_miso_i; --dataSh(dataSh'left);
dataSh(dataSh'left downto 1) <= dataSh(dataSh'left - 1 downto 0);
end if;
end if;
end if;
end process;
process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if iValidValue = '1' and sendingData = '0' then
bitCounter(0) <= '1';
bitCounter(bitCounter'left downto 1) <= (others => '0');
elsif sendingData = '1' and to_integer(divider) = 0 and iDacClk = '1' then
bitCounter(0) <= '0';
bitCounter(bitCounter'left downto 1) <= bitCounter(bitCounter'left - 1 downto 0);
end if;
end if;
end process;
endSendingData <= bitCounter(bitCounter'left);
regs_o.scr_ready_i <= not SendingData;
regs_o.scr_data_i <= dataSh;
spi_mosi_o <= dataSh(dataSh'left);
spi_cs_pll_n_o <= not(sendingData) or (not cs_sel_pll);
spi_cs_dac_n_o <= not(sendingData) or (not cs_sel_dac);
spi_cs_gpio_n_o <= not(sendingData) or (not cs_sel_gpio);
p_drive_sclk : process(iDacClk, regs_i)
begin
if(regs_i.scr_cpol_o = '0') then
spi_sclk_o <= (iDacClk);
else
spi_sclk_o <= not (iDacClk);
end if;
end process;
end behavioral;
......@@ -13,7 +13,8 @@ entity fd_timestamper_stat_unit is
trig_pulse_i : in std_logic;
raw_tag_valid_i : in std_logic;
regs_b : inout t_fd_registers);
regs_i : in t_fd_out_registers;
regs_o : out t_fd_in_registers);
end fd_timestamper_stat_unit;
......@@ -31,14 +32,15 @@ architecture behavioral of fd_timestamper_stat_unit is
begin -- behavioral
p_count_events : process(clk_ref_i)
begin
if rising_edge(clk_ref_i) then
if (rst_n_i = '0' or regs_b.gcr_input_en_o = '0' or regs_b.iepd_rst_stat_o = '1') then
if (rst_n_i = '0' or regs_i.gcr_input_en_o = '0' or regs_i.iepd_rst_stat_o = '1') then
event_count_raw <= (others => '0');
event_count_tagged <= (others => '0');
else
if(trig_pulse_i= '1') then
if(trig_pulse_i = '1') then
event_count_raw <= event_count_raw + 1;
end if;
......@@ -49,13 +51,13 @@ begin -- behavioral
end if;
end process;
regs_b.iecraw_i <= std_logic_vector(event_count_raw);
regs_b.iectag_i <= std_logic_vector(event_count_tagged);
regs_o.iecraw_i <= std_logic_vector(event_count_raw);
regs_o.iectag_i <= std_logic_vector(event_count_tagged);
p_measure_processing_delay : process(clk_ref_i)
begin
if rising_edge(clk_ref_i) then
if rst_n_i = '0' or regs_b.gcr_input_en_o = '0' or regs_b.iepd_rst_stat_o = '1' then
if rst_n_i = '0' or regs_i.gcr_input_en_o = '0' or regs_i.iepd_rst_stat_o = '1' then
cur_pdelay <= (others => '0');
worst_pdelay <= (others => '0');
pd_state <= PD_WAIT_TRIGGER;
......@@ -88,6 +90,6 @@ begin -- behavioral
end if;
end process;
regs_b.iepd_pdelay_i <= std_logic_vector(worst_pdelay);
regs_o.iepd_pdelay_i <= std_logic_vector(worst_pdelay);
end behavioral;
......@@ -6,13 +6,15 @@
-- Author : Tomasz Wlostowski
-- Company : CERN
-- Created : 2011-08-29
-- Last update: 2011-08-29
-- Last update: 2011-09-05
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Pipelined timestamp adder with re-normalization of the result.
-- Adds a to b, producing normalized timestamp q. Input timestamps must obey
-- the following constraints:
-- Adds a to b, producing normalized timestamp q. A timestmap is normalized when
-- the 0 <= frac < 2**g_frac_bits, 0 <= coarse <= g_coarse_range-1 and utc >= 0.
-- For correct operation of renormalizer, input timestamps must meet the
-- following constraints:
-- 1. 0 <= (a/b)_frac_i <= 2**g_frac_bits-1
-- 2. -g_coarse_range+1 <= (a_coarse_i + b_coarse_i) <= 3*g_coarse_range-1
-------------------------------------------------------------------------------
......@@ -48,7 +50,7 @@ use ieee.numeric_std.all;
entity fd_ts_adder is
generic
(
-- sizes of the respective bitfields
-- sizes of the respective bitfields of the input/output timestamps
g_frac_bits : integer := 12;
g_coarse_bits : integer := 28;
g_utc_bits : integer := 32;
......@@ -63,6 +65,8 @@ entity fd_ts_adder is
valid_i : in std_logic; -- when HI, a_* and b_* contain valid timestamps
-- Input timestamps
a_utc_i : in std_logic_vector(g_utc_bits-1 downto 0);
a_coarse_i : in std_logic_vector(g_coarse_bits-1 downto 0);
a_frac_i : in std_logic_vector(g_frac_bits-1 downto 0);
......@@ -71,6 +75,7 @@ entity fd_ts_adder is
b_coarse_i : in std_logic_vector(g_coarse_bits-1 downto 0);
b_frac_i : in std_logic_vector(g_frac_bits-1 downto 0);
-- Normalized sum output (valid when valid_o == 1)
valid_o : out std_logic;
q_utc_o : out std_logic_vector(g_utc_bits-1 downto 0);
q_coarse_o : out std_logic_vector(g_coarse_bits-1 downto 0);
......@@ -99,7 +104,7 @@ architecture rtl of fd_ts_adder is
begin -- rtl
-- Pipeline stage 0: just add the two timestamps
-- Pipeline stage 0: just add the two timestamps field by field
p_stage0 : process(clk_i)
begin
if rising_edge(clk_i) then
......@@ -212,6 +217,7 @@ begin -- rtl
end if;
end process;
-- clip the extra bits and output the result
valid_o <= pipe(c_NUM_PIPELINE_STAGES-1);
q_utc_o <= std_logic_vector(sums(c_NUM_PIPELINE_STAGES-1).utc(g_utc_bits-1 downto 0));
q_coarse_o <= std_logic_vector(sums(c_NUM_PIPELINE_STAGES-1).coarse(g_coarse_bits-1 downto 0));
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -7,6 +7,6 @@ syn_device = "xc6slx45t"
syn_grade = "-3"
syn_package = "fgg484"
syn_top = "spec_top"
syn_project = "finedelay_spec_1_1.xise"
syn_project = "spec_fine_delay.xise"
modules = { "local" : [ "../../top/spec_1_1" ] }
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
files = [
"spec_top_finedelay.vhd",
"spec_top_finedelay.ucf",
"wb_gpio_port_notristates.vhd"
"spec_top.vhd",
"spec_top.ucf",
#"wb_gpio_port_notristates.vhd"
];
fetchto = "../../ip_cores"
......
This diff is collapsed.
This diff is collapsed.
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