title: Iteration limit when implementing a multicycled processor
body: <p>I'm trying to implement a simple multicycle processor and I ran into some problems that I don't seem to be getting through. The code is below. I'm just experimenting right now to get this flowing. When I'm done, I'll begin implementing instructions and ALU. However, I'm stuck at this point. In the code below, I'm aware that <code>data_memory</code> is never used (I'll get to there if I can resolve this), some inputs and outputs are also not used for now, <code>x1</code> and <code>x2</code> are just variables I created to see what's really going on. What's in <code>definitions.v</code> file is self-evident.  </p>
  
  <p>I'm using Altera Quartus 15.1 with Verilog2001. This code compiles fine excepts some warnings due to unused stuff but when I try to simulate it with a clock period of 20ns it gives an error saying that "Error (suppressible): (vsim-3601) Iteration limit 5000 reached at time 100 ns". It also says this is suppressible but I don't know how to suppress either.</p>
  
  <p>I looked up for this error and I learned that this is happening because at some point the code goes into an infinite loop. I tried to solve this by creating another variable <code>ok</code>. A cycle will start by setting <code>ok</code> to <code>0</code> and after microoperations for that cycle are done, I set <code>ok</code> to <code>1</code>. So the cycle will not change at an improper time (it's like locking the cycle). Unfortunately, this resulted with the same error.</p>
  
  <p>I tried another flow, too. Instead of <code>cycle</code> and <code>next_cycle</code>, I created one variable for cycle. At every rising edge of clock, I checked the current state and did things accordingly, then set the cycle for next step. Example:  </p>
  
  <pre><code>always @ (posedge clk) begin
      case (cycle)
          3'b000: begin
              MAR &lt;= PC;
              cycle &lt;= 3'b001;
              ire &lt;= 1'b1;
              x2 &lt;= 2'b00; 
          3'b001: begin
              ...
              ...
  </code></pre>
  
  <p>This also compiles fine, and can be simulated without error! However, is not functioning correctly, giving weird(or unexpected) results. I find other approach more intuitive. So I will try to make it work.</p>
  
  <p>How can I resolve/implement this?</p>
  
  <pre><code>`include "definitions.v"
  
  module controller(
      input                           clk,
      input                           nres,
      output reg                      ire,
      output reg                      dwe,
      output reg                      dre,
      output reg  [1:0]               x2,
      output reg  [`IADR_WIDTH-1:0]   i_address,
      output reg  [`DADR_WIDTH-1:0]   d_address,
      output reg  [`DATA_WIDTH-1:0]   data_out);
  
      reg [2:0] cycle = 3'b000;
      reg [2:0] next_cycle;
  
      reg [`IADR_WIDTH-1:0] PC  = 6'b000000;
      reg [`INST_WIDTH-1:0] IR  = 12'b00000_0000000;
      reg [`DADR_WIDTH-1:0] MAR = 6'b000000;        
      reg [4:0]             OPC = 5'b00000;
  
      wire [`DATA_WIDTH-1:0] data_in;
      wire [`INST_WIDTH-1:0] instruction;
  
      reg [1:0] x1;
  
      data_memory dmem        (   .clk        (clk),
                                  .dwe        (dwe),
                                  .dre        (dre),
                                  .nres       (nres),
                                  .d_address  (d_address),
                                  .d_data     (data_out),
                                  .d_q        (data_in));
  
      instruction_memory imem (   .clk        (clk),
                                  .ire        (ire),
                                  .i_address  (i_address),
                                  .i_q        (instruction));
  
      reg ok = 1;
  
      always @ (posedge clk) begin
          cycle = (ok) ? next_cycle : cycle;
      end
  
      always @ (cycle) begin
          case (cycle)
              3'b000: begin
                  ok = 0;
                  MAR = PC;
                  next_cycle = 3'b001;
                  ire = 1'b1;
                  x2 = 2'b00;
                  ok = 1;
              end
              3'b001: begin
                  ok = 0;
                  i_address = MAR;
                  IR = instruction;
                  ire = 1'b0;
                  next_cycle = 3'b010;
                  x2 = 2'b01;
                  ok = 1;
              end
              3'b010: begin
                  ok = 0;
                  OPC = IR;
                  next_cycle = 3'b011;
                  x2 = 2'b10;
                  ok = 1;
              end
              3'b011: begin
                  ok = 0;
                  if (OPC==5'b01011)  x1 = 2'b11;
                  PC = PC + 1;
                  next_cycle = 3'b000;
                  x2 = 2'b11;
                  ok = 1;
              end
          endcase    
      end
  
  endmodule
  </code></pre>