Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
13 years ago

coding style: about Inferred latch for xxx at x.v

I use a ping-pong buffer which has 32 bytes length to cache incoming command, and each command length is 16 bytes.

The frequency of command shift in is faster than core frequency, due to serial transfer requirement.

The core takes WEIGHT_WEN with 1/8 frequency of each command byte ready.

and the command is 16 bytes long, that makes at least two or more times of execution of the ready command at opposite side, and that's fine.

It works very well on DE0 FPGA.

But, I still need to figure out what cased this and how to clean this msg.

I have tried my best to fill up all if else condition, but the msg still there.

Latch is not my design, and it leads to lower coverage when we use scan chain at digital tape-out flow.

any ideas? thanks for your help :)

Currently, I have set dont use all latch cell in synopsys DC, but I don't know if this will cause function mismatch prob.

Info (10041): Inferred latch for "WEIGHT_WEN[0]" at CHIP.v(528)

Info (10041): Inferred latch for "WEIGHT_WEN[1]" at CHIP.v(528)

Info (10041): Inferred latch for "WEIGHT_WEN[2]" at CHIP.v(528)

Info (10041): Inferred latch for "WEIGHT_WEN[3]" at CHIP.v(528)

Info (10041): Inferred latch for "WEIGHT_WEN[4]" at CHIP.v(528)

Info (10041): Inferred latch for "WEIGHT_WEN[5]" at CHIP.v(528)

Info (10041): Inferred latch for "WEIGHT_WEN[6]" at CHIP.v(528)

Info (10041): Inferred latch for "WEIGHT_WEN[7]" at CHIP.v(528)

Info (10041): Inferred latch for "WEIGHT_WEN[8]" at CHIP.v(528)

Info (10041): Inferred latch for "WEIGHT_WEN[9]" at CHIP.v(528)

Info (10041): Inferred latch for "WEIGHT_WEN[10]" at CHIP.v(528)

Info (10041): Inferred latch for "WEIGHT_WEN[11]" at CHIP.v(528)

--- Quote Start ---

reg [7:0] RX_CMD [0:31]; // for two command

reg [4:0] RX_CMD_COUNTER; // for two command

always@(posedge FAST_CLK)

if(RxD_data_ready)

RX_READY_COUNTER<=RX_READY_COUNTER+1;

always @ (*) begin

if(CMD_TYPE==6'b0000_01 && CMD_W!=0) begin //weight PAT

if(CMD_W==2'b01) begin //W2

if(RX_CMD[{~RX_CMD_COUNTER[4],4'b0001}][6:5]==2'b00) begin //bank 0

WEIGHT_WEN=12'b1110_1111_1111;

end else if(RX_CMD[{~RX_CMD_COUNTER[4],4'b0001}][6:5]==2'b01) begin //bank 1

WEIGHT_WEN=12'b1101_1111_1111;

end else if(RX_CMD[{~RX_CMD_COUNTER[4],4'b0001}][6:5]==2'b10) begin //bank 2

WEIGHT_WEN=12'b1011_1111_1111;

end else if(RX_CMD[{~RX_CMD_COUNTER[4],4'b0001}][6:5]==2'b11) begin //bank 3

WEIGHT_WEN=12'b0111_1111_1111;

end

end else if(CMD_W==2'b10) begin //W3

if(RX_CMD[{~RX_CMD_COUNTER[4],4'b0001}][6:5]==2'b00) begin //bank 0

WEIGHT_WEN=12'b1111_1110_1111;

end else if(RX_CMD[{~RX_CMD_COUNTER[4],4'b0001}][6:5]==2'b01) begin //bank 1

WEIGHT_WEN=12'b1111_1101_1111;

end else if(RX_CMD[{~RX_CMD_COUNTER[4],4'b0001}][6:5]==2'b10) begin //bank 2

WEIGHT_WEN=12'b1111_1011_1111;

end else if(RX_CMD[{~RX_CMD_COUNTER[4],4'b0001}][6:5]==2'b11) begin //bank 3

WEIGHT_WEN=12'b1111_0111_1111;

end

end else if(CMD_W==2'b11) begin //W4

if(RX_CMD[{~RX_CMD_COUNTER[4],4'b0001}][6:5]==2'b00) begin //bank 0

WEIGHT_WEN=12'b1111_1111_1110;

end else if(RX_CMD[{~RX_CMD_COUNTER[4],4'b0001}][6:5]==2'b01) begin //bank 1

WEIGHT_WEN=12'b1111_1111_1101;

end else if(RX_CMD[{~RX_CMD_COUNTER[4],4'b0001}][6:5]==2'b10) begin //bank 2

WEIGHT_WEN=12'b1111_1111_1011;

end else if(RX_CMD[{~RX_CMD_COUNTER[4],4'b0001}][6:5]==2'b11) begin //bank 3

WEIGHT_WEN=12'b1111_1111_0111;

end

end else if(CMD_W==2'b00) begin //00

WEIGHT_WEN=12'b1111_1111_1111;

end

end else

WEIGHT_WEN=12'b1111_1111_1111;

end

--- Quote End ---

2 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    In some situations a latch can involve safe behaviour, e..g. an address latch that is enabled by a single ALE signal. In your code, safe behaviour seems rather questionable, or in other words accidental. Because the individual enable conditions are a combination of bits, there's a high likelyhood that some output bits will flip into a different code due to delay skew of input signals.

    Save behaviour may be possibly achieved if CMD_TYPE is acting as a global select, deasserted before any other input term is changing. The fact, that safe behaviour of similar latch constructs can't be easily determined and rarely proved is reason enough to get the said warnings in Quartus, I think. If you are sure about the behaviour of your latch, just ignore it.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks, I have rewrite my code to assign statement, and there is no more latch now.

    --- Quote Start ---

    assign WEIGHT_WEN[0] = ~((CMD_TYPE==6'b0000_01 && CMD_W!=0) && (CMD_W==2'b11) && (RX_CMD[{~RX_CMD_COUNTER[4],4'b0001}][6:5]==2'b00));

    assign WEIGHT_WEN[1] = ~((CMD_TYPE==6'b0000_01 && CMD_W!=0) && (CMD_W==2'b11) && (RX_CMD[{~RX_CMD_COUNTER[4],4'b0001}][6:5]==2'b01));

    assign WEIGHT_WEN[2] = ~((CMD_TYPE==6'b0000_01 && CMD_W!=0) && (CMD_W==2'b11) && (RX_CMD[{~RX_CMD_COUNTER[4],4'b0001}][6:5]==2'b10));

    assign WEIGHT_WEN[3] = ~((CMD_TYPE==6'b0000_01 && CMD_W!=0) && (CMD_W==2'b11) && (RX_CMD[{~RX_CMD_COUNTER[4],4'b0001}][6:5]==2'b11));

    --- Quote End ---