01-08-2015 12:07 PM
I am using the ZC702 and Vivado 2014.3.
I have a system that includes an external differential signal that I would like to use in my PL. I route the differential pair through my IP files to the level where I wish to use the signal, and route the P and N through an IBUFDS like this:
//IBUFDS for trigger IBUFDS i_trig_ibuf ( .I (ext_trig_p), .IB (ext_trig_n), .O (ext_trig));
In that module, I define ext_trig as a wire, and can probe it using the integrated logic analyzer and see that the signal is being driven from the external world. However, I am trying to implement some logic like this:
/*Triggering*/ always @(posedge adc_clk) begin if (ext_trig == 1'b1) begin event_window <= 1'b1; end end always @(posedge adc_clk) begin if ((sample_count == 1'b1) && (event_window == 1'b1)) begin sample_count <= sample_count - 1'b1; end else if ((sample_count == 1'b0) && (event_window == 1'b1)) begin sample_count <= 5'h1f; event_window <= 1'b0; end end
While I do not get any synthesis errors, I can see from the schematic of the synthesized design that ext_trig is not connected to anything (unrouted, has no loads), and no registers are shown for sample_count and event_window which are defined as registers. There are no nets for them in the netlist. Can anyone tell me what I am doing wrong?
01-08-2015 12:38 PM
Well, "event_window" should not be assigned in 2 different "always" blocks. That should have thrown a multi-driver error I would think?? You should be able to combine those 2 blocks.
As well, if sample_count and/or event_window do not drive anything, then they would likely be optimized away.
Plus, I think the second always block might be flawed depending on how sample_count is initialized. Not sure what the intent is.
01-08-2015 01:06 PM
You are right. I can do this in one process.
sample_count is initialized like this:
reg [4:0] sample_count = 'h1f;
The intent is this: I want to gate a signal "adc_valid" to be high for 32 clock cycles afer ext_trig goes high. I was trying to use "event_window" unsuccessfully to later do this:
always @(posedge adc_clk) begin adc_valid <= event_window; ...
How would you do this?
01-08-2015 01:26 PM
always @(posedge clk) begin count <= count - 1; if (count == 0) begin adc_valid <= 0; end if (ext_trig) begin count <= 31; adc_valid <= 1; end end
01-08-2015 04:54 PM
I would be tempted to add something that would prevent count from continuing to cycle from 31 down to 0 in the absence of an ext_trig. While there is no functional difference, its a little harder to debug if the counter is continously cycling, and it also consumes a little extra power unecessarily.
01-09-2015 07:53 AM
Thank you both for the suggestions.
Wouldn't the count be restarted at the next clock if ext_trig is several clock cycles long? How can I only trigger the count at the rising edge of ext_trig?
01-09-2015 09:51 AM
I hate to say this, but this is pretty much basic digital system design - this is a pretty simple system that is handled by a counter in conjunction with some simple state variables (either combined together or coded separately - it doesn't matter).
If you are planning to implement a "real" system, you will need to be able to do this stuff for yourself. From where you are now, it looks like you need some pretty fundamental stuff in the realms of digital system design and RTL coding. I would suggest that you consider taking a class or getting a good book on these subjects... Xilinx offers some training that might help (like the Verilog class ), but even that is more about the mechanisms of Verilog rather than the concepts of counters and state machines (which is considered even more basic).
always @(posedge clk) begin
old_ext_trig <= ext_trig if (count != 0) begin count <= count - 1'b1; end else begin
if (ext_trig && !old_ext_trig) begin count <= 31; adc_valid <= 1'b1; end else begin
adc_valid <= 1'b0;