Advertisement
Guest User

Untitled

a guest
Dec 11th, 2019
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.29 KB | None | 0 0
  1. import ProcTypes;
  2.  
  3. import RegisterFile;
  4. import Decode;
  5. import Execute;
  6.  
  7. // MainMemory includes the MainMemory port
  8. // and the SingleCycleMemory modules
  9. import MainMemory;
  10.  
  11. // Milestone 2: Select which cache(s) to import
  12. import DirectMappedCache;
  13. //import TwoWayCache;
  14.  
  15.  
  16. typedef struct {
  17. // Add anything you need
  18. // NOTE: If you leave F2D empty, Maybe#(F2D) f2d will just be the valid bit.
  19. // In this case, you can set f2d to valid by writing: f2d <= Valid(?);
  20. } F2D;
  21.  
  22. typedef struct {
  23. Word pc;
  24. DecodedInst dInst;
  25. Word rVal1;
  26. Word rVal2;
  27. // Add anything you need
  28. } D2E;
  29.  
  30. typedef struct {
  31. Word pc;
  32. IType iType;
  33. Maybe#(RIndx) dst;
  34. Word data;
  35. // Add anything you need
  36. } E2W;
  37.  
  38. module Processor;
  39. Reg#(Word) pc(0);
  40. RegisterFile rf;
  41.  
  42. // Uncomment and use these in the processor
  43. // rule for useful debugging help tracking
  44. // cycles and instructions completed
  45. //Reg#(Bit#(64)) cycles(0);
  46. //Reg#(Bit#(64)) insts(0);
  47.  
  48. // Single Cycle Memories
  49. // Milestone 2: comment these declarations out
  50. //SingleCycleMemory iMem;
  51. //SingleCycleMemory dMem;
  52.  
  53. // Line-based Main Memories to use with caches
  54. // Milestone 2: uncomment these declarations
  55. MainMemory iMem;
  56. MainMemory dMem;
  57.  
  58. // Milestone 2: choose which type of cache to use
  59. // NOTE: The CacheWrapper#() type of the dCache
  60. // is critical, as it is used for detecting
  61. // that the program has finished running
  62. // iCache: Direct-Mapped or Two-Way Set Associative
  63. DirectMappedCache iCache(iMem);
  64. //TwoWayCache iCache(iMem);
  65. // dCache: Direct-Mapped or Two-Way Set Associative
  66. CacheWrapper#(DirectMappedCache) dCache(dMem);
  67. //CacheWrapper#(TwoWayCache) dCache(dMem);
  68.  
  69. // Pipeline Registers
  70. Reg#(Maybe#(F2D)) f2d(Invalid);
  71. Reg#(Maybe#(D2E)) d2e(Invalid);
  72. Reg#(Maybe#(E2W)) e2w(Invalid);
  73.  
  74. Reg#(Bool) reject_if(False);
  75. Reg#(Bool) repeat_if(False);
  76. // Performance counters
  77. // These are used for debugging, but are not needed for correctness; you
  78. // can modify or remove them
  79. Reg#(Bit#(32)) cycle(0);
  80. Reg#(Bit#(32)) instrs(0);
  81.  
  82. rule tick;
  83. //////////////////////
  84. // Debugging Helper //
  85. //////////////////////
  86. cycle <= cycle + 1;
  87. // Uncomment the code below to print pipeline state each cycle
  88. begin
  89. $write("[%d] F|D|E|W PCs: ", cycle);
  90. $write("%x|", pc);
  91. if (isValid(f2d)) $write("%x|", pc); else $write("%8s|", "NOP"); // F and D share pc
  92. if (isValid(d2e)) $write("%x|", fromMaybe(?, d2e).pc); else $write("%8s|", "NOP");
  93. if (isValid(e2w)) $write("%x", fromMaybe(?, e2w).pc); else $write("%8s", "NOP");
  94. $display(" instrs: %d", instrs);
  95. end
  96.  
  97. /////////////////////
  98. // Writeback Stage //
  99. /////////////////////
  100. // Signals used by decode to handle data hazards
  101. Maybe#(RIndx) dstW = Invalid;
  102. Word dataW = ?;
  103.  
  104. // Milestone 2:
  105. // Signal for dCache-induced stalls
  106. Bool dStall = False;
  107.  
  108. if (isValid(e2w)) begin
  109. let e2w_v = fromMaybe(?, e2w);
  110.  
  111. //////////////////////////
  112. // TODO: Your code here //
  113. //////////////////////////
  114. if (e2w_v.iType == LOAD) begin
  115. if (isValid(dCache.data)) begin
  116. rf.wr = Valid(RegWriteArgs{index: fromMaybe(?, e2w_v.dst), data: fromMaybe(?, dCache.data)}); // Load from data memory (dMem) if the instruction requires it
  117. dstW = Valid(fromMaybe(?, e2w_v.dst));
  118. $display("loading into register r", fromMaybe(?, e2w_v.dst));
  119. $display("loading data from mem: ", fromMaybe(?, dMem.data));
  120. end else begin
  121. dStall = True;
  122. rf.wr = Invalid;
  123. dstW = Invalid;
  124. end
  125.  
  126. end
  127. else if (isValid(e2w_v.dst)) begin
  128. dstW = Valid(fromMaybe(?, e2w_v.dst));
  129. rf.wr = Valid(RegWriteArgs{index: fromMaybe(?, e2w_v.dst), data: e2w_v.data}); // Write to a register if the instruction requires it
  130. $display("loading into register r", fromMaybe(?, e2w_v.dst));
  131. $display("loading data from exe: ", e2w_v.data);
  132. end else begin
  133. rf.wr = Invalid;
  134. end
  135.  
  136. // Count every instruction that leaves the writeback stage
  137. // (for debugging help)
  138. instrs <= instrs + 1;
  139.  
  140. // BEGIN: DO NOT REMOVE OR MODIFY THIS CODE
  141. // If unsupported instruction, stops simulation and print the state of the processor
  142. if (e2w_v.iType == Unsupported) begin
  143. $display("Reached unsupported instruction");
  144. $display("Dumping the state of the processor");
  145. $display("pc = 0x%x", e2w_v.pc);
  146. $display(rf.fshow);
  147. $display("Quitting simulation.");
  148. $finish;
  149. end
  150. // END: DO NOT REMOVE OR MODIFY THIS CODE
  151.  
  152. end else begin
  153. rf.wr = Invalid;
  154. end
  155.  
  156. ///////////////////
  157. // Execute Stage //
  158. ///////////////////
  159.  
  160. // Signals used to handle mispredictions
  161. Bool annul = False;
  162. Word redirectPC = ?;
  163.  
  164. // Signals used by decode to handle data hazards
  165. Maybe#(RIndx) dstE = Invalid;
  166. Word dataE = ?;
  167.  
  168. if (isValid(d2e)) begin
  169. let d2e_v = fromMaybe(?, d2e);
  170. if (dStall) begin
  171. e2w <= e2w;
  172.  
  173. end else begin
  174.  
  175. ExecInst eInst = execute(d2e_v.dInst, d2e_v.rVal1, d2e_v.rVal2, d2e_v.pc);
  176. if (eInst.iType == LOAD) begin
  177. if (dCache.reqEnabled) begin
  178. dCache.req = Valid(MemReq{addr: eInst.addr, op: Ld, data: ?});
  179. //eInst.data = dMem.data;
  180. end else begin
  181. dStall = True;
  182. dCache.req = Invalid;
  183. e2w <= Invalid;
  184. end
  185. end else if (eInst.iType == STORE) begin
  186. if (dCache.reqEnabled) begin
  187. dCache.req = Valid(MemReq{addr: eInst.addr, data: eInst.data, op: St}); // ** FIX THIS LINE
  188. end else begin
  189. dStall = True;
  190. dCache.req = Invalid;
  191. e2w <= Invalid;
  192. end
  193. end
  194. else begin
  195. dCache.req = Invalid;
  196. end
  197. E2W e_to_writeback = E2W{pc: d2e_v.pc, iType: eInst.iType, dst: eInst.dst, data: eInst.data};
  198. e2w <= Valid(e_to_writeback);
  199.  
  200. if (isValid(eInst.dst)) begin
  201. dstE = Valid(fromMaybe(?, eInst.dst));
  202. end
  203.  
  204. if (eInst.nextPc != d2e_v.pc + 4) begin
  205. annul = True;
  206. redirectPC = eInst.nextPc;
  207. end
  208. end
  209.  
  210. end else begin
  211. e2w <= Invalid;
  212. end
  213.  
  214.  
  215. //////////////////
  216. // Decode Stage //
  217. //////////////////
  218.  
  219. // Signal for decode stalls
  220. Bool stall = False;
  221.  
  222. if (isValid(f2d)) begin
  223. if (dStall) begin
  224. d2e <= d2e;
  225. end
  226. else begin
  227. if (!(isValid(iCache.data)) && !(iCache.reqEnabled)) begin // (in middle of a) CACHE MISS, stall
  228. stall = True;
  229. d2e <= Invalid;
  230. if (annul) begin
  231. reject_if <= True;
  232. end
  233. end
  234. else if (!(isValid(iCache.data))) begin
  235. d2e <= Invalid; // stall decode but not fetch
  236. end
  237. else begin
  238. DecodedInst dInst = decode(fromMaybe(?, iCache.data));
  239. // *** a MAYBE of type LINE not A WORD.
  240.  
  241. // Read source registers
  242. Word rVal1 = rf.rd1(dInst.src1);
  243. Word rVal2 = rf.rd2(dInst.src2);
  244.  
  245. if (isValid(dstE) && (fromMaybe(?, dstE) == dInst.src1 || fromMaybe(?, dstE) == dInst.src2)) begin
  246. stall = True;
  247. if (!(iCache.reqEnabled)) begin
  248. repeat_if <= True;
  249. end
  250. $display("e_hazard");
  251. end
  252. else if (isValid(dstW) && (fromMaybe(?, dstW) == dInst.src1 || fromMaybe(?, dstW) == dInst.src2)) begin
  253. stall = True;
  254. $display("w_hazard");
  255. if (!(iCache.reqEnabled)) begin
  256. repeat_if <= True;
  257. end
  258. end
  259.  
  260. let f2d_v = fromMaybe(?, f2d);
  261.  
  262. D2E d_to_execute = D2E{pc: pc, dInst: dInst, rVal1: rVal1, rVal2: rVal2};
  263.  
  264. if (reject_if) begin
  265. d2e <= Invalid;
  266. reject_if <= False;
  267. end
  268.  
  269. else if (stall || annul) begin
  270. d2e <= Invalid;
  271. end
  272.  
  273. else begin
  274. d2e <= Valid(d_to_execute);
  275. end
  276. end
  277.  
  278. end
  279. end else begin
  280. d2e <= Invalid;
  281. end
  282.  
  283. /////////////////
  284. // Fetch Stage //
  285. /////////////////
  286.  
  287.  
  288. if (isValid(f2d)) begin //aka if not first instr (more accurate: first time doing fetch code)
  289. let nextpc = pc;
  290. if (annul) begin
  291. nextpc = redirectPC;
  292. end
  293. else if (stall || dStall) begin
  294. nextpc = pc;
  295. end
  296. else if (iCache.reqEnabled) begin
  297. if (repeat_if) begin
  298. nextpc = pc;
  299. end
  300. else begin
  301. nextpc = pc + 4;
  302. end
  303. end
  304. // else begin
  305. // nextpc = pc;
  306. // end
  307. if (iCache.reqEnabled) begin
  308. if (repeat_if) begin
  309. repeat_if <= False;
  310. end
  311. iCache.req = Valid(MemReq{addr: nextpc, op: Ld, data: ?}); // do regardless of stall.
  312. end
  313. pc <= nextpc;
  314. end
  315. else begin // first instr, may or may not be in stall ***** CHANGE LOGIC SO THAT CAN USE VALID/INVALID F2D FOR STALLING
  316. iCache.req = Valid(MemReq{addr: pc, op: Ld, data: ?});
  317. end
  318.  
  319. f2d <= Valid(?);
  320. //////////////////////////
  321. // TODO: Your code here //
  322. //////////////////////////
  323.  
  324. endrule
  325.  
  326. method Word getPc = pc;
  327. endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement