Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Quartus Prime Lite: object assigned a value but never read

Status
Not open for further replies.

hornysquid

Newbie level 5
Joined
Jun 9, 2016
Messages
10
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
71
Hello. I am trying to synthesize a module written in SV and get this message despite I checked that signal is being used:
Code:
Warning: Verilog HDL or VHDL warning at crossbar.sv(28): object "next_tx_valid" assigned a value but never read

some code:
Code:
.......
logic 			next_tx_valid[SLAVES][1:3];
  
  // set round-robin to next non-empty transaction
  function logic [$clog2(MASTERS)-1:0] update_rr (input int i); 
    priority case (1'b1)
      next_tx_valid[i][1]: return rr_copy[i]+2'(1);
      next_tx_valid[i][2]: return rr_copy[i]+2'(2);
      next_tx_valid[i][3]: return rr_copy[i]+2'(3);
      default: return rr_copy[i];
    endcase // priority case (1'b1)
  endfunction
  
 .......
  
  always_ff @(posedge clk) begin

....

	      // save copy of transaction pointer in case rr_cnt gets
	      // overwritten in transaction push phase
	      rr_copy[i] <= rr_cnt[i];

	      for (int j=1; j<=3; j++) // see next_tx_valid declaration
		[SIZE=4][B]next_tx_valid[i][j] <= tx_queue[i][rr_cnt[i]+j].tx_valid;[/B][/SIZE]
	      
	    end // if (tx.tx_valid)
	  end // case: READY
	  
	  WAIT_ACK: begin
	    if (sif.ack[i]) begin
	      try[rr_copy[i]][i].ack <= 1'b1;
	      
	      // if write, then we are done, if read, wait for response
	      if (tx_queue[i][rr_copy[i]].cmd) begin
		sif_state[i] <= READY;
		[SIZE=4][B]rr_cnt[i] <= update_rr(i);[/B][/SIZE]
	      end
	      else sif_state[i] <= WAIT_RESP;
	    end // if (sif.ack[i])

	  end // case: WAIT_ACK
	  
	  WAIT_RESP: begin
	    if (sif.resp[i]) begin
	      try[rr_copy[i]][i].resp <= 1'b1;
	      try[rr_copy[i]][i].rdata <= sif.rdata[i];
	      sif_state[i] <= READY;
	     [SIZE=4][B]rr_cnt[i] <= update_rr(i);[/B][/SIZE]
	    end // if (sif.resp[i])
	    
	  end // case: WAIT_RESP
	  
	endcase // unique case (sif_state[i])	
      end // for (int i=0; i<SLAVES; i++)

...............................
    
  end // always_ff @ (posedge clk)
  
endmodule

And apparently, it gets optimized away. What am i doing wrong?
 

Sorry, it seems I actually misled you. This signal IS in the post-map netlist, but the warning remains.

next2.PNG

next.PNG
 

Too much code stripped off to see if any design output actually depends on next_tx_valid.

Why don't you check the design operation in a simulation? And review the synthesized netlist schematic?

- - - Updated - - -

Could it be that warning is only meaning some of the array elements? You can best check in the register browser of the netlist viewer
 

Could it be that warning is only meaning some of the array elements?

Hmm, nope. I checked the post-fitting netlist, and it is still there. Maybe it has something to do with that next_tx_valid is used not directly in an always block, but within a function?
next3.PNG
 

This shouldn't happen, may be a Quartus bug. If you can provide a complete (compilable) module source that reproduces the warning, we can check.
 

Code:
`ifndef INTERFACES
  `define INTERFACES

interface master_if #(N=4);
  logic req[N], ack[N], cmd[N], resp[N];
  logic [31:0] addr[N];
  logic [15:0] wdata[N];
  logic [15:0] rdata[N];

  modport crossbar(input req, cmd, addr, wdata,
		   output ack, resp, rdata);

  modport tb (input ack, resp, rdata,
	      output req, cmd, addr, wdata);
endinterface // master_if

interface slave_if #(N=4);
  logic 	     req[N], ack[N], cmd[N], resp[N];
  logic [31-$clog2(N):0] addr[N];
  logic [15:0] 		 wdata[N];
  logic [15:0] 		 rdata[N];

  modport crossbar (input ack, resp, rdata,
		    output req, cmd, addr, wdata);

  modport tb(input req, cmd, addr, wdata,
	     output ack, resp, rdata);

endinterface // slave_if

`endif
Code:
`include "interfaces.sv"

module crossbar
  #(MASTERS=4, SLAVES=4)
  (
   master_if.crossbar mif,
   slave_if.crossbar sif,
   input logic clk, rst
   );
  
  typedef struct {
    logic 	 tx_valid;
    logic [31-$clog2(SLAVES):0] addr;
    logic [15:0] 		data;
    logic 			cmd; // 0-read, 1-write
  } tx_type;

  // transaction cells
  tx_type tx_queue[SLAVES][MASTERS]; // [dst][src]

  enum logic[1:0] {READY, WAIT_ACK, WAIT_RESP} sif_state[SLAVES];

  // current transaction pointer for each slave
  logic [$clog2(MASTERS)-1:0] 	rr_cnt[SLAVES], rr_copy[SLAVES];

  // tx validity for +1, +2, +3 steps for each slave
  // is used to optimize (ex-)combinatorial-heavy update_rr()
  logic 			next_tx_valid[SLAVES][1:3];
  
  // set round-robin to next non-empty transaction
  function logic [$clog2(MASTERS)-1:0] update_rr (input int i); 
    priority case (1'b1)
      next_tx_valid[i][1]: return rr_copy[i]+2'(1);
      next_tx_valid[i][2]: return rr_copy[i]+2'(2);
      next_tx_valid[i][3]: return rr_copy[i]+2'(3);
      default: return rr_copy[i];
    endcase // priority case (1'b1)
  endfunction
  
  // table of slave responses for priority mux
  struct 			{
    logic 			ack, resp;
    logic [15:0] 		rdata;
  } try[MASTERS][SLAVES];
  

  
  always_ff @(posedge clk) begin


    
    if (rst) begin
      for (int i=0; i<SLAVES; i++) rr_cnt[i] <= 0;

      for (int i=0; i<SLAVES; i++)
	for (int j=0; j<MASTERS; j++) tx_queue[i][j].tx_valid <= 0;

      for (int i=0; i<MASTERS; i++)
	for (int j=0; j<SLAVES; j++) begin
	  try[i][j].ack <= 0;
	  try[i][j].resp <= 0;
	end
      
      for (int i=0; i<MASTERS; i++) begin
	mif.ack[i] <= 0;
	mif.resp[i] <= 0;
	mif.rdata[i] <= 0;
      end
      
      for (int i=0; i<SLAVES; i++) begin
	sif_state[i] <= READY;
	sif.req[i] <= 0;
	sif.cmd[i] <= 0;
	sif.addr[i] <= 0;
	sif.wdata[i] <= 0;
      end
    end // if (rst)

    
    
    else begin
      

      
      for (int i=0; i<MASTERS; i++) begin // store master requests
	
	logic [$clog2(SLAVES)-1:0] slave_addr;
	automatic logic 			   slave_q_has_txs = 0;
	slave_addr = mif.addr[i][31:31-$clog2(SLAVES)+1];
	
	// if master requests, we check that corresponding master-to-slave
	// transaction cell is empty and push the transaction, else ignore it
	if (mif.req[i] && !(tx_queue[slave_addr][i].tx_valid)) begin
	  tx_queue[slave_addr][i] <= '{tx_valid : 1'b1,
				       data : mif.wdata[i],
				       cmd : mif.cmd[i],
				       addr : mif.addr[i][31-$clog2(SLAVES):0]};

	  // set rr_cnt if no transactions in queue for current slave
	  for (int j=0; j<MASTERS; j++)
	    slave_q_has_txs |= tx_queue[slave_addr][j].tx_valid;
	  if (!slave_q_has_txs) rr_cnt[slave_addr] <= i;
	  
	end // if (mif.req[i] && !(tx_queue[slave_addr][i].tx_valid))
      end // for (int i=0; i<MASTERS; i++)

      

      for (int i=0; i<SLAVES; i++) begin // slave operations
	// defaults
	sif.req[i] <= 0;
	for (int j=0; j<MASTERS; j++) begin
	  try[j][i].ack <= 0;
	  try[j][i].resp <= 0;
	  try[j][i].rdata <= 0;
	end
	
	unique case (sif_state[i]) // slave FSMs
	  READY: begin
	    tx_type tx;
	    tx = tx_queue[i][rr_cnt[i]];
	    
	    if (tx.tx_valid) begin // transaction pull
 	      sif.req[i] <= 1'b1;
	      sif.cmd[i] <= tx.cmd;
	      sif.addr[i] <= tx.addr;
	      if (tx.cmd) sif.wdata[i] <= tx.data; // write
	      sif_state[i] <= WAIT_ACK;
	      
	      tx_queue[i][rr_cnt[i]].tx_valid <= 0; // erase transaction
	      
	      // save copy of transaction pointer in case rr_cnt gets
	      // overwritten in transaction push phase
	      rr_copy[i] <= rr_cnt[i];

	      for (int j=1; j<=3; j++) // see next_tx_valid declaration
		next_tx_valid[i][j] <= tx_queue[i][rr_cnt[i]+j].tx_valid;
	      
	    end // if (tx.tx_valid)
	  end // case: READY
	  
	  WAIT_ACK: begin
	    if (sif.ack[i]) begin
	      try[rr_copy[i]][i].ack <= 1'b1;
	      
	      // if write, then we are done, if read, wait for response
	      if (tx_queue[i][rr_copy[i]].cmd) begin
		sif_state[i] <= READY;
		rr_cnt[i] <= update_rr(i);
	      end
	      else sif_state[i] <= WAIT_RESP;
	    end // if (sif.ack[i])

	  end // case: WAIT_ACK
	  
	  WAIT_RESP: begin
	    if (sif.resp[i]) begin
	      try[rr_copy[i]][i].resp <= 1'b1;
	      try[rr_copy[i]][i].rdata <= sif.rdata[i];
	      sif_state[i] <= READY;
	      rr_cnt[i] <= update_rr(i);
	    end // if (sif.resp[i])
	    
	  end // case: WAIT_RESP
	  
	endcase // unique case (sif_state[i])	
      end // for (int i=0; i<SLAVES; i++)


      
      for (int i=0; i<MASTERS; i++) begin // drive slave responses to masters
	// defaults
	mif.ack[i] <= 0;
	mif.resp[i] <= 0;

	for (int j=0; j<SLAVES; j++)
	  if (try[i][j].ack) mif.ack[i] <= 1'b1;

	for (int j=0; j<SLAVES; j++)
	  if (try[i][j].resp) begin
	    mif.resp[i] <= 1'b1;
	    mif.rdata[i] <= try[i][j].rdata;
	    break; // if more than 1 simultaneous resp, first one is passed
	  end
	
      end // foreach (mif.ack[i])

      
      
    end // else: !if(rst)
    
  end // always_ff @ (posedge clk)
  
endmodule
 

nothing in that shows next_tx_valid being used.

Maybe something is using the hierarchical access outside of this module. I don't know if that is supported for synthesis.

Is it possible you are looking at old implementation results?
 

next_tx_valid is being used in function update_rr, which is called from WAIT_ACK and WAIT_RESP states.

I re-ran map and fit a few times, and warning still appears, and next_tx_valid is still on the final netlist. And this is the only module.
 

It is possible this is a tool error, although it is odd. I'm wondering if you would get the same warning if you switched to a task. Not so much because of logic, but because the tools might treat task differently internally.

Also, I just looked at Verilog's forward referencing scope rules. Just when I thought Verilog had too many dangerous features I manage to find one more.
 

At first sight, the warning is erroneous. Could you verify the intended module operation?
 

I'll post here again as soon as I finish the testbench and run a few tests.
 

Update: I tested the design, fixed a bunch of bugs (a couple of them related to next_tx_valid), but the warning still persists.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top