hdl verilog Compiler Errors - verilog

When I first tried to compile my code, I only had syntax errors and was able to fix them. Now I have errors that I cannot figure out at all. I don't know how to fix.
Here is my current code:
module p_5 (output y_out, input x_in, clk, reset_b);
parameter s_a = 2'd0;
parameter s_b = 2'd1;
parameter s_c = 2'd2;
reg Set_flag;
reg Clr_flag;
reg [1:0] state, next_state;
assign y_out = (state == s_b) || (state == s_c) ;
always # (posedge clk)
if (reset_b == 1'b0) state <= s_a;
else state <= next_state;
always # (state, x_in, flag) begin
next_state = s_a;
Set_flag = 0;
Clr_flag = 0;
case (state)
s_a: if ((x_in == 1'b1) && (flag == 1'b0))
begin next_state = s_a; Set_flag = 1; end
else if ((x_in == 1'b1) && (flag == 1'b1))
begin next_state = s_b; Set_flag = 0; end
else if (x_in == 1'b0) next_state = s_a;
s_b: if (x_in == 1'b0) next_state = s_b;
else begin next_state = s_c; Clr_flag = 1; end
s_c: if (x_in == 1'b0) next_state = s_c;
else next_state = s_a;
default: begin next_state = s_a; Clr_flag = 1'b0; Set_flag = 1'b0; end
endcase
end
always # (posedge clk)
if (reset_b == 1'b0) flag <= 0;
else if (Set_flag) flag <= 1'b1;
else if (Clr_flag) flag <= 1'b0;
endmodule
This is the test bench:
module test_5 ();
wire y_out;
reg x_in, clk, flag, reset_b;
p_5 M0 (y_out, x_in, clk, reset_b);
initial #500 $finish;
initial begin clk = 0; forever #5 clk = !clk; end
initial fork
reset_b = 1'b0;
#20 reset_b = 1;
#20 x_in = 1'b0;
#40 x_in = 1'b1;
#50 x_in = 1'b0;
#80 x_in = 1'b1;
#100 x_in = 0;
#150 x_in = 1'b1;
#160 x_in = 1'b0;
#200 x_in = 1'b1;
#230 reset_b = 1'b0;
#250 reset_b = 1'b1;
#300 x_in = 1'b0;
#300 flag = 1'b0;
join
endmodule
Errors:
p5.v:22: error: Unable to bind wire/reg/memory `flag' in `t_ques_5_50.M0'
p5.v:22: error: Unable to elaborate condition expression.
p5.v:17: error: Unable to bind wire/reg/memory `flag' in `t_ques_5_50.M0'
flag
p5.v:36: error: Could not find variable ``flag'' in ``t_ques_5_50.M0''
p5.v:37: error: Could not find variable ``flag'' in ``t_ques_5_50.M0''
p5.v:38: error: Could not find variable ``flag'' in ``t_ques_5_50.M0''
7 error(s) during elaboration.

You refer to the value flag repeatedly inside p5.v, yet it is not declared anywhere as an input, reg, or wire.
Add the appropriate declaration and it should be resolved.

Related

Why do I get a syntax error for omitting a semicolon after one #10, but it is not needed for others? [duplicate]

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

How to change the code. verilog testbench code

I make a design for an adder but the result is wrong.
module FMUL(CLK, St, F1, E1, F2, E2, F, V, done);
input CLK;
input St;
input [3:0] F1;
input [3:0] E1;
input [3:0] F2;
input [3:0] E2;
output[6:0] F;
output V;
output done;
reg[6:0] F;
reg done;
reg V;
reg[3:0] A;
reg[3:0] B;
reg[3:0] C;
reg[4:0] X;
reg[4:0] Y;
reg Load;
reg Adx;
reg SM8;
reg RSF;
reg LSF;
reg AdSh;
reg Sh;
reg Cm;
reg Mdone;
reg[1:0] PS1;
reg[1:0] NS1;
reg[2:0] State;
reg[2:0] Nextstate;
initial
begin
State = 0;
PS1 = 0;
NS1 = 0;
Nextstate=0;
end
always #(PS1 or St or Mdone or X or A or B)
begin : main_control
Load = 1'b0;
Adx = 1'b0;
NS1 = 0;
SM8 = 1'b0;
RSF = 1'b0;
LSF = 1'b0;
V = 1'b0;
F = 7'b0000000;
done = 1'b0;
case (PS1)
0 :
begin
F = 7'b0000000;
done = 1'b0;
V = 1'b0;
if(St == 1'b1)
begin
Load = 1'b1;
NS1 = 1;
end
end
1 :
begin
Adx = 1'b1;
NS1 = 2;
end
2 :
begin
if(Mdone == 1'b1)
begin
if(A==0)
begin
SM8 = 1'b1;
end
else if(A == 4 & B == 0)
begin
RSF = 1'b1;
end
else if (A[2] == A[1])
begin
LSF = 1'b1;
end
NS1 = 3;
end
else
begin
NS1 = 2;
end
end
3 : begin
if(X[4] != X[3])
begin
V = 1'b1;
end
else
begin
V = 1'b0;
end
done = 1'b1;
F = {A[2:0],B};
if(St==1'b0)
begin
NS1 = 0;
end
end
endcase
end
always #(State or Adx or B)
begin : mul2c
AdSh = 1'b0;
Sh = 1'b0;
Cm = 1'b0;
Mdone = 1'b0;
Nextstate = 0;
case(State)
0 :
begin
if(Adx==1'b1)
begin
if((B[0]) == 1'b1)
begin
AdSh = 1'b1;
end
else
begin
Sh = 1'b1;
end
Nextstate = 1;
end
end
1,2 :
begin
if((B[0])==1'b1)
begin
AdSh = 1'b1;
end
else
begin
Sh = 1'b1;
end
Nextstate = State + 1;
end
3:
begin
if((B[0])==1'b1)
begin
Cm = 1'b1;
AdSh = 1'b1;
end
else
begin
Sh = 1'b1;
end
Nextstate = 4;
end
4:
begin
Mdone = 1'b1;
Nextstate = 0;
end
endcase
end
wire [3:0] addout;
assign addout = (Cm == 1'b0)? (A+C) : (A-C);
always #(posedge CLK)
begin : update
PS1 <= NS1;
State <= Nextstate;
if(Load == 1'b1)
begin
X <= {E1[3], E1};
Y <= {E2[3], E2};
A <= 4'b0000;
B <= F1;
C <= F2;
end
if(Adx == 1'b1)
begin
X <= X+Y;
end
if(SM8 == 1'b1)
begin
X <= 5'b11000;
end
if(RSF == 1'b1)
begin
A <= {1'b0, A[3:1]};
B <= {A[0], B[3:1]};
X <= X+1;
end
if(LSF == 1'b1)
begin
A <= {A[2:0], B[3]};
B <= {B[2:0], 1'b0};
X <= X+31;
end
if(AdSh == 1'b1)
begin
A <= {(C[3]^Cm), addout[3:1]};
B <= {addout[0], B[3:1]};
end
if(Sh == 1'b1)
begin
A <= {A[3], A[3:1]};
B <= {A[0], B[3:1]};
end
end
endmodule
test bench.
module tb_FMUL();
wire[6:0] F;
wire done;
wire V;
reg[3:0] A;
reg[3:0] B;
reg[3:0] C;
reg[4:0] X;
reg[4:0] Y;
reg Load;
reg Adx;
reg SM8;
reg RSF;
reg LSF;
reg AdSh;
reg Sh;
reg Cm;
reg Mdone;
reg[1:0] PS1;
reg[1:0] NS1;
reg[2:0] State;
reg[2:0] Nextstate;
reg CLK;
reg St;
reg [3:0] F1;
reg [3:0] E1;
reg [3:0] F2;
reg [3:0] E2;
FMUL u0(CLK, St, F1, E1, F2, E2, F, V, done);
always
begin
#10 CLK <= ~CLK;
end
initial
begin
#100 F1 = 2.125;
E1 = 5; F2 = 5.1; E2 = 1; St=0;
#100 F1 = 1.125;
E1 = 5; F2 = 2.1; E2 = 2; St=0;
#100 F1 = 5.125;
E1 = 5; F2 = 3.1; E2 = 3; St=0;
end
endmodule
The simulation results waveform.
enter image description here
I refer to the book.There is no code test bench.
So I made. But did't operate.
also CLK not is not changed.
please review the testbench code.
You have (at least) two problems:
Your clock needs to be initialised (eg to 1'b0):
initial CLK = 1'b0;
The initial value of any wire or reg in Verilog is 1'bx; ~1'bx is 1'bx; so CLK remains at 1'bx.
Your simulation doesn't stop. I added a call to $finish in the main initial block.
https://www.edaplayground.com/x/r4U

Verilog code for shift and add multiplier

Good day guys, I'm created a Shift - And - Add multiplier. I'm confused on why my output is wrong and always at 85. Is it something with the Test bench ? It's working by the way.
new1.v
`define M ACC[0]
module mult4X4 (Clk, St, Mplier, Mcand, Done, Result);
input Clk,St;
input [3:0] Mplier, Mcand;
output Done;
output [7:0] Result;
reg [3:0] State;
reg [8:0] ACC;
initial
begin
State = 0;
ACC = 0;
end
always #(posedge Clk)
begin
case (State)
0:
begin
if(St == 1'b1)
begin
ACC[8:4] <= 5'b00000 ;
ACC[3:0] <= Mplier ;
State <= 1;
end
end
1,3,5,7 :
begin
if(`M==1'b1)
begin
ACC[8:4] <= {1'b0, ACC[7:4]} + Mcand ;
State <= State +1;
end
else
begin
ACC <= {1'b0, ACC[8:1]};
State <= State + 2;
end
end
2,4,6,8 :
begin
ACC <= {1'b0, ACC[8:1]};
State <= State +1;
end
9:
begin
State <= 0;
end
endcase
end
assign Done = (State == 9) ? 1'b1 : 1'b0 ;
assign Result = (State == 9) ? ACC[7:0] : 8'b01010101;
endmodule
tb_new1.v
module tb_mult4X4;
reg Clk,St,nReset;
reg [3:0] Mplier;
reg [3:0] Mcand;
wire Done;
wire [7:0] Result;
mult4X4 UUT (Clk,St,Mplier,Mcand,Done,Result);
initial begin
$dumpfile ("mult4X4.vpd");
$dumpvars;
end
initial
Clk = 0;
always
#5 Clk =~Clk;
initial begin
nReset = 0;
St = 0;
Mcand = 4'b1101;
Mplier = 4'b1011;
#10
nReset = 1;
St = 1;
Mcand = 4'b1111;
Mplier = 4'b1001;
#10
Mcand = 4'b0101;
Mplier = 4'b1010;
#10
Mcand = 4'b1111;
Mplier = 4'b1111;
#10
Mcand = 4'b1101;
Mplier = 4'b1010;
$finish;
end
endmodule
I ran though the code so many times and everything seems to be following my FSM. Can anyone please point out where went wrong. Really confused on this one
#10 is way to short. Your RTL requires 10 clocks to complete but you change the input every clock (half clk is #5).
Use #100 or better yet #(posedge Done); (which makes the test-bench to wait for done regardless the number of clocks that is required).

comparing t_data and rx_data for errors and giving the error value by total_error "verilog"

I have made a bit error rate (ber) file in verilog. In ber module, I have made total_error which compares the t_data and rx_data and totals up the number of errors it gets from comparing.
Here is the code
`timescale 1ns / 1ps
module ber
(
clk,
rstn,
T_Data,
RX_Data,
total_error,
enable
);
//inputs
input clk;
input rstn;
input [15 : 0] T_Data;
input [15 : 0] RX_Data;
input enable;
//outputs
output [15:0] total_error;
reg [4:0] i;
reg [15:0] subtotal, next_subtotal;
assign total_error = subtotal;
always #(posedge clk) begin : comb
next_subtotal = 0;
for (i = 0; i < 16; i = i + 1)
begin
if (T_Data[i] != RX_Data[i] )
begin
next_subtotal = next_subtotal + 1;
end
end
end
always #(posedge clk) begin : dff
if (rstn==1'b0)
begin
subtotal <= 7'b0000000;
end else
begin
subtotal <= next_subtotal;
end
end
endmodule
After making the BER file, I made another file known as BER_STATE_MACHINE where I made a state machine for TRANFERRING AND RECEIVING SIGNALS, I instantiated the ber file with this ber_state_machine file.
Here is the code
// --------------------------------------------------------------------
`timescale 1ns/1ps
module ber_state_machine
(
clk,
resetn,
T_Data [15:0],
T_Valid,
T_Ready,
RX_Data [15:0],
RX_Active,
RX_Valid,
total_error
);
//-----------------------------------
input resetn, clk;
// DECLARING INPUTS AND OUTPUTS FOR TRASMIT SIGNALS
input [15 : 0] T_Data;
input T_Valid;
output T_Ready;
// DECLARING INPUTS AND OUTPUTS FOR RECEIVING SIGNALS
input [15 : 0] RX_Data;
input RX_Active;
input RX_Valid;
//-----------------------------------
output [15 : 0] total_error;
//-----------------------------------
reg [6:0] sel;
reg execute_in;
reg T_Ready;
//------------------------------------------
ber uut
(
.clk(clk),
.rstn(resetn),
.T_Data(T_Data),
.RX_Data(RX_Data),
.total_error(total_error),
.enable(execute_in)
);
//------------------------------------------
// MAKING STATE MACHINE HERE //INPUTS
always # (posedge clk or negedge resetn) // state machine for changing states
begin
if (resetn == 1'b1) // idle state
begin
sel <= 7'b000; // state 0
end
else if (T_Valid == 7'b1)
begin
sel <= 7'b001; // state 1
end
else if (sel == 7'b001)
begin
sel <= 7'b010; // state 2
end
else if (RX_Active == 7'b1)
begin
sel <= 7'b011; // state 3
end
else if (T_Valid == 7'b1 && RX_Valid == 7'b1)
begin
sel <= 7'b100; // state 4
end
else if (sel == 7'b100)
begin
sel <= 7'b101; // state 5
end
else if (T_Valid == 2'b0 && RX_Valid == 2'b0)
begin
sel <= 7'b100; // going back to state 4
end
end
// STATE MACHINE //OUTPUTS
always # (posedge clk) // outputs for every state in state diagram
begin
case(sel)
7'b000 :
execute_in = 2'b0; // state 0
7'b001 :
T_Ready = 2'b1; // state 1
7'b010 :
T_Ready = 2'b0; // state 2
7'b011 :
execute_in = 2'b1; // state 3
7'b100 :
T_Ready = 2'b1; // state 4
7'b101 :
T_Ready = 2'b0; // state 5
endcase
end
endmodule
After this, I made a test bech to see the behavioral simulation.
There are few problems that I am getting which I am not able to fix due to less verilog experience.
the t_data and rx_data are undefined in the simulation, after the last bit, I can see the value each contains but from 0 - 15, they are undefined. I really dont know whats the problem.
I dont see any value in total_error, even though I put errors in t_data and rx_data but I dont see the number of errors in total_error. But I can observe in the simulation that there are errors in t_data and rx_data in their final values.
Here is the code for test bench
`timescale 1ns / 1ps
module test_bench();
//inputs
reg execute_in;
reg clk;
reg resetn;
//inputs for transferring signals
reg [15:0] T_Data;
reg T_Valid;
//inputs for receiving signals
reg [15:0] RX_Data;
reg RX_Active;
reg RX_Valid;
//outputs
wire [15:0] total_error;
wire T_Ready;
//instantiate the unit under test (UUT)
ber_state_machine uut_ber
(
.clk(clk),
.resetn(resetn),
.T_Data(T_Data),
.T_Valid(T_Valid),
.T_Ready(T_Ready),
.RX_Data(RX_Data),
.RX_Active(RX_Active),
.RX_Valid(RX_Valid),
.total_error(total_error)
);
initial begin
clk = 1'b0;
resetn = 1'b1;
repeat(4) #10 clk = ~clk;
resetn = 1'b0;
forever #10 clk = ~clk;
end
initial begin
#100
execute_in = 0;
#100
execute_in = 1;
#100
T_Valid = 1'b0;
RX_Active = 1'b0;
#100
RX_Valid = 1'b0;
//************//
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[0] = 1'b0; // data 0 // make it 0 for error
RX_Valid = 1'b1;
RX_Data[0] = 1'b1; // make it 0 for error
#50
T_Valid = 1'b0;
//************//
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[1] = 1'b1; // data 1
RX_Valid = 1'b1;
RX_Data[1] = 1'b1; // make it 0 for error
#50
T_Valid = 1'b0;
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[2] = 1'b1; // data 2
RX_Valid = 1'b1;
RX_Data[2] = 1'b1; // make it 0 for error
#50
T_Valid = 1'b0;
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[3] = 1'b0; // data 3
RX_Valid = 1'b1;
RX_Data[3] = 1'b1; // make it 0 for error
#50
T_Valid = 1'b0;
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[4] = 1'b1; // data 4
RX_Valid = 1'b1;
RX_Data[4] = 1'b1; // make it 0 for error
#50
T_Valid = 1'b0;
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[5] = 1'b1; // data 5
RX_Valid = 1'b1;
RX_Data[5] = 1'b1; // make it 0 for error
#50
T_Valid = 1'b0;
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[6] = 1'b1; // data 6
RX_Valid = 1'b1;
RX_Data[6] = 1'b1; // make it 0 for error
#50
T_Valid = 1'b0;
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[7] = 1'b1; // data 7
RX_Valid = 1'b1;
RX_Data[7] = 1'b1; // make it 0 for error
#50
T_Valid = 1'b0;
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[8] = 1'b1; // data 8
RX_Valid = 1'b1;
RX_Data[8] = 1'b0; // make it 0 for error
#50
T_Valid = 1'b0;
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[9] = 1'b1; // data 9
RX_Valid = 1'b1;
RX_Data[9] = 1'b1; // make it 0 for error
#50
T_Valid = 1'b0;
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[10] = 1'b1; // data 10
RX_Valid = 1'b1;
RX_Data[10] = 1'b1; // make it 0 for error
#50
T_Valid = 1'b0;
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[11] = 1'b1; // data 11
RX_Valid = 1'b1;
RX_Data[11] = 1'b1; // make it 0 for error
#50
T_Valid = 1'b0;
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[12] = 1'b1; // data 12
RX_Valid = 1'b1;
RX_Data[12] = 1'b1; // make it 0 for error
#50
T_Valid = 1'b0;
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[13] = 1'b1; // data 13
RX_Valid = 1'b1;
RX_Data[13] = 1'b1; // make it 0 for error
#50
T_Valid = 1'b0;
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[14] = 1'b1; // data 14
RX_Valid = 1'b1;
RX_Data[14] = 1'b1; // make it 0 for error
#50
T_Valid = 1'b0;
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[15] = 1'b1; // data 15
RX_Valid = 1'b1;
RX_Data[15] = 1'b1; // make it 0 for error
#50
T_Valid = 1'b0;
end
endmodule
Please help me out in this
Your logic uses an active-low reset. However, your testbench starts with the reset signal de-asserted (resetn=1), then asserts it (resetn=0) after 40ns. I think you need to invert the polarity in the testbench:
initial begin
clk = 1'b0;
resetn = 0; // Assert active-low reset
repeat(4) #10 clk = ~clk;
resetn = ~resetn; // De-assert reset
forever #10 clk = ~clk;
end

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.
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

Resources