-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
Showing
5 changed files
with
247 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters