cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
matthuszagh
Observer
Observer
1,678 Views
Registered: ‎07-16-2018

net does not have driver

Jump to solution

Vivado seems to be optimizing away a core piece of my HDL. Here's the relevant module:

`ifndef _FFT_R22SDF_BFI_V_
`define _FFT_R22SDF_BFI_V_
`default_nettype none

`include "shift_reg.v"

module fft_r22sdf_bfi #(
   parameter DATA_WIDTH    = 25,
   parameter SHIFT_REG_LEN = 512
) (
   input wire                         clk_i,
   input wire                         rst_n,
   input wire                         sel_i,
   input wire signed [DATA_WIDTH-1:0] x_re_i,
   input wire signed [DATA_WIDTH-1:0] x_im_i,
   output reg signed [DATA_WIDTH-1:0] z_re_o,
   output reg signed [DATA_WIDTH-1:0] z_im_o
);

   wire signed [DATA_WIDTH-1:0]       sr_re;
   wire signed [DATA_WIDTH-1:0]       sr_im;

   // reg signed [DATA_WIDTH-1:0]        sr_re_reg [0:SHIFT_REG_LEN-1];
   // reg signed [DATA_WIDTH-1:0]        sr_im_reg [0:SHIFT_REG_LEN-1];
   // integer                            i;
   // always @(posedge clk_i) begin
   //    if (!rst_n) begin
   //       for (i=0; i<SHIFT_REG_LEN; i=i+1) begin
   //          sr_re_reg[i] <= {DATA_WIDTH{1'b0}};
   //          sr_im_reg[i] <= {DATA_WIDTH{1'b0}};
   //       end
   //    end else begin
   //       sr_re_reg[0] <= zsr_re;
   //       sr_im_reg[0] <= zsr_im;
   //       for (i=1; i<SHIFT_REG_LEN; i=i+1) begin
   //          sr_re_reg[i] <= sr_re_reg[i-1];
   //          sr_im_reg[i] <= sr_im_reg[i-1];
   //       end
   //    end
   // end
   // assign sr_re = sr_re_reg[SHIFT_REG_LEN-1];
   // assign sr_im = sr_im_reg[SHIFT_REG_LEN-1];
   generate
      if (SHIFT_REG_LEN > 32) begin
         shift_reg #(
            .DATA_WIDTH (DATA_WIDTH    ),
            .LEN        (SHIFT_REG_LEN )
         ) shift_reg_re (
            .clk    (clk_i  ),
            .rst_n  (rst_n  ),
            .ce     (1'b1   ),
            .di     (zsr_re ),
            .data_o (sr_re  )
         );

         shift_reg #(
            .DATA_WIDTH (DATA_WIDTH    ),
            .LEN        (SHIFT_REG_LEN )
         ) shift_reg_im (
            .clk    (clk_i  ),
            .rst_n  (rst_n  ),
            .ce     (1'b1   ),
            .di     (zsr_im ),
            .data_o (sr_im  )
         );
      end else begin
         reg signed [DATA_WIDTH-1:0]        sr_re_reg [0:SHIFT_REG_LEN-1];
         reg signed [DATA_WIDTH-1:0]        sr_im_reg [0:SHIFT_REG_LEN-1];
         integer                    i;
         always @(posedge clk_i) begin
            if (!rst_n) begin
               for (i=0; i<SHIFT_REG_LEN; i=i+1) begin
                  sr_re_reg[i] <= {DATA_WIDTH{1'b0}};
                  sr_im_reg[i] <= {DATA_WIDTH{1'b0}};
               end
            end else begin
               sr_re_reg[0] <= zsr_re;
               sr_im_reg[0] <= zsr_im;
               for (i=1; i<SHIFT_REG_LEN; i=i+1) begin
                  sr_re_reg[i] <= sr_re_reg[i-1];
                  sr_im_reg[i] <= sr_im_reg[i-1];
               end
            end
         end
         assign sr_re = sr_re_reg[SHIFT_REG_LEN-1];
         assign sr_im = sr_im_reg[SHIFT_REG_LEN-1];
      end
   endgenerate

   wire signed [DATA_WIDTH-1:0]       xsr_re;
   wire signed [DATA_WIDTH-1:0]       xsr_im;
   reg signed [DATA_WIDTH-1:0]        zsr_re;
   reg signed [DATA_WIDTH-1:0]        zsr_im;

   assign xsr_re = sr_re;
   assign xsr_im = sr_im;

   always @(*) begin
      if (sel_i) begin
         z_re_o = x_re_i + xsr_re;
         z_im_o = x_im_i + xsr_im;

         zsr_re = xsr_re - x_re_i;
         zsr_im = xsr_im - x_im_i;
      end else begin
         z_re_o = xsr_re;
         z_im_o = xsr_im;

         zsr_re = x_re_i;
         zsr_im = x_im_i;
      end
   end

endmodule
`endif

I'm getting a number of warnings like the following

WARNING: [Synth 8-3848] Net zsr_re in module/entity fft_r22sdf_bfi__parameterized3 does not have driver. [/home/matt/src/libdigital/libdigital/hdl/fft/r22sdf/fft_r22sdf_bfi.v:92]

And sure enough, when I run the design I'm getting nothing out of this part of the module. When I replace the entire generate construct with the commented region, the design works as expected (and I don't see any of the above warnings). The behavior of each of these is identical in simulation. What's going wrong here? Have I misused the generate construct? I'm happy to post the code for the shift register if that helps, but I don't believe that's the problem.

Note that the reason I prefer the failing version is because it saves resources by using dual port RAM blocks for sufficiently large shift registers. The other method implements the whole thing with flip-flops.

0 Kudos
1 Solution

Accepted Solutions
apetley
Xilinx Employee
Xilinx Employee
1,591 Views
Registered: ‎06-14-2018

Hi @matthuszagh ,

Lets workout scenaio with smaller testcase:

module top(

input clk,
input [3:0] din,
output [3:0] out
);

parameter TRUE = 1;

generate
if (TRUE == 1)
begin
sub U1 (.clk(clk), .din(w1), .dout(out));
end
endgenerate

wire [3:0] w1;
assign w1 = ~din;
endmodule

module sub(
input clk,
input [3:0] din,
output reg [3:0] dout
);

always@(posedge clk)
dout <= din;

endmodule

WARNING: [Synth 8-3848] Net w1 in module/entity top does not have driver.

Here, w1 is instantiated in submodule sub, however not decalred.

When wire/net is used in instantiation without declaration(implicit declaration) its always single bit.

Here thats declared in generate block so name for wire will be like GENBLK1.w1 which is undriven in dut.

Later in code w1 is driven however w1 and GENBLK1.w1 are different wires/nets altogther.

Hope this answers reason for "WARNING: [Synth 8-3848] Net w1 in module/entity top does not have driver."

Thanks,

Ajay 

View solution in original post

8 Replies
baltintop
Voyager
Voyager
1,653 Views
Registered: ‎06-28-2018

@matthuszagh 

Give a label to every generate block in your design such as

if (SHIFT_REG_LEN > 32) begin : gen_shift_reg

and use hierarchical referencing throughout your design.

To access the top module signals from the generate block add the module name before the signal name such as

fft_r22sdf_bfi.sr_re

to access the local signals of the generate block from the top module use the block's label

gen_shift_reg.sr_re_reg

The warning seems to be related to an incorrect referencing.

0 Kudos
matthuszagh
Observer
Observer
1,643 Views
Registered: ‎07-16-2018

Unfortunately, I'm not having any luck with that. Here's the updated module.

`ifndef _FFT_R22SDF_BFI_V_
`define _FFT_R22SDF_BFI_V_
`default_nettype none

`include "shift_reg.v"

module fft_r22sdf_bfi #(
   parameter DATA_WIDTH    = 25,
   parameter SHIFT_REG_LEN = 512
) (
   input wire                         clk_i,
   input wire                         rst_n,
   input wire                         sel_i,
   input wire signed [DATA_WIDTH-1:0] x_re_i,
   input wire signed [DATA_WIDTH-1:0] x_im_i,
   output reg signed [DATA_WIDTH-1:0] z_re_o,
   output reg signed [DATA_WIDTH-1:0] z_im_o
);

   wire signed [DATA_WIDTH-1:0]       sr_re;
   wire signed [DATA_WIDTH-1:0]       sr_im;

   // reg signed [DATA_WIDTH-1:0]        sr_re_reg [0:SHIFT_REG_LEN-1];
   // reg signed [DATA_WIDTH-1:0]        sr_im_reg [0:SHIFT_REG_LEN-1];
   // integer                            i;
   // always @(posedge clk_i) begin
   //    if (!rst_n) begin
   //       for (i=0; i<SHIFT_REG_LEN; i=i+1) begin
   //          sr_re_reg[i] <= {DATA_WIDTH{1'b0}};
   //          sr_im_reg[i] <= {DATA_WIDTH{1'b0}};
   //       end
   //    end else begin
   //       sr_re_reg[0] <= zsr_re;
   //       sr_im_reg[0] <= zsr_im;
   //       for (i=1; i<SHIFT_REG_LEN; i=i+1) begin
   //          sr_re_reg[i] <= sr_re_reg[i-1];
   //          sr_im_reg[i] <= sr_im_reg[i-1];
   //       end
   //    end
   // end
   // assign sr_re = sr_re_reg[SHIFT_REG_LEN-1];
   // assign sr_im = sr_im_reg[SHIFT_REG_LEN-1];
   generate
      if (SHIFT_REG_LEN > 32) begin : gen_shift_reg
         shift_reg #(
            .DATA_WIDTH (DATA_WIDTH    ),
            .LEN        (SHIFT_REG_LEN )
         ) shift_reg_re (
            .clk    (fft_r22sdf_bfi.clk_i  ),
            .rst_n  (fft_r22sdf_bfi.rst_n  ),
            .ce     (1'b1                  ),
            .di     (fft_r22sdf_bfi.zsr_re ),
            .data_o (fft_r22sdf_bfi.sr_re  )
         );

         shift_reg #(
            .DATA_WIDTH (DATA_WIDTH    ),
            .LEN        (SHIFT_REG_LEN )
         ) shift_reg_im (
            .clk    (fft_r22sdf_bfi.clk_i  ),
            .rst_n  (fft_r22sdf_bfi.rst_n  ),
            .ce     (1'b1                  ),
            .di     (fft_r22sdf_bfi.zsr_im ),
            .data_o (fft_r22sdf_bfi.sr_im  )
         );
      end else begin : gen_shift_reg_fallback
         reg signed [DATA_WIDTH-1:0]        sr_re_reg [0:SHIFT_REG_LEN-1];
         reg signed [DATA_WIDTH-1:0]        sr_im_reg [0:SHIFT_REG_LEN-1];
         integer                    i;
         always @(posedge fft_r22sdf_bfi.clk_i) begin
            if (!fft_r22sdf_bfi.rst_n) begin
               for (i=0; i<SHIFT_REG_LEN; i=i+1) begin
                  sr_re_reg[i] <= {DATA_WIDTH{1'b0}};
                  sr_im_reg[i] <= {DATA_WIDTH{1'b0}};
               end
            end else begin
               sr_re_reg[0] <= fft_r22sdf_bfi.zsr_re;
               sr_im_reg[0] <= fft_r22sdf_bfi.zsr_im;
               for (i=1; i<SHIFT_REG_LEN; i=i+1) begin
                  sr_re_reg[i] <= sr_re_reg[i-1];
                  sr_im_reg[i] <= sr_im_reg[i-1];
               end
            end
         end
         assign fft_r22sdf_bfi.sr_re = sr_re_reg[SHIFT_REG_LEN-1];
         assign fft_r22sdf_bfi.sr_im = sr_im_reg[SHIFT_REG_LEN-1];
      end
   endgenerate

   wire signed [DATA_WIDTH-1:0]       xsr_re;
   wire signed [DATA_WIDTH-1:0]       xsr_im;
   reg signed [DATA_WIDTH-1:0]        zsr_re;
   reg signed [DATA_WIDTH-1:0]        zsr_im;

   assign xsr_re = sr_re;
   assign xsr_im = sr_im;

   always @(*) begin
      if (sel_i) begin
         z_re_o = x_re_i + xsr_re;
         z_im_o = x_im_i + xsr_im;

         zsr_re = xsr_re - x_re_i;
         zsr_im = xsr_im - x_im_i;
      end else begin
         z_re_o = xsr_re;
         z_im_o = xsr_im;

         zsr_re = x_re_i;
         zsr_im = x_im_i;
      end
   end

endmodule
`endif

I'm additionally getting the error

tying undriven pin gen_shift_reg.shift_reg_re:di[24] to constant 0

maybe that is also relevant.

0 Kudos
matthuszagh
Observer
Observer
1,633 Views
Registered: ‎07-16-2018

I got this working. Apparently, the generate block needs to appear after the sr_re and sr_im declarations. I wasn't aware that verilog required this. Is this a bug, or have I missed some part of the standard?

0 Kudos
baltintop
Voyager
Voyager
1,613 Views
Registered: ‎06-28-2018

@matthuszagh


Apparently, the generate block needs to appear after the sr_re and sr_im declarations.

You mean zsr_re and zsr_im, right?


Is this a bug, or have I missed some part of the standard?

Having to declare variables before using them sounds reasonable to me.



0 Kudos
matthuszagh
Observer
Observer
1,609 Views
Registered: ‎07-16-2018

Correct, zsr etc. Apologies for the mistake. Sure it seems reasonable, but none of the simulations or linters I ran complained about this. Nor did Vivado in a clear way, it just tied it to 0. It would be much easier to spot it as an issue if Vivado issued an error and terminated synthesis. As it stands I have a very hard time sifting through Vivados warnings/messages bc they emit tons of them, most are benign and they don't provide a filter option. Additionally, I've done this (use before declaration) in many other places and it synthesizes fine, it just seems to be with generate blocks where the issue arises.

 

Anyway, thanks for the help in diagnosing this.

0 Kudos
apetley
Xilinx Employee
Xilinx Employee
1,592 Views
Registered: ‎06-14-2018

Hi @matthuszagh ,

Lets workout scenaio with smaller testcase:

module top(

input clk,
input [3:0] din,
output [3:0] out
);

parameter TRUE = 1;

generate
if (TRUE == 1)
begin
sub U1 (.clk(clk), .din(w1), .dout(out));
end
endgenerate

wire [3:0] w1;
assign w1 = ~din;
endmodule

module sub(
input clk,
input [3:0] din,
output reg [3:0] dout
);

always@(posedge clk)
dout <= din;

endmodule

WARNING: [Synth 8-3848] Net w1 in module/entity top does not have driver.

Here, w1 is instantiated in submodule sub, however not decalred.

When wire/net is used in instantiation without declaration(implicit declaration) its always single bit.

Here thats declared in generate block so name for wire will be like GENBLK1.w1 which is undriven in dut.

Later in code w1 is driven however w1 and GENBLK1.w1 are different wires/nets altogther.

Hope this answers reason for "WARNING: [Synth 8-3848] Net w1 in module/entity top does not have driver."

Thanks,

Ajay 

View solution in original post

matthuszagh
Observer
Observer
1,506 Views
Registered: ‎07-16-2018
Thanks @apetley, that was a really clear and useful explanation of the issue.
0 Kudos
olupj
Explorer
Explorer
996 Views
Registered: ‎01-27-2008

One small detail that I didn't see in the test case, but was realized in the original code, I just encountered in a design (old, vivado 2014.3).

  • declared `default_nettype none so I eliminate Verilog's implicit declaration sneak path.
  • Had an instance expressing a logic signal in the system (used the signal before declaring it).
    • Expect an error when default nettype none is used with that case but didn't check the systemverilog standard
  • then declared the signal (and subsequently used it):
    • logic [15:0] someSignal;

This gave the same warning as the OP but I expected and error, as the signal net is used before being declared.

I think that's probably a vivado (fixed by now?) issue that should have caught that simple coding error.

Jerry