4.53

1. data hazard

something handled by data-forward must be handled by stall if no data-forward anymore. so when

d_srcA in { e_dstE, M_dstM, M_dstE, W_dstM, W_dstE } ||
d_srcB in { e_dstE, M_dstM, M_dstE, W_dstM, W_dstE }

data hazard happens, we have to insert bubble in phase E and stall phase F&D

load/use hazard

load/use hazard only happens when we use data-forward. no load/use hazard if no data-forward.

pay attention

  • previous load/use toggle condition d_srcA == E_dstM || d_srcB == E_dstM now toggles data hazard.
  • in the beginning, d_srcA == RNONE == e_dstE == E_dstM == ...etc, that’s not data hazard

so we get:

situation: data_hazard
bool s_data_hazard =
  (
    (
      d_srcA != RNONE  &&
      d_srcA in { e_dstE, E_dstM, M_dstM, M_dstE, W_dstM, W_dstE }
    ) ||
    (
      d_srcB != RNONE  &&
      d_srcB in { e_dstE, E_dstM, M_dstM, M_dstE, W_dstM, W_dstE }
    )
  )

2. ret situation

keep same

situation: ret
bool s_ret = IRET in { D_icode, E_icode, M_icode };

3. jxx error

keep same

situation: jxx error
bool s_jxx_error = (E_icode == IJXX && !e_Cnd);

4. hazard composition

X means nothing to do; stall means stall; bubble means inserting bubble

numdataretjxxFDEMW
1000XXXXX
2001XbubblebubbleXX
3010stallbubbleXXX
4100stallstallbubbleXX

situation 1: nothing happens, every thing is fine

situation 2: just jxx error, keep same with book

situation 3: just ret, keep same with book

situation 4: just data hazard, stall phase F and D, insert bubble in phase E, M and W keep same

what if two/three of them happen same time?

ret:

  +-----------+    +-----------+    +-----------+
M |           |  M |           |  M |    ret    |
  +-----------+    +-----------+    +-----------+
E |           |  E |    ret    |  E |    nop    |
  +-----------+    +-----------+    +-----------+
D |    ret    |  D |    nop    |  D |    nop    |
  +-----------+    +-----------+    +-----------+
        1                2                3

one of them

jxx error:

  +-----------+
M |           |
  +-----------+
E |    jxx    |
  +-----------+
D |           |
  +-----------+

when jxx error happens, E_icode must be jxx

data hazard:

               <--+
  +-----------+   |
M |           |<--+
  +-----------+   |
E |           |<--+
  +-----------+   |
D |    xxx    +---+
  +-----------+

when data hazard happens, D_icode is not sure, xxx means any instruction

composition 1: ret and jxx

keep same on book

composition 2: ret and data hazard

they two happens same time, so xxx must be ret

               <--+
  +-----------+   |
M |           |<--+
  +-----------+   |
E |           |<--+
  +-----------+   |
D |    ret    +---+
  +-----------+

when they happen same time, data hazard is prior to ret because if ret doesn’t stall to avoid data hazard, we get wrong answer with ISA

composition 3: jxx error and data hazard

               <--+
  +-----------+   |
M |           |<--+
  +-----------+   |
E |    jxx    |<--+
  +-----------+   |
D |    xxx    +---+
  +-----------+

when they two happens same time, jxx error is prior to data hazard because next 2 instructions is canceled when jxx error, xxx is canceled anymore.

composition 4: ret & jxx error & data hazard

               <--+
  +-----------+   |
M |           |<--+
  +-----------+   |
E |    jxx    |<--+
  +-----------+   |
D |    ret    +---+
  +-----------+

same like composition 3.

finally:

numdataretjxxFDEMW
1000XXXXX
2001XbubblebubbleXX
3010stallbubbleXXX
4100stallstallbubbleXX
5011XbubblebubbleXX
6101XbubblebubbleXX
7110stallstallbubbleXX
8111XbubblebubbleXX

F:

  • stall: (data || ret) && !jxx
  • bubble: 0

D:

  • stall: data && !jxx
  • bubble: jxx || (!data && ret)

E:

  • stall: 0
  • bubble: jxx || data

M:

keep same

W:

keep same

finally:

check file ./site/content/chapter4/code/sim/pipe/pipe-stall.hcl

watch changes with origin pipe-stall.hcl file

(cd ./site/content/chapter4/code/sim/pipe; diff -u origin-pipe-stall.hcl pipe-stall.hcl)
--- origin-pipe-stall.hcl	2021-02-25 07:26:33.309259378 +0000
+++ pipe-stall.hcl	2021-02-25 07:26:33.309259378 +0000
@@ -303,40 +303,95 @@
 ];
 
 ################ Pipeline Register Control #########################
+# situation: ret
+# bool s_ret = IRET in { D_icode, E_icode, M_icode };
+#
+# situation: jxx error
+# bool s_jxx_error = (E_icode == IJXX && !e_Cnd);
+#
+# situation: data_hazard
+# bool s_data_hazard =
+#   (
+#     (
+#       d_srcA != RNONE  &&
+#       d_srcA in { e_dstE, E_dstM, M_dstM, M_dstE, W_dstM, W_dstE }
+#     ) ||
+#     (
+#       d_srcB != RNONE  &&
+#       d_srcB in { e_dstE, E_dstM, M_dstM, M_dstE, W_dstM, W_dstE }
+#     )
+#   )
 
 # Should I stall or inject a bubble into Pipeline Register F?
 # At most one of these can be true.
-bool F_stall =
-	# Modify the following to stall the update of pipeline register F
-	0 ||
-	# Stalling at fetch while ret passes through pipeline
-	IRET in { D_icode, E_icode, M_icode };
+# bool F_stall = (s_ret || s_data_hazard) && !s_jxx_error;
+bool F_stall = (
+    (IRET in { D_icode, E_icode, M_icode }) ||
+    (
+      (
+        d_srcA != RNONE  &&
+        d_srcA in { e_dstE, E_dstM, M_dstM, M_dstE, W_dstM, W_dstE }
+      ) ||
+      (
+        d_srcB != RNONE  &&
+        d_srcB in { e_dstE, E_dstM, M_dstM, M_dstE, W_dstM, W_dstE }
+      )
+    )
+  ) &&
+  !(E_icode == IJXX && !e_Cnd);
 
 bool F_bubble = 0;
 
 # Should I stall or inject a bubble into Pipeline Register D?
 # At most one of these can be true.
-bool D_stall = 
-	# Modify the following to stall the instruction in decode
-	0;
+# bool D_stall = s_data_hazard && !s_jxx_error;
+# bool D_bubble = s_jxx_error || (!s_data_hazard && s_ret)
+bool D_stall = (
+    (
+      d_srcA != RNONE  &&
+      d_srcA in { e_dstE, E_dstM, M_dstM, M_dstE, W_dstM, W_dstE }
+    ) ||
+    (
+      d_srcB != RNONE  &&
+      d_srcB in { e_dstE, E_dstM, M_dstM, M_dstE, W_dstM, W_dstE }
+    )
+  ) &&
+  !(E_icode == IJXX && !e_Cnd);
 
 bool D_bubble =
-	# Mispredicted branch
-	(E_icode == IJXX && !e_Cnd) ||
-	# Stalling at fetch while ret passes through pipeline
-	!(E_icode in { IMRMOVQ, IPOPQ } && E_dstM in { d_srcA, d_srcB }) &&
-	# but not condition for a generate/use hazard
-	!0 &&
-	  IRET in { D_icode, E_icode, M_icode };
+  (E_icode == IJXX && !e_Cnd) ||
+  (
+    !(
+      (
+        d_srcA != RNONE  &&
+        d_srcA in { e_dstE, E_dstM, M_dstM, M_dstE, W_dstM, W_dstE }
+      ) ||
+      (
+        d_srcB != RNONE  &&
+        d_srcB in { e_dstE, E_dstM, M_dstM, M_dstE, W_dstM, W_dstE }
+      )
+    ) &&
+    (IRET in { D_icode, E_icode, M_icode })
+  );
 
 # Should I stall or inject a bubble into Pipeline Register E?
 # At most one of these can be true.
+# bool E_stall = 0;
+# bool E_bubble = s_jxx_error || s_data_hazard
 bool E_stall = 0;
 bool E_bubble =
-	# Mispredicted branch
-	(E_icode == IJXX && !e_Cnd) ||
-	# Modify the following to inject bubble into the execute stage
-	0;
+  (E_icode == IJXX && !e_Cnd) ||
+  (
+    (
+      d_srcA != RNONE  &&
+      d_srcA in { e_dstE, E_dstM, M_dstM, M_dstE, W_dstM, W_dstE }
+    ) ||
+    (
+      d_srcB != RNONE  &&
+      d_srcB in { e_dstE, E_dstM, M_dstM, M_dstE, W_dstM, W_dstE }
+    )
+  );
+
 
 # Should I stall or inject a bubble into Pipeline Register M?
 # At most one of these can be true.
comments powered by Disqus