Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Verilog Code For Simple FSM

Status
Not open for further replies.

kseng2002

Member level 2
Joined
Aug 27, 2004
Messages
51
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Location
Malaysia
Activity points
467
verilog code for fsm

Hi , can any1 guide me on how to write the following Verilog code from the table below ? Im new to Verilog and using Quartus II. Thanks in advance.

PS Inputs NS Outputs
y1y2 rw rdy Y1Y2 oe we
0 0 0 0 0 0 0 0
0 0 0 1 0 1 0 0
0 0 1 1 0 1 0 0
0 0 1 0 0 0 0 0

0 1 0 0 1 1 0 0
0 1 0 1 1 1 0 0
0 1 1 1 1 0 0 0
0 1 1 0 1 0 0 0

1 1 0 0 1 1 0 1
1 1 0 1 0 0 0 1
1 1 1 1 0 0 0 1
1 1 1 0 1 1 0 1

1 0 0 0 1 0 1 0
1 0 0 1 0 0 1 0
1 0 1 1 0 0 1 0
1 0 1 0 1 0 1 0
 

verilog fsm

Hi look at page 38 of
http://www.vlsiip.com/ipba.pdf
this will give you a bit of idea how to write a state machine in HDL.

Here is a bit of code of a state machine based on page 38 of the doc above. It might help

always @ (rx_in or reset_ps or bitcounter)
case({rx_in,reset_ps})
3'b100 : reset_ns = 2'b00;
3'b000 : reset_ns = 2'b01;

3'b001 : reset_ns = 2'b10;
3'b101 : reset_ns = 2'b00;

3'b010 : reset_ns = 2'b11;
3'b110 : reset_ns = 2'b00;

3'b011 :
begin
if(bitcounter == 11)
reset_ns = 2'b00;
else
reset_ns = 2'b11;
end
3'b111 : reset_ns = 2'b11;
default : reset_ns = 2'b00;
endcase

always @ (posedge clk)
reset_ps <= reset_ns;

always @ (posedge clk)
begin
if(reset_ps == 2'b11)
reset <= 1'b1;
else
reset <= 1'b0;
end

which is the part of the code at
http://www.vlsiip.com/verilog/rx.v

Hope it helps,
kr,
Avi
http://www.vlsiip.com
 

fsm verilog

Try this. I basically copied your table into a 'case' statement.
The register initializations require Verilog 2001.
Code:
module top (clk, rw, rdy, oe, we);
  input         clk;
  reg           y1=0, y2=0;
  input         rw, rdy;
  output reg    oe=0, we=0;

  always @ (posedge clk) begin
    case ({y1,y2,rw,rdy})
      4'b0000: {y1,y2,oe,we} <= 4'b0000;
      4'b0001: {y1,y2,oe,we} <= 4'b0100;
      4'b0011: {y1,y2,oe,we} <= 4'b0100;
      4'b0010: {y1,y2,oe,we} <= 4'b0000;
      4'b0100: {y1,y2,oe,we} <= 4'b1100;
      4'b0101: {y1,y2,oe,we} <= 4'b1100;
      4'b0111: {y1,y2,oe,we} <= 4'b1000;
      4'b0110: {y1,y2,oe,we} <= 4'b1000;
      4'b1100: {y1,y2,oe,we} <= 4'b1101;
      4'b1101: {y1,y2,oe,we} <= 4'b0001;
      4'b1111: {y1,y2,oe,we} <= 4'b0001;
      4'b1110: {y1,y2,oe,we} <= 4'b1101;
      4'b1000: {y1,y2,oe,we} <= 4'b1010;
      4'b1001: {y1,y2,oe,we} <= 4'b0010;
      4'b1011: {y1,y2,oe,we} <= 4'b0010;
      4'b1010: {y1,y2,oe,we} <= 4'b1010;
    endcase
  end
endmodule
 

verilog coding fsms

echo47 said:
Try this. I basically copied your table into a 'case' statement.
The register initializations require Verilog 2001.
Code:
module top (clk, rw, rdy, oe, we);
  input         clk;
  reg           y1=0, y2=0;
  input         rw, rdy;
  output reg    oe=0, we=0;

  always @ (posedge clk) begin
    case ({y1,y2,rw,rdy})
      4'b0000: {y1,y2,oe,we} <= 4'b0000;
      4'b0001: {y1,y2,oe,we} <= 4'b0100;
      4'b0011: {y1,y2,oe,we} <= 4'b0100;
      4'b0010: {y1,y2,oe,we} <= 4'b0000;
      4'b0100: {y1,y2,oe,we} <= 4'b1100;
      4'b0101: {y1,y2,oe,we} <= 4'b1100;
      4'b0111: {y1,y2,oe,we} <= 4'b1000;
      4'b0110: {y1,y2,oe,we} <= 4'b1000;
      4'b1100: {y1,y2,oe,we} <= 4'b1101;
      4'b1101: {y1,y2,oe,we} <= 4'b0001;
      4'b1111: {y1,y2,oe,we} <= 4'b0001;
      4'b1110: {y1,y2,oe,we} <= 4'b1101;
      4'b1000: {y1,y2,oe,we} <= 4'b1010;
      4'b1001: {y1,y2,oe,we} <= 4'b0010;
      4'b1011: {y1,y2,oe,we} <= 4'b0010;
      4'b1010: {y1,y2,oe,we} <= 4'b1010;
    endcase
  end
endmodule

Hi, thanks for ur advice. But is this possible write in to "if else" condition statement ? Pls advice. Thanks.
 

simple fsm code

Yes it is very much possible to write 'if else' statement, and it will be functionally correct, BUT 'if else' will include priority encoding giving you very long ctitical path. So unless you want the priority, you wont use it.
Kr,
Avi
http://www.vlsiip.com
 

fsm verilog code

avimit said:
Yes it is very much possible to write 'if else' statement, and it will be functionally correct, BUT 'if else' will include priority encoding giving you very long ctitical path. So unless you want the priority, you wont use it.
Kr,
Avi
http://www.vlsiip.com

Hi, Is it possible avimit write me a few lines just to show me the diff btw "case" & "if else" statement ? Thx in advance. And actually i cant really understand the example that avimit show me earlier. And for the answer that echo47 provided, why the Y1,Y2 never define ? Why the Y1,Y2 is treat as an output with the combination of "oe,we" ? How the state table tell us that is a Moore machine ? Pls advice.
 

verilog fsm code

kseng2002 said:
Hi , can any1 guide me on how to write the following Verilog code from the table below ? Im new to Verilog and using qu(at)rtus II. Thanks in advance.

PS Inputs NS Outputs
y1y2 rw rdy Y1Y2 oe we
0 0 0 0 0 0 0 0
0 0 0 1 0 1 0 0
0 0 1 1 0 1 0 0
0 0 1 0 0 0 0 0

0 1 0 0 1 1 0 0
0 1 0 1 1 1 0 0
0 1 1 1 1 0 0 0
0 1 1 0 1 0 0 0

1 1 0 0 1 1 0 1
1 1 0 1 0 0 0 1
1 1 1 1 0 0 0 1
1 1 1 0 1 1 0 1

1 0 0 0 1 0 1 0
1 0 0 1 0 0 1 0
1 0 1 1 0 0 1 0
1 0 1 0 1 0 1 0


Hi all, refering to the table above, the state diagram that i draw as attchment is that correct ? Pls advice ! Thx !

 

fsm verilog code

I think u shud go thru basics of fsm !

search in upload n download section !
 

verilog simple example fsm

Your state diagram shows S1 branching to both S2 and S3 when the input is 10.
 

simple fsm in verilog

echo47 said:
Try this. I basically copied your table into a 'case' statement.
The register initializations require Verilog 2001.
Code:
module top (clk, rw, rdy, oe, we);
  input         clk;
  reg           y1=0, y2=0;
  input         rw, rdy;
  output reg    oe=0, we=0;

  always @ (posedge clk) begin
    case ({y1,y2,rw,rdy})
      4'b0000: {y1,y2,oe,we} <= 4'b0000;
      4'b0001: {y1,y2,oe,we} <= 4'b0100;
      4'b0011: {y1,y2,oe,we} <= 4'b0100;
      4'b0010: {y1,y2,oe,we} <= 4'b0000;
      4'b0100: {y1,y2,oe,we} <= 4'b1100;
      4'b0101: {y1,y2,oe,we} <= 4'b1100;
      4'b0111: {y1,y2,oe,we} <= 4'b1000;
      4'b0110: {y1,y2,oe,we} <= 4'b1000;
      4'b1100: {y1,y2,oe,we} <= 4'b1101;
      4'b1101: {y1,y2,oe,we} <= 4'b0001;
      4'b1111: {y1,y2,oe,we} <= 4'b0001;
      4'b1110: {y1,y2,oe,we} <= 4'b1101;
      4'b1000: {y1,y2,oe,we} <= 4'b1010;
      4'b1001: {y1,y2,oe,we} <= 4'b0010;
      4'b1011: {y1,y2,oe,we} <= 4'b0010;
      4'b1010: {y1,y2,oe,we} <= 4'b1010;
    endcase
  end
endmodule

Hi echo47, if i wish to add a "reset" in this code, how can i do that ? Pls advice. Thanks in advance !
 

fsm codes on verilog

For synchronous reset, here's one way to do it:
Code:
module top (clk, reset, rw, rdy, oe, we);
  input         clk;
  reg           y1=0, y2=0;
  input         reset, rw, rdy;
  output reg    oe=0, we=0;

  always @ (posedge clk) begin
    if (reset)
      {y1,y2,oe,we} <= 4'b0000;
    else
      case ({y1,y2,rw,rdy})
        4'b0000: {y1,y2,oe,we} <= 4'b0000;
        4'b0001: {y1,y2,oe,we} <= 4'b0100;
        4'b0011: {y1,y2,oe,we} <= 4'b0100;
        4'b0010: {y1,y2,oe,we} <= 4'b0000;
        4'b0100: {y1,y2,oe,we} <= 4'b1100;
        4'b0101: {y1,y2,oe,we} <= 4'b1100;
        4'b0111: {y1,y2,oe,we} <= 4'b1000;
        4'b0110: {y1,y2,oe,we} <= 4'b1000;
        4'b1100: {y1,y2,oe,we} <= 4'b1101;
        4'b1101: {y1,y2,oe,we} <= 4'b0001;
        4'b1111: {y1,y2,oe,we} <= 4'b0001;
        4'b1110: {y1,y2,oe,we} <= 4'b1101;
        4'b1000: {y1,y2,oe,we} <= 4'b1010;
        4'b1001: {y1,y2,oe,we} <= 4'b0010;
        4'b1011: {y1,y2,oe,we} <= 4'b0010;
        4'b1010: {y1,y2,oe,we} <= 4'b1010;
        default: {y1,y2,oe,we} <= 4'bxxxx;
      endcase
  end
endmodule
I also added a 'default' case because it helps catch bugs (undefined module inputs) during simulation.

Here's another way, using 'casex':
Code:
module top (clk, reset, rw, rdy, oe, we);
  input         clk;
  reg           y1=0, y2=0;
  input         reset, rw, rdy;
  output reg    oe=0, we=0;

  always @ (posedge clk) begin
    casex ({y1,y2,reset,rw,rdy})
      5'b00000: {y1,y2,oe,we} <= 4'b0000;
      5'b00001: {y1,y2,oe,we} <= 4'b0100;
      5'b00011: {y1,y2,oe,we} <= 4'b0100;
      5'b00010: {y1,y2,oe,we} <= 4'b0000;
      5'b01000: {y1,y2,oe,we} <= 4'b1100;
      5'b01001: {y1,y2,oe,we} <= 4'b1100;
      5'b01011: {y1,y2,oe,we} <= 4'b1000;
      5'b01010: {y1,y2,oe,we} <= 4'b1000;
      5'b11000: {y1,y2,oe,we} <= 4'b1101;
      5'b11001: {y1,y2,oe,we} <= 4'b0001;
      5'b11011: {y1,y2,oe,we} <= 4'b0001;
      5'b11010: {y1,y2,oe,we} <= 4'b1101;
      5'b10000: {y1,y2,oe,we} <= 4'b1010;
      5'b10001: {y1,y2,oe,we} <= 4'b0010;
      5'b10011: {y1,y2,oe,we} <= 4'b0010;
      5'b10010: {y1,y2,oe,we} <= 4'b1010;
      5'bxx1xx: {y1,y2,oe,we} <= 4'b0000;   // reset
    endcase
  end
endmodule
I don't like the 'casex' method as much, because the helpful 'default' case that I added to the previous example would be ineffective in the 'casex'.
 

    kseng2002

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top