Signal is assigned but never used. This unconnected signal will be trimmed

4.1k views Asked by At

To start with - I have three dimensional reg, assigned only in initial begin.

reg [4:0] PS[0:9];

PS[0] = 24; PS[1] = 10; PS[2] = 8; PS[3] = 8; PS[4] = 17;
PS[5] = 16; PS[6] = 4; PS[7] = 4; PS[8] = 16; PS[9] = 16;

At first i was trying to access bit like this (pc is my program counter):

if(PS[pc][4] == 0) Z1 <= 0;
else Z1 <= 1;

But optimization have been trimming my signals. Later I've found out that i need new reg to keep whole reg, then i can access bits. So I made this:

reg [4:0] tempPS;

[...]

tempPS = PS[pc];
Z1 <= tempPS[4];

My signals stopped to be trimmed, but now optimization wants to trim tempPS because:

Signal is assigned but never used. This unconnected signal will be trimmed during the optimization process.

Well - as pc is changing, tempPS is used, I don't know what exactly this error means, how can I fix it. Any help appreciated.

1

There are 1 answers

11
mcleod_ideafix On BEST ANSWER

"Signal is assigned but never used" means that in your design there is a variable which receives a value, that is, there is a write access to the flip flops of that variable, but the value it receives is never used in any other part of the design. That is, there's no read access to that flip flop.

So you have to check whether yout tempPS register is used as a RHS in a Verilog expression, or their pins are outputted to the TLD ports of your design.

In your design, the only part of tempPS that is both assigned and read is tempPS[4]. The rest of the bits of that register are never read so it's pontless to store a value in them (nobody will read them!).

And like a chain reaction, if values stored in PS memory are transfered only to tempPS, and the only part of tempPS that is actually used is tempPS[4], that means that the only part of PS that will be actually used is bit 4 of all 10 values, so expect the synthetizer to trim PS[0], PS[1] and PS[2] of all 10 values of PS as well.


In other words:

  • If a reg is read from (used on the right side of a expression, or connected to an output port which in turn is connected to somwhere else) but is not written to, that reg will be converted to a constant with value equal to the one that was initialized to in an initial block. Electronically, a constant is a signal with bits tied to VCC or GND to implement 1 or 0.

  • If a reg is written from (used on the left side of a expression, or connected to an input port which in turn is connected to somewhere else) but is not read from, that reg will be trimmed. The logic behind this decission is: "if nobody cares about what my value is, it doesn't matter if I exist or not"

Trimming occurs in cascade: if you have a code like this:

reg r0=0,r1=0,r2=0,r3=0;
always @(posedge clk) begin
  r1 <= r0;
  r2 <= r1;
  r3 <= r2;
end

Then:

  • r0 will be converted to a constant, because it is not written to, but it seems that it is read from (first non blocking assignment)

  • Both r1 and r2 seem to be read from and written to, so the synthetizer should preserve them, but...

  • Here comes r3: it is written to, but nobody reads its value, so the synthetizer trimes it. As a consequence of this, the third assignment (r3 <= r2) is deleted, and hence, r2 is no longer used in the RHS of a expression (i.e. nobody reads its value), so it is trimmed too. Because of that, the second assigment (r2 <= r1) is deleted. Once again, r1 is no longer read from so it is trimmed, making the first assignment (r1 <=r0) useless, thus causing r0 to no to be read from, and hence, trimmed too. So our always block contains no code, so the synthetizer deletes it, leaving a completely empty circuit as result .