Question

I'm trying to create a Finite state machine in verilog. The system has 4 1-bit inputs rst, clk, A, B and one output, Z.

Z is equal to 1 if either: A had same value on last two clock edges.

or B has been high (1) on every clock edge since the last rule was true.

Otherwise z=0;

I don't have the tools to simulate my attempt atm. So I'm wondering if this is the correct method and if i'm on the right track?

module StateMachine( R, A, B, clk, Z);
   input R, A, B, clk;
   output reg Z;

   reg ATemp;
   reg state;

   always @ (posedge clk or A)
      if (A == 1'b1) 
      /////////////////
      begin
         if (ATemp == 1'b1) state <= 1'b1; 
         else ATemp <= A;
       end
       ////////////////
       else
       ////////////
       begin
          if (ATemp == 1'b0) state <= 1'b1;
          else ATemp <= A;
       end


   always @ (state)
      case(state)
         1'b0: Z=0;
         1'b1: Z=1;

         default: Z=0;
      endcase

endmodule
Was it helpful?

Solution

You can use the following tools:

GHDL is an open-source simulator for the VHDL language ( User Guide )

Additionally these are the most popular simulation tools:

Further resources:

There is also the stackexchange electronics community and codereview.

Additionally, heed the C to HDL compiler tool

(.. I doubt many can review your code in 3 minutes, nor would I want them too )

OTHER TIPS

You have no next state logic so state will never change, and there's no reset so state will start as 1'bz. I recommend starting with Xilinx guidelines when coding state machines.

Your definition of a flipflop is slightly wrong. You have always @ (posedge clk or A). You should not combine edge triggers and non-edge triggers. It might work in simulation but you will not get what you want in synthesis.

If you only want the value to change on a clock edge then use always @( posedge clk) or for a combinatorial input, that is output changes with input use always @( A ) or the more modern version always @*. @* will trigger for any changes. Missing items from the sensitivity list use to be a main reason for synthesised code not simulating the same as the RTL.

Saying that if you are building a flip flop you should include a reset. always @ (posedge clk or negedge rst_n)

Also note the state is never set to 0, so first impression is that this will lock up into to a particular state/output. It is hard for me to see how the code implements the question being asked. My solution would be some thing like:

module statemachine(
  input      rst,
  input      A,
  input      B,
  input      clk,
  output reg Z
);

  reg  [1:0] a_last_two;
  wire      rule_one;

  always @ (posedge clk or negedge rst) begin
    if (~rst) begin
      a_last_two <= 2'b0;
    end
    else begin
      a_last_two <= {a_last_two[0] ,A}; 
    end
  end

  assign rule_one = (a_last_two[1] == a_last_two[0]); 
  //rule one could be written as ~^a_last_two (xnor reduction operator)

  reg rule_two;
  always @ (posedge clk or negedge rst) begin
    if (~rst) begin
      rule_two <= 1'b0 ;
    end
    else begin
      //rule 2 resets when rule_one is true
      if (rule_one) begin
        rule_two <= 1'b1 ;
      end
      else begin
        rule_two <= rule_two & B ;
      end
    end
  end

  assign Z = rule_one | rule_two ;

endmodule
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top