Using case statement and if-else at the same time?

I am trying to write Verilog HDL behavioral description of the machine specified in the state diagram below.

enter image description here

I am using if-else statements inside a case statement, and this gives me syntax errors regarding those lines. Do you see what the problem is?

My code is attached below:

module foo(y_out, state, x_in, clk, reset); input x_in, clk, reset; output reg y_out; parameter s0 = 3'b000, s1 = 3'b001, s2 = 3'b010, s3 = 3'b011, s4 = 3'b100; output reg[2:0] state; reg[2:0] next_state; always @(posedge clk) begin if(reset == 1'b0) state <= s0; else state <= next_state; end always @(state, x_in) begin y_out = 0; next_state = s0; case(state, x_in) s0: if (!x_in) begin next_state = s3; y_out = 1'b0; end else begin next_state = s4; y_out =1'b1; end s1: if (!x_in) begin next_state = s1; y_out = 1'b0; end else begin next_state = s4; y_out =1'b1; end s2: if (!x_in) begin next_state = s2; y_out = 1'b0; end else begin next_state = s0; y_out =1'b1; end s3: if (!x_in) begin next_state = s1; y_out = 1'b0; end else begin next_state = s2; y_out =1'b1; end s4: if (!x_in) begin next_state = s2; y_out = 1'b0; end else begin next_state = s3; y_out =1'b0; end default begin next_state = s0; y_out = 1'b0; end endcase end
endmodule
module t_foo; wire t_y_out, t_state; reg t_x_in, t_clock, t_reset; foo M1(t_y_out, t_state, t_x_in, t_clock, t_reset); initial #200 $finish; initial begin t_reset = 0; t_clock = 0; #5 t_reset = 1; repeat (16) #5 t_clock = ~t_clock; end initial begin t_x_in = 0; #15 t_x_in = 1; repeat (8) #10 t_x_in = ~t_x_in; end initial begin $monitor("ABC: %d, x_in: %d, Clock: %d, Reset: %d", state, t_x_in, t_clock, t_reset); $dumpfile("5_41_wv.vcd"); $dumpvars; end
endmodule
0

3 Answers

case statements expect a single item if this is to be based on multiple wire/regs then they need to be concatenated using {}.

I would avoid using things like always @(state, x_in) begin and just write always @* begin. The @* will take care of the sensitivity list.

Using the concatenation operator would allow you to remove the if statements:

 always @* begin y_out = 0; next_state = s0; case({state, x_in}) //Added {} {s0, 1'b0}: begin next_state = s3; y_out = 1'b0; end {s0, 1'b1}: begin next_state = s4; y_out = 1'b1; end {s1, 1'b0}: begin next_state = s1; y_out = 1'b0; end {s1, 1'b1}: begin next_state = s4; y_out = 1'b1; end

Using a casez would allow you to add do not cares to the next_state logic:

 always @* begin y_out = 0; next_state = s0; casez({state, x_in}) //Added {} {s0, 1'bx}: //Do not care about the state of x_in begin next_state = s3; y_out = 1'b0; end {s1, 1'b0}: begin next_state = s1; y_out = 1'b0; end {s1, 1'b1}: begin next_state = s4; y_out = 1'b1; end
1

Change:

case(state, x_in)

to:

case(state)

That fixes a compile error for me. The case items in your code only depend on your state parameters, not x_in.

I also get a compile error in your testbench module. To fix it, change:

 $monitor("ABC: %d, x_in: %d, Clock: %d, Reset: %d", state, t_x_in, t_clock, t_reset);

to:

 $monitor("ABC: %d, x_in: %d, Clock: %d, Reset: %d", t_state, t_x_in, t_clock, t_reset);

And fix a warning by changing:

wire t_y_out, t_state;

to:

wire t_y_out;
wire [2:0] t_state;

Using state in case expression and xin in if condition is working fine. Please find below working code.

module fsm_state( input clk, input rst_n, input xin, output reg yout ); reg [2:0] state; reg [2:0] next_state; parameter s0 = 3'b000, s1 = 3'b001, s2 = 3'b010, s3 = 3'b011, s4 = 3'b100; always @ (posedge clk) begin if (!rst_n) state = s0; else state = next_state; end always @* begin yout = 1'b0; case (state) s0: begin if (xin) begin yout = 1'b1; next_state = s4; end else next_state = s3; end s1: begin if (xin) begin yout = 1'b1; next_state = s4; end else next_state = s1; end s2: begin if (xin) begin yout = 1'b1; next_state = s0; end else next_state = s2; end s3: begin if (xin) begin yout = 1'b1; next_state = s2; end else next_state = s1; end s4: begin if (xin) next_state = s3; else next_state = s2; end endcase end
endmodule

Thanks

1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like