I am trying to write Verilog HDL behavioral description of the machine specified in the state diagram below.
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
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
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
Related
This question already has answers here:
Difference between #(posedge Clk); a<= 1'b1; and #(posedge Clk) a<= 1'b1;
(2 answers)
Closed last month.
My friend wrote an FSM code that generates 3 numbers (1,4,1) in binary.
The code works and compiles in modelsim.
I wrote a testbench for it so I can simulate it.
The testbench code errors in line 24 and says this:
** Error: (vlog-13069) C:/Users/******/*****/fsm/fsm_tb.v(24): near "end": syntax error, unexpected end.
Which indicates that end is unexpected after the previous line #10. So maybe there is a semicolon missing, but I don't have semicolons in the other lines #10 either, so I do not understand the problem.
This is the actual FSM code
module fsm_detector (
input wire clk,
input wire in,
output wire out
);
parameter s0 = 0, s1 = 1, s2 = 2, s3 = 3, s4 = 4, s5 = 5, s6 = 6, s7 = 7, s8 = 8, s9 = 9, s10 = 10;
reg [3:0] state, next_state;
always #(posedge clk) begin
state <= next_state;
end
always #* begin
case (state)
s0: begin
if (in == 1'b0) next_state = s1;
else next_state = s0;
end
s1: begin
if (in == 1'b0) next_state = s2;
else next_state = s0;
end
s2: begin
if (in == 1'b0) next_state = s3;
else next_state = s0;
end
s3: begin
if (in == 1'b1) next_state = s4;
else next_state = s0;
end
s4: begin
if (in == 1'b0) next_state = s5;
else next_state = s0;
end
s5: begin
if (in == 1'b1) next_state = s6;
else next_state = s0;
end
s6: begin
if (in == 1'b0) next_state = s7;
else next_state = s0;
end
s7: begin
if (in == 1'b0) next_state = s8;
else next_state = s0;
end
s8: begin
if (in == 1'b0) next_state = s9;
else next_state = s0;
end
s9: begin
if (in == 1'b0) next_state = s10;
else next_state = s0;
end
s10: begin
if (in == 1'b1) next_state = s0;
else next_state = s0;
end
endcase
end
assign out = (state == s10);
endmodule
This is the test bench I wrote:
`timescale 1ns / 1ps
module fsm_detector_tb;
reg clk;
reg in;
wire out;
fsm_detector dut (
.clk(clk),
.in(in),
.out(out)
);
// Initialize input and output signals
initial begin
clk = 0;
in = 0;
#10
clk = 1;
#10
clk = 0;
#10
end
// Stimulus for detecting "000101000001" sequence
initial begin
#20 in = 1'b0;
#20 in = 1'b0;
#20 in = 1'b0;
#20 in = 1'b1;
#20 in = 1'b0;
#20 in = 1'b1;
#20 in = 1'b0;
#20 in = 1'b0;
#20 in = 1'b0;
#20 in = 1'b0;
#20 in = 1'b0;
#20 in = 1'b1;
end
endmodule
How can I fix this?
The problem is in this testbench initial block:
initial begin
clk = 0;
in = 0;
#10
clk = 1;
#10
clk = 0;
#10
end
The fix is to add a semicolon after the last #10:
initial begin
clk = 0;
in = 0;
#10
clk = 1;
#10
clk = 0;
#10;
end
All statements must end with a semicolon. What is tricky about your code is that the 1st 2 times you use #10, you don't need the semicolon.
The compiler parsers the code like:
initial begin
clk = 0;
in = 0;
#10 clk = 1;
#10 clk = 0;
#10
end
The #10 clk = 1; is the complete statement.
Also, you could use a semicolon after all 3 #10:
initial begin
clk = 0;
in = 0;
#10;
clk = 1;
#10;
clk = 0;
#10;
end
module FiniteStateMachine(output reg [2:0] Count, input clock, reset);
reg[2:0] state, next_state;
parameter S0 = 3'b000, S1 = 3'b001, S2 = 3'b010, S3 = 3'b011, S4 = 3'b100, S5 = 3'b101, S6 = 3'b110, S7 = 3'b111;
always # (posedge clock, negedge reset)
if(reset==0) state<=S0;
else state <= next_state;
always # (state)
case(state)
S0: begin
Count = S0;
next_state = S1;
end
S1: begin
Count = S1;
next_state = S2;
end
S2: begin
Count = S3;
next_state = S3;
end
S3: begin
Count = S7;
next_state = S4:
end
S4: begin
Count = S6;
next_state = S5;
end
S5: begin
Count = S4;
next_state = S0;
end
endcase
endmodule
Getting the error:
Syntax in assignment statement l-value
I've also tried "<=" instead of "=" for all the assignments in case, but I'm getting the same error.
You used a colon instead of a semicolon. Change:
next_state = S4:
to:
next_state = S4;
I am new to veriloghdl and I am getting this error in verilog hdl
Error (10170): Verilog HDL syntax error at TrafficLight.v(59) near text "endcase"; expecting "end"
Can anyone tell me what is wrong?
my code is
module TrafficLight(t, state, next_state, clk, out);
input t, clk;
output out;
localparam s0=3'b000, s1=3'b001, s2=3'b010, s3=3'b011, s4=3'b100, s5=3'b101;
reg[2:0] state, next_state, tt;
always#(posedge clk)
begin
case(state)
3'b000:
if(tt < 5)
next_state = s0;
else
begin
next_state = s1;
assign out [5:0] = 6'b100001;
end
3'b001:
if(tt < 1)
next_state = s1;
else
begin
next_state = s2;
assign out [5:0] = 6'b010001;
end
3'b010:
if(tt < 1)
next_state = s2;
else
begin
next_state = s3;
assign out [5:0] = 6'b001001;
end
3'b011:
if(tt < 5)
next_state = s3;
else
begin
next_state = s4;
assign out [5:0] = 6'b001100;
end
3'b100:
if(tt < 1)
next_state = s4;
else
begin
next_state = s5;
assign out [5:0] = 6'b001010;
end
3'b101:
if(tt < 1)
next_state = s0;
else
begin
next_state = s5;
assign out [5:0] = 6'b001001;
end
endcase
always#(posedge clk);
begin
state = next_state;
tt = tt - 1;
end
endmodule
The error occured I think on the lines endcase and endmodule. I think I would have to close them with something.
There are a couple of errors in your code -
You missed the "end" after the "endcase" statement. The end is required for the begin block just before the case statement.
You have added ";" in the always block declaration.
always#(posedge clk);
begin
state = next_state;
tt = tt - 1;
end
There is no need of an ";" in the always block.
module TrafficLight(t, state, next_state, clk, out);
input t, clk;
output out;
localparam s0=3'b000, s1=3'b001, s2=3'b010, s3=3'b011, s4=3'b100, s5=3'b101;
reg[2:0] state, next_state, tt;
In the above snippet I see that you have added "state" and "next_state" as ports to the module but haven't assigned any direction to them. Either remove them as ports or make them as "input" or "output".
You would also need to remove the "assign" statement when driving the out reg. Since it is inside a procedural block you don't need an "assign" here.
You can find all the updates to your code here
verilog error while I try to implement a traffic light system with six states I wanted to display lights red, green, yellow on the led display of ALTERA DE2 board
code is as below
module TrafficLight(clk, t, out);
input clk, t;
output out;
localparam s0=3'b000, s1=3'b001, s2=3'b010, s3=3'b011, s4=3'b100, s5=3'b101;
reg[2:0] state, next_state, t;
always#(posedge clk)
begin
state = next_state;
t = t - 1;
end
always#(t or state)
begin
case(state)
3'b000:
if(t < 5)
next_state = s0;
else
begin
next_state = s1;
assign out [5:0] = 6'b100001;
end
3'b001:
if(t < 1)
next_state = s1;
else
begin
next_state = s2;
assign out [5:0] = 6'b010001;
end
3'b010:
if(t < 1)
next_state = s2;
else
begin
next_state = s3;
assign out [5:0] = 6'b001001;
end
3'b011:
if(t < 5)
next_state = s3;
else
begin
next_state = s4;
assign out [5:0] = 6'b001100;
end
3'b100:
if(t < 1)
next_state = s4;
else
begin
next_state = s5;
assign out [5:0] = 6'b001010;
end
3'b101:
if(t < 1)
next_state = s0;
else
begin
next_state = s5;
assign out [5:0] = 6'b001001;
end
endcase
end
endmodule
What is wrong with this code can anyone fix it?
In Verilog an input cannot be a reg, as the error message says. Don't declare t as a reg by changing this line:
reg[2:0] state, next_state, t;
to this:
reg[2:0] state, next_state;
I am trying to design a fsm for showing rotational which runs the 4-digit 7-segment LED display unit, to cause a rotating pattern of circulating squares in clockwise or counterclockwise. I am trying to fix the syntax errors in my case block but I am in verilog coding and I cannot find my mistake. Here is the code:
module fsm( EN, CW, clk, AN1,AN2,AN3,AN4, leds );
//inputs and outputs
input EN, CW, clk;
output AN1,AN2,AN3,AN4;
output reg leds[6:0];
//state register and parameters
reg state[3:0];
parameter s0 = 3'b000;
parameter s1 = 3'b001;
parameter s2 = 3'b010;
parameter s3 = 3'b011;
parameter s4 = 3'b100;
parameter s5 = 3'b101;
parameter s6 = 3'b110;
parameter s7 = 3'b111;
//states and outputs according to the states
always # (posedge clk)
begin
if (EN == 1)
begin
case(state)
s0: leds<=7'b1100011; if(CW)begin state <= s1; end else begin state <= s7; end
s1: leds<=7'b1100011; if(CW)begin state <= s2; end else begin state <= s0; end
s2: leds<=7'b1100011; if(CW)begin state <= s3; end else begin state <= s1; end
s3: leds<=7'b1100011; if(CW)begin state <= s4; end else begin state <= s2; end
s4: leds<=7'b1011100; if(CW)begin state <= s5; end else begin state <= s3; end
s5: leds<=7'b1011100; if(CW)begin state <= s6; end else begin state <= s4; end
s6: leds<=7'b1011100; if(CW)begin state <= s7; end else begin state <= s5; end
s7: leds<=7'b1011100; if(CW)begin state <= s0; end else begin state <= s6; end
endcase
end
end
//output logic
assign AN1 = ~((state == s0) | (state == s7));
assign AN2 = ~((state == s1) | (state == s6));
assign AN3 = ~((state == s2) | (state == s5));
assign AN4 = ~((state == s3) | (state == s4));
endmodule
A few things.
You should declare your vector signals like this:
output reg [6:0] leds;
//state register and parameters
reg [3:0] state;
And, you need to wrap each case item with a begin/end. I also spread the statements across a few lines, which might make it more readable:
s0: begin
leds <= 7'b1100011;
if (CW) begin
state <= s1;
end else begin
state <= s7;
end
end
Or, you could replace the if/else with a ternary:
s0: begin
leds <= 7'b1100011;
state <= (CW) ? s1 : s7;
end