Author Topic: Vivado: Synthesis crash (address violation) at "Start Cross Boundary" stage  (Read 826 times)

0 Members and 1 Guest are viewing this topic.

Offline tom66

  • Super Contributor
  • ***
  • Posts: 5298
  • Country: gb
  • Electronics Hobbyist & FPGA/Embedded Systems EE
I am seeing Vivado crash at "Start Cross Boundary and Area Optimization" in synthesis, about a minute into starting synthesis.

With some liberal commenting of blocks out I was able to locate the fault to a custom IP of mine.  Inside this IP is a module that computes the address of a buffer using a few combinatorial inputs.  I cannot disclose the exact source but it has the structure:

Code: [Select]
reg [31:0] addr;

always @* begin
    case (protocol)
        PROTOCOL1: begin
            if (yc_sel == 0) begin
                addr <= base_mask | (buff_y_base + (fram_arhd_segment * MEM_BUFF_HALF));
            end
        end
       
        PROTOCOL2: begin
            if (yc_sel == 0) begin
                addr <= base_mask | buff_y_base;
            end
        end
       
        PROTOCOL3: begin
            addr <= base_mask + MEM_COMP_BASE + (comp_use * MEM_COMP_SIZE);
        end
       
        default : begin
            addr <= 32'hXXXXXXXX;
        end
    endcase
end

My intention with the default assigning to dont-care was to say to the synthesis/implementation tool that "this won't happen, so optimise the logic for it not happening to be irrelevant".   

But later I noticed that I had mistakenly not included all conditions as yc_sel being nonzero would result in a non-assignment to addr.  (The intention was in the future versions of the IP to support these.)  However, adding in the missing conditions did not fix the crash.

I then changed the file to a SystemVerilog file and rewrote this as an always_comb block. This no longer crashes.  (I am still getting used to SV, so it was not my natural first choice.)

Has anyone seen this before?  Is there something wrong with what I've written, or is this just yet another Vivado bug?
 

Offline tom66

  • Super Contributor
  • ***
  • Posts: 5298
  • Country: gb
  • Electronics Hobbyist & FPGA/Embedded Systems EE
I was misleading myself.  In testing always_comb I left a statement in place to the effect of replacing the combinatorial output of that.  Vivado still crashed with always_comb once I removed that statement.  However, I found the actual cause.  'fram_arhd_segment' was typoed in a downstream module, which was causing the disconnected net to be optimised out.  Why this led the synthesis process to crash is anyone's guess though, it's clearly a bug of some kind in the tool.
 

Online asmi

  • Super Contributor
  • ***
  • Posts: 2130
  • Country: ca
This code has non-blocking assignments in combinatorial block.
 
The following users thanked this post: tom66, BrianHG, dtodorov

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 6934
  • Country: ca
Have you considered:

Code: [Select]
wire [31:0] addr = (protocol==PROTOCOL1) ? base_mask | (buff_y_base + (fram_arhd_segment * MEM_BUFF_HALF)) :
                   (protocol==PROTOCOL2) ? base_mask | buff_y_base :
                   (protocol==PROTOCOL3) ? base_mask + MEM_COMP_BASE + (comp_use * MEM_COMP_SIZE) :
                                           32'hXXXXXXXX;
A simple wire, identical in both styles of verilog.

The problem is '(yc_sel == 0)', since you are not clocking anything, Im not sure your coding here with combinational logic is a good choice.  You could call this 'wire [31:0] address_select = .....' and later on say if (yc_sel == 0) addr <= address_select; where it is being clocked...

Also, if you want this addr to be driven by another se of logic, either tristate IO pins, or dangerous internal fpga logic, 32'hXXXXXXXX should be changed to 32'hZZZZZZZZ, though I do not know what you are trying to do.  I reserve the 'x' for displaying an erroneous or unknown state for those simulating my code, not for actual FPGA functionality.

Also, remember, if you are creating IP for release, or more than 1 vendor of FPGA, you will need to test your code in other environments as they all reveal different degree of nuances of error and warning checking during compile.
« Last Edit: August 12, 2022, 07:21:29 pm by BrianHG »
 
The following users thanked this post: tom66

Offline tom66

  • Super Contributor
  • ***
  • Posts: 5298
  • Country: gb
  • Electronics Hobbyist & FPGA/Embedded Systems EE
Thanks.

I did consider the ternary operator, but felt it looked messier than the alternative of an always_comb/always mux block.  I'll fix the non-blocking assignment, I've literally not used always_comb before this so still learning the ropes, as SystemVerilog is still new to me.  (However I do recall trying both and Vivado still crashed.)

For clarity base_mask, buff_y_base etc all change very infrequently (external control, <100Hz update rate) and are latched on the same clock as the logic using the addr after a register stage.  The purpose of this logic is to compute the base address of some array which is then incremented by another block until an end state is reached.

It only needs to work on a Xilinx device, so no vendor compatibility issues.

My thought with 32'hXXXXXXXX is that it tells the synthesis tool that I don't care what this output is.  That state is unreachable (within normal operation) and if that does somehow get reached then there's probably a serious bug so it doesn't really matter.  I therefore include it only to get the synthesis tool to stop worrying about a default condition and design the logic to output whatever makes the Karnaugh mapping smaller.  I've used the same 'trick' on the AXI register slave which controls the interface to this block, the result is reading back unassigned registers usually returns an adjacent register or part thereof.  It seems to simplify the multiplexing logic at no cost.
« Last Edit: August 12, 2022, 07:53:41 pm by tom66 »
 

Offline emece67

  • Frequent Contributor
  • **
  • Posts: 616
  • Country: 00
« Last Edit: August 19, 2022, 05:44:47 pm by emece67 »
 
The following users thanked this post: tom66, coldfiremc

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 10606
  • Country: fr
However messy the code may have been, the tools should not crash. ::)
 
The following users thanked this post: tom66

Offline tom66

  • Super Contributor
  • ***
  • Posts: 5298
  • Country: gb
  • Electronics Hobbyist & FPGA/Embedded Systems EE
However messy the code may have been, the tools should not crash. ::)

Exactly my thought.   'Error' during build is fine.  An 'access violation' with absolutely no debug information, and no one else having encountered it before, is a royal PITA.

Annoyingly Xilinx have no option switch for 'extra debug' during logs (according to Xilinx support.)  The official method for locating a crash like this is to black box things until the bug goes away.  Commenting out stuff is the lazier approach but it got there eventually.  Still, it shouldn't be necessary!
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 6934
  • Country: ca
However messy the code may have been, the tools should not crash. ::)
You are right.  You have no idea how many time I could make Quartus crash having to work around internal bugs.  Especially a divide by zero bug which even Modelsim isn't immune from.
I also hated Protel 98, too many arcs traces with the wrong dimensions and you loose everything.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 10606
  • Country: fr
Yep. Now I never had a crash with Xilinx ISE or Lattice Diamond that I can remember of. Not all tools are equally as buggy, but yes, complex software without bugs is rather uncommon.
 
The following users thanked this post: coldfiremc

Offline coldfiremc

  • Regular Contributor
  • *
  • Posts: 75
  • Country: cl
Report this crash to Xilinx in the "support" forum
 

Offline Sal Ammoniac

  • Super Contributor
  • ***
  • Posts: 1579
  • Country: us
Why are you using non-blocking assignments in a combinatorial always block?
Complexity is the number-one enemy of high-quality code.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf