Advertisement
Guest User

Untitled

a guest
Dec 11th, 2019
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.36 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. if (!(dCache.reqEnabled)) begin
  122. dStall = True;
  123. end
  124. rf.wr = Invalid;
  125. dstW = Invalid;
  126. end
  127.  
  128. end
  129. else if (isValid(e2w_v.dst)) begin
  130. dstW = Valid(fromMaybe(?, e2w_v.dst));
  131. rf.wr = Valid(RegWriteArgs{index: fromMaybe(?, e2w_v.dst), data: e2w_v.data}); // Write to a register if the instruction requires it
  132. $display("loading into register r", fromMaybe(?, e2w_v.dst));
  133. $display("loading data from exe: ", e2w_v.data);
  134. end else begin
  135. rf.wr = Invalid;
  136. end
  137.  
  138. // Count every instruction that leaves the writeback stage
  139. // (for debugging help)
  140. instrs <= instrs + 1;
  141.  
  142. // BEGIN: DO NOT REMOVE OR MODIFY THIS CODE
  143. // If unsupported instruction, stops simulation and print the state of the processor
  144. if (e2w_v.iType == Unsupported) begin
  145. $display("Reached unsupported instruction");
  146. $display("Dumping the state of the processor");
  147. $display("pc = 0x%x", e2w_v.pc);
  148. $display(rf.fshow);
  149. $display("Quitting simulation.");
  150. $finish;
  151. end
  152. // END: DO NOT REMOVE OR MODIFY THIS CODE
  153.  
  154. end else begin
  155. rf.wr = Invalid;
  156. end
  157.  
  158. ///////////////////
  159. // Execute Stage //
  160. ///////////////////
  161.  
  162. // Signals used to handle mispredictions
  163. Bool annul = False;
  164. Word redirectPC = ?;
  165.  
  166. // Signals used by decode to handle data hazards
  167. Maybe#(RIndx) dstE = Invalid;
  168. Word dataE = ?;
  169.  
  170. if (isValid(d2e)) begin
  171. let d2e_v = fromMaybe(?, d2e);
  172. if (dStall) begin
  173. e2w <= e2w;
  174.  
  175. end else begin
  176.  
  177. ExecInst eInst = execute(d2e_v.dInst, d2e_v.rVal1, d2e_v.rVal2, d2e_v.pc);
  178. if (eInst.iType == LOAD) begin
  179. if (dCache.reqEnabled) begin
  180. dCache.req = Valid(MemReq{addr: eInst.addr, op: Ld, data: ?});
  181. //eInst.data = dMem.data;
  182. end else begin
  183. dStall = True;
  184. dCache.req = Invalid;
  185. end
  186. end else if (eInst.iType == STORE) begin
  187. if (dCache.reqEnabled) begin
  188. dCache.req = Valid(MemReq{addr: eInst.addr, data: eInst.data, op: St}); // ** FIX THIS LINE
  189. end else begin
  190. dStall = True;
  191. dCache.req = Invalid;
  192. end
  193. end
  194. else begin
  195. dCache.req = Invalid;
  196. end
  197. if (dStall) begin
  198. E2W e_to_writeback = E2W{pc: d2e_v.pc, iType: eInst.iType, dst: eInst.dst, data: eInst.data};
  199. e2w <= Valid(e_to_writeback);
  200. end
  201. else begin
  202. e2w <= Invalid;
  203. end
  204. if (isValid(eInst.dst)) begin
  205. dstE = Valid(fromMaybe(?, eInst.dst));
  206. end
  207.  
  208. if (eInst.nextPc != d2e_v.pc + 4) begin
  209. annul = True;
  210. redirectPC = eInst.nextPc;
  211. end
  212. end
  213.  
  214. end else begin
  215. e2w <= Invalid;
  216. end
  217.  
  218.  
  219. //////////////////
  220. // Decode Stage //
  221. //////////////////
  222.  
  223. // Signal for decode stalls
  224. Bool stall = False;
  225.  
  226. if (isValid(f2d)) begin
  227. if (dStall) begin
  228. d2e <= d2e;
  229. end
  230. else begin
  231. if (!(isValid(iCache.data)) && !(iCache.reqEnabled)) begin // (in middle of a) CACHE MISS, stall
  232. stall = True;
  233. d2e <= Invalid;
  234. if (annul) begin
  235. reject_if <= True;
  236. end
  237. end
  238. else if (!(isValid(iCache.data))) begin
  239. d2e <= Invalid; // stall decode but not fetch
  240. end
  241. else begin
  242. DecodedInst dInst = decode(fromMaybe(?, iCache.data));
  243. // *** a MAYBE of type LINE not A WORD.
  244.  
  245. // Read source registers
  246. Word rVal1 = rf.rd1(dInst.src1);
  247. Word rVal2 = rf.rd2(dInst.src2);
  248.  
  249. if (isValid(dstE) && (fromMaybe(?, dstE) == dInst.src1 || fromMaybe(?, dstE) == dInst.src2)) begin
  250. stall = True;
  251. if (!(iCache.reqEnabled)) begin
  252. repeat_if <= True;
  253. end
  254. $display("e_hazard");
  255. end
  256. else if (isValid(dstW) && (fromMaybe(?, dstW) == dInst.src1 || fromMaybe(?, dstW) == dInst.src2)) begin
  257. stall = True;
  258. $display("w_hazard");
  259. if (!(iCache.reqEnabled)) begin
  260. repeat_if <= True;
  261. end
  262. end
  263.  
  264. let f2d_v = fromMaybe(?, f2d);
  265.  
  266. D2E d_to_execute = D2E{pc: pc, dInst: dInst, rVal1: rVal1, rVal2: rVal2};
  267.  
  268. if (reject_if) begin
  269. d2e <= Invalid;
  270. reject_if <= False;
  271. end
  272.  
  273. else if (stall || annul) begin
  274. d2e <= Invalid;
  275. end
  276.  
  277. else begin
  278. d2e <= Valid(d_to_execute);
  279. end
  280. end
  281.  
  282. end
  283. end else begin
  284. d2e <= Invalid;
  285. end
  286.  
  287. /////////////////
  288. // Fetch Stage //
  289. /////////////////
  290.  
  291.  
  292. if (isValid(f2d)) begin //aka if not first instr (more accurate: first time doing fetch code)
  293. let nextpc = pc;
  294. if (annul) begin
  295. nextpc = redirectPC;
  296. end
  297. else if (stall || dStall) begin
  298. nextpc = pc;
  299. end
  300. else if (iCache.reqEnabled) begin
  301. if (repeat_if) begin
  302. nextpc = pc;
  303. end
  304. else begin
  305. nextpc = pc + 4;
  306. end
  307. end
  308. // else begin
  309. // nextpc = pc;
  310. // end
  311. if (iCache.reqEnabled) begin
  312. if (repeat_if) begin
  313. repeat_if <= False;
  314. end
  315. iCache.req = Valid(MemReq{addr: nextpc, op: Ld, data: ?}); // do regardless of stall.
  316. end
  317. pc <= nextpc;
  318. end
  319. else begin // first instr, may or may not be in stall ***** CHANGE LOGIC SO THAT CAN USE VALID/INVALID F2D FOR STALLING
  320. iCache.req = Valid(MemReq{addr: pc, op: Ld, data: ?});
  321. end
  322.  
  323. f2d <= Valid(?);
  324. //////////////////////////
  325. // TODO: Your code here //
  326. //////////////////////////
  327.  
  328. endrule
  329.  
  330. method Word getPc = pc;
  331. endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement