UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Observer solsen
Observer
928 Views
Registered: ‎04-26-2017

Unwanted logic trimming during synthesis

Jump to solution

Hello all,

 

I'm in the process of debugging an ADC design, and I am trying to create a "dummy" AXI4 Stream data source to replace my ADC interface.

 

I want it to work in a way that I can trigger it, and it asserts TVALID for a preselected number of samples. The "data" is from a 32-bit counter.  To do this, I am writing 1 to  the "run" register when the trigger signal is received, but only if it's not already in the running state. I am storing the previous value of run in the register run_1 for the purpose of this comparison.

 

However, when I synthesize my design, the run register is trimmed: 

[Synth 8-3352] multi-driven net Q with 1st driver pin 'inst/run_reg__1/Q' [".../axis_dummy_source.v":63]

[Synth 8-3352] multi-driven net Q with 2nd driver pin 'GND' [".../axis_dummy_source.v":63]

[Synth 8-5559] multi-driven net Q is connected to constant driver, other driver is ignored [".../axis_dummy_source.v":63]

Consequently, the trig input is disconnected, and the TVALID output is tied to ground. (See attached picture)

 

I am thinking this is due to either a fundamental misunderstanding of HDL design/Verilog or a typo somewhere. Either way, I have been staring at this for some hours now and trying different alterations without any luck.

 

Can anyone point me in the right direction here?

 

Thanks, and kind regards,

Snorre

 

dummy_source_fail.PNG

 

Code:

 

module axis_dummy_source
#(
    parameter MAX_PKT_LENGTH = 512                  // Max consecutive reads.
)
(
    // Clocks and resets
    input                               aclk,          // Data clock
    input                               resetn,        // Synchronous, active low reset
    
    // Control signals
    input [$clog2(MAX_PKT_LENGTH)-1:0]  pkt_length,
    input                               trig,

    // Parellel interface
//    input [15:0]                        adc1,           // ADC 1 [MSB:LSB]
//    input [15:0]                        adc2,           // ADC 2 [MSB:LSB]
    input                               adc_dvalid,     // ADC Data valid
    
    // Master AXI4 Stream interface
    output                              m_axis_tvalid,
    input                               m_axis_tready,
    output                              m_axis_tlast,
    output [31:0]                       m_axis_tdata
);

    // Internal signals
    reg [$clog2(MAX_PKT_LENGTH)-1:0]    cnt = 0;            // This register holds the count of words sent
    reg [31:0]                          adc = 0;            // This registers simulates ADC data
    reg                                 run = 0;            // This is the run/stop state (1=run, 0=stop)
    reg                                 run_1 = 0;          // To keep track of previous state of run

    // Control adc and cnt counters    
    always @ (posedge aclk) begin
        if (~resetn) begin
            adc <= 0;
            cnt <= 0;
            run <= 0;
        end
        else if (adc_dvalid) begin
            adc <= adc + 1;                                 // Increase adc count independently of downstream status (like real-world data source)
            if (m_axis_tready) cnt <= cnt + 1;              // Keep count of words sent.
        end
    end
    
    // Control run/stop state
    always @(posedge aclk) begin
        run_1 <= run;                                       // Previous state of run
        if (~resetn | m_axis_tlast)   run <= 0;             // Single packet mode, deassert run after @pkt_length packets has been sent.
        else if (trig && ~run_1)      run <= 1;              // Assert run on first rising edge after trig.               
    end
    
    
    // Assign AXI signals
    assign m_axis_tvalid    =   (run & adc_dvalid);
    assign m_axis_tdata     =   adc;        
    assign m_axis_tlast     =   (cnt == pkt_length-1);      // Generate tlast for every packet boundary    
    
endmodule

 

Tags (3)
0 Kudos
1 Solution

Accepted Solutions
Explorer
Explorer
1,346 Views
Registered: ‎10-05-2010

Re: Unwanted logic trimming during synthesis

Jump to solution

You have two always blocks, and run is assigned in both of them. Remove the statement run <= 0; from the first always block.

 

---

Joe Samson

2 Replies
Explorer
Explorer
1,347 Views
Registered: ‎10-05-2010

Re: Unwanted logic trimming during synthesis

Jump to solution

You have two always blocks, and run is assigned in both of them. Remove the statement run <= 0; from the first always block.

 

---

Joe Samson

Observer solsen
Observer
882 Views
Registered: ‎04-26-2017

Re: Unwanted logic trimming during synthesis

Jump to solution

@josephsamson: Thank you so much, that seemed to do the trick! How could I miss that? Code brain I guess. If any moderators are reading this, feel free to delete this thread, as it is helpful to no one and embarassing to me :)

 

Anyhow, I'm surprised that the tools simply removed the register, couldn't they have left one of the drivers or at least generated an error (I got a "Critical Warning", but I'm afraid to say that they don't scare me so much after working with Vivado and IP cores for while now...) 

 

Cheers,

Snorre

 

PS: @balkris: I think you replied to the wrong thread....

0 Kudos