0
votes

Verilog case statmenet expression is always true

module test(input clk,
input reset,
output reg[3:0] ledss

);

reg[31:0] dataread;

always @(posedge clk)
begin

case(dataread)

    32'b1010101010101010101:ledss='b1010;

endcase


 end
endmodule

dont understand why this line executed

32'b1010101010101010101:ledss='b1010;

leds is on same pattern 1010

also after executing this code , leds not on

module test(input clk,
input reset,
output reg[3:0] ledss

);

reg[31:0] dataread;

always @(posedge clk)
begin


    if(dataread==32'b1010101010101010101)   ledss='b1010;




 end
endmodule

but if i execute this,leds is on ,pattern 1010

module test(input clk,
input reset,
output reg[3:0] ledss

);

reg[31:0] dataread;

always @(posedge clk)
begin

case(dataread)

    32'b101010101010:
    begin
    if(dataread==32'b101010101010)  ledss='b1010;
    end
endcase



 end
endmodule

dont understand how case statement works in verilog

1
What I can see is that you have not given dataread any value so it will be all XXX-es. Read up on the Verilog rules for case and if when the data is not ones or zeros. - Oldfart
@Oldfart Thanks for answer,yes you are right but why third code on leds? if(dataread==32'b101010101010) ledss='b1010; does this rule works for if statement too? and if it is,why this rule not work for second code? - misha
1. What exactly are you trying to achieve? Your code seems to be more complicated that it could be. 2. You should use non-blocking assignments in always block. 3. Be aware that your comparison (last piece of code) leads to 1-bit uknown value. Thus, most tools will consider it false. In tool that I am using leds won't be ON. - Qiu
@Qiu I want to read from 1 port ram ip. Same result after adding if statement. Ram for testing filled with 1s. Still not understand why leds on. code pastebin.com/8snsegVx - misha
I think it is hardware isue or compilator bug,cant explain why this happend. leds is on pattern 1010 even after executing this pastebin.com/VL1FuiZD - misha

1 Answers

0
votes

I believe you are skipping Verilog simulation and loading your code directly to FPGA.

In simulation. ledss would be X until the patter match is satisfied (both case or if). In the provided code dataread is never assigned so it will be X, therefore in simulation ledss will always be X. In your pastebin links you have dataread driven by a ROM output, so it will have a know output that might match the checking condition.

FPGA synthesizes your RTL and typically goes through some optimization. ledss is not explicitly initialized and has only one possible value if ever assigned. Because of this the optimizer might assume the initial value is don't care, then simplify logic by choosing the initial value to be the same as the only possible value it can be assigned to. Or it might assume the initial value is 0 and keep the logic. For this scenario in general, case tends the follow the former and if tends to follow the latter. Though your code is functionally equivalent, it is uncommon to have a case-statement with only one condition.

I suggest you improve your coding style so your intended behavior is more explicitly understood by the synthesizer and anyone reading your code. Bellow are some suggestions. Remember to assign dataread to a known value. (Note: replaced 32'b1010101010101010101 with the equivalent 32'h0005_5555 for human readability)

always @(posedge clk)
begin
  case(dataread)
    32'h0005_5555 : ledss <= 4'b1010;
    default : ledss <= 4'b1111;
  endcase
end

Or equivalent:

always @(posedge clk)
begin
  if (dataread == 32'h0005_5555)
    ledss <= 4'b1010;
  else
    ledss <= 4'b1111;
end

If you want ledss to keep the 1010 patter after assignment, then you could do:

always @(posedge clk)
begin
  if (reset) begin
    ledss <= 4'b1111;
  end
  case(dataread)
    32'h0005_5555 : ledss <= 4'b1010;
  endcase
end

Or equivalent:

always @(posedge clk)
begin
  if (reset) begin
    ledss <= 4'b1111;
  end
  else if (dataread == 32'h0005_5555) begin
    ledss <= 4'b1010;
  end
end