Skip to content

Commit

Permalink
Merge branch 'etrig' into 'master'
Browse files Browse the repository at this point in the history
etrig_bridge

* Import external trigger module (etrig_bridge.v) and its corresponding testbench from lcls2_llrf git repository to here.
* dsp/Makefile: Adds dependency to generate cordicg_b22.v

See merge request hdl-libraries/bedrock!203
  • Loading branch information
ldoolitt committed Oct 8, 2024
2 parents be94c9a + abddd57 commit 737ef37
Show file tree
Hide file tree
Showing 5 changed files with 247 additions and 1 deletion.
1 change: 1 addition & 0 deletions dsp/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
include ../dir_list.mk
VERILOG_AUTOGEN += "cordicg_b22.v"
.PHONY: all
all: targets
include $(BUILD_DIR)/top_rules.mk
Expand Down
28 changes: 28 additions & 0 deletions dsp/hosted/etrig_bridge.gtkw
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[timestart] 0
[size] 1166 445
[pos] 763 125
*-23.377670 3480000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] etrig_bridge_tb.
[treeopen] etrig_bridge_tb.UUT.
[sst_width] 233
[signals_width] 198
[sst_expanded] 1
[sst_vpaned_height] 93
@28
etrig_bridge_tb.UUT.adc_clk
etrig_bridge_tb.UUT.lb_clk
etrig_bridge_tb.UUT.trign_0
etrig_bridge_tb.UUT.trign_1
@29
etrig_bridge_tb.UUT.trign_2
@28
etrig_bridge_tb.UUT.sel[1:0]
@24
etrig_bridge_tb.UUT.period[25:0]
etrig_bridge_tb.UUT.delay[25:0]
etrig_bridge_tb.etrig_pulse_cnt[15:0]
@28
etrig_bridge_tb.UUT.etrig_pulse
etrig_bridge_tb.UUT.etrig_pulse_delayed
[pattern_trace] 1
[pattern_trace] 0
134 changes: 134 additions & 0 deletions dsp/hosted/etrig_bridge.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// Module that manages the asynchronous external trigger, and the internally-generated periodic trigger.
// Performs clock-domain synchronization, and delays the assertion of the trigger accordingly.
// ----------

module etrig_bridge (
// Two clocks, ADC clock and local clock
input lb_clk,
input adc_clk,
// Three external triggers, active-low
input trign_0,
input trign_1,
input trign_2,
// Control registers
input [1:0] sel, // external
input [25:0] period, // external
input [25:0] delay, // external
// Trigger Counter
output [15:0] etrig_pulse_cnt,
// Trigger Outputs
output etrig_pulse,
output etrig_pulse_delayed
);

// -------
// Multi-board synchronization w/ selectable external or programmable trigger
// -------
localparam ETRIG_0 = 0,
ETRIG_1 = 1,
ETRIG_2 = 2,
ETRIG_PROG = 3;

// wires and regs
reg [25:0] etrig_p_cnt = 0; // counter for internally-generated trigger
wire etrig_p_pulse, etrig_p_pulse_x; // the internal trigger and its synced partner
wire async_trig, etrig; // MUX outputs
reg [6:0] async_filt_cnt = 0; // to filter-out glitches in the external trigger
wire async_trig_filt; // filtered-out trigger
reg etrig_r = 0, etrig_r1 = 0, etrig_pulse_i = 0; // for edge detection
reg [1:0] etrig_sreg = 0; // shift register to ensure proper delay
reg [15:0] etrig_pulse_cnt_i = 0; // count the triggers that are issued
reg [25:0] delay_cnt = 0; // delay counter
reg etrig_pulse_delayed_i = 0; // delayed pulse
reg etrig_toggle = 0; // flag indicating that we received a pulse

// 2-FF synchronizers
(* ASYNC_REG = "TRUE" *) reg [1:0] trign_0_sync=0, trign_1_sync=0, trign_2_sync=0;

// Move delay control to adc_clk domain. Should be attainable using newad.
reg [25:0] delay_r=0; always @(posedge adc_clk) delay_r <= delay;

// generates the internal trigger
always @(posedge lb_clk) begin
etrig_p_cnt <= (etrig_p_cnt == 0) ? period : etrig_p_cnt - 1;
end

assign etrig_p_pulse = (etrig_p_cnt == 1);

// from lb to adc clock domain
flag_xdomain i_flagx_etrig (
.clk1(lb_clk), .flagin_clk1(etrig_p_pulse),
.clk2(adc_clk), .flagout_clk2(etrig_p_pulse_x));

// 2-FF synchronizer before handling further
reg [1:0] sel_r=0;
always @(posedge adc_clk) begin
trign_0_sync <= {trign_0_sync[0], trign_0};
trign_1_sync <= {trign_1_sync[0], trign_1};
trign_2_sync <= {trign_2_sync[0], trign_2};
sel_r <= sel; // arrived in lb_clk
end

// MUX to decide which trigger to propagate (external triggers are active-low)
assign async_trig = (sel_r == ETRIG_0) ? ~trign_0_sync[1] :
(sel_r == ETRIG_1) ? ~trign_1_sync[1] :
(sel_r == ETRIG_2) ? ~trign_2_sync[1] :
1'b0;

// Glitch filter async inputs by ignoring pulses shorter than 128/adc_clk = 1.356 us
always @(posedge adc_clk) begin
if (async_trig == 0) async_filt_cnt <= 0;
else if (!async_trig_filt) async_filt_cnt <= async_filt_cnt + 1;
end
assign async_trig_filt = &(async_filt_cnt);

assign etrig = (sel_r == ETRIG_PROG) ? etrig_p_pulse_x : async_trig_filt;

// Rising-edge detect
always @(posedge adc_clk) begin
etrig_r <= etrig;
etrig_r1 <= etrig_r;
etrig_pulse_i <= etrig_r & ~etrig_r1;
if (etrig_pulse_i)
etrig_pulse_cnt_i <= etrig_pulse_cnt_i + 1;
end

// Delay the trigger strobe
always @(posedge adc_clk) begin
if (etrig_pulse_i == 1'b1) begin
delay_cnt <= 0; // reset
etrig_toggle <= 1'b1; // raise the flag
etrig_pulse_delayed_i <= 1'b0; // not ready yet
end
else if (etrig_toggle == 1'b1 && delay_cnt < delay_r) begin
delay_cnt <= delay_cnt + 1; // keep rolling
etrig_toggle <= etrig_toggle; // retain
etrig_pulse_delayed_i <= 1'b0; // not ready yet
end
else if (etrig_toggle == 1'b1 && delay_cnt == delay_r) begin
delay_cnt <= 0; // reset
etrig_toggle <= 1'b0; // reset
etrig_pulse_delayed_i <= 1'b1; // one-clock pulse
end
else begin
delay_cnt <= 0; // reset
etrig_toggle <= 1'b0; // keep low
etrig_pulse_delayed_i <= 1'b0; // keep low
end
end

// two-bit shift-register
// ensures one-cycle delay between trigger and delayed trigger if delay == 1
always @(posedge adc_clk) begin
etrig_sreg <= etrig_sreg << 1;
etrig_sreg[0] <= etrig_pulse_i;
end

// assigning to output ports
assign etrig_pulse_cnt = etrig_pulse_cnt_i;
assign etrig_pulse = etrig_sreg[1];

// mux for the case that the delay is zero
assign etrig_pulse_delayed = (delay_r == 0) ? etrig_sreg[1] : etrig_pulse_delayed_i;

endmodule
83 changes: 83 additions & 0 deletions dsp/hosted/etrig_bridge_tb.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// etrig_bridge_tb.v

`timescale 1 ns/10 ps // time-unit = 1 ns, precision = 10 ps

module etrig_bridge_tb;

reg j5_24v = 1, j4_24v = 1, de9_rxd = 1, de9_dsr = 1; // Active-low
reg [1:0] etrig_sel = 0;
reg [25:0] etrig_period = 26'h0000ff;
reg [25:0] etrig_delay = 26'h000000;
wire [15:0] etrig_pulse_cnt;
wire etrig_pulse;
wire etrig_pulse_delayed;

// Testbench parameters and clocking
reg fail = 0;
integer seed_int=123;
localparam SIM_TIME = 50000; // ns
localparam period_lb_clk = 20;
localparam period_adc_clk = 10;

reg free_lb_clk=0;
wire lb_clk;
always begin free_lb_clk = ~free_lb_clk; #(period_lb_clk/2); end

reg free_adc_clk=0;
wire adc_clk;
always begin free_adc_clk = ~free_adc_clk; #(period_adc_clk/2); end

reg pll_lock_emu=0;

// Testbench control
initial begin
if ($test$plusargs("vcd")) begin
$dumpfile("etrig_bridge.vcd");
$dumpvars(5, etrig_bridge_tb);
end

while ($time < SIM_TIME) @(posedge lb_clk);
if (!fail) begin
$display("WARNING: Not a self-checking testbench. Will always PASS.");
$finish(0);
end else begin
$display("FAIL");
$stop(0);
end
end

etrig_bridge UUT (
.lb_clk(lb_clk), .adc_clk(adc_clk),
.trign_0(j5_24v),
.trign_1(j4_24v),
.trign_2(de9_rxd&de9_dsr),
.sel(etrig_sel), .period(etrig_period), .delay(etrig_delay),
.etrig_pulse_cnt(etrig_pulse_cnt), .etrig_pulse(etrig_pulse),
.etrig_pulse_delayed(etrig_pulse_delayed)
);

// trigger loop
always begin
if (!pll_lock_emu) begin
#(($urandom(seed_int)%20)*period_lb_clk);
pll_lock_emu <= 1'b1;
end

#(($urandom(seed_int)%20)*20);
{j4_24v, j5_24v, de9_rxd, de9_dsr} <= $urandom(seed_int)%16;
@(posedge adc_clk);

#(($urandom(seed_int)%20)*200);
{j4_24v, j5_24v, de9_rxd, de9_dsr} <= (1<<4)-1;
etrig_delay <= etrig_delay + 1;
@(posedge adc_clk);
end

always @(posedge adc_clk)
etrig_sel <= etrig_sel + etrig_pulse;

// clocking
assign lb_clk = (pll_lock_emu) ? free_lb_clk : 1'b0;
assign adc_clk = (pll_lock_emu) ? free_adc_clk : 1'b0;

endmodule
2 changes: 1 addition & 1 deletion dsp/hosted/rules.mk
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
VFLAGS_DEP += -I. -y . -y$(DSP_DIR) -y$(CORDIC_DIR)
VFLAGS += -I. -y . -y$(DSP_DIR) -y$(CORDIC_DIR) -I$(AUTOGEN_DIR)

TEST_BENCH = lp_tb lp_2notch_tb lp_notch_tb phs_avg_tb mp_proc_tb
TEST_BENCH = lp_tb lp_2notch_tb lp_notch_tb phs_avg_tb mp_proc_tb etrig_bridge_tb

TGT_ := $(TEST_BENCH)

Expand Down

0 comments on commit 737ef37

Please sign in to comment.