-1
\$\begingroup\$

I'm new to Verilog. I was trying to write the next Finite State Machines (miley machine) in Verilog: enter image description here

this what I got:

// clk - clock, i - input, o - output
module test (clk,reset,i,o);

input   clk,reset,i;
output  o;
reg     o;
wire    clk,reset,i;

reg [2:0] present_state;
reg [2:0] next_state;

parameter A=2'b00, B=2'b01, C=2'b10;

always @(present_state,i)
begin
    case (present_state)
    A: if(i)        next_state = B;
       else         next_state = A;
    B: if(i)        next_state = A;
       else         next_state = C;
    C: if(i)        next_state = C;
       else         next_state = B;
    default:        next_state = A;
    endcase
end

always @(posedge clk, posedge reset)
begin
    if(reset)
        present_state = 0'b0;
    else
        present_state = next_state;
end


always @(present_state)
begin
    if(present_state == A)
        o = 1'b0;
    else if(present_state == C)
        o = 1'b1;
    else
        o = i;
end

endmodule

I have a tester and every time I run it, I receive failure. What is the order of the block statement (which comes first?). Even thought my program compiled, It doesn't work.

\$\endgroup\$
10
  • 2
    \$\begingroup\$ Could you share the compilation error? One of the error could be using a keyword "input" as a variable so might want to change it to "in" or something of your choice. Could you also share the test bench as well. May be there could be some errors in it. \$\endgroup\$
    – rsg1710
    Nov 12 '17 at 17:44
  • \$\begingroup\$ You can tidy up the case statement using a ternary construct, and also change to an always_comb block. But yes, a lot more info needed :) \$\endgroup\$
    – awjlogan
    Nov 12 '17 at 17:47
  • 1
    \$\begingroup\$ Also the code is bit confusing, as comment in top of the code, you show 'i' to be input, yet its not defined as input and also you dont initialise present_state. How is it supposed to next state when it doesnt know which state it is starting from? \$\endgroup\$
    – rsg1710
    Nov 12 '17 at 17:49
  • \$\begingroup\$ @rsg1710 the code doesn't have errors, it's just doesn't do what I need. About the input, I edited the code (while I was writing this post I have changed the syntax a little, that's the reason for the mistake) , it's should compile. \$\endgroup\$
    – kicklog
    Nov 12 '17 at 18:00
  • \$\begingroup\$ Please share your testbench and the output you see at present. \$\endgroup\$
    – rsg1710
    Nov 12 '17 at 18:02
0
\$\begingroup\$

I think the problem in your code is that the "present_state -> next_state" clocked block doesn't employ non-blocking assignment syntax.

Please study carefully the following articles,

"Synthesizable Finite State Machine Design Techniques"

and

"The Fundamentals of Efficient Synthesizable Finite State Machine Design",

and follow their advice and notation/syntax meticulously. You will get right results.

And another one, from the same expert Clifford E. Cummings.

\$\endgroup\$
0
\$\begingroup\$
// Testbench
`timescale 1ns/1ns
module test;

  reg clk   ;
  reg reset ;
  reg i     ;


  // Instantiate design under test
  test01 TST(.clk(clk), 
             .reset(reset),
             .i(i), 
             .o(o));

  initial begin
    $dumpfile("dump.vcd");
    $dumpvars(1);
    clk     =   1'b0;
    reset   =   1'b1;
    i       =   1'b0;
    end

  always begin
    #10     reset   = 1'b0;
    #15     i       = 1'b1;
    #20     i       = 1'b0;
  end

  always
    #5  clk = !clk;

endmodule

To this test bench I see it working fine :)

module test01 (clk,reset,i,o);

input   clk,reset,i;
output  o;
reg     o;
wire    clk,reset,i;

reg [2:0] present_state;
reg [2:0] next_state;

parameter A=2'b00, B=2'b01, C=2'b10;

always @(present_state,i)
begin
    case (present_state)
    A: if(i)        next_state = B;
       else         next_state = A;
    B: if(i)        next_state = A;
       else         next_state = C;
    C: if(i)        next_state = C;
       else         next_state = B;
    default:        next_state = A;
    endcase
end

always @(posedge clk, posedge reset)
begin
    if(reset)
        present_state = 2'b00;
    else
        present_state = next_state;
end


always @(present_state)
begin
    if(present_state == A)
        o = 1'b0;
    else if(present_state == C)
        o = 1'b1;
    else
        o = i;
end

endmodule

enter image description here

Test 2: This works as well

// Testbench
module test;

  reg clk   ;
  reg reset ;
  reg i     ;


  // Instantiate design under test
  test01 TST(.clk(clk), 
             .reset(reset),
             .i(i), 
             .o(o));

  initial begin
    $dumpfile("dump.vcd");
    $dumpvars(1);
    clk     =   1'b1;
    reset   =   1'b1;
    i       =   1'b1;
    end

  always begin
    #10     reset   = 1'b0;
    //#15   i       = 1'b1;
    //#20       i       = 1'b0;
  end

  always
    #5  clk = !clk;

endmodule

enter image description here

\$\endgroup\$
5
  • \$\begingroup\$ The code still doesn't work for me, I think I have problem with the always clock block. Try the next test: clk=1,reset=1,i=1 the output should be 0 - this tests works fine, but if then I try reset=0 the output should still be 0 but it isn't. \$\endgroup\$
    – kicklog
    Nov 12 '17 at 22:08
  • \$\begingroup\$ Check the edited answer, I did the test and it works, please consider to share your testbench to see what is going wrong in your code. \$\endgroup\$
    – rsg1710
    Nov 13 '17 at 8:59
  • \$\begingroup\$ can you provide an email or some other way of private communication so I could send you in private? (this site doesn't support private messages) \$\endgroup\$
    – kicklog
    Nov 13 '17 at 10:31
  • \$\begingroup\$ you could edit your question and add the testbench or continue in chat \$\endgroup\$
    – rsg1710
    Nov 13 '17 at 10:53
  • \$\begingroup\$ I have edited my post, please take a look \$\endgroup\$
    – kicklog
    Nov 13 '17 at 11:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.