Forum Discussion

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

Problem simulating FSM

Hi,

I am trying to simulate a FSM using vector simulator...

the state machine variable is called "Tstep_Q", I added it to waveform editor... however, when I start the functional simulation

all signals are displayed and change over time except the Tstep_Q signal!! It stays Undefined.

While I was trying to resolve this issue I noticed that the simulator is throwing a warning says: "Warning: Tstep_Q - signal not found in VCD."

I managed to solve another signal had the same problem "incr_PC" by using the directive /* synthesis keep */.


module proc_enhanced (Clock, DIN, Resetn, Run, Done, ADDR, DOUT, W);
    input  DIN;
    input Resetn, Clock, Run;
    output reg Done;
    output  ADDR;
    output  DOUT;
    output W;
    
    
    // FSM variables
    parameter T0 = 3'b000, T1 = 3'b001, T2 = 3'b010, T3 = 3'b011, T4 = 3'b100;
    reg  Tstep_Q, Tstep_D;
    
    // Instructions
    parameter mv = 3'b000, mvi = 3'b001, add = 3'b010, sub = 3'b011,
    ld = 3'b100, st = 3'b101, mvnz = 3'b110;
    
    // Registers and Wires
    wire  BusWires;
    wire  I;
    wire  IR;
    wire  R0, R1, R2, R3, R4, R5, R6, R7;
    wire  A, G;
    reg IRin;
    reg  Rin;
    reg  Rout;
    reg Ain;
    reg Gin;
    reg Gout;
    reg DINout;
    reg AddSub;
    wire  Xreg, Yreg;
    wire  adr_subr_out;
    reg incr_PC /* synthesis keep */;
    reg ADDRin;
    reg DOUTin;
    reg W_D;
    
    // Registers
    regn reg_IR (DIN, IRin, Clock, IR);
    regn reg_0    (BusWires, Rin, Clock, R0);
    regn reg_1    (BusWires, Rin, Clock, R1);
    regn reg_2    (BusWires, Rin, Clock, R2);
    regn reg_3    (BusWires, Rin, Clock, R3);
    regn reg_4    (BusWires, Rin, Clock, R4);
    regn reg_5    (BusWires, Rin, Clock, R5);
    regn reg_6    (BusWires, Rin, Clock, R6);
    // regn reg_7    (BusWires, Rin, Clock, R7); This is replaced with the Program Counter (PC).
    regn reg_A    (BusWires, Ain, Clock, A);
    regn reg_G    (adr_subr_out, Gin, Clock, G);
    regn reg_ADDR (BusWires, ADDRin, Clock, ADDR);
    regn reg_DOUT (BusWires, DOUTin, Clock, DOUT);
    regn reg_W (W_D, 1'b1, Clock, W);
    defparam reg_W.n = 1;
    
    // Program Counter
    counter PC (Clock, Resetn, Rin, incr_PC, BusWires, R7);
    
    assign I = IR;
    dec3to8 decX (IR, 1'b1, Xreg);
    dec3to8 decY (IR, 1'b1, Yreg);
    
    // FSM State Table
    always @ (Tstep_Q, Run, Done) begin
        case (Tstep_Q)
            T0:
                if(!Run) Tstep_D = T0;
                else Tstep_D = T1;
            T1:
                Tstep_D = T2;
            T2:
                if(Done) Tstep_D = T0;
                else Tstep_D = T3;
            T3:
                Tstep_D = T4;
            T4:
                Tstep_D = T0;
            default: Tstep_D = 3'bxxx;
        endcase
    end
    
    // FSM Flip-Flops
    always @ (posedge Clock, negedge Resetn)
    begin
        if (~Resetn)
            Tstep_Q = T0;
        else
            Tstep_Q = Tstep_D;
    end
    
    // FSM outputs
    always @(Tstep_Q or I or Xreg or Yreg)
    begin
        // initial values
        IRin = 1'b0;
        Rin = 8'b0;
        Rout = 8'b0;
        Gin = 1'b0;
        Gout = 1'b0;
        Ain = 1'b0;
        DINout = 1'b0;
        AddSub = 1'b0;
        Done = 1'b0;
        incr_PC = 1'b0;
        ADDRin = 1'b0;
        DOUTin = 1'b0;
        W_D = 1'b0;
        
        case(Tstep_Q)
            T0:
            begin
                Rout = 1'b1; // Program Counter
                ADDRin = 1'b1;
            end
            T1:
            begin
                IRin = 1'b1;
                incr_PC = 1'b1;
            end
            T2:
                case(I)
                    mv:
                    begin
                        Rin = Xreg;
                        Rout = Yreg;
                        Done = 1'b1;
                    end
                    mvi:
                    begin
                        DINout = 1'b1;
                        Rin = Xreg;
                        Done = 1'b1;
                    end
                    add, sub:
                    begin
                        Rout = Xreg;
                        Ain = 1'b1;
                    end
                    ld:
                    begin
                        Rout = Yreg;
                        ADDRin = 1'b1;
                    end
                    st:
                    begin
                        Rout = Xreg;
                        DOUTin = 1'b1;
                    end
                    mvnz:
                    begin
                        if (&G != 1'b0) begin
                            Rout = Yreg;
                            Rin = Xreg;
                            Done = 1'b1;
                        end
                    end
                endcase
            T3:
                case(I)
                    add:
                    begin
                        Rout = Yreg;
                        Gin = 1'b1;
                    end
                    sub:
                    begin
                        Rout = Yreg;
                        Gin = 1'b1;
                        AddSub = 1'b1;
                    end
                    ld:
                    begin
                        DINout = 1'b1;
                        Rin = Xreg;
                        Done = 1'b1;
                    end
                    st:
                    begin
                        Rout = Yreg;
                        ADDRin = 1'b1;
                        W_D = 1'b1;
                        Done = 1'b1;
                    end
                endcase
            T4:
                case(I)
                    add, sub:
                    begin
                        Gout = 1'b1;
                        Rin = Xreg;
                        Done = 1'b1;
                    end
                endcase
        endcase
    end
    
    // Adder/Substractor
    assign adr_subr_out = (AddSub == 0) ? (A + BusWires) : (A - BusWires);
    
    // Multiplexer
    wire  MUXsel;
    assign MUXsel = Rout;
    assign MUXsel = Gout;
    assign MUXsel = DINout;
    mulpxr bus_multiplexer (MUXsel, DIN, G, R0, R1, R2, R3, R4, R5, R6, R7, BusWires);
endmodule
module mulpxr (sel, DIN, G, R0, R1, R2, R3, R4, R5, R6, R7, BusWires);
    input  sel;
    input  DIN, G, R0, R1, R2, R3, R4, R5, R6, R7;
    output reg  BusWires;
    
    always @ (*)
    begin
        case (sel)
            10'b0000000001: BusWires = DIN;
            10'b0000000010: BusWires = G;
            10'b0000000100: BusWires = R0;
            10'b0000001000: BusWires = R1;
            10'b0000010000: BusWires = R2;
            10'b0000100000: BusWires = R3;
            10'b0001000000: BusWires = R4;
            10'b0010000000: BusWires = R5;
            10'b0100000000: BusWires = R6;
            10'b1000000000: BusWires = R7;
            default: BusWires = 9'bxxxxxxxxx;
        endcase
    end
endmodule
module regn (R, Rin, clock, Q);
    parameter n = 9;
    input  R;
    input Rin, clock;
    output reg  Q;
    
    always @(posedge clock)
        if (Rin)
            Q <= R;
endmodule
module dec3to8 (W, En, Y);
    input  W;
    input En;
    output reg  Y;
    
    always @(W or En)
    begin
        if (En == 1)
            case (W)
                3'b000: Y = 8'b00000001;
                3'b001: Y = 8'b00000010;
                3'b010: Y = 8'b00000100;
                3'b011: Y = 8'b00001000;
                3'b100: Y = 8'b00010000;
                3'b101: Y = 8'b00100000;
                3'b110: Y = 8'b01000000;
                3'b111: Y = 8'b10000000;
            endcase
        else 
            Y = 8'b00000000;
    end
endmodule
module counter (clk, reset, load, en, D, Q);
    input clk, reset, load, en;
    input  D;
    output reg  Q;
    
    always @ (posedge clk)
    begin
        if (~reset) Q = 9'b0;
        if (load) Q = D;
        if (en) Q = Q + 9'b1;
    end
endmodule

Any clue would be appreciated... I have been trying to figure it out tow days ago!!

6 Replies

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

    --- Quote Start ---

    why not post the origional code?

    --- Quote End ---

    Sure, by the way, all my FSM projects have the same issue, so I'll post a simple example because

    that one is very long.

    
    module FSM(clock, reset, w, z);
    	input clock, reset, w;
    	output z;
    	
    	reg  y_Q, Y_D;	// y_Q represents the current state, Y_D represents the next state.
    	parameter A = 4'b0000, B = 4'b0001, C = 4'b0010, D = 4'b0011, E = 4'b0100,
    	F = 4'b0101, G = 4'b0110, H = 4'b0111, I = 4'b1000;
    	
    	always@(w, y_Q)
    	begin: state_table
    		case(y_Q)
    			A: if(!w) Y_D = B;
    				else Y_D = F;
    			B: if(!w) Y_D = C;
    				else Y_D = F;
    			C: if(!w) Y_D = D;
    				else Y_D = F;
    			D: if(!w) Y_D = E;
    				else Y_D = F;
    			E: if(!w) Y_D = E;
    				else Y_D = F;
    			F: if(!w) Y_D = B;
    				else Y_D = G;
    			G: if(!w) Y_D = B;
    				else Y_D = H;
    			H: if(!w) Y_D = B;
    				else Y_D = I;
    			I: if(!w) Y_D = B;
    				else Y_D = I;
    			default: Y_D = 4'bxxxx;
    		endcase
    	end	// state_table
    	
    	always @(posedge clock)
    	begin: state_FFs
    		if(~reset) y_Q <= A;
    		else y_Q <= Y_D;
    	end // state_FFs
    	
    	// ---------------------------
    	// Outputs
    	// ---------------------------
    	assign z = (y_Q == E) | (y_Q == I);
    endmodule
    

    Thank you so much sir, your help is so appreciated.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    This isnt all of the code..

    --- Quote End ---

    OK, here you go... this is the code of interest:

    
    module proc_enhanced (Clock, DIN, Resetn, Run, Done, ADDR, DOUT, W);
    	input  DIN;
    	input Resetn, Clock, Run;
    	output reg Done;
    	output  ADDR;
    	output  DOUT;
    	output W;
    	
    	
    	// FSM variables
    	parameter T0 = 3'b000, T1 = 3'b001, T2 = 3'b010, T3 = 3'b011, T4 = 3'b100;
    	reg  Tstep_Q, Tstep_D;
    	
    	// Instructions
    	parameter mv = 3'b000, mvi = 3'b001, add = 3'b010, sub = 3'b011,
    	ld = 3'b100, st = 3'b101, mvnz = 3'b110;
    	
    	// Registers and Wires
    	wire  BusWires;
    	wire  I;
    	wire  IR;
    	wire  R0, R1, R2, R3, R4, R5, R6, R7;
    	wire  A, G;
    	reg IRin;
    	reg  Rin;
    	reg  Rout;
    	reg Ain;
    	reg Gin;
    	reg Gout;
    	reg DINout;
    	reg AddSub;
    	wire  Xreg, Yreg;
    	wire  adr_subr_out;
    	reg incr_PC /* synthesis keep */;
    	reg ADDRin;
    	reg DOUTin;
    	reg W_D;
    	
    	// Registers
    	regn reg_IR (DIN, IRin, Clock, IR);
    	regn reg_0	(BusWires, Rin, Clock, R0);
    	regn reg_1	(BusWires, Rin, Clock, R1);
    	regn reg_2	(BusWires, Rin, Clock, R2);
    	regn reg_3	(BusWires, Rin, Clock, R3);
    	regn reg_4	(BusWires, Rin, Clock, R4);
    	regn reg_5	(BusWires, Rin, Clock, R5);
    	regn reg_6	(BusWires, Rin, Clock, R6);
    	// regn reg_7	(BusWires, Rin, Clock, R7); This is replaced with the Program Counter (PC).
    	regn reg_A	(BusWires, Ain, Clock, A);
    	regn reg_G	(adr_subr_out, Gin, Clock, G);
    	regn reg_ADDR (BusWires, ADDRin, Clock, ADDR);
    	regn reg_DOUT (BusWires, DOUTin, Clock, DOUT);
    	regn reg_W (W_D, 1'b1, Clock, W);
    	defparam reg_W.n = 1;
    	
    	// Program Counter
    	counter PC (Clock, Resetn, Rin, incr_PC, BusWires, R7);
    	
    	assign I = IR;
    	dec3to8 decX (IR, 1'b1, Xreg);
    	dec3to8 decY (IR, 1'b1, Yreg);
    	
    	// FSM State Table
    	always @ (Tstep_Q, Run, Done) begin
    		case (Tstep_Q)
    			T0:
    				if(!Run) Tstep_D = T0;
    				else Tstep_D = T1;
    			T1:
    				Tstep_D = T2;
    			T2:
    				if(Done) Tstep_D = T0;
    				else Tstep_D = T3;
    			T3:
    				Tstep_D = T4;
    			T4:
    				Tstep_D = T0;
    			default: Tstep_D = 3'bxxx;
    		endcase
    	end
    	
    	// FSM Flip-Flops
    	always @ (posedge Clock, negedge Resetn)
    	begin
    		if (~Resetn)
    			Tstep_Q = T0;
    		else
    			Tstep_Q = Tstep_D;
    	end
    	
    	// FSM outputs
    	always @(Tstep_Q or I or Xreg or Yreg)
    	begin
    		// initial values
    		IRin = 1'b0;
    		Rin = 8'b0;
    		Rout = 8'b0;
    		Gin = 1'b0;
    		Gout = 1'b0;
    		Ain = 1'b0;
    		DINout = 1'b0;
    		AddSub = 1'b0;
    		Done = 1'b0;
    		incr_PC = 1'b0;
    		ADDRin = 1'b0;
    		DOUTin = 1'b0;
    		W_D = 1'b0;
    		
    		case(Tstep_Q)
    			T0:
    			begin
    				Rout = 1'b1; // Program Counter
    				ADDRin = 1'b1;
    			end
    			T1:
    			begin
    				IRin = 1'b1;
    				incr_PC = 1'b1;
    			end
    			T2:
    				case(I)
    					mv:
    					begin
    						Rin = Xreg;
    						Rout = Yreg;
    						Done = 1'b1;
    					end
    					mvi:
    					begin
    						DINout = 1'b1;
    						Rin = Xreg;
    						Done = 1'b1;
    					end
    					add, sub:
    					begin
    						Rout = Xreg;
    						Ain = 1'b1;
    					end
    					ld:
    					begin
    						Rout = Yreg;
    						ADDRin = 1'b1;
    					end
    					st:
    					begin
    						Rout = Xreg;
    						DOUTin = 1'b1;
    					end
    					mvnz:
    					begin
    						if (&G != 1'b0) begin
    							Rout = Yreg;
    							Rin = Xreg;
    							Done = 1'b1;
    						end
    					end
    				endcase
    			T3:
    				case(I)
    					add:
    					begin
    						Rout = Yreg;
    						Gin = 1'b1;
    					end
    					sub:
    					begin
    						Rout = Yreg;
    						Gin = 1'b1;
    						AddSub = 1'b1;
    					end
    					ld:
    					begin
    						DINout = 1'b1;
    						Rin = Xreg;
    						Done = 1'b1;
    					end
    					st:
    					begin
    						Rout = Yreg;
    						ADDRin = 1'b1;
    						W_D = 1'b1;
    						Done = 1'b1;
    					end
    				endcase
    			T4:
    				case(I)
    					add, sub:
    					begin
    						Gout = 1'b1;
    						Rin = Xreg;
    						Done = 1'b1;
    					end
    				endcase
    		endcase
    	end
    	
    	// Adder/Substractor
    	assign adr_subr_out = (AddSub == 0) ? (A + BusWires) : (A - BusWires);
    	
    	// Multiplexer
    	wire  MUXsel;
    	assign MUXsel = Rout;
    	assign MUXsel = Gout;
    	assign MUXsel = DINout;
    	mulpxr bus_multiplexer (MUXsel, DIN, G, R0, R1, R2, R3, R4, R5, R6, R7, BusWires);
    endmodule
    module mulpxr (sel, DIN, G, R0, R1, R2, R3, R4, R5, R6, R7, BusWires);
    	input  sel;
    	input  DIN, G, R0, R1, R2, R3, R4, R5, R6, R7;
    	output reg  BusWires;
    	
    	always @ (*)
    	begin
    		case (sel)
    			10'b0000000001: BusWires = DIN;
    			10'b0000000010: BusWires = G;
    			10'b0000000100: BusWires = R0;
    			10'b0000001000: BusWires = R1;
    			10'b0000010000: BusWires = R2;
    			10'b0000100000: BusWires = R3;
    			10'b0001000000: BusWires = R4;
    			10'b0010000000: BusWires = R5;
    			10'b0100000000: BusWires = R6;
    			10'b1000000000: BusWires = R7;
    			default: BusWires = 9'bxxxxxxxxx;
    		endcase
    	end
    endmodule
    module regn (R, Rin, clock, Q);
    	parameter n = 9;
    	input  R;
    	input Rin, clock;
    	output reg  Q;
    	
    	always @(posedge clock)
    		if (Rin)
    			Q <= R;
    endmodule
    module dec3to8 (W, En, Y);
    	input  W;
    	input En;
    	output reg  Y;
    	
    	always @(W or En)
    	begin
    		if (En == 1)
    			case (W)
    				3'b000: Y = 8'b00000001;
    				3'b001: Y = 8'b00000010;
    				3'b010: Y = 8'b00000100;
    				3'b011: Y = 8'b00001000;
    				3'b100: Y = 8'b00010000;
    				3'b101: Y = 8'b00100000;
    				3'b110: Y = 8'b01000000;
    				3'b111: Y = 8'b10000000;
    			endcase
    		else 
    			Y = 8'b00000000;
    	end
    endmodule
    module counter (clk, reset, load, en, D, Q);
    	input clk, reset, load, en;
    	input  D;
    	output reg  Q;
    	
    	always @ (posedge clk)
    	begin
    		if (~reset) Q = 9'b0;
    		if (load) Q = D;
    		if (en) Q = Q + 9'b1;
    	end
    endmodule