pipeline.vhd 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use work.core_pkg.all;
  4. use work.mem_pkg.all;
  5. use work.op_pkg.all;
  6. entity pipeline is
  7. port (
  8. clk : in std_logic;
  9. res_n : in std_logic;
  10. -- instruction interface
  11. mem_i_out : out mem_out_type;
  12. mem_i_in : in mem_in_type;
  13. -- data interface
  14. mem_d_out : out mem_out_type;
  15. mem_d_in : in mem_in_type
  16. );
  17. end entity;
  18. architecture impl of pipeline is
  19. type pipeline_ctrl_t is record
  20. stall : std_logic;
  21. flush : std_logic;
  22. stall_fetch : std_logic;
  23. stall_dec : std_logic;
  24. stall_exec : std_logic;
  25. stall_mem : std_logic;
  26. stall_wb : std_logic;
  27. flush_fetch : std_logic;
  28. flush_dec : std_logic;
  29. flush_exec : std_logic;
  30. flush_mem : std_logic;
  31. flush_wb : std_logic;
  32. end record;
  33. signal ctrl : pipeline_ctrl_t;
  34. type fetch_t is record
  35. -- to control
  36. mem_busy : std_logic;
  37. pcsrc : std_logic;
  38. pc_in : pc_type;
  39. pc_out : pc_type;
  40. instr : instr_type;
  41. end record;
  42. signal fetch : fetch_t;
  43. type decode_t is record
  44. -- from fetch
  45. pc_in : pc_type;
  46. instr : instr_type;
  47. -- from writeback
  48. reg_write : reg_write_type;
  49. -- towards next stages
  50. pc_out : pc_type;
  51. exec_op : exec_op_type;
  52. mem_op : mem_op_type;
  53. wb_op : wb_op_type;
  54. -- exceptions
  55. exc_dec : std_logic;
  56. end record;
  57. signal decode : decode_t;
  58. type exec_t is record
  59. -- from DEC
  60. op : exec_op_type;
  61. pc_in : pc_type;
  62. -- to MEM
  63. pc_old_out : pc_type;
  64. pc_new_out : pc_type;
  65. aluresult : data_type;
  66. wrdata : data_type;
  67. zero : std_logic;
  68. memop_in : mem_op_type;
  69. memop_out : mem_op_type;
  70. wbop_in : wb_op_type;
  71. wbop_out : wb_op_type;
  72. -- FWD
  73. exec_op : exec_op_type;
  74. reg_write_mem : reg_write_type;
  75. reg_write_wr : reg_write_type;
  76. end record;
  77. signal exec : exec_t;
  78. type mem_t is record
  79. -- to Ctrl
  80. mem_busy : std_logic;
  81. -- from EXEC
  82. mem_op : mem_op_type;
  83. wbop_in : wb_op_type;
  84. pc_new_in : pc_type;
  85. pc_old_in : pc_type;
  86. aluresult_in : data_type;
  87. wrdata : data_type;
  88. zero : std_logic;
  89. -- to EXEC (forwarding)
  90. reg_write : reg_write_type;
  91. -- to FETCH
  92. pc_new_out : pc_type;
  93. pcsrc : std_logic;
  94. -- to WB
  95. wbop_out : wb_op_type;
  96. pc_old_out : pc_type;
  97. aluresult_out : data_type;
  98. memresult : data_type;
  99. -- exceptions
  100. exc_load : std_logic;
  101. exc_store : std_logic;
  102. end record;
  103. signal mem : mem_t;
  104. type wb_t is record
  105. -- from MEM
  106. op : wb_op_type;
  107. aluresult : data_type;
  108. memresult : data_type;
  109. pc_old_in : pc_type;
  110. -- to FWD and DEC
  111. reg_write : reg_write_type;
  112. end record;
  113. signal wb : wb_t;
  114. signal cntrl_res_n, cntrl_res_n_next : std_logic := '0';
  115. begin
  116. -- synchronous
  117. res_cntrl : process(clk, res_n)
  118. begin
  119. if res_n = '0' then
  120. cntrl_res_n_next <= '0';
  121. else
  122. cntrl_res_n_next <= '1';
  123. end if;
  124. if rising_edge(clk) then
  125. cntrl_res_n <= cntrl_res_n_next;
  126. end if;
  127. end process;
  128. -- concurrent
  129. ctrl.stall <= fetch.mem_busy or mem.mem_busy or not cntrl_res_n;
  130. ctrl.flush <= '0';
  131. -- structural
  132. -- STAGE 1
  133. fetch_inst : entity work.fetch
  134. port map (
  135. clk => clk,
  136. res_n => res_n,
  137. stall => ctrl.stall or ctrl.stall_fetch,
  138. flush => ctrl.flush or ctrl.flush_fetch,
  139. -- to control
  140. mem_busy => fetch.mem_busy,
  141. pcsrc => fetch.pcsrc,
  142. pc_in => fetch.pc_in,
  143. pc_out => fetch.pc_out,
  144. instr => fetch.instr,
  145. -- memory controller interface
  146. mem_out => mem_i_out,
  147. mem_in => mem_i_in
  148. );
  149. fetch.pcsrc <= mem.pcsrc;
  150. fetch.pc_in <= mem.pc_new_out;
  151. -- STAGE 2
  152. decode_inst : entity work.decode
  153. port map (
  154. clk => clk,
  155. res_n => res_n,
  156. stall => ctrl.stall or ctrl.stall_dec,
  157. flush => ctrl.flush or ctrl.flush_dec,
  158. -- from fetch
  159. pc_in => decode.pc_in,
  160. instr => decode.instr,
  161. -- from writeback
  162. reg_write => decode.reg_write,
  163. -- towards next stages
  164. pc_out => decode.pc_out,
  165. exec_op => decode.exec_op,
  166. mem_op => decode.mem_op,
  167. wb_op => decode.wb_op,
  168. -- exceptions
  169. exc_dec => decode.exc_dec
  170. );
  171. decode.pc_in <= fetch.pc_out;
  172. decode.instr <= fetch.instr;
  173. decode.reg_write <= wb.reg_write;
  174. -- STAGE 3
  175. execute_inst : entity work.exec
  176. port map (
  177. clk => clk,
  178. res_n => res_n,
  179. stall => ctrl.stall or ctrl.stall_exec,
  180. flush => ctrl.flush or ctrl.flush_exec,
  181. -- from DEC
  182. op => exec.op,
  183. pc_in => exec.pc_in,
  184. -- to MEM
  185. pc_old_out => exec.pc_old_out,
  186. pc_new_out => exec.pc_new_out,
  187. aluresult => exec.aluresult,
  188. wrdata => exec.wrdata,
  189. zero => exec.zero,
  190. memop_in => exec.memop_in,
  191. memop_out => exec.memop_out,
  192. wbop_in => exec.wbop_in,
  193. wbop_out => exec.wbop_out,
  194. -- FWD
  195. exec_op => exec.exec_op,
  196. reg_write_mem => exec.reg_write_mem,
  197. reg_write_wr => exec.reg_write_wr
  198. );
  199. exec.pc_in <= decode.pc_out;
  200. exec.op <= decode.exec_op;
  201. exec.memop_in <= decode.mem_op;
  202. exec.wbop_in <= decode.wb_op;
  203. exec.reg_write_mem <= mem.reg_write;
  204. exec.reg_write_wr <= wb.reg_write;
  205. -- STAGE 4
  206. memory_inst : entity work.mem
  207. port map (
  208. clk => clk,
  209. res_n => res_n,
  210. stall => ctrl.stall or ctrl.stall_mem,
  211. flush => ctrl.flush or ctrl.flush_mem,
  212. -- to Ctrl
  213. mem_busy => mem.mem_busy,
  214. -- from EXEC
  215. mem_op => mem.mem_op,
  216. wbop_in => mem.wbop_in,
  217. pc_new_in => mem.pc_new_in,
  218. pc_old_in => mem.pc_old_in,
  219. aluresult_in => mem.aluresult_in,
  220. wrdata => mem.wrdata,
  221. zero => mem.zero,
  222. -- to EXEC (forwarding)
  223. reg_write => mem.reg_write,
  224. -- to FETCH
  225. pc_new_out => mem.pc_new_out,
  226. pcsrc => mem.pcsrc,
  227. -- to WB
  228. wbop_out => mem.wbop_out,
  229. pc_old_out => mem.pc_old_out,
  230. aluresult_out => mem.aluresult_out,
  231. memresult => mem.memresult,
  232. -- memory controller interface
  233. mem_out => mem_d_out,
  234. mem_in => mem_d_in,
  235. -- exceptions
  236. exc_load => mem.exc_load,
  237. exc_store => mem.exc_store
  238. );
  239. -- to MEM
  240. mem.pc_old_in <= exec.pc_old_out;
  241. mem.pc_new_in <= exec.pc_new_out;
  242. mem.aluresult_in <= exec.aluresult;
  243. mem.wrdata <= exec.wrdata;
  244. mem.zero <= exec.zero;
  245. mem.mem_op <= exec.memop_out;
  246. mem.wbop_in <= exec.wbop_out;
  247. -- STAGE 5
  248. writeback_inst : entity work.wb
  249. port map (
  250. clk => clk,
  251. res_n => res_n,
  252. stall => ctrl.stall or ctrl.stall_wb,
  253. flush => ctrl.flush or ctrl.flush_wb,
  254. -- from MEM
  255. op => wb.op,
  256. aluresult => wb.aluresult,
  257. memresult => wb.memresult,
  258. pc_old_in => wb.pc_old_in,
  259. -- to FWD and DEC
  260. reg_write => wb.reg_write
  261. );
  262. wb.op <= mem.wbop_out;
  263. wb.aluresult <= mem.aluresult_out;
  264. wb.memresult <= mem.memresult;
  265. wb.pc_old_in <= mem.pc_old_out;
  266. -- CTRL
  267. ctrl_inst : entity work.ctrl
  268. port map (
  269. clk => clk,
  270. res_n => res_n,
  271. stall => ctrl.stall,
  272. stall_fetch => ctrl.stall_fetch,
  273. stall_dec => ctrl.stall_dec,
  274. stall_exec => ctrl.stall_exec,
  275. stall_mem => ctrl.stall_mem,
  276. stall_wb => ctrl.stall_wb,
  277. flush_fetch => ctrl.flush_fetch,
  278. flush_dec => ctrl.flush_dec,
  279. flush_exec => ctrl.flush_exec,
  280. flush_mem => ctrl.flush_mem,
  281. flush_wb => ctrl.flush_wb,
  282. wb_op_exec => exec.wbop_out,
  283. exec_op_dec => decode.exec_op,
  284. pcsrc_in => mem.pcsrc,
  285. pcsrc_out => open
  286. );
  287. end architecture;