Advertisement
Guest User

Untitled

a guest
May 19th, 2016
110
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. From 509359c00a59591e0dbfa5c2db3fc35fac15e38d Mon Sep 17 00:00:00 2001
  2. From: "Alex L. White" <space.monkey.delivers@gmail.com>
  3. Date: Thu, 19 May 2016 19:36:06 +0300
  4. Subject: [PATCH] Introducing saturation counter branch predictor
  5.  
  6. ---
  7. rtl/verilog/mor1kx_branch_prediction.v | 84 ++++++++++++++++------
  8. .../mor1kx_branch_predictor_saturation_counter.v | 83 +++++++++++++++++++++
  9. rtl/verilog/mor1kx_branch_predictor_simple.v | 36 ++++++++++
  10. rtl/verilog/mor1kx_cpu_cappuccino.v | 14 +++-
  11. rtl/verilog/mor1kx_decode_execute_cappuccino.v | 10 +++
  12. 5 files changed, 204 insertions(+), 23 deletions(-)
  13. create mode 100644 rtl/verilog/mor1kx_branch_predictor_saturation_counter.v
  14. create mode 100644 rtl/verilog/mor1kx_branch_predictor_simple.v
  15.  
  16. diff --git a/rtl/verilog/mor1kx_branch_prediction.v b/rtl/verilog/mor1kx_branch_prediction.v
  17. index a82c1f9..0143e87 100644
  18. --- a/rtl/verilog/mor1kx_branch_prediction.v
  19. +++ b/rtl/verilog/mor1kx_branch_prediction.v
  20. @@ -18,35 +18,77 @@
  21.  
  22. module mor1kx_branch_prediction
  23. #(
  24. - parameter OPTION_OPERAND_WIDTH = 32
  25. + parameter OPTION_OPERAND_WIDTH = 32,
  26. + parameter FEATURE_BRANCH_PREDICTOR = "NONE"
  27. )
  28. (
  29. - input clk,
  30. - input rst,
  31. + input clk,
  32. + input rst,
  33.  
  34. - // Signals belonging to the stage where the branch is predicted.
  35. - input op_bf_i,
  36. - input op_bnf_i,
  37. - input [9:0] immjbr_upper_i,
  38. - output predicted_flag_o,
  39. + // Signals belonging to the stage where the branch is predicted.
  40. + input op_bf_i, // from decode stage, brn is bf
  41. + input op_bnf_i, // from decode stage, brn is bnf
  42. + input [9:0] immjbr_upper_i, // from decode stage, imm
  43. + output predicted_flag_o, // to decode-execute stage, flag we predicate to be
  44.  
  45. - // Signals belonging to the stage where the branch is resolved.
  46. - input prev_op_brcond_i,
  47. - input prev_predicted_flag_i,
  48. - input flag_i,
  49. + // Signals belonging to the stage where the branch is resolved.
  50. + input prev_op_brcond_i, // from decode-execute stage, prev brn was cond
  51. + input prev_predicted_flag_i, // from decode-execute, prev predicated flag
  52. + input flag_i, // from execute-ctrl stage, real flag we got
  53.  
  54. - // Branch misprediction indicator
  55. - output branch_mispredict_o
  56. - );
  57. + input padv_decode_i, // is decode stage stalled
  58. + input execute_bf_i, // prev insn was bf
  59. + input execute_bnf_i, // prev insn was bnf
  60. +
  61. + // Branch misprediction indicator
  62. + output branch_mispredict_o // to decode-execute stage, was brn mispredicted or not
  63. + );
  64.  
  65. // Compare the real flag with the previously predicted flag and signal a
  66. // misprediction in case of a mismatch.
  67. - assign branch_mispredict_o = prev_op_brcond_i &
  68. - (flag_i != prev_predicted_flag_i);
  69. + assign branch_mispredict_o = prev_op_brcond_i & (flag_i != prev_predicted_flag_i);
  70.  
  71. - // Static branch prediction - backward branches are predicted as taken,
  72. - // forward branches as not taken.
  73. - assign predicted_flag_o = op_bf_i & immjbr_upper_i[9] |
  74. - op_bnf_i & !immjbr_upper_i[9];
  75. +generate
  76. +if (FEATURE_BRANCH_PREDICTOR=="SAT_COUNTER") begin : branch_predictor_saturation_counter
  77. + mor1kx_branch_predictor_saturation_counter
  78. + #(
  79. + .OPTION_OPERAND_WIDTH(OPTION_OPERAND_WIDTH)
  80. + )
  81. + mor1kx_branch_predictor_saturation_counter
  82. + (
  83. + // Outputs
  84. + .predicted_flag_o (predicted_flag_o),
  85. + // Inputs
  86. + .clk (clk),
  87. + .rst (rst),
  88. + .execute_op_bf_i (execute_op_bf_i),
  89. + .execute_op_bnf_i (execute_op_bnf_i),
  90. + .op_bf_i (op_bf_i),
  91. + .op_bnf_i (op_bnf_i),
  92. + .prev_op_brcond_i (prev_op_brcond_i),
  93. + .branch_mispredict_i (branch_mispredict_o));
  94. +
  95. +end else if (FEATURE_BRANCH_PREDICTOR=="SIMPLE") begin : branch_predictor_simple
  96. + mor1kx_branch_predictor_simple
  97. + #(
  98. + .OPTION_OPERAND_WIDTH(OPTION_OPERAND_WIDTH)
  99. + )
  100. + mor1kx_branch_predictor_simple
  101. + (
  102. + // Outputs
  103. + .predicted_flag_o (predicted_flag_o),
  104. + // Inputs
  105. + .op_bf_i (op_bf_i),
  106. + .op_bnf_i (op_bnf_i),
  107. + .immjbr_upper_i (immjbr_upper_i));
  108. +
  109. +end else if (FEATURE_BRANCH_PREDICTOR!="SIMPLE" &&
  110. + FEATURE_BRANCH_PREDICTOR!="SAT_COUNTER") begin
  111. + initial begin
  112. + $display("Error: FEATURE_PREDICTOR_TYPE, %s, not valid", FEATURE_PREDICTOR_TYPE);
  113. + $finish();
  114. + end
  115. +end
  116. +endgenerate
  117.  
  118. endmodule
  119. diff --git a/rtl/verilog/mor1kx_branch_predictor_saturation_counter.v b/rtl/verilog/mor1kx_branch_predictor_saturation_counter.v
  120. new file mode 100644
  121. index 0000000..07c7efb
  122. --- /dev/null
  123. +++ b/rtl/verilog/mor1kx_branch_predictor_saturation_counter.v
  124. @@ -0,0 +1,83 @@
  125. +/******************************************************************************
  126. + This Source Code Form is subject to the terms of the
  127. + Open Hardware Description License, v. 1.0. If a copy
  128. + of the OHDL was not distributed with this file, You
  129. + can obtain one at http://juliusbaxter.net/ohdl/ohdl.txt
  130. +
  131. + Description: Branch prediction module
  132. + Generates a predicted flag output and compares that to the real flag
  133. + when it comes back in the following pipeline stage.
  134. + Signals are deliberately not named after the pipeline stage they belong to,
  135. + in order to keep this module generic.
  136. +
  137. + Copyright (C) 2013 Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
  138. +
  139. + ******************************************************************************/
  140. +
  141. +`include "mor1kx-defines.v"
  142. +
  143. +module mor1kx_branch_predictor_saturation_counter
  144. + #(
  145. + parameter OPTION_OPERAND_WIDTH = 32
  146. + )
  147. + (
  148. + input clk,
  149. + input rst,
  150. +
  151. + // Signals belonging to the stage where the branch is predicted.
  152. + output predicted_flag_o, //result of predictor
  153. +
  154. + input execute_op_bf_i, // prev insn was bf
  155. + input execute_op_bnf_i, // prev insn was bnf
  156. + input op_bf_i, // cur insn is bf
  157. + input op_bnf_i, // cur insn is bnf
  158. + input padv_decode_i, // pipeline is moved
  159. +
  160. + // Signals belonging to the stage where the branch is resolved.
  161. + input prev_op_brcond_i, // prev op was cond brn
  162. + input branch_mispredict_i // prev brn was mispredicted
  163. + );
  164. +
  165. + localparam [1:0]
  166. + STATE_STRONGLY_NOT_TAKEN = 2'b00,
  167. + STATE_WEAKLY_NOT_TAKEN = 2'b01,
  168. + STATE_WEAKLY_TAKEN = 2'b10,
  169. + STATE_STRONGLY_TAKEN = 2'b11;
  170. +
  171. + reg [1:0] state = STATE_WEAKLY_TAKEN;
  172. +
  173. + assign predicted_flag_o = (state[1] && op_bf_i) || (!state[1] && op_bnf_i);
  174. + wire brn_taken = (execute_op_bf_i && flag_i) || (execute_op_bnf_i && !flag_i);
  175. +
  176. + always @(posedge clk) begin
  177. + if (rst) begin
  178. + // set default state to STATE_WEAKLY_TAKEN
  179. + state <= STATE_WEAKLY_TAKEN;
  180. + end else begin
  181. + // if previous insn was cond brn and pipe is not stalled
  182. + if (prev_op_brcond_i && padv_decode_i) begin
  183. + // if brn was not taken
  184. + if (!brn_taken) begin
  185. + // change fsm state:
  186. + // STATE_STRONGLY_TAKEN -> STATE_WEAKLY_TAKEN
  187. + // STATE_WEAKLY_TAKEN -> STATE_WEAKLY_NOT_TAKEN
  188. + // STATE_WEAKLY_NOT_TAKEN -> STATE_STRONGLY_NOT_TAKEN
  189. + // STATE_STRONGLY_NOT_TAKEN -> STATE_STRONGLY_NOT_TAKEN
  190. + state <= (state == STATE_STRONGLY_TAKEN) ? STATE_WEAKLY_TAKEN :
  191. + (state == STATE_WEAKLY_TAKEN) ? STATE_WEAKLY_NOT_TAKEN
  192. + : STATE_STRONGLY_NOT_TAKEN;
  193. + // if brn was taken
  194. + end else begin
  195. + // change fsm state:
  196. + // STATE_STRONGLY_NOT_TAKEN -> STATE_WEAKLY_NOT_TAKEN
  197. + // STATE_WEAKLY_NOT_TAKEN -> STATE_WEAKLY_TAKEN
  198. + // STATE_WEAKLY_TAKEN -> STATE_STRONGLY_TAKEN
  199. + // STATE_STRONGLY_TAKEN -> STATE_STRONGLY_TAKEN
  200. + state <= (state == STATE_STRONGLY_NOT_TAKEN) ? STATE_WEAKLY_NOT_TAKEN :
  201. + (state == STATE_WEAKLY_NOT_TAKEN) ? STATE_WEAKLY_TAKEN
  202. + : STATE_STRONGLY_TAKEN;
  203. + end
  204. + end
  205. + end
  206. + end
  207. +endmodule
  208. diff --git a/rtl/verilog/mor1kx_branch_predictor_simple.v b/rtl/verilog/mor1kx_branch_predictor_simple.v
  209. new file mode 100644
  210. index 0000000..8ad2f08
  211. --- /dev/null
  212. +++ b/rtl/verilog/mor1kx_branch_predictor_simple.v
  213. @@ -0,0 +1,36 @@
  214. +/******************************************************************************
  215. + This Source Code Form is subject to the terms of the
  216. + Open Hardware Description License, v. 1.0. If a copy
  217. + of the OHDL was not distributed with this file, You
  218. + can obtain one at http://juliusbaxter.net/ohdl/ohdl.txt
  219. +
  220. + Description: Branch prediction module
  221. + Generates a predicted flag output and compares that to the real flag
  222. + when it comes back in the following pipeline stage.
  223. + Signals are deliberately not named after the pipeline stage they belong to,
  224. + in order to keep this module generic.
  225. +
  226. + Copyright (C) 2013 Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
  227. +
  228. + ******************************************************************************/
  229. +
  230. +`include "mor1kx-defines.v"
  231. +
  232. +module mor1kx_branch_predictor_simple
  233. + #(
  234. + parameter OPTION_OPERAND_WIDTH = 32
  235. + )
  236. + (
  237. + // Signals belonging to the stage where the branch is predicted.
  238. + input op_bf_i, // branch if flag
  239. + input op_bnf_i, // branch if not flag
  240. + input [9:0] immjbr_upper_i, // branch offset
  241. + output predicted_flag_o //result of predictor
  242. + );
  243. +
  244. + // Static branch prediction - backward branches are predicted as taken,
  245. + // forward branches as not taken.
  246. + assign predicted_flag_o = op_bf_i & immjbr_upper_i[9] |
  247. + op_bnf_i & !immjbr_upper_i[9];
  248. +
  249. +endmodule
  250. diff --git a/rtl/verilog/mor1kx_cpu_cappuccino.v b/rtl/verilog/mor1kx_cpu_cappuccino.v
  251. index f282374..6501e87 100644
  252. --- a/rtl/verilog/mor1kx_cpu_cappuccino.v
  253. +++ b/rtl/verilog/mor1kx_cpu_cappuccino.v
  254. @@ -96,7 +96,8 @@ module mor1kx_cpu_cappuccino
  255.  
  256. parameter FEATURE_MULTICORE = "NONE",
  257.  
  258. - parameter FEATURE_TRACEPORT_EXEC = "NONE"
  259. + parameter FEATURE_TRACEPORT_EXEC = "NONE",
  260. + parameter FEATURE_BRANCH_PREDICTOR = "SAT_COUNTER" // SIMPLE|SAT_COUNTER
  261. )
  262. (
  263. input clk,
  264. @@ -665,6 +666,8 @@ module mor1kx_cpu_cappuccino
  265. .execute_op_movhi_o (execute_op_movhi_o),
  266. .execute_op_msync_o (execute_op_msync_o),
  267. .execute_op_fpu_o (execute_op_fpu_o),
  268. + .execute_op_bf_o (execute_op_bf_o),
  269. + .execute_op_bnf_o (execute_op_bnf_o),
  270. .execute_jal_result_o (execute_jal_result_o[OPTION_OPERAND_WIDTH-1:0]),
  271. .execute_opc_insn_o (execute_opc_insn_o[`OR1K_OPCODE_WIDTH-1:0]),
  272. .decode_branch_o (decode_branch_o),
  273. @@ -745,6 +748,9 @@ module mor1kx_cpu_cappuccino
  274. /* mor1kx_branch_prediction AUTO_TEMPLATE (
  275. .op_bf_i (decode_op_bf_o),
  276. .op_bnf_i (decode_op_bnf_o),
  277. + .execute_bf_i (execute_op_bf_o),
  278. + .execute_bnf_i (execute_op_bnf_o),
  279. + .padv_decode_i (padv_decode_o),
  280. .immjbr_upper_i (decode_immjbr_upper_o),
  281. .prev_op_brcond_i (execute_op_brcond_o),
  282. .prev_predicted_flag_i (execute_predicted_flag_o),
  283. @@ -752,7 +758,8 @@ module mor1kx_cpu_cappuccino
  284. );*/
  285. mor1kx_branch_prediction
  286. #(
  287. - .OPTION_OPERAND_WIDTH(OPTION_OPERAND_WIDTH)
  288. + .OPTION_OPERAND_WIDTH(OPTION_OPERAND_WIDTH),
  289. + .FEATURE_BRANCH_PREDICTOR(FEATURE_BRANCH_PREDICTOR)
  290. )
  291. mor1kx_branch_prediction
  292. (/*AUTOINST*/
  293. @@ -764,6 +771,9 @@ module mor1kx_cpu_cappuccino
  294. .rst (rst),
  295. .op_bf_i (decode_op_bf_o), // Templated
  296. .op_bnf_i (decode_op_bnf_o), // Templated
  297. + .execute_bf_i (execute_op_bf_o), // Templated
  298. + .execute_bnf_i (execute_op_bnf_o), // Templated
  299. + .padv_decode_i (padv_decode_o), // Templated
  300. .immjbr_upper_i (decode_immjbr_upper_o), // Templated
  301. .prev_op_brcond_i (execute_op_brcond_o), // Templated
  302. .prev_predicted_flag_i (execute_predicted_flag_o), // Templated
  303. diff --git a/rtl/verilog/mor1kx_decode_execute_cappuccino.v b/rtl/verilog/mor1kx_decode_execute_cappuccino.v
  304. index beadc5d..8d48b12 100644
  305. --- a/rtl/verilog/mor1kx_decode_execute_cappuccino.v
  306. +++ b/rtl/verilog/mor1kx_decode_execute_cappuccino.v
  307. @@ -168,6 +168,8 @@ module mor1kx_decode_execute_cappuccino
  308. output reg execute_op_shift_o,
  309. output reg execute_op_ffl1_o,
  310. output reg execute_op_movhi_o,
  311. + output reg execute_op_bf_o,
  312. + output reg execute_op_bnf_o,
  313. output reg execute_op_msync_o,
  314. output [`OR1K_FPUOP_WIDTH-1:0] execute_op_fpu_o,
  315.  
  316. @@ -218,6 +220,8 @@ module mor1kx_decode_execute_cappuccino
  317. // Op control signals to execute stage
  318. always @(posedge clk `OR_ASYNC_RST)
  319. if (rst) begin
  320. + execute_op_bf_o <= 1'b0;
  321. + execute_op_bnf_o <= 1'b0;
  322. execute_op_alu_o <= 1'b0;
  323. execute_op_add_o <= 1'b0;
  324. execute_op_mul_o <= 1'b0;
  325. @@ -242,6 +246,8 @@ module mor1kx_decode_execute_cappuccino
  326. execute_op_brcond_o <= 1'b0;
  327. execute_op_branch_o <= 0;
  328. end else if (pipeline_flush_i) begin
  329. + execute_op_bf_o <= 1'b0;
  330. + execute_op_bnf_o <= 1'b0;
  331. execute_op_alu_o <= 1'b0;
  332. execute_op_add_o <= 1'b0;
  333. execute_op_mul_o <= 1'b0;
  334. @@ -264,6 +270,8 @@ module mor1kx_decode_execute_cappuccino
  335. execute_op_brcond_o <= 1'b0;
  336. execute_op_branch_o <= 1'b0;
  337. end else if (padv_i) begin
  338. + execute_op_bf_o <= decode_op_bf_i;
  339. + execute_op_bnf_o <= decode_op_bnf_i;
  340. execute_op_alu_o <= decode_op_alu_i;
  341. execute_op_add_o <= decode_op_add_i;
  342. execute_op_mul_o <= decode_op_mul_i;
  343. @@ -288,6 +296,8 @@ module mor1kx_decode_execute_cappuccino
  344. execute_op_brcond_o <= decode_op_brcond_i;
  345. execute_op_branch_o <= decode_op_branch_i;
  346. if (decode_bubble_o) begin
  347. + execute_op_bf_o <= 1'b0;
  348. + execute_op_bnf_o <= 1'b0;
  349. execute_op_alu_o <= 1'b0;
  350. execute_op_add_o <= 1'b0;
  351. execute_op_mul_o <= 1'b0;
  352. --
  353. 1.9.1
Advertisement
RAW Paste Data Copied
Advertisement