]> git.sesse.net Git - pistorm/blobdiff - rtl/pistorm.v
Improve 68k cycle state machine
[pistorm] / rtl / pistorm.v
index 0b26ffdbf0981b218a18ef949956e40e397480ad..2f0fc815a5dc75145f4f85c3b7415399b16aa064 100644 (file)
@@ -50,7 +50,9 @@ module pistorm(
   );
 
   wire c200m = PI_CLK;
-  wire c7m = M68K_CLK;
+  reg [2:0] c7m_sync;
+//  wire c7m = M68K_CLK;
+  wire c7m = c7m_sync[2];
 
   localparam REG_DATA = 2'd0;
   localparam REG_ADDR_LO = 2'd1;
@@ -117,47 +119,8 @@ module pistorm(
     LTCH_D_RD_OE_n <= !(PI_A == REG_DATA && PI_RD);
   end
 
-  reg [2:0] s1_sync;
-  reg [2:0] s7_sync;
-
-  always @(posedge c200m) begin
-    s1_sync <= {s1_sync[1:0], S1};
-    s7_sync <= {s7_sync[1:0], S7};
-  end
-
-  wire rising_s1 = !s1_sync[2] && s1_sync[1];
-  wire rising_s7 = !s7_sync[2] && s7_sync[1];
-
   reg a0;
 
-  always @(posedge c200m) begin
-    if (rising_s1)
-      op_req <= 1'b0;
-
-    if (rising_s7)
-      PI_TXN_IN_PROGRESS <= 1'b0;
-
-    if (wr_rising) begin
-      case (PI_A)
-        REG_ADDR_LO: begin
-          a0 <= PI_D[0];
-          PI_TXN_IN_PROGRESS <= 1'b1;
-        end
-        REG_ADDR_HI: begin
-          op_req <= 1'b1;
-          op_rw <= PI_D[9];
-          op_uds_n <= PI_D[8] ? a0 : 1'b0;
-          op_lds_n <= PI_D[8] ? !a0 : 1'b0;
-        end
-        REG_STATUS: begin
-          status <= PI_D;
-        end
-      endcase
-    end
-  end
-
-  reg [2:0] c7m_sync;
-
   always @(posedge c200m) begin
     c7m_sync <= {c7m_sync[1:0], M68K_CLK};
   end
@@ -201,78 +164,112 @@ module pistorm(
       M68K_E <= 1'b1;
   end
 
-  reg [1:0] state = 2'd0;
-  reg wait_req = 1'b1;
-  reg wait_dtack = 1'b0;
-
-  wire S0 = state == 2'd0 && c7m && !wait_req;
-  wire Sr = state == 2'd0 && wait_req;
-  wire S1 = state == 2'd1 && !c7m;
-  wire S2 = state == 2'd1 && c7m;
-  wire S3 = state == 2'd2 && !c7m && !wait_dtack;
-  wire S4 = state == 2'd2 && c7m && !wait_dtack;
-  wire Sw = state == 2'd2 && wait_dtack;
-  wire S5 = state == 2'd3 && !c7m;
-  wire S6 = state == 2'd3 && c7m;
-  wire S7 = state == 2'd0 && !c7m && !wait_req;
-
-  always @(*) begin
-    LTCH_A_OE_n <= !(S1 || S2 || S3 || S4 || Sw || S5 || S6 || S7);
-    LTCH_D_WR_OE_n <= !(!op_rw && (S3 || S4 || Sw || S5 || S6 || S7));
+  reg [2:0] state = 3'd0;
+  reg [2:0] PI_TXN_IN_PROGRESS_delay;
 
-    LTCH_D_RD_U <= S7;
-    LTCH_D_RD_L <= S7;
+  always @(posedge c200m) begin
 
-    M68K_AS_n <= !(S2 || S3 || S4 || Sw || S5 || S6);
-    M68K_UDS_n <= (op_rw && (S2 || S3)) || (S4 || Sw || S5 || S6) ? op_uds_n : 1'b1;
-    M68K_LDS_n <= (op_rw && (S2 || S3)) || (S4 || Sw || S5 || S6) ? op_lds_n : 1'b1;
-  end
+    if (wr_rising) begin
+      case (PI_A)
+        REG_ADDR_LO: begin
+          a0 <= PI_D[0];
+          PI_TXN_IN_PROGRESS <= 1'b1;
+        end
+        REG_ADDR_HI: begin
+          op_req <= 1'b1;
+          op_rw <= PI_D[9];
+          op_uds_n <= PI_D[8] ? a0 : 1'b0;
+          op_lds_n <= PI_D[8] ? !a0 : 1'b0;
+        end
+        REG_STATUS: begin
+          status <= PI_D;
+        end
+      endcase
+    end
 
-  always @(negedge c7m) begin
     case (state)
-      2'd0: begin // S0|Sr -> S1|Sr
-        if (op_req_sync) begin
-          wait_req <= 1'b0;
-          state <= state + 2'd1;
+      3'd0: begin // S0
+        M68K_RW <= 1'b1; // S7 -> S0
+//        if (c7m_falling) begin
+//          if (op_req) begin
+            state <= 2'd1;
+//          end
+//        end
+      end
+
+      3'd1: begin // S1
+        if (op_req) begin
+          if(c7m_rising) begin
+            state <= 3'd2;
+          end
         end
-        else begin
-          wait_req <= 1'b1;
+      end
+      3'd2: begin // S2
+        M68K_RW <= op_rw; // S1 -> S2
+        LTCH_D_WR_OE_n <= op_rw;
+        LTCH_A_OE_n <= 1'b0;
+        M68K_AS_n <= 1'b0;
+        M68K_UDS_n <= op_rw ? op_uds_n : 1'b1;
+        M68K_LDS_n <= op_rw ? op_lds_n : 1'b1;
+        if (c7m_falling) begin
+          M68K_UDS_n <= op_uds_n;
+          M68K_LDS_n <= op_lds_n;
+          state <= 3'd3;
         end
       end
 
-      2'd1: begin // S2 -> S3
-        state <= state + 2'd1;
+      3'd3: begin // S3
+        op_req <= 1'b0;
+        if(c7m_rising) begin
+          if (!M68K_DTACK_n || (!M68K_VMA_n && e_counter == 4'd8)) begin
+            state <= 3'd4;
+            PI_TXN_IN_PROGRESS_delay[2:0] <= 3'b111;
+          end
+          else begin
+            if (!M68K_VPA_n && e_counter == 4'd2) begin
+              M68K_VMA_n <= 1'b0;
+            end
+          end
+        end
+      end
+      3'd4: begin // S4
+        PI_TXN_IN_PROGRESS_delay <= {PI_TXN_IN_PROGRESS_delay[1:0],1'b0};
+        PI_TXN_IN_PROGRESS <= PI_TXN_IN_PROGRESS_delay[2];
+        LTCH_D_RD_U <= 1'b1;
+        LTCH_D_RD_L <= 1'b1;
+        if (c7m_falling) begin
+          state <= 3'd5;
+          PI_TXN_IN_PROGRESS <= 1'b0;
+        end
       end
 
-      2'd2: begin // S4|Sw -> S5|Sw
-        if (!M68K_DTACK_n || (!M68K_VMA_n && e_counter == 4'd8)) begin
-          wait_dtack <= 1'b0;
-          state <= state + 2'd1;
+      3'd5: begin // S5
+        LTCH_D_RD_U <= 1'b0;
+        LTCH_D_RD_L <= 1'b0;
+        if (c7m_rising) begin
+          state <= 3'd6;
         end
-        else begin
-          if (!M68K_VPA_n && e_counter == 4'd2) begin
-            M68K_VMA_n <= 1'b0;
-          end
-          wait_dtack <= 1'b1;
+      end
+       
+      3'd6: begin // S6
+        if (c7m_falling) begin
+          M68K_VMA_n <= 1'b1;
+          state <= 3'd7;
         end
       end
-
-      2'd3: begin // S6 -> S7
-        M68K_VMA_n <= 1'b1;
-        state <= state + 2'd1;
+       
+      3'd7: begin // S7
+        LTCH_D_WR_OE_n <= 1'b1;
+        LTCH_A_OE_n <= 1'b1;
+        M68K_AS_n <= 1'b1;
+        M68K_UDS_n <= 1'b1;
+        M68K_LDS_n <= 1'b1;
+//        if(c7m_rising) begin
+//          M68K_RW <= 1'b1; // S7 -> S0
+          state <= 3'd0;
+//        end
       end
     endcase
   end
 
-  reg op_req_sync;
-
-  always @(posedge c7m) begin
-    op_req_sync <= op_req;
-
-    case (state)
-      2'd0: M68K_RW <= 1'b1; // S7 -> S0
-      2'd1: M68K_RW <= op_rw; // S1 -> S2
-    endcase
-  end
-
 endmodule