0
\$\begingroup\$

I am trying to debug my finite state machine in modelsim and I have no idea what's wrong with the code. It would be helpful to see the state/next_state internal signals in the waveform viewer. Is this possible?

Is there anything that is wrong with this code? It compiles but it's not progressing to the next state after starting at Start at the posedge of clk.

  module statemachine(resetb, slow_clock, dscore, pscore, pcard3, loadpcard1, loadpcard2, loadpcard3, loaddcard1, loaddcard2, loaddcard3, player_win_light, dealer_win_light);
  input logic resetb;
  input logic slow_clock;
  input logic  [3:0] dscore;
  input logic [3:0] pscore;
  input logic [3:0] pcard3;
  output logic loadpcard1, loadpcard2, loadpcard3, loaddcard1,loaddcard2, loaddcard3;
  output logic player_win_light, dealer_win_light;

  enum reg [2:0] {Start = 3'b000, FirstP = 3'b001, FirstD = 3'b010, SecondP = 3'b011, SecondD = 3'b100, ThirdP = 3'b101, ThirdD =  3'b110, GameOver = 3'b111} state, next_state;

always_comb
begin
  case(state)
    Start: next_state = FirstP; 
    FirstP: next_state = FirstD;
    FirstD: next_state = SecondP;
    SecondP: next_state = SecondD;
    SecondD: next_state = pscore == 4'b1000 || pscore == 4'b1001 || dscore == 4'b1000 || dscore == 4'b1001 ? GameOver :
               pscore <= 1'd5 ? ThirdP :
             dscore <= 3'd5 ? ThirdD : GameOver;                
    ThirdP: next_state = dscore == 3'd7 ? GameOver : 
             dscore == 3'd6 && (pcard3 == 3'd6 || pcard3 == 3'd7) ? ThirdD :
                   dscore == 3'd5 && (pcard3 == 2'd4 || pcard3 == 3'd5 || pcard3 == 3'd6 || pcard3 == 3'd7) ? ThirdD :
             dscore == 3'd4 && (pcard3 != 1'd0 && pcard3 != 1'd1 && pcard3 != 3'd8) ? ThirdD :
               dscore == 3'd3 && pcard3 != 8 ? ThirdD :
                 GameOver;  
    ThirdD: next_state = GameOver;
    GameOver: next_state = GameOver;
   endcase
end

always_ff @ (posedge slow_clock) begin
    if (resetb == 0)
      state <= Start;
    else
      state <= next_state;
   end

always_comb
begin
  case(state)
    Start: 
    begin
            loadpcard1 = 0;
        loaddcard1 = 0;
        loadpcard2 = 0;
        loaddcard2 = 0;
        loadpcard3 = 0;
        loaddcard3 = 0;
        player_win_light = 0;
        dealer_win_light = 0;
    end
    FirstP:
    begin 
        loadpcard1 = 1;
        loaddcard1 = 0;
        loadpcard2 = 0;
        loaddcard2 = 0;
        loadpcard3 = 0;
        loaddcard3 = 0;
        player_win_light = 0;
        dealer_win_light = 0;   
    end 
    FirstD: 
      begin loaddcard1 = 1;
            loadpcard1 = 0;
        loadpcard2 = 0;
        loaddcard2 = 0;
        loadpcard3 = 0;
        loaddcard3 = 0;
        player_win_light = 0;
        dealer_win_light = 0;
      end   
    SecondP: 
      begin
        loadpcard1 = 0;
        loaddcard1 = 0;
            loadpcard2 = 1;
        loaddcard2 = 0;
        loadpcard3 = 0;
        loaddcard3 = 0;
        player_win_light = 0;
        dealer_win_light = 0;
      end
    SecondD:
      begin
        loadpcard1 = 0;
        loaddcard1 = 0;
            loadpcard2 = 0;
        loaddcard2 = 1;
        loadpcard3 = 0;
        loaddcard3 = 0;
        player_win_light = 0;
        dealer_win_light = 0;
      end

    ThirdP:  
     begin
        loadpcard1 = 0;
        loaddcard1 = 0;
            loadpcard2 = 0;
        loaddcard2 = 0;
        loadpcard3 = 1;
        loaddcard3 = 0;
        player_win_light = 0;
        dealer_win_light = 0;
      end
    ThirdD:
     begin
        loadpcard1 = 0;
        loaddcard1 = 0;
            loadpcard2 = 0;
        loaddcard2 = 0;
        loadpcard3 = 0;
        loaddcard3 = 1;
        player_win_light = 0;
        dealer_win_light = 0;
      end
    GameOver:
      begin
        loadpcard1 = 0;
        loaddcard1 = 0;
            loadpcard2 = 0;
        loaddcard2 = 0;     
            loaddcard3 = 0;
        loaddcard3 = 0;
        player_win_light = 0;
        dealer_win_light = 0;
        player_win_light = (pscore > dscore) ? 1 : ((dscore > pscore) ? 0 : 0);
        dealer_win_light = (dscore > pscore) ? 1 : ((pscore > dscore) ? 0 : 0);  
      end
  endcase
end

endmodule
\$\endgroup\$
0
\$\begingroup\$

There is an 'objects' window.

That allows you to browse your design going up and down the hierarchy (e.g. like a computer directory structure).

From there you can either drag the signals onto the waveform windows or right click on one or more signals and select "add wave".

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thank you. It works now. \$\endgroup\$ – GauiX3 May 17 '19 at 5:19
0
\$\begingroup\$

All RTL signals are accessible for probing in waveform viewers. If your are using standard VCD, you can dump all signals by adding the below to your top level module. Some simulators support additional waveform file types and/or UI to enable dumping and select signals; in which case refer to tutorials and manuals on your simulator.

initial begin
  $dumpfile("dump.vcd");
  $dumpvars;
end

As for your code:
Your simulator has a race condition because the clock is being referenced in your always_comb block. In your case it sounds like always_ff is being evaluated before always_comb, thereby next_state will have the value with the condition of slow_clock being low.

If you were to try to synthesize your current code. Then you would likely have a setup and hold time violations. And if it didn't you would get the same behavior as what you are currently seeing.

The solution is to remove slow_clock from your always_comb. For example: Start: next_state = slow_clock ? FirstP : Start; should be Start: next_state = FirstP;

Another issue is your outputs are inferred latches (level-sensitive) and assigned in an always_comb. In ideal simulator should throw an error or warning when this is done, but leave this check to synthesizers, linters, and logical equivalent checkers. Latching are discouraged for most RTL design. For detail read Why are inferred latches bad? and What is inferred latch and how it is created when it is missing else statement in if condition

The output can be combinational, but I'd recommend making then flip-flops to avoid glitches on the output.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thank you. This is very helpful \$\endgroup\$ – GauiX3 May 17 '19 at 5:19

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.