Commit 5a33ed4b authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

merged HDL from private repo

parents 43328f0f e502cb54
*.*\#
\#*
.\#*
*.*~
hdl/ip_cores/*
modelsim.ini
vsim.wlf
work
*.bak
hdl/syn/spec_1_1/*
\ No newline at end of file
`timescale 1ps/1ps
// R-Mode only!
module acam_model
(
input PuResN,
input Alutrigger,
input RefClk,
input WRN,
input RDN,
input CSN,
input OEN,
input [3:0] Adr,
input DStart,
input DStop1,
input DStop2,
input TStart,
input[8:1] TStop,
input StartDis,
input[4:1] StopDis,
output IrFlag,
output ErrFlag,
output reg EF1,
output LF1,
inout[27:0] D
/* sim-only */
);
parameter real g_rmode_resolution = 80.9553ps / 3.0;
parameter int g_verbose = 1;
const real c_empty_flag_delay = 75ns;
wire start_masked;
wire stop1_masked;
wire r_MasterAluTrig;
wire r_StartDisStart;
reg[27:0] RB[0:14];
reg[27:0] DQ = 0;
reg EF1_int = 1'b1;
reg start_disabled_int;
int rmode_start_offset;
mailbox q_start, q_stop1;
mailbox q_hit;
int t = 0;
assign rmode_start_offset = RB[5][17:0];
always #(g_rmode_resolution) t <= t + 1;
assign r_MasterAluTrig = RB[5][23];
assign r_StartDisStart = RB[5][22];
task master_reset;
int i;
q_start = new(32);
q_stop1 = new(32);
q_hit = new(32);
EF1 <= 1;
start_disabled_int <= 0;
for(i=0;i<15;i++)
RB[i] = 0;
endtask // master_reset
initial master_reset();
always@(negedge PuResN) begin
master_reset();
end
always@(posedge Alutrigger) begin
if(r_MasterAluTrig)
begin
int dummy;
while(q_hit.num() > 0) q_hit.get(dummy);
start_disabled_int <= 0;
// EF1 <= 0;
end
// master_reset();
end
always@(negedge Alutrigger) begin
if(r_MasterAluTrig)
begin
// EF1 <= 1;
end
end
//
always@(posedge DStart)
if(PuResN && !StartDis && !start_disabled_int) begin
if(g_verbose)$display("acam::start %d", t);
q_start.put(t);
start_disabled_int <= r_StartDisStart;
end
always@(posedge DStop1)
if(PuResN && !StopDis[1]) begin
if(g_verbose)$display("acam::stop1 %d", t);
q_stop1.put(t);
end
always@(negedge WRN) if (!CSN && RDN)
begin
RB[Adr] <= D;
if(g_verbose)$display("acam::write reg %x val %x\n", Adr, D);
end
always@(negedge RDN) if (!CSN && WRN)
begin
if(g_verbose)$display("acam::read reg %x val %x\n", Adr, RB[Adr]);
if(Adr == 8) begin
int hit;
q_hit.try_get(hit);
DQ <= hit;
end else
DQ <= RB[Adr];
end
always@(negedge PuResN) begin
int i;
for (i=0;i<14;i++) RB[i] <= 0;
end
assign D = (!OEN)?DQ:28'bz;
initial forever
begin
int t_start, t_stop1, n_starts, tmp, hit;
#1;
q_stop1.get(t_stop1);
while(q_start.num() > 0) begin
q_start.peek(t_start);
if(t_start < t_stop1)
begin
q_start.get(tmp);
end
else
break;
end
if(t_stop1 - t_start > 3780)
hit = (t_stop1 - t_start) - (128ns/g_rmode_resolution) + rmode_start_offset * 3;
else
hit = t_stop1 - t_start + rmode_start_offset * 3;
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);
end
q_hit.put(hit);
end
reg fifo_empty =1;
reg fifo_notempty = 0;
initial forever begin
#1;
if(q_hit.num() > 0)
EF1 = #(12ns) 0;
else
EF1 = 1;
end
endmodule // acam_model
`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_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 8'h10
`define FD_TDCSR_WRITE_OFFSET 0
`define FD_TDCSR_WRITE 32'h00000001
`define FD_TDCSR_READ_OFFSET 1
`define FD_TDCSR_READ 32'h00000002
`define FD_TDCSR_ERR_OFFSET 2
`define FD_TDCSR_ERR 32'h00000004
`define FD_TDCSR_INT_OFFSET 3
`define FD_TDCSR_INT 32'h00000008
`define FD_TDCSR_LOAD_OFFSET 4
`define FD_TDCSR_LOAD 32'h00000010
`define FD_TDCSR_EMPTY_OFFSET 5
`define FD_TDCSR_EMPTY 32'h00000020
`define FD_TDCSR_START_DIS_OFFSET 6
`define FD_TDCSR_START_DIS 32'h00000040
`define FD_TDCSR_START_EN_OFFSET 7
`define FD_TDCSR_START_EN 32'h00000080
`define FD_TDCSR_STOP_DIS_OFFSET 8
`define FD_TDCSR_STOP_DIS 32'h00000100
`define FD_TDCSR_STOP_EN_OFFSET 9
`define FD_TDCSR_STOP_EN 32'h00000200
`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,
input rst_n_i,
input enable_i,
input trig_a_i,
input [31:0] csync_utc_i,
input [27:0] csync_coarse_i,
input csync_p1_i
);
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 [12:0] cntr_frac;
reg tag_valid_p1;
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 = '{};
end
always@(posedge clk_ref_i)
cntr_frac <= 0;
always@(posedge clk_ref_i)
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;
end
initial forever #(c_frac_step) cntr_frac <= cntr_frac + 1;
always@(posedge trig_a_i) begin
if(enable_i)
begin
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;
else if(ts_queue.size() > 0)
begin
timestamp_t ts;
ts = ts_queue.pop_front();
tag_frac_o <= ts.frac;
tag_utc_o <= ts.utc;
tag_coarse_o <= ts.coarse;
tag_valid_p1 <= 1'b1;
end
assign tag_valid_p1_o = tag_valid_p1;
assign cntr_coarse_o = cntr_coarse;
assign cntr_utc_o = cntr_utc;
-----/\----- EXCLUDED -----/\----- */
endmodule // ideal_timestamper
//
// Title : Software Wishbone master unit for testbenches
//
// File : if_wishbone.sv
// Author : Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
// Created : Tue Mar 23 12:19:36 2010
// Standard : SystemVerilog
//
// Default values of certain WB parameters.
`include "simdrv_defs.sv"
interface IWishbone
(
input clk_i,
input rst_n_i
);
parameter g_data_width = 32;
parameter g_addr_width = 32;
/* Interface signals */
logic [g_addr_width - 1 : 0] adr;
logic [g_data_width - 1 : 0] dat_o;
logic [3 : 0] sel; // FIXME: 32-bit only
wire [g_data_width - 1 : 0] dat_i;
wire ack;
logic cyc;
logic stb;
logic we;
wire stall;
initial begin
adr = 0;
dat_o = 0;
sel = 0;
cyc = 0;
stb = 0;
we = 0;
end
time last_access_t = 0;
reg [g_data_width-1:0] dummy;
// enables/disables displaying information about each read/write operation.
int tb_verbose = 0;
task verbose(int onoff);
tb_verbose = onoff;
endtask // wb_verbose
task classic_single_rw_generic;
input [g_addr_width - 1 : 0] trans_addr;
input [g_data_width - 1 : 0] trans_wdata;
output [g_data_width - 1 : 0] trans_rdata;
input rw;
input [3:0] size;
begin : rw_generic_main
if(tb_verbose && rw)
$display("WB write %s: addr %x, data %x",
(size==1?"byte":((size==2)?"short":"int")),
trans_addr, trans_wdata);
if($time != last_access_t) begin
@(posedge clk_i);
end
stb<=1;
cyc<=1;
adr <= {2'b00, trans_addr[31:2]};
we <= rw;
if(rw) begin
case(size)
4: begin dat_o<=trans_wdata; sel <= 4'b1111; end
2: begin
if(adr[1]) begin
dat_o[31:16] <= trans_wdata[15:0];
sel <= 4'b1100;
end else begin
dat_o[15:0] <= trans_wdata[15:0];
sel <= 4'b0011;
end
end
1: begin
case(adr[1:0])
0: begin dat_o[31:24] <= trans_wdata[7:0]; sel <= 4'b1000; end
1: begin dat_o[23:16] <= trans_wdata[7:0]; sel <= 4'b0100; end
2: begin dat_o[15:8] <= trans_wdata[7:0]; sel <= 4'b0010; end
3: begin dat_o[7:0] <= trans_wdata[7:0]; sel <= 4'b0001; end
endcase // case(addr[1:0])
end
endcase // case(size)
end // if (rw)
@(posedge clk_i);
if(ack == 0) begin
while(ack == 0) begin @(posedge clk_i); end
end
trans_rdata = dat_i;
cyc <= 0;
we<=0;
stb<=0;
if(tb_verbose && !rw)
$display("WB read %s: addr %x, data %x",
(size==1?"byte":((size==2)?"short":"int")),
trans_addr, trans_rdata);
last_access_t = $time;
end
endtask // rw_generic
task write32;
input [g_addr_width - 1 : 0] addr;
input [31 : 0] data_i;
begin
classic_single_rw_generic(addr, data_i, dummy, 1, 4);
end
endtask // write32
task read32;
input [g_addr_width - 1 : 0] addr;
output [31 : 0] data_o;
begin : read32_body
reg [g_data_width - 1 : 0] rval;
classic_single_rw_generic(addr, 0, rval, 0, 4);
data_o = rval[31:0];
end
endtask // write32
modport master
(
output adr,
output dat_o,
output sel,
output cyc,
output stb,
output we,
input ack,
input dat_i,
input stall);
endinterface // IWishbone
module jittery_delay
(
input in_i,
output reg out_o
);
parameter g_delay = 10ns;
parameter g_jitter = 10ps;
int seed = 1;
always@(in_i)
begin
real delta;
seed = $urandom(seed);
delta = $dist_normal(seed, g_delay, g_jitter);
out_o <= #(delta) in_i;
end
endmodule // jittery_delay
\ No newline at end of file
`timescale 1ps/1ps
module mc100ep195
(
input len,
input i,
input [9:0] delay,
output o
);
const int c_min_delay = 2ns;
const int c_time_per_tap = 10ps;
reg [9:0] cur_dly = 0;
reg o_reg = 0;
assign o = o_reg;
always@(len)
if(!len)
cur_dly <= delay;
always@(i)
o_reg <= #(c_min_delay + cur_dly * c_time_per_tap) i;
endmodule // mc100ep195
module random_pulse_gen
(
input enable_i,
output reg pulse_o
);
parameter real g_pulse_width = 30ns;
parameter real g_min_spacing = 300ns;
parameter real g_max_spacing = 600ns;
int seed = 1;
initial forever
if(enable_i)
begin
real delta;
seed = $urandom(seed);
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;
#(delta);
end else begin
pulse_o <= 1'b0;
#1;
end
endmodule // random_pulse_gen
`ifndef SIMDRV_DEFS_SV
`define SIMDRV_DEFS_SV 1
virtual class CBusAccessor;
pure virtual task write32(int addr, bit[31:0] data);
pure virtual task read32(int addr, output bit[31:0] rdata);
endclass // CBusAccessor
`endif
\ No newline at end of file
`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
`timescale 10fs/10fs
module tunable_clock_gen
(
input real vtune_i,
input enable_i,
output clk_o);
parameter g_tunable = 0;
parameter g_tuning_range = 20e-6; // 20 ppm
parameter g_tuning_voltage = 1.0;
parameter real g_period = 8ns;
parameter real g_jitter = 10ps;
reg clk = 1'b1;
real cur_offset = 0;
real prev_err = 0;
real next_offset;
real cur_err;
real cur_period;
int seed = 1;
real max_range;
initial begin
cur_offset = 0;
prev_err = 0;
end
initial forever
if(enable_i)
begin
seed = $urandom(seed);
cur_err = (real'($urandom_range(0, 1000)) -500.0)/ 1000.0 * g_jitter;
// $display("%.15f %.15f", cur_err, g_jitter);
if(g_tunable)
begin
realtime period_tune;
period_tune = realtime'(real'(g_period/2) * (vtune_i-(real'(g_tuning_voltage/2)))/(real'(g_tuning_voltage/2)) * real'(g_tuning_range));
cur_period = g_period/2 + period_tune ;
end else
cur_period = g_period/2;
next_offset = -prev_err + cur_period + cur_err;
prev_err = cur_err;
// $display("NextOffs: %.15f", next_offset);
#(integer'(next_offset)) clk = ~clk;
end else begin // if (enable)
cur_offset = 0;
cur_period = 0;
clk = 1;
#1;
end // else: !if(enable)
assign clk_o = clk;
endmodule // tunable_clock_gen
\ No newline at end of file
files = ["fd_acam_timestamper.vhd",
"fd_wbgen2_pkg.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_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" ]
};
#!/bin/bash
~/wbgen2/wishbone-gen/wbgen2 -V fine_delay_wb.vhd -H record -p fd_registers_pkg.vhd -K ../sim/fine_delay_regs.v -s defines -C fd_core.h -D 1.html fine_delay_wb.wb
\ No newline at end of file
-------------------------------------------------------------------------------
-- 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 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 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);
-- 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_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
if rst_n_i = '0' then
tag_valid_o <= '0';
tag_coarse_o <= (others => '0');
tag_utc_o <= (others => '0');
tag_frac_o <= (others => '0');
else
-- pipeline stage 1:
-- - subtract the start offset from the fractional value got from the ACAM,
pp_pipe(0) <= raw_valid_i;
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.
-- 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_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
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
-- the rest to the coarse part, along with the start-to-timescale offset
pp_pipe(3) <= pp_pipe(2);
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(post_frac_multiplied(post_frac_multiplied'left downto c_SCALER_SHIFT + g_frac_bits)));
-- extra coarse counts from ACAM's frac part after rescaling
tag_frac_o <= std_logic_vector(post_frac_multiplied(c_SCALER_SHIFT + g_frac_bits-1 downto c_SCALER_SHIFT));
tag_valid_o <= pp_pipe(3);
end if;
end if;
end process;
end behavioral;
This diff is collapsed.
-------------------------------------------------------------------------------
-- 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;
use work.fd_wbgen2_pkg.all;
entity fd_csync_generator is
generic (
-- 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);
-- 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);
-- 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;
component fd_ts_adder
generic (
g_frac_bits : integer;
g_coarse_bits : integer;
g_utc_bits : integer;
g_coarse_range : integer);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
valid_i : in std_logic;
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);
b_utc_i : in std_logic_vector(g_utc_bits-1 downto 0);
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);
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);
q_frac_o : out std_logic_vector(g_frac_bits-1 downto 0));
end component;
signal coarse : unsigned(27 downto 0);
signal utc : unsigned(31 downto 0);
signal coarse_adjusted : unsigned(27 downto 0);
signal utc_adjusted : unsigned(31 downto 0);
signal csync_int : std_logic;
begin -- behavioral
U_Timescale_Adjust : fd_ts_adder
generic map (
g_frac_bits => 2,
g_coarse_bits => 28,
g_utc_bits => 32,
g_coarse_range => g_coarse_range)
port map (
clk_i => clk_ref_i,
rst_n_i => rst_n_i,
valid_i => csync_int,
a_utc_i => std_logic_vector(utc),
a_coarse_i => std_logic_vector(coarse),
a_frac_i => (others => '0'),
b_utc_i => (others => '0'),
b_coarse_i => std_logic_vector(to_signed(c_ADDER_PIPELINE_DELAY+1, coarse'length)),
b_frac_i => (others => '0'),
valid_o => csync_p1_o,
q_utc_o => csync_utc_o,
q_coarse_o => csync_coarse_o,
q_frac_o => open);
regs_o.gcr_wr_ready_i <= wr_time_valid_i;
process(clk_ref_i)
begin
if rising_edge(clk_ref_i) then
if rst_n_i = '0' then
coarse <= (others => '0');
utc <= (others => '0');
else
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_i.gcr_csync_int_o;
elsif(coarse = g_coarse_range-1) then
coarse <= (others => '0');
utc <= utc + 1;
csync_int <= regs_i.gcr_csync_int_o;
else
coarse <= coarse + 1;
csync_int <= regs_i.gcr_csync_int_o;
end if;
end if;
end if;
end process;
end behavioral;
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;
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;
library ieee;
use ieee.std_logic_1164.all;
use work.fd_wbgen2_pkg.all;
entity fd_reset_generator is
port (
clk_sys_i : in std_logic;
clk_ref_i : in std_logic;
rst_n_i : in std_logic;
rst_n_sys_o : out std_logic;
rst_n_ref_o : out std_logic;
regs_i : in t_fd_out_registers);
end fd_reset_generator;
architecture behavioral of fd_reset_generator is
constant c_RSTR_TRIGGER_VALUE : std_logic_vector(31 downto 0) := x"deadbeef";
signal rstn_host_sysclk : std_logic;
signal rstn_host_refclk : std_logic;
signal rstn_host_d0 : std_logic;
signal rstn_host_d1 : std_logic;
begin -- behavioral
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_i.rstr_wr_o = '1' and regs_i.rstr_o = c_RSTR_TRIGGER_VALUE) then
rstn_host_sysclk <= '0';
else
rstn_host_sysclk <= '1';
end if;
end if;
end if;
end process;
p_sync_reset_refclk : process(clk_ref_i)
begin
if rising_edge(clk_ref_i) then
rstn_host_refclk <= rst_n_i and rstn_host_sysclk;
rstn_host_d0 <= rstn_host_sysclk;
rstn_host_d1 <= rstn_host_d0;
rstn_host_refclk <= rstn_host_d1;
end if;
end process;
rst_n_ref_o <= rstn_host_sysclk;
rst_n_sys_o <= rstn_host_refclk;
end behavioral;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.genram_pkg.all;
use work.fd_wbgen2_pkg.all;
entity fd_ring_buffer is
generic (
g_size_log2 : integer := 8;
g_frac_bits : integer := 12);
port (
rst_n_sys_i : in std_logic;
rst_n_ref_i : in std_logic;
clk_ref_i : in std_logic;
clk_sys_i : in std_logic;
tag_valid_i : in std_logic;
tag_utc_i : in std_logic_vector(31 downto 0);
tag_coarse_i : in std_logic_vector(27 downto 0);
tag_frac_i : in std_logic_vector(g_frac_bits-1 downto 0);
advance_rbuf_i : in std_logic;
buf_irq_o : out std_logic;
regs_i : in t_fd_out_registers;
regs_o : out t_fd_in_registers
);
end fd_ring_buffer;
architecture behavioral of fd_ring_buffer is
constant c_PACKED_TS_SIZE : integer := 32 + 28 + g_frac_bits + 16;
constant c_FIFO_SIZE : integer := 64;
type t_internal_timestamp is record
utc : std_logic_vector(31 downto 0);
coarse : std_logic_vector(27 downto 0);
frac : std_logic_vector(g_frac_bits-1 downto 0);
seq_id : std_logic_vector(15 downto 0);
end record;
function f_pack_timestamp(ts : t_internal_timestamp) return std_logic_vector is
variable tmp : std_logic_vector(c_PACKED_TS_SIZE-1 downto 0);
begin
tmp(31 downto 0) := ts.utc;
tmp(32 + 27 downto 32) := ts.coarse;
tmp(32 + 28 + g_frac_bits-1 downto 32 + 28) := ts.frac;
tmp(32 + 28 + g_frac_bits + 16-1 downto 32 + 28 + g_frac_bits) := ts.seq_id;
return tmp;
end f_pack_timestamp;
function f_unpack_timestamp(ts : std_logic_vector)return t_internal_timestamp is
variable tmp : t_internal_timestamp;
begin
tmp.utc := ts(31 downto 0);
tmp.coarse := ts(32 + 27 downto 32);
tmp.frac := ts(32+ 28 + g_frac_bits-1 downto 32+28);
tmp.seq_id := ts(32 + 28 + g_frac_bits + 16 -1 downto 32 + 28 + g_frac_bits);
return tmp;
end f_unpack_timestamp;
signal fifo_in, fifo_out : std_logic_vector(c_PACKED_TS_SIZE-1 downto 0);
signal fifo_write, fifo_read : std_logic;
signal fifo_empty, fifo_full : std_logic;
signal ts_fifo_in : t_internal_timestamp;
signal cur_seq_id : unsigned(15 downto 0);
signal buf_wr_ptr : unsigned(g_size_log2-1 downto 0);
signal buf_rd_ptr : unsigned(g_size_log2-1 downto 0);
signal buf_full : std_logic;
signal buf_empty : std_logic;
signal buf_wr_data : std_logic_vector(c_PACKED_TS_SIZE-1 downto 0);
signal buf_rd_data : std_logic_vector(c_PACKED_TS_SIZE-1 downto 0);
signal buf_write : std_logic;
signal buf_ram_out : t_internal_timestamp;
signal fifo_read_d0 : std_logic;
signal update_regs : std_logic;
begin -- behavioral
p_count_seq_id : process(clk_ref_i)
begin
if rising_edge(clk_ref_i) 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;
end if;
end if;
end process;
fifo_in <= f_pack_timestamp(ts_fifo_in);
ts_fifo_in.utc <= tag_utc_i;
ts_fifo_in.coarse <= tag_coarse_i;
ts_fifo_in.frac <= tag_frac_i;
ts_fifo_in.seq_id <= std_logic_vector(cur_seq_id);
fifo_write <= not fifo_full and tag_valid_i;
U_Clock_Adjustment_Fifo : generic_async_fifo
generic map (
g_data_width => fifo_in'length,
g_size => c_FIFO_SIZE)
port map (
rst_n_i => rst_n_sys_i,
clk_wr_i => clk_ref_i,
d_i => fifo_in,
we_i => fifo_write,
wr_full_o => fifo_full,
clk_rd_i => clk_sys_i,
q_o => fifo_out,
rd_i => fifo_read,
rd_empty_o => fifo_empty);
buf_wr_data <= fifo_out;
U_Buffer_RAM : generic_dpram
generic map (
g_data_width => c_PACKED_TS_SIZE,
g_size => 2**g_size_log2,
g_dual_clock => false)
port map (
rst_n_i => rst_n_sys_i,
clka_i => clk_ref_i,
bwea_i => (others => '1'),
wea_i => buf_write,
aa_i => std_logic_vector(buf_wr_ptr),
da_i => buf_wr_data,
qa_o => open,
clkb_i => clk_sys_i,
bweb_i => (others => '0'),
web_i => '0',
ab_i => std_logic_vector(buf_rd_ptr),
db_i => (others => '0'),
qb_o => buf_rd_data);
fifo_read <= not fifo_empty;
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_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_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_i.tsbcr_purge_o = '1' then
buf_rd_ptr <= (others => '0');
buf_wr_ptr <= (others => '0');
fifo_read_d0 <= '0';
else
fifo_read_d0 <= fifo_read;
--update_regs <= advance_rbuf_i and not (buf_write and buf_full);
if(buf_write = '1') then
buf_wr_ptr <= buf_wr_ptr + 1;
end if;
if((advance_rbuf_i = '1' or (buf_write = '1' and buf_full = '1')) and buf_empty = '0') then
buf_rd_ptr <= buf_rd_ptr + 1;
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;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.fd_wbgen2_pkg.all;
entity fd_timestamper_stat_unit is
port(
clk_ref_i : in std_logic;
rst_n_i : in std_logic;
trig_pulse_i : in std_logic;
raw_tag_valid_i : in std_logic;
regs_i : in t_fd_out_registers;
regs_o : out t_fd_in_registers);
end fd_timestamper_stat_unit;
architecture behavioral of fd_timestamper_stat_unit is
type t_pdelay_meas_state is (PD_WAIT_TRIGGER, PD_WAIT_TAG, PD_UPDATE_STATS);
-- stat counters signals
signal event_count_raw : unsigned(31 downto 0);
signal event_count_tagged : unsigned(31 downto 0);
signal pd_state : t_pdelay_meas_state;
signal cur_pdelay : unsigned(7 downto 0);
signal worst_pdelay : unsigned(7 downto 0);
begin -- behavioral
p_count_events : process(clk_ref_i)
begin
if rising_edge(clk_ref_i) 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
event_count_raw <= event_count_raw + 1;
end if;
if(raw_tag_valid_i = '1') then
event_count_tagged <= event_count_tagged + 1;
end if;
end if;
end if;
end process;
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_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;
else
case pd_state is
when PD_WAIT_TRIGGER =>
if(trig_pulse_i = '1') then
cur_pdelay <= (others => '0');
pd_state <= PD_WAIT_TAG;
end if;
when PD_WAIT_TAG =>
if(trig_pulse_i = '1') then
pd_state <= PD_WAIT_TRIGGER;
elsif(raw_tag_valid_i = '1') then
pd_state <= PD_UPDATE_STATS;
else
cur_pdelay <= cur_pdelay + 1;
end if;
when PD_UPDATE_STATS =>
if(cur_pdelay > worst_pdelay) then
worst_pdelay <= cur_pdelay;
end if;
pd_state <= PD_WAIT_TRIGGER;
when others => null;
end case;
end if;
end if;
end process;
regs_o.iepd_pdelay_i <= std_logic_vector(worst_pdelay);
end behavioral;
-------------------------------------------------------------------------------
-- Title : Pipelined timestamp adder with normalization
-- Project : Fine Delay Core (FmcDelay1ns4cha)
-------------------------------------------------------------------------------
-- File : fd_ts_adder.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN
-- Created : 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. 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
-------------------------------------------------------------------------------
--
-- 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;
entity fd_ts_adder is
generic
(
-- 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;
-- upper bound of the coarse part
g_coarse_range : integer := 125000000
);
port(
clk_i : in std_logic;
rst_n_i : in std_logic;
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);
b_utc_i : in std_logic_vector(g_utc_bits-1 downto 0);
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);
q_frac_o : out std_logic_vector(g_frac_bits-1 downto 0)
);
end fd_ts_adder;
architecture rtl of fd_ts_adder is
constant c_NUM_PIPELINE_STAGES : integer := 4;
type t_internal_sum is record
utc : signed(g_utc_bits-1 downto 0);
coarse : signed(g_coarse_bits+1 downto 0);
frac : signed(g_frac_bits+1 downto 0);
end record;
type t_internal_sum_array is array (integer range <>) of t_internal_sum;
signal pipe : std_logic_vector(c_NUM_PIPELINE_STAGES-1 downto 0);
signal sums : t_internal_sum_array(0 to c_NUM_PIPELINE_STAGES-1);
signal ovf_frac : std_logic;
signal ovf_coarse : std_logic_vector(1 downto 0);
signal unf_coarse : std_logic;
begin -- rtl
-- Pipeline stage 0: just add the two timestamps field by field
p_stage0 : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
pipe(0) <= '0';
sums(0).utc <= (others => '0');
sums(0).coarse <= (others => '0');
sums(0).frac <= (others => '0');
else
pipe(0) <= valid_i;
sums(0).frac <= signed("00" & a_frac_i) + signed("00" & b_frac_i);
sums(0).coarse <= resize(signed(a_coarse_i), sums(0).coarse'length) +
resize(signed(b_coarse_i), sums(0).coarse'length);
sums(0).utc <= signed(a_utc_i) + signed(b_utc_i);
end if;
end if;
end process;
ovf_frac <= std_logic(sums(0).frac(g_frac_bits));
-- Pipeline stage 1: check the fractional sum for overflow and eventually adjust
-- the coarse sum
p_stage1 : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
pipe(1) <= '0';
sums(1).utc <= (others => '0');
sums(1).coarse <= (others => '0');
sums(1).frac <= (others => '0');
else
pipe(1) <= pipe(0);
if(ovf_frac = '1') then
sums(1).frac <= sums(0).frac - 2**g_frac_bits;
sums(1).coarse <= sums(0).coarse + 1;
else
sums(1).frac <= sums(0).frac;
sums(1).coarse <= sums(0).coarse;
end if;
sums(1).utc <= sums(0).utc;
end if;
end if;
end process;
-- Pipeline stage 2: check the coarse sum for under/overflows
p_stage2 : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
pipe(2) <= '0';
ovf_coarse <= (others => '0');
unf_coarse <= '0';
else
sums(2) <= sums(1);
pipe(2) <= pipe(1);
if(sums(1).coarse < 0) then
unf_coarse <= '1';
ovf_coarse <= "00";
elsif(sums(1).coarse >= 2 * g_coarse_range) then
ovf_coarse <= "10";
unf_coarse <= '0';
elsif(sums(1).coarse >= g_coarse_range) then
ovf_coarse <= "01";
unf_coarse <= '0';
else
ovf_coarse <= "00";
unf_coarse <= '0';
end if;
end if;
end if;
end process;
-- Pipeline stage 3: adjust the coarse & UTC sums according to normalize the
-- previously detected under/overflows
p_stage3 : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
pipe(3) <= '0';
else
pipe(3) <= pipe(2);
if(unf_coarse = '1') then
sums(3).coarse <= sums(2).coarse + g_coarse_range;
sums(3).utc <= sums(2).utc - 1;
elsif(ovf_coarse = "10") then
sums(3).coarse <= sums(2).coarse - (2*g_coarse_range);
sums(3).utc <= sums(2).utc + 2;
elsif(ovf_coarse = "01") then
sums(3).coarse <= sums(2).coarse - g_coarse_range;
sums(3).utc <= sums(2).utc + 1;
else
sums(3).coarse <= sums(2).coarse;
sums(3).utc <= sums(2).utc;
end if;
sums(3).frac <= sums(2).frac;
end if;
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));
q_frac_o <= std_logic_vector(sums(c_NUM_PIPELINE_STAGES-1).frac(g_frac_bits-1 downto 0));
end rtl;
library ieee;
use ieee.std_logic_1164.all;
entity fd_ts_normalizer is
generic
(
-- sizes of the respective bitfields
g_frac_bits : integer := 12;
g_coarse_bits : integer := 28;
g_utc_bits : integer := 32;
-- upper bound of the coarse part
g_coarse_range : integer := 125000000
);
port(
clk_i : in std_logic;
rst_n_i : in std_logic;
valid_i : in std_logic;
utc_i : in std_logic_vector(g_utc_bits-1 downto 0);
coarse_i : in std_logic_vector(g_coarse_bits-1 downto 0);
frac_i : in std_logic_vector(g_frac_bits-1 downto 0);
valid_o : out std_logic;
utc_o : out std_logic_vector(g_utc_bits-1 downto 0);
coarse_o : out std_logic_vector(g_coarse_bits-1 downto 0);
frac_o : out std_logic_vector(g_frac_bits-1 downto 0)
);
end fd_ts_normalizer;
architecture wrapper of fd_ts_normalizer is
component fd_ts_adder
generic (
g_frac_bits : integer;
g_coarse_bits : integer;
g_utc_bits : integer;
g_coarse_range : integer);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
valid_i : in std_logic;
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);
b_utc_i : in std_logic_vector(g_utc_bits-1 downto 0);
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);
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);
q_frac_o : out std_logic_vector(g_frac_bits-1 downto 0));
end component;
begin
U_TS_Adder: fd_ts_adder
generic map (
g_frac_bits => g_frac_bits,
g_coarse_bits => g_coarse_bits,
g_utc_bits => g_utc_bits,
g_coarse_range => g_coarse_range)
port map (
clk_i => clk_i,
rst_n_i => rst_n_i,
valid_i => valid_i,
a_utc_i => utc_i,
a_coarse_i => coarse_i,
a_frac_i => frac_i,
b_utc_i => (others => '0'),
b_coarse_i => (others => '0'),
b_frac_i => (others => '0'),
valid_o => valid_o,
q_utc_o => utc_o,
q_coarse_o => coarse_o,
q_frac_o => frac_o);
end wrapper;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package fine_delay_pkg is
constant c_fd_num_outputs : integer := 4;
constant c_fd_refclk_freq : integer := 125000000;
type t_fd_timestamp is record
secs : unsigned(31 downto 0);
cycles : unsigned(27 downto 0);
fine : unsigned(11 downto 0);
end record;
type t_fd_timestamp_array is array (0 to c_fd_num_outputs-1) of t_fd_timestamp;
end fine_delay_pkg;
This diff is collapsed.
target = "xilinx"
action = "synthesis"
fetchto = "../../ip_cores"
syn_device = "xc6slx45t"
syn_grade = "-3"
syn_package = "fgg484"
syn_top = "spec_top"
syn_project = "spec_fine_delay.xise"
modules = { "local" : [ "../../top/spec_1_1" ] }
This diff is collapsed.
This diff is collapsed.
action = "simulation"
vlog_opt="+incdir+../../include"
files = ["main.sv", "../../rtl/fd_ts_adder.vhd"];
#files = "../modules = {"local": [ "../../rtl" ] }
//#`include "simdrv_defs.svh"
`timescale 1ns/1ps
typedef longint unsigned uint64_t;
typedef struct {
bit[27:0] coarse;
bit[31:0] utc;
bit[11:0] frac;
} timestamp_t;
class Timestamp;
const int coarse_range = 125;
const int frac_range = 4096;
rand int coarse;
rand int utc;
rand int frac;
function new(timestamp_t ts);
coarse = ts.coarse;
utc = ts.utc;
frac = ts.frac;
endfunction // new
function timestamp_t get();
timestamp_t ts;
ts.coarse = coarse;
ts.frac = frac;
ts.utc = utc;
return ts;
endfunction // get
function automatic bit is_normalized();
if(frac < 0|| frac >=frac_range)
return 0;
if(coarse < 0|| coarse >= coarse_range)
return 0;
return 1;
endfunction // is_normalized
constraint c_frac
{
frac >= 0;
frac < frac_range;
};
constraint c_utc {
utc >= 0;
utc < 100000000;
};
function automatic uint64_t flatten();
return frac + coarse * frac_range + utc * frac_range * coarse_range;
endfunction // flatten
endclass // Timestamp
// a is always normalized
class ATimestamp extends Timestamp;
function new();
timestamp_t ts;
super.new(ts);
endfunction // new
constraint c_coarse
{
coarse >= 0;
coarse < coarse_range;
};
endclass // ATimestamp
// a is always normalized
class BTimestamp extends Timestamp;
function new();
timestamp_t ts;
super.new(ts);
endfunction // new
constraint c_coarse
{
coarse > -coarse_range;
coarse < coarse_range + 10;
};
endclass // BTimestamp
module main;
reg clk_sys = 0;
reg rst_n = 0;
always #4ns clk_sys <= ~clk_sys;
initial begin
repeat(3)@(posedge clk_sys);
rst_n <= 1;
end
reg valid_in = 0;
timestamp_t ta,tb,tq;
fd_ts_adder
#(
.g_frac_bits (12),
.g_coarse_bits (28),
.g_utc_bits (32),
.g_coarse_range (125)
) DUT (
.clk_i (clk_sys),
.rst_n_i (rst_n),
.valid_i (valid_in),
.a_utc_i (ta.utc),
.a_coarse_i (ta.coarse),
.a_frac_i (ta.frac),
.b_utc_i (tb.utc),
.b_coarse_i (tb.coarse),
.b_frac_i (tb.frac),
.valid_o (valid_out),
.q_utc_o (tq.utc),
.q_coarse_o (tq.coarse),
.q_frac_o (tq.frac)
);
const int num_tries = 10000000;
uint64_t expected[$];
always@(posedge clk_sys)
begin
if(valid_out)
begin
Timestamp tmp;
uint64_t sum;
sum = expected.pop_front();
tmp = new(tq);
if(tmp.flatten() != sum)
begin
$display("Failed: %d vs %d ", sum, tmp.flatten());
$stop;
end
end
end
initial begin
int i;
ATimestamp a;
BTimestamp b;
a = new;
b = new;
wait(rst_n != 0);
@(posedge clk_sys);
for(i=0;i<num_tries;i++)
begin
a.randomize();
b.randomize();
ta <= a.get();
tb <= b.get();
expected.push_back(a.flatten() + b.flatten());
valid_in <= 1;
@(posedge clk_sys);
end
valid_in <= 0;
@(posedge clk_sys);
end
endmodule // main
make
vsim -L XilinxCoreLib work.main -voptargs="+acc"
radix -hexadecimal
do wave.do
run 1us
wave zoomfull
\ No newline at end of file
This diff is collapsed.
action = "simulation"
vlog_opt="+incdir+../../include +incdir+../../include/wb"
files = "main.sv"
modules = {"local": [ "../../rtl" ] }
This diff is collapsed.
make
vsim -L XilinxCoreLib work.main -voptargs="+acc"
radix -hexadecimal
do wave.do
run 1us
wave zoomfull
\ No newline at end of file
This diff is collapsed.
files = [
"spec_top.vhd",
"spec_top.ucf",
#"wb_gpio_port_notristates.vhd"
];
fetchto = "../../ip_cores"
modules = {"local" : "../../rtl",
"svn" : "http://svn.ohwr.org/gn4124-core/branches/hdlmake-compliant/rtl" }
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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