Issue Bus Fields Shift Function OP function 0 sll 1 N/A 2 sra 3 srl ALU OP Same as ALU unit Issue Bus Type ROB Set Numbits 4 1 Issue Bus Type ROB Op Numbits 4 2 VkValid 1 Vk 32 Shamt 5 Qk 4 Total Bits: 48 Vj 32 VkValid 1 Vk 32 Qj 4 Qk 4 Total Bits: 48 Vj 32 VkValid 1 Vk 32 Qj 4 Qk 4 Total Bits: 79 Type predict Vjvalid Vkvalid Numbits 1 1 1 OP 2 ROB 4 Type Numbits Qk 4 PC 32 Qj 4 Vj 32 SetU ALUop VjValid 1 3 1 Mult OP function Type ROB 0 mult Numbits 4 1 div Branch OP function 0 beq 1 bne 2 bgez 3 bltz OP 1 Vj 32 VjValid 1 Vk 32 Qj 4 Move OP function 0 lo 1 hi Type ROB Numbits 4 OP 1 Total Bits: 5 MemOP OP function 0 lw 1 sw Type ROB Numbits 4 OP 1 Vjvalid 1 otherPC 32 Total Bits: 144 iMem 32 Jr Type ROB VjValid Numbits 4 1 Jal Type ROB Numbits 4 PC+8 32 Qj 4 Vj 32Total Bits: 37 Total Bits: 74 Appendix I – Notebooks: Phoebus Chen = Index ========================================================= Mon Apr 23 16:00:29 PDT 2001 - Group discussion on how to split up work. Wed Apr 25 16:58:12 PDT 2001 - Planning for Branch prediction. Fri Apr 27 01:41:51 PDT 2001 - drew 2 bit predictor and starting branch predictor. Fri Apr 27 18:45:02 PDT 2001 - Finished making symbol for branch history table. Mon Apr 30 01:01:29 PDT 2001 - Finished making branch history table entry. Mon Apr 30 17:52:13 PDT 2001 - Finished making branch prediction unit, changed branch history table entry, untested. Fri May 4 23:49:00 PDT 2001 - Finished writing VHDL for testing branch predictor, but doesn't compile. Sat May 5 17:20:15 PDT 2001 - Got testbench for branch predictor to compile but branch predictor fails. Sun May 6 23:37:26 PDT 2001 - Debugged more of branch predictor. (- 2 hours for dinner break) Mon May 7 17:38:19 PDT 2001 - Got tester working. Tue May 8 00:07:35 PDT 2001 - Finished testing branch predictor, fixed some bugs (we didn't test branch addresses before). Wed May 9 01:38:55 PDT 2001 - Almost completed building branch validation unit. (- 2 hours for dinner break) Time Spent: ================================================================= +++ Mon Apr 23 12:15:41 PDT 2001 ================================ Goal: Figure out how to do branch prediction. We divided up the work for Tomasulo today. I got to do branch prediction. For branch prediction, I need to build a cache of past branches branch predictor. I also need to pass the address of the branch that the branch FU reservation station. I'll be working with Manda on how instruction quickly, and squashing. It's likely that I'll be working as well. and the 2 bit I didn't take to to issue the next on the branch unit --- Mon Apr 23 16:00:29 PDT 2001 ================================ +++ Wed Apr 25 14:32:23 PDT 2001 ================================ Goal: Layout branch prediction unit's I/O. * We always don't branch the first time we see a new branch instruction. * remember to give an invalid_next signal to Manda, so that when we invalidate a branch, she will throw away the next instruction fetched from memory. * if a previous branch was incorrect, we flush all instructions after it. This means that if we get a "branch_invalid" signal, the nextPC mux will not see the result of the branch predictor unit. This means the branch prediction unit needs not update the history table until the transition at the beginning of the next cycle. Branch History Table: Entries: PC valid bit PC + Immediate (branch) 2 bits for taken/not taken Tag comparator 2 bit state machine ALU - for new branches, to calculate branch to address and store in table Branch Validation FU: Comparator register storing non-predicted address reservation station *ALG* Branch Prediction (direct mapped, simple 2-bit): At clock edge, latch in updated entry if misprediction in previous cycle. ||Check Opcode for branch ||Calculate branch address (immed + PC, in ALU) ||Use lower part of PC to index table ||check valid bit ||check tag with PC ||check taken/not taken ||fetch branch address if (branch_opcode) then if (not_valid or not_tag_match) then nextPC_mux_sel chooses PC+4 //predict not branch store new calculated branch address to table (next cycle) elseif (taken) then nextPC_mux_sel chooses branch address from table else //not taken nextPC_mux_sel chooses PC+4 endif endif Haven't coded anything yet today. --- Wed Apr 25 16:58:12 PDT 2001 ================================ +++ Fri Apr 27 00:39:23 PDT 2001 ================================ Goal: Build 2 bit predictor and test unit. Too tired. predictor. I built the untested 2 bit predictor and drew an alu for the branch I kmapped the 2 bit predictor. --- Fri Apr 27 01:41:51 PDT 2001 ================================ +++ Fri Apr 27 16:47:09 PDT 2001 ================================ Goal: Finish Branch History Table. Finished the symbol for the Branch History Table, but not the schematic yet. --- Fri Apr 27 18:45:02 PDT 2001 ================================ +++ Sun Apr 29 22:39:03 PDT 2001 ================================ Goal: Finish Branch predictor. Ack, still didn't finish building it. Once I finish building the branch history table, I should be able to begin testing. I did finish the branch history table entry, however. --- Mon Apr 30 01:01:29 PDT 2001 ================================ +++ Mon Apr 30 14:48:08 PDT 2001 ================================ Goal: Finish Branch Predictor and Start planning for branch unit. Okay, after talking with JimmyD I realized how stupid it is to store the target branch address considering that it's not a bottleneck for the branch prediction unit - it can still complete in one cycle with an adder. I'll continue to store the tag so that we don't branch predict for different instructions, I suppose. This may make debugging easier. Yes, finished the branch predictor. It's really simple now. building the validation unit. Shouldn't be too bad. Next comes testing and --- Mon Apr 30 17:52:13 PDT 2001 ================================ +++ Fri May 4 22:20:11 PDT 2001 ================================ Goal: Test Branch Predictor, look at branch validation unit. Well, I finished compiling all the files and i write the VHDL file, but I'm having problems compiling it. Will look at this tomorrow. --- Fri May 4 23:49:00 PDT 2001 ================================ +++ Sat May 5 14:08:05 PDT 2001 ================================ Goal: Finish Testing Branch Predictor and build branch validation unit. Ack, I got the testbench to compile, but my component is failing the tests. Will keep testing tomorrow (I hate VHDL, wasted so many hours getting the testbench to compile and run correctly). --- Sat May 5 17:20:15 PDT 2001 ================================ +++ Sun May 6 09:13:44 PDT 2001 ================================ Goal: Get Branch Predictor Working. I realized that I made some really stupid mistakes yesterday, like not having CLK and RESET pins into my branch predictor. I also realized that i should not use the lower 2 bits of the PC as the index into the branch table (they're always 00). I didn't get to finish changing the pins on the decoder in bhtable (I just realized there were bars over all of the outputs!) Gotta go. --- Sun May 6 10:58:57 PDT 2001 ================================ +++ Sun May 6 16:57:12 PDT 2001 ================================ Goal: GET BRANCH PREDICTION WORKING!!!!! Okay, I've taken a 2 hour dinner break, so that doesn't count to my time total. I've found various bugs in my branch predictor... didn't bother documenting them because this is still initial testing. tags. I made a fundamental design change... I'm no longer keeping track of the branch Now, my branch history table entries look wimpy. I don't know what's wrong with the testbench tests, but the original ones work fine. Another frustrating day....IT'S STILL NOT WORKING WITH TESTBENCHES. --- Sun May 6 23:37:26 PDT 2001 ================================ +++ Mon May 7 12:36:53 PDT 2001 ================================ Goal: debug testbench? Make branch validation unit. I'll need 1 FF to store branch prediction result and 32 bit register to store not taken value. Yea! I finally got the testbench to work. I made a schematic and a symbol for the testbench, changed a few things for the testbench, then tested through this. All tests have passed thus far. Dinner break! --- Mon May 7 17:38:19 PDT 2001 ================================ +++ Mon May 7 18:28:52 PDT 2001 ================================ Goal: write more test cases for testbench. Yes, it passes most of my test cases. Checks that: 1) the 2 bit predictor works - to saturation, toggling TFTF 2) updates can happen while another entry is being accessed 3) instructions that should collide in the branch history table actually affect the same entry 4) non-branch instructions don't cause branches 5) both bne and beq are recognized I have used 20 ns delays, because the components are not optimized (I'm using ALU, mux, and tristate in critical path). I also added in testing for the untaken address and the new branch address, to make sure they were computed properly. --- Tue May 8 00:07:35 PDT 2001 ================================ +++ Tue May 8 11:05:08 PDT 2001 ================================ Goal: Finish building branch validation unit. Okay, I didn't build the unit yet. I was looking at Mark's schematic to see how it works. There are some questions I have of his implementation. --- Tue May 8 12:09:07 PDT 2001 ================================ +++ Tue May 8 15:54:04 PDT 2001 ================================ Goal: Finish building branch validation unit. The main changes from Mark's ALU reservation station is that I've added the UNTAKEN_ADDR[31:0] and B_TAKEN value to be stored in the stations and I've changed the ISSUE[112:0] bus values that feed into each register in the reservation station. I've also removed unnecessary pins from each reservation station and made the symbol bigger. Here's the values from the branch issue bus, as given to me by Po: Name numbits range predict 1 [144] Vjvalid 1 [143] Vkvalid 1 [142] OP 2 [141:140] ROB 4 [139:136] Vj 32 [135:104] Vk 32 [103:72] Qj 4 [71:68] Qk 4 [67:64] PC 32 [63:32] otherPC 32 [31:0] Here's beq = bne = bgez = bltz = the opcodes, from Po: 00 01 10 11 1 hour dinner break. Almost done with branch validation unit, just have to fix the control. squishers! --- Wed May 9 01:38:55 PDT 2001 ================================ +++ Wed May 9 13:49:24 PDT 2001 ================================ Even has Goal: Finish building branch validation unit. Koichi has taken on the jump register unit. I used Mark's RSctrlShift units, and edited it to remove the issue[84:0] pin because it's not used. Here's the values from the jal issue bus: Name numbits range ROB 4 [35:32] PC 32 [31:0] (- 40 minutes for HKN meeting) (- 2 hours for HKN meeting) Just got the jal unit finished... pretty easy. Now I'm working on the mfhi, mflo units... Here's the values from the move issue bus: Name numbits range OP 1 [73] valuevalid 1 [72] waitMulROB 4 [71:68] ROB 4 [67:64] HILO 64 [63:0] These are not in the issue bus: mult_not_done MulROB 4 HI 32 [63:32] LO 32 [31:0] Mark Chew Mon Apr 23 17:43:41 PDT 2001 - Just brainstorming about what it's going to take. Tue Apr 24 16:27:57 PDT 2001 - Got reservation station schematics drawn. Wed Apr 25 16:00:48 PDT 2001 - Got framework of RS controller. Thu Apr 26 21:49:16 PDT 2001 - Started multiply unit Sat Apr 28 15:01:12 PDT 2001 - Working on VHDL for RS controllers Wed May 2 23:48:03 PDT 2001 - Wrote most of the code for ALU RS controller. to debug. Still have Fri May 4 00:23:32 PDT 2001 - Finished preliminary version of ALU RS controller. Also wrote the initial test file for it; just need to resolve technical difficulties next time. Fri May 4 18:36:59 PDT 2001 - More stuff with the arithmetic units. right, but the RS controller still needs some major work. Got a slt working Sat May 5 22:38:53 PDT 2001 - Got some instructions executing, but I still need to work on timing. Tue May 8 00:10:08 PDT 2001 - Got ALU-related instructions working. the CDB, and drive the CDB properly now, I think. They stall, request Wed May 9 01:02:19 PDT 2001 - Got Shift-related instructions working and improved the algorithm that decides which RS to launch. Now need to work on the multiplying next. Thu May 10 07:18:49 PDT 2001 - I hate CS 152. =============================================================================== Mon Apr 23 14:32:34 PDT 2001 Discussed project as a group. Argh!!! I doesn't work. Going to get asynchronous DRAM controller working now. We're going to have to ask James or something about this one. Forget it. Going to work on the reservation stations. An RS needs: name, busy(not available), Op, Vj, Vk, Qj, Qk It also needs some abstractions, like "source operand ready" or ... When source operands are ready, it's going to be really hard to nullify Qj and write Vj in hardware, all at the same time. Also, RS's need to have some way of interfacing with the CDB. Argh...this is really really complicated. Mon Apr 23 17:43:41 PDT 2001 (3 hours) ------------------------------------------------------------------------------Tue Apr 24 15:40:33 PDT 2001 Goal: Get reservation stations moving!! I'm not quite sure when a reservation station would be busy, but not have an OP, or have an OP, but not be busy. Not sure how to identify each RS. For now, I'm just going to have people wire it up from the outside. So it just returns whatever name you give it. Reservation stations done, in gates. I don't think there's a need to test yet, since everything is pretty self-explanatory and basic. The next task I need to do is build the RS controller. This would be difficult because I'm not going to know exactly the format of the instruction issues. Also, it's going to need to arbitrate and choose which RS under its domain gets to use the functional unit, if 2 RS's become ready at the same time. Tue Apr 24 16:27:57 PDT 2001 (1 hour) ------------------------------------------------------------------------------Wed Apr 25 14:07:48 PDT 2001 Goal: Do about half of RS controller Got framework of RS controller. Dang. This thing's complicated. Wed Apr 25 16:00:48 PDT 2001 (2 hours) ------------------------------------------------------------------------------Thu Apr 26 15:18:30 PDT 2001 Goal: Understand the interfaces that the RS controller is going to do, and start working on some vhdl for it. We need sets of RS's for shifts, ALU-related operations, multiplies and branches. project is seeming as difficult as ever. Working on multiply Thu Apr 26 21:49:16 PDT 2001 (5.5 hours) ------------------------------------------------------------------------------Sat Apr 28 13:07:20 PDT 2001 Goal: Get working on RS controller, in VHDL. It's coming...slowly. Sat Apr 28 15:01:12 PDT 2001 (2 hours) ------------------------------------------------------------------------------Wed May 2 14:22:19 PDT 2001 This I think the reservation stations should be more intelligent than they are now. Right now, they're just a collection of flip-flops, but I think they should be able to listen to the CDB and know when to latch stuff in, instead of relying on the RS controllers. Ok, now a reservation station only needs to know when it can latch stuff. It can sit on the bus and just automatically know whether to listen to a valud. Still, it needs to be able to launch instructions correctly. Wed May 2 16:06:25 PDT 2001 Wed May Back 2 18:47:30 PDT 2001 (minus 2.5 hours) I *think* the reservation station module is done. The RS controller just needs to raise "go" on the cycle that the execution of that instruction gets put into a functional unit, and raise "reset" for a cycle at the completion of the functional unit's execution. This changes the RS controllers big-time, but this is a good change, since it's a change for the better (simpler). I need to ask Po what happens on a set. How do I tell what kind of set it is? Aha! If I want to use the CDB on a specific cycle, I'm going to have to request it the cycle before that. For ALU operations, that means that I need to request during the cycle that I launch. Ok, code for the ALU RS controller is getting filled in now. matter of debugging this stuff. Soon, it'll just be a Wed May 2 23:48:03 PDT 2001 (7 hours) ------------------------------------------------------------------------------Thu May 3 15:40:56 PDT 2001 Goal: Have RS controllers done to my satisfaction, and start working on multiplier and divider units. Aha!!! There is a SEPARATE EX and WB stage. This means that as long as I request the CDB during the EX stage, then most of the time the WB stage can go smoothly. Also, If I latch the output of the EX stage, I can pipeline everything so that the FU stays busy all the time. A complexity problem with this is that the RS controller has to stall everything when it doesn't get the CDB. This means not letting the flip-flop get written and putting the same values into the ALU. Remind Po that we've changed the interface, adding more information so that signed and unsigned sets will work in the ALU unit. Changing the issue "standard" to make debugging a lot easier. Ok, the initial test file is written. I still need to figure out the compile/fusion errors, but I think this is a good stopping point. (minus 1.5 hours for dinner and watching Diehard) Fri May 4 00:23:32 PDT 2001 (8 hours) ------------------------------------------------------------------------------Fri May 4 14:43:28 PDT 2001 Ok, got one instruction that came out correctly. Dang, it took forever for me to get the logic at the end right. But I still need to worry about the RS controller, which is my main task. It still doesn't seem to be conducting things the right way. Fri May 4 18:36:59 PDT 2001 (4 hours) ------------------------------------------------------------------------------Sat May 5 10:56:19 PDT 2001 Goal: Get all the ALU-related instructions working. Minus 2.5 hours for acupuncture. Right now, the issue unit seems to be working OK, but the launch doesn't. Now, the instructions are executing and coming out at Dout correctly. However I'm still having a few timing problems. One thing is, it seems like I usually have trouble executing instructions every cycle. I'm seeing a bunch of zeros between every meaningful set of values going into the ALU. Also, I'm having trouble with the CDBrequest. I need an asynchronous arbiter so that I can get the CDB the cycle AFTER I launch. However, I'm having problems with this. The request needs to happen each time I launch an instruction AND each time I have an instruction that still needs to broadcast. How to do this is not clear to me, but I'm so brain-dead from this whole day of working that I need to stop now. Sat May 5 22:38:53 PDT 2001 (9 hours) ------------------------------------------------------------------------------Mon May 7 12:21:25 PDT 2001 Goal: Get ALU-related instructions totally working. After 11.5 hours, it's finally working. units. Now going to port everything over to the shift We need to improve the launch algorithm so that it picks the oldest instruction to launch. Koichi will work on this. Tomorrow, I need to do the shifter and the multiply/divide units. Minus 4 hours for discussion and break Tue May 8 00:10:08 PDT 2001 - (8 hours) ------------------------------------------------------------------------------Tue May 8 15:57:29 PDT 2001 Working on algorithm and the shifts. Koichi did a good job on the algorithm so making the shifts work wasn't too much work. Yay! Minus a lot of time for breaks. Wed May 9 01:02:19 PDT 2001 (~ 4 hours) 53.5 hours so far ------------------------------------------------------------------------------Wed May 9 15:50:35 PDT 2001 Goal: Get multiplier and divider working. Darn it. Giving up on mult and div. Insight: if we eventually decide to support branch prediction, I'm going to have to modify the launch unit. It needs to not launch when the squish signal is high. Darn it. Why am I still here? Thu May 10 07:18:49 PDT 2001 (15.5 hours) 69 hours so far ------------------------------------------------------------------------------- Manda Sutijono ----------------------------------------------------------------------------------------*Start: Mon Apr 23 14:12:50 PDT 2001 Met with group to talk about final project. We split up Tomasulu into parts. I'll be working on the op queue. Looks like we're making it circular, and having 2 counters, the head and tail. The size will be probably twice that of the reorder buffer. So first I'll make it 16, since Koichi's going to first make the reorder buffer 8. I'll also need to make sure to reset the counter and place it correctly for when squashing occurs. So far I've just placed 16 32-bit registers into the op_queue schematic. more on Tomasulu tomorrow. Going to read *End: Mon Apr 23 16:21:34 PDT 2001 Approx. total: 2 hours ----------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------*Start: Wed Apr 25 14:16:27 PDT 2001 Working on the op queue. I also have to add when to issue instructions. I must check if there's an empty reservation station and an empty slot in the reorder buffer. If all reservations are full or reorder buffer is full, the instruction issue is stalled until both have available entries. We just talked and now we decided that Po will handle the issuing. Also, I'll have to look and see whether an instruction is j, jal, or jr. For a jr instruction, the delay slot will be freezed until a signal comes from Po. Also, Phoebus needs another input to the PC mux for branch prediction. *End: Wed Apr 25 16:00:12 PDT 2001 Approx. total: 2 hours --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*Start: Fri Apr 27 20:36:04 PDT 2001 Finally done with 164, so now I can concentrate on this op queue. Haven't done much. Just put in the register enable signals that come from the head counter. I have to finish labelling tomorrow. Also have to add the datapath stuff for PC, etc. *End: Fri Apr 27 22:20:27 PDT 2001 Approx. total: 1.5 hours --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*Start: Sat Apr 28 11:24:15 PDT 2001 Back to finish the op queue. I remembered how to figure out the FULL and EMPTY signals - see if HEAD = TAIL, then check the previous operation. If it was an insert, that means HEAD moved, so the queue is FULL. If the prev operation was a send, so TAIL moved and the queue is empty. Starting the op_queue symbol! *End: Sat Apr 28 13:55:19 PDT 2001 Approx. total: 2.5 hours --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*Start: Sun Apr 29 14:48:56 PDT 2001 Finish making op_queue symbol, and check that I did full/empty signals correctly, then test whole queue. A little tricky testing because I found out I was using the old tri state buffer, which was low-enabled. I switched to the hi-enabled one and then I was getting stuff for instr_out when I asserted send signal. Oh, and I also forgot to put the squash pin to the symbol. That signal also affects the empty signal, so I fixed that too. *End: Sun Apr 29 17:15:31 PDT 2001 Approx. total: 2.5 hours ----------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------*Start: Wed May 2 14:05:38 PDT 2001 Meeting with group today to talk about stuff. cache. I think I'll try and think/start on victim Ok, now I'm going to work on the integer unit. It takes in 2 32-bit inputs, plus a 5-bit operation input. The first 3 bits are to specify the operation for the ALU. The last 2 bits enable which output to take: slt, sltu, or the alu. *End: Wed May 2 17:14:16 PDT 2001 Approx. total: 3 hours --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*Start: Thu May 3 12:43:03 PDT 2001 Going to try and get the lw/sw unit going. I got that done, and so it takes in 2 inputs, the offset and then the address. It outputs the sum of the sign-extended address with the address. *End: Thu May 3 13:56:29 PDT 2001 Approx. total: 1 hours --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*Start: Thu May 3 17:00:13 PDT 2001 I'm going to think about the PC FSM. When to freeze it, etc. So I finally got that working. I messed up because I put ground incorrectly into the flip flop. So what the pcwrite symbol does is send hi if the instruction is not jr. If it is, then the pcwrite will be low, so it can freeze the pc. Only when the go signal is asserted (which will come from Po's stuff) will the pcwrite signal be asserted. *End: Thu May 3 20:22:48 PDT 2001 Approx. total: 3 hours --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*Start: Fri May 4 13:35:28 PDT 2001 Koichi needs me to modify the op queue. Now it needs to hold the PC, so I need more 32bit registers. After I finish with that, I'll try and start on the victim cache. I started to place the some units into the tomasulo datapath, such as mux and reg for PC, op queue, integer unit, shifter, and lw/sw unit. Now I'm going to make a symbol that spits out PC+4 and PC+8. I read a bit about victim caches. They should be fully associative. look at victim cache. If a hit, swap blocks with cache. *End: Fri May When miss in cache, 4 15:47:53 PDT 2001 Approx. total: 2 hours --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*Start: Sat May 5 10:53:36 PDT 2001 I'm reading about victim caches again. that. Haha, it's in the project spec. Wondering how big it should be and stuff like Victim cache'll be 4 cache lines. (Took 1hr lunch break) Oh, found an article on 152 page about victim caches. So I should read it. I added another register to op queue, to hold the used to see if it's a j, jr, or jal instruction. write_pc signal, freezing the pc. If it's a j or address from the pc mux. So I added a j/jal unit instructions. *End: Sat May most recent instruction. This will be If it's jr, then it should disable the jal instruction, it will select that that detects for j and jal 5 20:03:47 PDT 2001 Approx. total: 7.5 hours --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*Start: Tue May 8 17:31:22 PDT 2001 Going to add more stuff to op queue for branch prediction. each slot and flip-flops also. Need 32 bit registers for Took 1hr break. I added another input for pc to the op_queue. I also tested the tomasulo datapath with just the pc stuff, op queue, cache and dram. Looks good. *End: Wed May 9 01:31:44 PDT 2001 Approx. total: 7 hours --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*Start: Wed May 9 11:02:46 PDT 2001 Um, tested the op queue again. Worked on report, started on presentation slides. Took 30min break. *End: Wed May 9 14:47:23 PDT 2001 Approx. total: 3 hours --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*Start: Wed May 9 20:57:01 PDT 2001 Guess I'll work on slides and more of report. *End: Thu May 10 07:13:38 PDT 2001 Approx. total: 10 hours ----------------------------------------------------------------------------------------- Koichi Tsunoda ---------------------------------------------------------------------Hours: 4.5 Mon Apr 23 14:00:46 PDT 2001 Met with my group to talk about the details of what we are going to implement. Mon Apr 23 16:11:11 PDT 2001 We decided on what, and split the work up. I am going to work on the reorder buffer aspect of our processor. Mon Apr 23 18:23:00 PDT 2001 Still in the process of designing the reorder buffer. Total hours so far: 4.5 ---------------------------------------------------------------------Hours: 1 Tue Apr 24 12:51:19 PDT 2001 Dropped by to work on the reorder buffer again. Tue Apr 24 14:00:01 PDT 2001 Still working on the datapath. Finished the Buffer-full logic. Now working on the datapath that will allow us to add an entry, and commit the instruction. Class for now. Total hours so far: 5.5 ---------------------------------------------------------------------Hours: 7.5 Tue Apr 24 17:40:00 PDT 2001 Came in. Datapath time. Wed Apr 25 01:00:55 PDT 2001 Datapath is hard. Lots of issues came up so need to talk about it with members later. Total hours so far: 13 ---------------------------------------------------------------------Hours: 3.75 Wed Apr 25 14:36:59 PDT 2001 Lab time. Wed Apr 25 18:15:14 PDT 2001 Working on the renaming part. Given the source, I want to be able to give a ROB # if it's in there. Gotta go for now. Will be back later. Total hours so far: 16.75 ---------------------------------------------------------------------Hours: 5.25 Wed Apr 25 20:44:51 PDT 2001 Came back. Working on the renaming part still. Wed Apr 25 22:27:19 PDT 2001 Done with the renaming part. Now, I will make a tester for it. Thu Apr 26 01:56:56 PDT 2001 Woohoo! Got the renaming part working. Done and tested with a testing component. Time to go home!!! Total hours so far: 22 ---------------------------------------------------------------------Hours: 2 Thu Apr 26 14:01:44 PDT 2001 Starting to work on the ROB again. Thu Apr 26 16:04:01 PDT 2001 Gotta go for now. Working on the value output for the ROB. Total hours so far: 24 ---------------------------------------------------------------------Hours: 6.5 Thu Apr 26 19:09:59 PDT 2001 Came in with a surprise of MORE things to do for ROB. Yeah. Need to handle stuff for hi and lo registers. Fri Apr 27 01:42:43 PDT 2001 Figured out a lot but still not done. Gotta do the controls and talk about the lw unit with mark later. Think everything else is fine...but not sure... Total hours so far: 30.5 ---------------------------------------------------------------------Hours: 3 Fri Apr 27 14:10:52 PDT 2001 Will start working on the controls for the issuing aspect. Fri Apr 27 19:41:19 PDT 2001 Food time. Making the symbol for the ROB slots. After this, I can actually work on the ROB itself. Too many pins!!! Total hours so far: 33.5 ---------------------------------------------------------------------Hours: 1.25 Fri Apr 27 21:07:00 PDT 2001 Back to work! Fri Apr 27 22:22:11 PDT 2001 Will work on commit controller tomorrow. Total hours so far: 34.75 ---------------------------------------------------------------------Hours: 3 Sat Apr 28 11:08:59 PDT 2001 Back to the lab. Woohoo~. Gotta work on the commit controller. Sat Apr 28 14:00:31 PDT 2001 Go for now. Now gotta add all the ROB slots into it and make the actual ROB. Total hours so far: 37.75 ---------------------------------------------------------------------Hours: 2 Sat Apr 28 18:31:59 PDT 2001 I will now try to make the actual ROB stuff (with the ROB slots all wired up). Sat Apr 28 20:27:53 PDT 2001 Blah blah. No. I'm going to worry about the LW/SW stuff more seriously later. I have to out put RT_VALUE_VALID and RS_VALUE_VALID and I should (that is, SHOULD) be done with the ROB. So I can start testing. yeah. Total hours so far: 39.75 ---------------------------------------------------------------------Hours: 3.5 Sun Apr 29 14:28:23 PDT 2001 I will add the two signals that I said that I need to add. And then finish up the ROB. Sun Apr 29 17:05:19 PDT 2001 Got the ROB finished. Now, let me connect the controllers, and then make a testing component via VHDL. Sun Apr 29 18:02:11 PDT 2001 I decided that making a testing component for ROB is kind of long and tedious and annoying. Therefore, I will make a CMD file which will test it. But that's when I come back next time. Total hours so far: 43.25 ---------------------------------------------------------------------Hours: 4 Wed May 2 14:29:53 PDT 2001 Back to lab. Now going to test ROB. Wed May 2 18:35:11 PDT 2001 Gotta go for now. But remember to check the CDB_WRITE_VALUE thing. It's writing to all of it and need to fix it but...weird. Total hours so far: 47.25 ---------------------------------------------------------------------Hours: 3 Wed May 2 21:45:00 PDT 2001 Back. Testing. Thu May 3 00:49:11 PDT 2001 The integer instruction related stuff seems to be working. I will check the stuff with multiply tomorrow. I will need to check if the multiply and integer unit finishing at the same time works too. I will do that tomorrow. Total hours so far: 50.25 ---------------------------------------------------------------------Hours: 1.25 Thu May 3 12:43:12 PDT 2001 More testing. Thu May Class! 3 14:00:00 PDT 2001 Total hours so far: 51.5 ---------------------------------------------------------------------Hours: 4.75 Thu May 3 17:00:05 PDT 2001 About to start checking the sw/lw related stuff. I still have to do the squishing thing for the misprediction but I'll take care of it later. For now, I will do this. Thu May Food. 3 20:31:33 PDT 2001 Thu May Back. 3 21:14:55 PDT 2001 Thu May 3 22:36:35 PDT 2001 Got the main things tested. Seems like it's working fine. Still have couple more things to do. Gotta take care of branch thing and other junks. Total hours so far: 56.25 ---------------------------------------------------------------------Hours: 2 Fri May 4 13:55:33 PDT 2001 I will make a monitor for the final thing right now. Just have to modify the old one we have to make it work with the new one. Fri May 4 15:50:11 PDT 2001 Time to stop. Total hours so far: 58.25 ---------------------------------------------------------------------Hours: 7.75 Sat May 5 10:59:59 PDT 2001 Test my monitor. Sat May 5 11:23:44 PDT 2001 Monitor seems to be fine. Now, I will fix up the Asynch-dram controller. Sat May Food 5 12:30:11 PDT 2001 Sat May Back. 5 13:43:53 PDT 2001 Sat May 5 20:06:21 PDT 2001 Gotta take care of jump instruction. Don't forget. But super-semi-async-dram controller seems to be fine :) Total hours so far: 66 ---------------------------------------------------------------------Hours: 10 Mon May 7 13:18:55 PDT 2001 I still have to take care of jump, branch, lw in the ROB. But I will work on the whole tomasulo datapath. I will take what Manda worked on and try to find out what we're still missing. Tue May 8 01:37:11 PDT 2001 Think the ROB is pretty much done. We were going to keep the lw seperate from ROB but I think it's better to add it to the ROB. jump and branch is taken care of now. Wow. 12 hours - time for dinner - time for tv. Total hours so far: 76 ---------------------------------------------------------------------Hours: 1 Tue May 8 12:46:14 PDT 2001 Back to work. Tue May 8 13:49:33 PDT 2001 Finished the lw related utility. Therefore, I am done. Not. Now I will have to try to put everything together...figure out what's missing...and then work on that. We MUST get some instructions running today. Total hours so far: 77 ---------------------------------------------------------------------Hours: 7 Tue May 8 15:32:59 PDT 2001 Back. Will test the lw/sw related unit. Tue May 8 17:33:19 PDT 2001 Worked on an algorithm which will choose who's going to be issued next. It makes sure that the oldest one that is available gets issued next. Haven't tested the lw/sw unit yet. I will test that next perhaps. Tue May 8 21:27:22 PDT 2001 Got the algorithm for choosing the right instruction to launch done. Now, I will help get the whole tomasulo thing working. Tue May 8 21:51:19 PDT 2001 Looking good. Got the memory thing ported. Tue May 8 23:01:51 PDT 2001 Got the integer related stuff ported. Tue May 9 01:31:23 PDT 2001 Time to jet for now... Total hours so far: 84 ---------------------------------------------------------------------Hours: .5 Tue May Back. 9 11:04:32 PDT 2001 Tue May 9 11:43:23 PDT 2001 Eat. Making the JR unit. Total hours so far: 84.5 ---------------------------------------------------------------------Hours: 2.5 Tue May Back. 9 12:20:11 PDT 2001 Tue May 9 14:50:51 PDT 2001 Commencement. Total hours so far: 87 ---------------------------------------------------------------------Hours: Tue May 9 18:48:01 PDT 2001 Back. JR again. Total hours so far: ---------------------------------------------------------------------- Posu Yan ==================================================================== Fri Apr 27 13:57:42 PDT 2001 - starting to make carry look ahead adder Fri Apr 27 16:02:33 PDT 2001 - starting squasher thing - revised the algorithm Fri Apr 27 18:15:26 PDT 2001 - finished the squasher thing ==================================================================== Sat Apr 28 13:28:56 PDT 2001 - slightly modifying squasher Sat Apr 28 15:07:23 PDT 2001 - starting decode for issuer.. trying to decode everything in parallel Sat Apr 28 18:54:02 PDT 2001 - finished most of the instruction decodes ==================================================================== Wed May 2 13:34:21 PDT 2001 - going to finish instruction decodes.. not sure about what kind of FSM i need, so i'll hold off on that Wed May 2 19:06:10 PDT 2001 - more or less finished decode... not completely sure where jumps, loads are going (their own station?) ==================================================================== Sat May 5 12:45:24 PDT 2001 - finishing up issuer Sat May 5 17:18:48 PDT 2001 - pretty much finished with issuer.. not completely sure if i need a state machine in it tho - i'll test this tomorrow ==================================================================== Sun May 6 16:44:44 PDT 2001 - starting to do final test of issuer, then finalize the data format Sun May 6 17:13:05 PDT 2001 - finished testing.. it works, now finalizing data formats Sun May 6 18:00:52 PDT 2001 - pretty much done, just need to add some more interface signals with ROB ==================================================================== Mon May 7 14:27:42 PDT 2001 - making final changes to issuer Mon May 7 15:30:56 PDT 2001 - creating vhdl component to output for invalid instructions Mon May 7 16:37:02 PDT 2001 - finished vhdl complainer component Mon May 7 17:20:36 PDT 2001 - starting to design CDB arbiter ==================================================================== Mon May 7 18:38:25 PDT 2001 - i think i've got the arbiter FSM structure, it's more high level than the other arbiter, i think i'll need some higher level comparators and adders Mon May 7 19:08:42 PDT 2001 - starting to make a one hot adder in vhdl, it should need 16 inputs, but only 8 outputs Mon May 7 23:58:22 PDT 2001 - finished cdb arbiter, gonna test it tomorrow ==================================================================== Tue May 8 13:15:38 PDT 2001 - starting arbiter testing Tue May 8 13:36:19 PDT 2001 - arbiter works fine! no bugs at all - starting to create symbol Tue May 8 14:02:32 PDT 2001 - arbiter is done!... although may need to add some data muxing, depends on how mark wants to do it ==================================================================== Tue May 8 17:01:44 PDT 2001 - starting to make lw/sw reservation station unit Tue May 8 22:12:12 PDT 2001 - this lw/sw thing is much more complicated than i thought... might have to rewrite it completely Wed May 9 01:35:12 PDT 2001 - argggggggghhh, i've got most of the datapath for lw/sw.. can't think right now so i'll do the control tomorrow ==================================================================== Wed May 9 14:04:55 PDT 2001 - starting to make PC fsm... it's much more complicated than we thought Wed May 9 17:13:12 PDT 2001 - i think i'm finished with the PC fsm.. it's not even an fsm, just a combinational logic controller - i'll go back to working on the lw/sw unit ==================================================================== Wed May 9 18:34:51 PDT 2001 - going to need lots of arbiters in the lw/sw unit.. but i have a pretty good idea of how i'm going to do it Appendix II – Schematics: ï‚· Operation Queue ï‚· Reorder Buffer Slot ï‚· Reorder Buffer ï‚· MultROB ï‚· Squasher ï‚· ROB Oracle ï‚· Address to ROB ï‚· Address to ROB Slot ï‚· J/JR/JAL Detector Unit ï‚· Reservation Station ï‚· Common Data Bus Arbiter ï‚· Common Data Bus Arbiter FSM ï‚· Carry Lookahead Adder ï‚· Full Adder ï‚· JR Unit ï‚· Integer Unit ï‚· Squasher ï‚· Issuer ï‚· PC FSM ï‚· Tomasulo Datapath Appendix III – VHDL Files Complainer library pack1076; use pack1076.pack1076.all; use std.textio.all; entity complainer is port (clk: in vlbit; invalid: in vlbit); end complainer; architecture behavior of complainer is begin -- behavior complainer_process: process begin wait until prising(clk); if (invalid = '1') then assert false report "invalid instruction!!" severity error; end if; end process; end behavior; Monitor library pack1076; use pack1076.pack1076.all; use std.textio.all; entity monitor is port(signal CLK : in vlbit; signal INVALIDATE : in vlbit; signal PC : in vlbit_1d(31 downto 0); signal INSTRUCTION : in vlbit_1d(31 downto 0); signal VALUE : in vlbit_1d(31 downto 0); signal MFHI : in vlbit_1d(31 downto 0); signal MFLO : in vlbit_1d(31 downto 0); signal MEM_ADDRESS : in vlbit_1d(31 downto 0)); end monitor; architecture behavior of monitor is function vec32tohex(vec: vlbit_1d) return string is variable str: string(10 downto 1); variable lo: integer; variable hi: integer; begin for i in 1 to 8 loop lo := (i-1)*4; hi := ((i-1)*4)+3; if(vec(hi downto lo) = "0000") then str(i) := '0'; elsif(vec(hi downto lo) = "0001") then str(i) := '1'; elsif(vec(hi downto lo) = "0010") then str(i) := '2'; elsif(vec(hi downto lo) = "0011") then str(i) := '3'; elsif(vec(hi downto lo) = "0100") then str(i) := '4'; elsif(vec(hi downto lo) = "0101") then str(i) := '5'; elsif(vec(hi downto lo) = "0110") then str(i) := '6'; elsif(vec(hi downto lo) = "0111") then str(i) := '7'; elsif(vec(hi downto lo) = "1000") then str(i) := '8'; elsif(vec(hi downto lo) = "1001") then str(i) := '9'; elsif(vec(hi downto lo) = "1010") then str(i) := 'A'; elsif(vec(hi downto lo) = "1011") then str(i) := 'B'; elsif(vec(hi downto lo) = "1100") then str(i) := 'C'; elsif(vec(hi downto lo) = "1101") then str(i) := 'D'; elsif(vec(hi downto lo) = "1110") then str(i) := 'E'; elsif(vec(hi downto lo) = "1111") then str(i) := 'F'; else str(i) := 'X'; end if; end loop; str(9) := 'x'; str(10) := '0'; return str; end; function vec16tohex(vec: vlbit_1d) return string is variable str: string(6 downto 1); variable lo: integer; variable hi: integer; begin for i in 1 to 4 loop lo := (i-1)*4; hi := ((i-1)*4)+3; if(vec(hi downto lo) = "0000") then str(i) := '0'; elsif(vec(hi downto lo) = "0001") then str(i) := '1'; elsif(vec(hi downto lo) = "0010") then str(i) := '2'; elsif(vec(hi downto lo) = "0011") then str(i) := '3'; elsif(vec(hi downto lo) = "0100") then str(i) := '4'; elsif(vec(hi downto lo) = "0101") then str(i) := '5'; elsif(vec(hi downto lo) = "0110") then str(i) := '6'; elsif(vec(hi downto str(i) := '7'; elsif(vec(hi downto str(i) := '8'; elsif(vec(hi downto str(i) := '9'; elsif(vec(hi downto str(i) := 'A'; elsif(vec(hi downto str(i) := 'B'; elsif(vec(hi downto str(i) := 'C'; elsif(vec(hi downto str(i) := 'D'; elsif(vec(hi downto str(i) := 'E'; elsif(vec(hi downto str(i) := 'F'; else str(i) := 'X'; end if; end loop; str(5) := 'x'; str(6) := '0'; return str; end; lo) = "0111") then lo) = "1000") then lo) = "1001") then lo) = "1010") then lo) = "1011") then lo) = "1100") then lo) = "1101") then lo) = "1110") then lo) = "1111") then function vec2intstr(vec: vlbit_1d) return string is variable stmp: string(2 downto 1); variable itmp: integer; begin itmp := v1d2int(vec); for i in 1 to 2 loop case (itmp mod 10) is when 0 => stmp(i downto i) := when 1 => stmp(i downto i) := when 2 => stmp(i downto i) := when 3 => stmp(i downto i) := when 4 => stmp(i downto i) := when 5 => stmp(i downto i) := when 6 => stmp(i downto i) := when 7 => stmp(i downto i) := when 8 => stmp(i downto i) := when OTHERS => stmp(i downto i) := end case; "0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; itmp := itmp / 10; end loop; return stmp; end; function toString(dumb: string) return string is begin return dumb; end; begin monitor: process variable variable variable variable variable variable variable variable variable variable variable variable variable outputLine : line; opcode : integer; funct : integer; destR : string(3 downto 1); sourceR1 : string(3 downto 1); sourceR2 : string(3 downto 1); instr_addr : string(10 downto 1); destRData : string(10 downto 1); immed : string(6 downto 1); shiftAmt : string(2 downto 1); bz : integer; mfhiData : string(10 downto 1); mfloData : string(10 downto 1); constant constant constant constant constant constant constant constant constant constant constant constant constant constant constant RTYPE_OP : integer := 0; ADDIU_OP : integer := 9; LW_OP : integer := 35; LUI_OP : integer := 15; SW_OP : integer := 43; BEQ_OP : integer := 4; BNE_OP : integer := 5; BZ_OP : integer := 1; ANDI_OP : integer := 12; ORI_OP : integer := 13; XORI_OP : integer := 14; SLTI_OP : integer := 10; SLTIU_OP : integer := 11; J_OP : integer := 2; JAL_OP : integer := 3; constant constant constant constant constant constant constant constant constant constant constant constant constant constant ADDU_FUNCT : integer := 33; SUBU_FUNCT : integer := 35; AND_FUNCT : integer := 36; OR_FUNCT : integer := 37; XOR_FUNCT : integer := 38; SLL_FUNCT : integer := 0; SRL_FUNCT : integer := 2; SRA_FUNCT : integer := 3; SLT_FUNCT : integer := 42; SLTU_FUNCT : integer := 43; JR_FUNCT : integer := 8; MFHI_FUNCT : integer := 16; MFLO_FUNCT : integer := 18; MULTU_FUNCT : integer := 25; -- for bgez and bltz instructions constant BGEZ_RT : integer := 1; constant BLTZ_RT : integer := 0; begin wait until pfalling(CLK); if INVALIDATE = '1' then opcode := vec2int(INSTRUCTION(31 downto 26)); funct := vec2int(INSTRUCTION(5 downto 0)); instr_addr := vec32tohex(PC); destRData := vec32tohex(VALUE); mfhiData := vec32tohex(MFHI); mfloData := vec32tohex(MFLO); sourceR1(2 downto 1) := vec2intstr(INSTRUCTION(25 downto 21)); sourceR1(3) := 'r'; write(outputLine, toString(instr_addr & ": ")); case opcode is when RTYPE_OP => sourceR2(2 downto 1) := vec2intstr(INSTRUCTION(20 downto 16)); sourceR2(3) := 'r'; destR(2 downto 1) := vec2intstr(INSTRUCTION(15 downto 11)); destR(3) := 'r'; shiftAmt := vec2intstr(INSTRUCTION(10 downto 6)); case funct is when ADDU_FUNCT => write(outputLine, write(outputLine, write(outputLine, when SUBU_FUNCT => write(outputLine, write(outputLine, write(outputLine, when AND_FUNCT => write(outputLine, write(outputLine, write(outputLine, when OR_FUNCT => write(outputLine, write(outputLine, write(outputLine, when XOR_FUNCT => write(outputLine, write(outputLine, write(outputLine, when SLL_FUNCT => write(outputLine, write(outputLine, write(outputLine, when SRL_FUNCT => write(outputLine, write(outputLine, write(outputLine, when SRA_FUNCT => write(outputLine, write(outputLine, write(outputLine, when SLT_FUNCT => write(outputLine, write(outputLine, write(outputLine, when SLTU_FUNCT => write(outputLine, write(outputLine, write(outputLine, when JR_FUNCT => write(outputLine, write(outputLine, when MFHI_FUNCT => write(outputLine, write(outputLine, write(outputLine, when MFLO_FUNCT => write(outputLine, write(outputLine, write(outputLine, when MULTU_FUNCT => write(outputLine, write(outputLine, write(outputLine, write(outputLine, when OTHERS => write(outputLine, end case; when OTHERS => toString("addu ")); toString(destR & "," & sourceR1 & "," & sourceR2)); toString(" R[" & destR & "]=" & destRData)); toString("subu ")); toString(destR & "," & sourceR1 & "," & sourceR2)); toString(" R[" & destR & "]=" & destRData)); toString("and ")); toString(destR & "," & sourceR1 & "," & sourceR2)); toString(" R[" & destR & "]=" & destRData)); toString("or ")); toString(destR & "," & sourceR1 & "," & sourceR2)); toString(" R[" & destR & "]=" & destRData)); toString("xor ")); toString(destR & "," & sourceR1 & "," & sourceR2)); toString(" R[" & destR & "]=" & destRData)); toString("sll ")); toString(destR & "," & sourceR2 & "," & shiftAmt)); toString(" R[" & destR & "]=" & destRData)); toString("srl ")); toString(destR & "," & sourceR2 & "," & shiftAmt)); toString(" R[" & destR & "]=" & destRData)); toString("sra ")); toString(destR & "," & sourceR2 & "," & shiftAmt)); toString(" R[" & destR & "]=" & destRData)); toString("slt ")); toString(destR & "," & sourceR1 & "," & sourceR2)); toString(" R[" & destR & "]=" & destRData)); toString("sltu ")); toString(destR & "," & sourceR1 & "," & sourceR2)); toString(" R[" & destR & "]=" & destRData)); toString("jr ")); toString(sourceR1)); toString("mfhi ")); toString(destR)); toString(" R[" & destR & "]=" & destRData)); toString("mflo ")); toString(destR)); toString(" R[" & destR & "]=" & destRData)); toString("multu ")); toString(sourceR1 & "," & sourceR2)); toString(" HI=" & mfhiData)); toString(", LO=" & mfloData)); toString("UNKNOWN FUNCT")); destR(2 downto 1) := vec2intstr(INSTRUCTION(20 downto 16)); destR(3 downto 3) := "r"; immed := vec16tohex(INSTRUCTION(15 downto 0)); case opcode is when ADDIU_OP => write(outputLine, toString("addiu ")); write(outputLine, toString(destR & "," & sourceR1 & "," & immed)); write(outputLine, toString(" R[" & destR & "]=" & destRData)); when ANDI_OP => write(outputLine, toString("andi ")); write(outputLine, toString(destR & "," & sourceR1 & "," & immed)); write(outputLine, toString(" R[" & destR & "]=" & destRData)); when XORI_OP => write(outputLine, toString("xori ")); write(outputLine, toString(destR & "," & sourceR1 & "," & immed)); write(outputLine, toString(" R[" & destR & "]=" & destRData)); when ORI_OP => write(outputLine, toString("ori ")); write(outputLine, toString(destR & "," & sourceR1 & "," & immed)); write(outputLine, toString(" R[" & destR & "]=" & destRData)); when LW_OP => write(outputLine, toString("lw ")); write(outputLine, toString(destR & "," & immed & "(" & sourceR1 & ")")); write(outputLine, toString(" R[" & destR & "]=" & destRData)); when LUI_OP => write(outputLine, toString("lui ")); write(outputLine, toString(destR & "," & immed)); write(outputLine, toString(" R[" & destR & "]=" & destRData)); when SW_OP => write(outputLine, toString("sw ")); write(outputLine, toString(destR & "," & immed & "(" & sourceR1 & ")")); write(outputLine, toString(" MEM[" & vec32tohex(MEM_ADDRESS) & "]=" & destRData)); when BEQ_OP => write(outputLine, toString("beq ")); write(outputLine, toString(destR & "," & sourceR1 & "," & immed)); when BNE_OP => write(outputLine, toString("bne ")); write(outputLine, toString(destR & "," & sourceR1 & "," & immed)); when BZ_OP => bz := v1d2int(INSTRUCTION(20 downto 16)); destR(2 downto 1) := vec2intstr(INSTRUCTION(25 downto 21)); case bz is when BGEZ_RT => write(outputLine, toString("bgez ")); write(outputLine, toString(destR & "," & immed)); when BLTZ_RT => write(outputLine, toString("bltz ")); write(outputLine, toString(destR & "," & immed)); when OTHERS => write(outputLine, toString("UNKNOWN BRANCH INSTR")); end case; when SLTI_OP => write(outputLine, toString("slti ")); write(outputLine, toString(destR & "," & sourceR1 & "," & immed)); write(outputLine, toString(" R[" & destR & "]=" & destRData)); when SLTIU_OP => write(outputLine, toString("sltiu ")); write(outputLine, toString(destR & "," & sourceR1 & "," & immed)); write(outputLine, toString(" R[" & destR & "]=" & destRData)); when J_OP => immed := vec16tohex(INSTRUCTION(25 downto 0)); write(outputLine, toString("j ")); write(outputLine, toString(immed)); when JAL_OP => immed := vec16tohex(INSTRUCTION(25 downto 0)); write(outputLine, toString("jal ")); write(outputLine, toString(immed)); when OTHERS => write(outputLine, toString("UNKNOWN OPCODE")); end case; end case; writeline(output, outputLine); end if; end process; end behavior; Renamer library pack1076; use pack1076.pack1076.all; entity renamer is port(signal DIN: signal DOUT: end renamer; in out vlbit; vlbit); architecture behavior of renamer is begin renamer : process(DIN) begin DOUT <= DIN; end process renamer; end behavior; ROB Issue Controller library pack1076; use pack1076.pack1076.all; entity rob_issue_controller is generic (delay: TIME := 1 ns); -- for now port(signal INSTR_TYPE : in vlbit_1d(5 downto 0); signal ISSUE_INSTR : in vlbit; signal NOT_SUPPLEMENTARY_DATA_READY : out vlbit; signal INSTRUCTION_TYPE : out vlbit_1d(4 downto 0); signal ISSUE_ADDRESS_CALC : out vlbit); end rob_issue_controller; architecture behavior of rob_issue_controller is begin rob_issue_controller_process: process(INSTR_TYPE, ISSUE_INSTR) constant swOp : integer := 1; constant lwOp : integer := 2; constant regOp : integer := 4; constant branchOp : integer := 8; constant multOp : integer := 16; constant jJrOp : integer := 32; begin if ISSUE_INSTR = '1' then case v1d2int(INSTR_TYPE) is when swOP => NOT_SUPPLEMENTARY_DATA_READY <= '1' after INSTRUCTION_TYPE <= "00010" after delay; ISSUE_ADDRESS_CALC <= '1' after delay; when lwOp => NOT_SUPPLEMENTARY_DATA_READY <= '0' after INSTRUCTION_TYPE <= "00100" after delay; ISSUE_ADDRESS_CALC <= '1' after delay; when regOp => NOT_SUPPLEMENTARY_DATA_READY <= '0' after INSTRUCTION_TYPE <= "00100" after delay; ISSUE_ADDRESS_CALC <= '0' after delay; when branchOp => NOT_SUPPLEMENTARY_DATA_READY <= '0' after INSTRUCTION_TYPE <= "00001" after delay; ISSUE_ADDRESS_CALC <= '0' after delay; when multOp => NOT_SUPPLEMENTARY_DATA_READY <= '0' after delay; delay; delay; delay; delay; INSTRUCTION_TYPE <= "01000" after delay; ISSUE_ADDRESS_CALC <= '0' after delay; when jJrOp => NOT_SUPPLEMENTARY_DATA_READY <= '0' after delay; INSTRUCTION_TYPE <= "10000" after delay; ISSUE_ADDRESS_CALC <= '0' after delay; when others => null; end case; else NOT_SUPPLEMENTARY_DATA_READY <= '1' after delay; INSTRUCTION_TYPE <= "00001" after delay; ISSUE_ADDRESS_CALC <= '0' after delay; end if; -- when jrFunct => end process; end behavior; ROB Commit Controller library pack1076; use pack1076.pack1076.all; entity rob_commit_controller is generic (delay: TIME := 1 ns); -- for now port(signal INSTR_TYPE : in vlbit_1d(4 downto 0); signal COMMIT : in vlbit; signal STALL : in vlbit; signal INVALIDATE : out vlbit; signal REG_WRITE : out vlbit; signal MEM_WRITE : out vlbit; signal MULT_REG_WRITE : out vlbit); end rob_commit_controller; architecture behavior of rob_commit_controller is begin rob_commit_controller_process: process(INSTR_TYPE, COMMIT, STALL) constant branchOp : integer := 1; constant swOp : integer := 2; constant regOp : integer := 4; constant multOp : integer := 8; constant jJrOp : integer := 16; begin if COMMIT = '1' then case v1d2int(INSTR_TYPE) is when swOP => if (STALL = '1') then INVALIDATE <= '0' after delay; else INVALIDATE <= '1' after delay; end if; REG_WRITE <= '0' after delay; MEM_WRITE <= '1' after delay; MULT_REG_WRITE <= '0' after delay; when regOp => INVALIDATE <= '1' after delay; REG_WRITE <= '1' after delay; MEM_WRITE <= '0' after delay; MULT_REG_WRITE <= '0' after delay; when branchOp => INVALIDATE <= '1' after delay; REG_WRITE <= '0' after delay; MEM_WRITE <= '0' after delay; MULT_REG_WRITE <= '0' after delay; when multOp => INVALIDATE <= '1' after delay; REG_WRITE <= '0' after delay; MEM_WRITE <= '0' after delay; MULT_REG_WRITE <= '1' after delay; when jJrOp => INVALIDATE <= '1' after delay; REG_WRITE <= '0' after delay; MEM_WRITE <= '0' after delay; MULT_REG_WRITE <= '0' after delay; when others => null; end case; else INVALIDATE <= '0' after delay; REG_WRITE <= '0' after delay; MEM_WRITE <= '0' after delay; MULT_REG_WRITE <= '0' after delay; end if; end process; end behavior; Reservation Station ALU Issuer --------------------------------------------------------------------------------This is the Controller for the Reservation Stations ------------------------------------------------------------------------------library pack1076; use pack1076.pack1076.all; entity RSctrlALUI is generic (delay: time := 6 ns); port( --Also add signal signal signal signal --we'll probably have to change this inputs to account for the instruction broadcasts. CLK : in vlbit; issue : in vlbit; instr : in vlbit_1d(84 downto 0); taken : in vlbit_1d(15 downto 0); signal listen : out vlbit_1d(3 downto 0); signal full : out vlbit ); end RSctrlALUI; architecture behavior of RSctrlALUI is -- purpose: to loop-increment next_issue function inc(x: integer) return integer is begin -- inc if (x = 15) then return 0; elsif (x < 0) then return -1; elsif (x > 15) then return -1; else return (x + 1); end if; end inc; function vlbit_1dtoint(input : vlbit_1d) return integer is variable x : vlbit_1d(3 downto 0) := input; variable y : integer; begin case x is when "0000" => y := 0; when "0001" => y := 1; when "0010" y := 2; when "0011" y := 3; when "0100" y := 4; when "0101" y := 5; when "0110" y := 6; when "0111" y := 7; when "1000" y := 8; when "1001" y := 9; when "1010" y := 10; when "1011" y := 11; when "1100" y := 12; when "1101" y := 13; when "1110" y := 14; when "1111" y := 15; when others y := -1; end case; return y; end; => => => => => => => => => => => => => => => function inttovlbit_1d(x : integer) return vlbit_1d is variable y : vlbit_1d(3 downto 0); begin case x is when 0 => y := "0000"; when 1 => y := "0001"; when 2 => y := "0010"; when 3 => y := "0011"; when 4 => y := "0100"; when 5 => y := "0101"; when 6 => y := "0110"; when 7 => y := "0111"; when 8 => y := "1000"; when 9 => y := "1001"; when 10 => y := "1010"; when 11 => y := "1011"; when 12 => y := "1100"; when 13 => y := "1101"; when 14 => y := "1110"; when 15 => y := "1111"; when others => y := "XXXX"; end case; return y; end; begin RSctrlALUI:process constant numStations : integer := 16; variable next_issue : integer := 1; variable count : integer := 0; variable keepLooping : boolean := true; variable stationsOccupied : vlbit_1d((numStations - 1) downto 0); variable initialSetupDone : boolean := false; --This is where everything REALLY begins begin if not initialSetupDone then listen <= "0000"; initialSetupDone := true; end if; wait until pfalling(CLK); -- just remember that this actually calculates the NEXT reservation that it -- needs to listen to. this avoids the glitch problem in the issue. it will -- only check the issue signal at the falling edge, and use the current one -- for the reservation station, and have the next one calculated. if (issue = '1') then count := 0; keepLooping := true; while ((count < numStations) and (keepLooping = true)) loop if (taken(next_issue) = '1') then next_issue := inc(next_issue); else listen <= inttovlbit_1d(next_issue) after delay; keepLooping := false; next_issue := inc(next_issue); end if; count := count + 1; end loop; end if; if (taken full <= else full <= end if; end process end behavior; = "1111111111111111") then '1' after delay; '0' after delay; RSctrlALUI; Reservation Station ALU Launcher --------------------------------------------------------------------------------This is the Controller for the Reservation Stations ------------------------------------------------------------------------------library pack1076; use pack1076.pack1076.all; use std.textio.all; entity RSctrlALUL is generic (delay: time := 6 ns); port( --Also add signal signal signal signal signal signal --we'll probably have to change this inputs to account for the instruction broadcasts. CLK : in vlbit; taken : in vlbit_1d(15 downto 0); notReady : in vlbit_1d(15 downto 0); granted : in vlbit; busy : in vlbit_1d(15 downto 0); squish : in vlbit; signal toFU : out vlbit_1d(3 downto 0); signal CDBreq : out vlbit; signal resetRS : out vlbit_1d(3 downto 0 ); signal issue : in vlbit; signal listen : in vlbit_1d(3 downto 0) ); end RSctrlALUL; architecture behavior of RSctrlALUL is function toString(dumb: string) return string is begin return dumb; end; -- purpose: to loop-increment next_issue function inc(x: integer) return integer is begin -- inc if (x = 15) then return 0; elsif (x < 0) then return -1; elsif (x > 15) then return -1; else return (x + 1); end if; end inc; function vlbit_1dtoint(input : vlbit_1d) return integer is variable x : vlbit_1d(3 downto 0) := input; variable y : integer; begin case x is when "0000" => y := 0; when "0001" => y := 1; when "0010" => y := 2; when "0011" => y := 3; when "0100" => y := 4; when "0101" => y := 5; when "0110" => y := 6; when "0111" => y := 7; when "1000" => y := 8; when "1001" => y := 9; when "1010" => y := 10; when "1011" => y := 11; when "1100" => y := 12; when "1101" => y := 13; when "1110" => y := 14; when "1111" => y := 15; when others => y := -1; end case; return y; end; function inttovlbit_1d(x : integer) return vlbit_1d is variable y : vlbit_1d(3 downto 0); begin case x is when 0 => y := "0000"; when 1 => y := "0001"; when 2 => y := "0010"; when 3 => y := "0011"; when 4 => y := "0100"; when 5 => y := "0101"; when 6 => y := "0110"; when 7 => y := "0111"; when 8 => y := "1000"; when 9 => y := "1001"; when 10 => y := "1010"; when 11 => y := "1011"; when 12 => y := "1100"; when 13 => y := "1101"; when 14 => y := "1110"; when 15 => y := "1111"; when others => y := "XXXX"; end case; return y; end; constant numOfStations : integer := 16; type queue is array((numOfStations-1) downto 0) of integer; -- initialized so that queue has not duplicates; -- lowest address is next to be evicted begin RSctrlALUL:process variable stationsNotReady : vlbit_1d((numOfStations - 1) downto 0); variable stationsTaken : vlbit_1d((numOfStations - 1) downto 0); variable stationsBusy : vlbit_1d((numOfStations - 1) downto 0); variable count : integer := 0; variable launchNum : integer := 0; variable keepLooping : boolean := true; variable justRequestedCDB : boolean := false; variable requestedLongAgo : boolean := false; variable outputline : line; variable lastLaunched : integer := -1; variable oldestInstr : integer := 0; variable execQueue : queue; variable initSetupDone : boolean := false; variable numIssued : integer; variable issueInQueue : boolean; variable tempCounter : integer; --This is where everything REALLY begins begin if not initSetupDone then for i in 0 to numOfStations - 1 loop execQueue(i) := -1; end loop; -- i initSetupDone := true; end if; wait until pfalling(CLK); --latch a few key values if ISSUE = '1' then -- check and see if the LISTEN is already in the queue or not. numIssued := v1d2int(LISTEN); issueInQueue := false; for i in 0 to numOfStations - 1 loop if execQueue(i) = numIssued then issueInQueue := true; end if; end loop; -- i if not issueInQueue then -- it was not in the queue so add it to the queue. tempCounter := 0; while not issueInQueue loop if execQueue(tempCounter) = -1 then execQueue(tempCounter) := numIssued; issueInQueue := true; else tempCounter := tempCounter + 1; assert tempCounter < numOfStations report "something is wrong in the RSctrlALUL" severity error; end if; end loop; else assert false report "this means that something that has been issued is being issued again. obviously an error." severity error; end if; end if; stationsNotReady := notReady(15 downto 0); stationsTaken := taken(15 downto 0); stationsBusy := busy(15 downto 0); keepLooping := true; if ((requestedLongAgo = true) and (granted = '0')) then -- Do this if you requested, but weren't granted CDBreq <= '1' after delay; requestedLongAgo := justRequestedCDB; justRequestedCDB := true; else tempCounter := -1; keepLooping := true; while tempCounter < 15 and keepLooping loop tempCounter := tempCounter + 1; launchNum := execQueue(tempCounter); if launchNum /= -1 then if((stationsTaken(launchNum) = '1') and (stationsNotReady(launchNum) = '0') and (stationsBusy(launchNum) = '0') and (squish /= '1')) then keepLooping := false; end if; else keepLooping := false; end if; end loop; -- at this point, if the launchNum is -1, that means nothing can be -- launched cause it is not ready. if launchNum /= -1 then -- now, get rid of the station that has been just launched from the -- queue. the station to be launched is # tempCounter. if tempCounter <= numOfStations - 2 then for i in tempCounter to numOfStations - 2 loop execQueue(i) := execQueue(i+1); end loop; -- i end if; execQueue(numOfStations-1) := -1; toFU <= inttovlbit_1d(launchNum) after delay; CDBreq <= '1' after delay; requestedLongAgo := justRequestedCDB; resetRS <= inttovlbit_1d(lastLaunched) after delay; lastLaunched := launchNum; justRequestedCDB := true; --write(outputline, launchNum); --write(outputline, toString(" is the RS we're choosing to launch ")); --writeline(output, outputline); else --write(outputline, toString("Nothing to launch")); --writeline(output, outputline); CDBreq <= '0' after delay; requestedLongAgo := justRequestedCDB; justRequestedCDB := false; end if; end if; end process RSctrlALUL; end behavior; Tri-state Buffer Low Enable library pack1076; use pack1076.pack1076.all; entity bts4x32 is generic ( delay: time:= 1 ns ); port ( T_L: DIN: DOUT: ); end bts4x32; in vlbit; in vlbit_1d (31 downto 0); out vlbit_1d (31 downto 0) architecture behavior of bts4x32 is begin -- behavior bts4x32_process: process (T_L, DIN) begin if (T_L = '1') then DOUT <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" after delay; else DOUT <= DIN (31 downto 0) after delay; end if; end process; end behavior; Tri-state Buffer High Enable library pack1076; use pack1076.pack1076.all; entity bts4x32_h is generic ( delay: time:= 1 ns ); port ( T_H: DIN: DOUT: ); end bts4x32_h; in vlbit; in vlbit_1d (31 downto 0); out vlbit_1d (31 downto 0) architecture behavior of bts4x32_h is begin -- behavior bts4x32_process: process (T_H, DIN) begin if (T_H = '0') then DOUT <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" after delay; else DOUT <= DIN (31 downto 0) after delay; end if; end process; end behavior; One Hot Adder library pack1076; use pack1076.pack1076.all; entity oha16 is generic(delay: TIME := 2 ns); port (i: in vlbit_1d(15 downto 0); o0: out vlbit; o1: out vlbit; o2: out vlbit; o3: out vlbit; o4: out vlbit; o5: out vlbit; o6: out vlbit; o7: out vlbit); end oha16; architecture behavior of oha16 is begin oha16_process: variable sum variable ot0 variable ot1 variable ot2 variable ot3 variable ot4 variable ot5 variable ot6 variable ot7 begin sum := 0; ot0 := '0'; ot1 := '0'; ot2 := '0'; ot3 := '0'; ot4 := '0'; ot5 := '0'; ot6 := '0'; ot7 := '0'; : : : : : : : : : process(i) integer := 0; vlbit := '0'; vlbit := '0'; vlbit := '0'; vlbit := '0'; vlbit := '0'; vlbit := '0'; vlbit := '0'; vlbit := '0'; -- process for junk in 0 to 15 loop sum := sum + vlb2int(i(junk)); end loop; -- junk case sum is when 0 => ot0 := '1'; when 1 => ot1 := '1'; when 2 => ot2 := '1'; when 3 => ot3 := '1'; when 4 => ot4 := '1'; when 5 => ot5 := '1'; when 6 => -- behavior ot6 := '1'; when 7 => ot7 := '1'; when others => null; end case; o0 <= ot0 after o1 <= ot1 after o2 <= ot2 after o3 <= ot3 after o4 <= ot4 after o5 <= ot5 after o6 <= ot6 after o7 <= ot7 after end process; end behavior; delay; delay; delay; delay; delay; delay; delay; delay; In Out Test library pack1076; use pack1076.pack1076.all; use std.textio.all; entity inout_test is generic ( delay : time := 6 ns); port ( --Interface to Pipeline signal clk : in vlbit; signal r_w : in vlbit; --1 when processor is doing a write signal d_ioo : inout vlbit_1d(31 downto 0); signal d_ioe : inout vlbit_1d(31 downto 0); signal d64out : out vlbit_1d(63 downto 0)); end inout_test; architecture behavior of inout_test is function toString(dumb: string) return string is begin return dumb; end; function vec32tohex(vec: vlbit_1d; inlo:integer) return string is variable str: string(8 downto 1); variable lo: integer; variable hi: integer; begin for i in 1 to 8 loop lo := inlo+(i-1)*4; hi := inlo+((i-1)*4)+3; if(vec(hi downto lo) = "0000") then str(i) := '0'; elsif(vec(hi downto lo) = "0001") then str(i) := '1'; elsif(vec(hi downto lo) = "0010") then str(i) := '2'; elsif(vec(hi downto lo) = "0011") then str(i) := '3'; elsif(vec(hi downto lo) = "0100") then str(i) := '4'; elsif(vec(hi downto lo) = "0101") then str(i) := '5'; elsif(vec(hi downto lo) = "0110") then str(i) := '6'; elsif(vec(hi downto lo) = "0111") then str(i) := '7'; elsif(vec(hi downto lo) = "1000") then str(i) := '8'; elsif(vec(hi downto lo) = "1001") then str(i) := '9'; elsif(vec(hi downto lo) = "1010") str(i) := 'A'; elsif(vec(hi downto lo) = "1011") str(i) := 'B'; elsif(vec(hi downto lo) = "1100") str(i) := 'C'; elsif(vec(hi downto lo) = "1101") str(i) := 'D'; elsif(vec(hi downto lo) = "1110") str(i) := 'E'; elsif(vec(hi downto lo) = "1111") str(i) := 'F'; elsif((vec(hi downto hi) = "X") or (vec(hi-1 downto hi-1) = or (vec(hi-2 downto hi-2) = or (vec(hi-3 downto hi-3) = str(i) := 'X'; else str(i) := 'Z'; end if; end loop; return str; end; begin then then then then then then "X") "X") "X")) then -- behavior inout_test: process variable d64in : vlbit_1d(63 downto 0); begin wait until pfalling(clk); if r_w = '1' then wait for 5 ns; d_ioo <= "11111111111111111111111111111111"; d_ioe <= "01010101010101010101010101010101"; wait for 5 ns; else wait for 5 ns; d64in(63 downto 32) := d_ioo; d64in(31 downto 0) := d_ioe; d64out <= d64in after delay; wait for 5 ns; end if; d_ioo <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"; d_ioe <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"; wait for 5 ns; end process; end behavior; Memory Control library pack1076; use pack1076.pack1076.all; use std.textio.all; entity mc is generic ( delay : time := 6 ns; long_delay : time := 12 ns; freaking_long_delay : time := 31 ns); port ( --Interface to Pipeline signal c : in vlbit; signal req : in vlbit; --1 when processor making req signal r_w : in vlbit; --1 when processor is doing a write signal d_in : in vlbit_1d(63 downto 0); signal ad : in vlbit_1d(9 downto 0); signal d_out : out vlbit_1d(63 downto 0); signal w_h : out vlbit; --Interface to DRAM Controller signal d_ioo : inout vlbit_1d(31 downto 0); signal d_ioe : inout vlbit_1d(31 downto 0); signal a_oo : out vlbit_1d(4 downto 0); signal a_oe : out vlbit_1d(4 downto 0); signal RAS_L : out vlbit; signal CAS_L : out vlbit; signal OE_L : out vlbit; signal WE_L : out vlbit; signal REF_L : out vlbit; signal S : in vlbit); end mc; architecture behavior of mc is function toString(dumb: string) return string is begin return dumb; end; function vec32tohex(vec: vlbit_1d; inlo:integer) return string is variable str: string(8 downto 1); variable lo: integer; variable hi: integer; begin for i in 1 to 8 loop lo := inlo+(i-1)*4; hi := inlo+((i-1)*4)+3; if(vec(hi downto lo) = "0000") then str(i) := '0'; elsif(vec(hi downto lo) = "0001") then str(i) := '1'; elsif(vec(hi downto lo) = "0010") then str(i) := '2'; elsif(vec(hi downto lo) = "0011") then str(i) := '3'; elsif(vec(hi downto lo) = "0100") then str(i) := '4'; elsif(vec(hi downto lo) = "0101") then str(i) := '5'; elsif(vec(hi downto lo) = "0110") then str(i) := '6'; elsif(vec(hi downto lo) = "0111") then str(i) := '7'; elsif(vec(hi downto lo) = "1000") then str(i) := '8'; elsif(vec(hi downto lo) = "1001") then str(i) := '9'; elsif(vec(hi downto lo) = "1010") then str(i) := 'A'; elsif(vec(hi downto lo) = "1011") then str(i) := 'B'; elsif(vec(hi downto lo) = "1100") then str(i) := 'C'; elsif(vec(hi downto lo) = "1101") then str(i) := 'D'; elsif(vec(hi downto lo) = "1110") then str(i) := 'E'; elsif(vec(hi downto lo) = "1111") then str(i) := 'F'; elsif((vec(hi downto hi) = "X") or (vec(hi-1 downto hi-1) = "X") or (vec(hi-2 downto hi-2) = "X") or (vec(hi-3 downto hi-3) = "X")) then str(i) := 'X'; else str(i) := 'Z'; end if; end loop; return str; end; begin -- behavior mc: process variable outputline : line; variable addr : vlbit_1d(9 downto 0); variable startingup : boolean := true; variable storedD_in : vlbit_1d(63 downto 0); variable delay_1 : time; variable delay_2 : time; variable delay_2p1 : time; variable ras_high_time : time; variable ras_precharge_time : time; variable wait_time : time; variable time_to_wait : time; constant X32 : vlbit_1d := "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; constant X64 : vlbit_1d := "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; constant wait_prop_delay : time := 10 ns; variable cycle_time : time; variable last_clock_time : time; variable cycle_read_done : integer; variable cycle_write_done : integer; variable temp_time : time; variable r_done_time : time; variable w_done_time : time; variable r_wait_cause_of_prop : time; variable w_wait_cause_of_prop : time; begin wait until pfalling(c); if (startingup = true) then RAS_L <= '1'; CAS_L <= '1'; OE_L <= '1'; WE_L <= '1'; w_h <= '1'; ras_high_time := now; last_clock_time := now; wait until pfalling(c); cycle_time := now - last_clock_time; ---- if S = '1' then delay_1 := 95 ns; delay_2 := 120 ns; delay_2p1 := 121 ns; ras_precharge_time := 195 ns; r_done_time := 227 ns; w_done_time := 225 ns; else delay_1 := 21 ns; delay_2 := 30 ns; delay_2p1 := 31 ns; ras_precharge_time := 45 ns; r_done_time := 63 ns; w_done_time := 61 ns; end if; write(outputline, cycle_time); write(outputline, toString(" is the cycle time.")); writeline(output, outputline); startingup := false; end if; REF_L <= '1'; --change this later if (req = '1') then --have a request ----------- --- wait_time := now - ras_high_time; w_h <= '1'; write(outputline, now); write(outputline, toString(" is now. ")); write(outputline, wait_time); write(outputline, toString(" is time i waited. ")); write(outputline, ras_high_time); write(outputline, toString(" is the last time RAS went high.")); writeline(output, outputline); if wait_time < ras_precharge_time then write(outputline, toString("Precharge time not met so will have to wait ")); time_to_wait := ras_precharge_time - wait_time; write(outputline, time_to_wait); writeline(output, outputline); wait for time_to_wait; else time_to_wait := 0 ns; write(outputline, toString("Precharge time met so will not have to wait")); writeline(output, outputline); end if; -- find the time this must wait later on. don't ask what it does unless -- you REALLY want to know cause it's kind of crazy. temp_time := 0 ns; cycle_read_done := 0; while temp_time < r_done_time + time_to_wait loop temp_time := temp_time + cycle_time; cycle_read_done := cycle_read_done + 1; end loop; temp_time := 0 ns; cycle_write_done := 0; while temp_time < w_done_time + time_to_wait loop temp_time := temp_time + cycle_time; cycle_write_done := cycle_write_done + 1; end loop; temp_time := temp_time - (w_done_time + time_to_wait); if temp_time < wait_prop_delay then w_wait_cause_of_prop := temp_time; else w_wait_cause_of_prop := 0 ns; end if; temp_time := cycle_read_done * cycle_time - (r_done_time + time_to_wait); if temp_time < wait_prop_delay then r_wait_cause_of_prop := temp_time; else r_wait_cause_of_prop := 0 ns; end if; -write(outputline, -write(outputline, -writeline(output, -write(outputline, -write(outputline, -writeline(output, -write(outputline, -write(outputline, time.")); -writeline(output, -write(outputline, -write(outputline, time.")); -writeline(output, cycle_write_done); toString(" is the cycle write is going to finish.")); outputline); cycle_read_done); toString(" is the cycle read is going to finish.")); outputline); r_wait_cause_of_prop); toString(" is the time needed for the wait to have enough outputline); w_wait_cause_of_prop); toString(" is the time needed for the wait to have enough outputline); if (r_w = '1') then addr := ad; storedD_in := d_in; d_out <= X64; a_oo <= addr(9 downto 5); a_oe <= addr(9 downto 5); d_ioo <= X32; --a write d_ioe <= X32; wait for 5 ns; RAS_L <= '0'; wait for delay_1; a_oo(4 downto 1) <= addr(4 downto 1); a_oo(0) <= '1'; a_oe(4 downto 1) <= addr(4 downto 1); a_oe(0) <= '0'; d_ioo <= storedD_in(63 downto 32); d_ioe <= storedD_in(31 downto 0); WE_L <= '0'; wait for 5 ns; CAS_L <= '0'; wait for delay_2; wait for w_wait_cause_of_prop; -- RAS go high now 60/225 ns later. The -- 40/175 ns. But the precharge time of else --A read addr := ad; d_out <= X64; a_oo <= addr(9 downto 5); a_oe <= addr(9 downto 5); wait for 5 ns; RAS_L <= '0'; wait for delay_1; a_oo(4 downto 1) <= addr(4 downto 1); a_oo(0) <= '1'; a_oe(4 downto 1) <= addr(4 downto 1); a_oe(0) <= '0'; OE_L <= '0'; wait for 5 ns; CAS_L <= '0'; wait for delay_2p1; d_out(63 downto 32) <= d_ioo; d_out(31 downto 0) <= d_ioe; wait for 1 ns; wait for r_wait_cause_of_prop; -- RAS go high now 62/227 ns later. The -- 38/173 ns. But the precharge time of end if; ras_high_time := now; end if; RAS must not go down for at least 50/200 ns must be met as well. RAS must not go down for at least 50/200 ns must be met as well. -- I will make the wait go low right now so that the processor can go do whatever -- it needs to do. But if a request comes before the precharge time is met, -- it'll need to take care of it by doing some wait before the RAS goes -- down low again. So we keep the "now" time to do that calculation later. CAS_L <= '1'; RAS_L <= '1'; WE_L <= '1'; OE_L <= '1'; w_h <= '0'; d_ioo <= X32; d_ioe <= X32; a_oo <= "XXXXX"; a_oe <= "XXXXX"; d_ioo <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"; d_ioe <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"; end process; end behavior; Source to ROB Tester ------------------------------------------------- source2rob test bench version 3.1415926535897 -----------------------------------------------library pack1076; use pack1076.pack1076.all; library ieee; use std.textio.all; entity source2rob_tester is generic ( delay : time := 25 ns; prop_delay : time := 1 ns); port(signal signal signal signal signal signal signal signal signal CLK : out vlbit; REG_DEST : out vlbit_1d(4 downto 0); NEW_ROB : out vlbit_1d(3 downto 0); ISSUE : out vlbit; ROB_TO_COMMIT: out vlbit_1d(3 downto 0); COMMIT : out vlbit; REG_SOURCE : out vlbit_1d(4 downto 0); ROB_OUT : in vlbit_1d(3 downto 0); VALID : in vlbit); end source2rob_tester; architecture behavior of source2rob_tester is -- Function definition of str2vec() function str2vec(str: string; hi: integer; lo: integer) return vlbit_1d is variable vtmp: vlbit_1d((hi-lo) downto 0); variable index: integer; begin for i in lo to hi loop--str'range loop index := i - lo; if(str(i) = '1') then vtmp(index) := '1'; elsif(str(i) = '0') then vtmp(index) := '0'; else vtmp(index) := 'X'; end if; end loop; return vtmp; end; function toString (str : string) return string is begin return str; end; begin main: process constant zero : vlbit_1d := "00000000000000000000000000000000"; variable file_line : line; variable outputline : line; file test_file : text is in "behv\source2rob_tester.txt"; variable str_in : string(32 downto 1); variable reg_dest_in : vlbit_1d(4 downto 0); variable new_rob_in : vlbit_1d(3 downto 0); variable issue_in : vlbit; variable rob_to_commit_in : vlbit_1d(3 downto 0); variable commit_in : vlbit; variable reg_source_in : vlbit_1d(4 downto 0); variable rob_out_in : vlbit_1d(3 downto 0); variable valid_in : vlbit; variable error_num : integer; begin error_num := 0; while not endfile(test_file) loop readline(test_file, file_line); read(file_line, str_in); reg_dest_in := str2vec(str_in, 32, 28); new_rob_in := str2vec(str_in, 26, 23); issue_in := int2vlb(v1d2int(str2vec(str_in, 21, 21))); rob_to_commit_in := str2vec(str_in, 19, 16); commit_in := int2vlb(v1d2int(str2vec(str_in, 14, 14))); reg_source_in := str2vec(str_in, 12, 8); rob_out_in := str2vec(str_in, 6, 3); valid_in := int2vlb(v1d2int(str2vec(str_in, 1, 1))); REG_DEST <= reg_dest_in after prop_delay; NEW_ROB <= new_rob_in after prop_delay; ISSUE <= issue_in after prop_delay; ROB_TO_COMMIT <= rob_to_commit_in after prop_delay; COMMIT <= commit_in after prop_delay; REG_SOURCE <= reg_source_in after prop_delay; CLK <= '0'; wait for delay; CLK <= '1'; wait for delay; if ROB_OUT /= rob_out_in or VALID /= valid_in then write(outputline, toString("ROB or VALID does not agree: ")); write(outputline, toString("ROB->")); write(outputline, v1d2int(ROB_OUT)); write(outputline, toString(" ?= ")); write(outputline, v1d2int(rob_out_in)); write(outputline, toString(", VALID->")); write(outputline, vlb2int(VALID)); write(outputline, toString(" ?= ")); write(outputline, vlb2int(valid_in)); error_num := error_num + 1; else write(outputline, toString("ROB and VALID agrees: ")); write(outputline, toString("ROB->")); write(outputline, v1d2int(ROB_OUT)); write(outputline, toString(" = ")); write(outputline, v1d2int(rob_out_in)); write(outputline, toString(", VALID->")); write(outputline, vlb2int(VALID)); write(outputline, toString(" = ")); write(outputline, vlb2int(valid_in)); end if; writeline(output, outputline); end loop; write(outputline, write(outputline, write(outputline, writeline(output, wait; end process main; toString("Test ended with ")); error_num); toString(" errors.")); outputline); end behavior; Appendix IV – Testing 4-bit mod adder clock clk 0 1 vector in in[3:0] vector out out[3:0] wave 4BMaddtest.wfm clk in out assign in 0\h cycle assign in 1\h cycle assign in 2\h cycle assign in 3\h cycle assign in 4\h cycle assign in 5\h cycle assign in 6\h cycle assign in 7\h cycle assign in 8\h cycle assign in 9\h cycle assign in A\h cycle assign in B\h cycle assign in C\h cycle assign in D\h cycle assign in E\h cycle assign in F\h cycle Branch Prediction testbench ------------------------------------------------------------------- VHDL Model of Branch Predictor Testbench -----------------------------------------------------------------library pack1076; use pack1076.pack1076.all; library ieee; use std.textio.all; entity bpred_testbench is port(signal PC : out vlbit_1d(31 downto 0); signal INSTR : out vlbit_1d(31 downto 0); signal UPDATE_ADDR: out vlbit_1d(31 downto 0); signal RESET : out vlbit; signal BRANCH_VALID : out vlbit; signal PRED_VALIDATE : out vlbit; signal CLK : in vlbit; signal NEW_BRANCH_ADDR : in vlbit_1d(31 downto 0); signal UNTAKEN_ADDR : in vlbit_1d(31 downto 0); signal BRANCH : in vlbit); end bpred_testbench; architecture behavior of bpred_testbench is function toString(dumb: string) return string is begin return dumb; end; function vlb2str(bit_in : vlbit) return string is variable stmp: string(1 downto 1); begin if(bit_in = '1') then stmp(1) := '1'; elsif(bit_in = '0') then stmp(1) := '0'; else stmp(1) := 'X'; end if; return stmp; end; function vec32tohex(vec: vlbit_1d) return string is variable str: string(10 downto 1); variable lo: integer; variable hi: integer; begin for i in 1 to 8 loop lo := (i-1)*4; hi := ((i-1)*4)+3; if(vec(hi downto lo) = "0000") then str(i) := '0'; elsif(vec(hi downto lo) = "0001") then str(i) := '1'; elsif(vec(hi downto lo) = "0010") then str(i) := '2'; elsif(vec(hi downto lo) = "0011") then str(i) := '3'; elsif(vec(hi downto lo) = "0100") then str(i) := '4'; elsif(vec(hi downto lo) = "0101") then str(i) := '5'; elsif(vec(hi downto lo) = "0110") then str(i) := '6'; elsif(vec(hi downto lo) = "0111") then str(i) := '7'; elsif(vec(hi downto lo) = "1000") then str(i) := '8'; elsif(vec(hi downto lo) = "1001") then str(i) := '9'; elsif(vec(hi downto lo) = "1010") then str(i) := 'A'; elsif(vec(hi downto lo) = "1011") then str(i) := 'B'; elsif(vec(hi downto lo) = "1100") then str(i) := 'C'; elsif(vec(hi downto lo) = "1101") then str(i) := 'D'; elsif(vec(hi downto lo) = "1110") then str(i) := 'E'; elsif(vec(hi downto lo) = "1111") then str(i) := 'F'; else str(i) := 'X'; end if; end loop; str(9) := 'x'; str(10) := '0'; return str; end; -- Function definition of vec2str() function vec2str(vec: vlbit_1d) return string is variable stmp: string(vec'left+1 downto 1); begin for i in vec'reverse_range loop if(vec(i) = '1') then stmp(i+1) := '1'; elsif(vec(i) = '0') then stmp(i+1) := '0'; else stmp(i+1) := 'X'; end if; end loop; return stmp; end; -- Function definition of str2vec() function str2vec(str: string; hi: integer; lo: integer) return vlbit_1d is variable vtmp: vlbit_1d((hi-lo) downto 0); begin for i in lo to hi loop--str'range loop if(str(i) = '1') then vtmp(i-lo) := '1'; elsif(str(i) = '0') then vtmp(i-lo) := '0'; else vtmp(i-lo) := 'X'; end if; end loop; return vtmp; end; -- Function definition of hexstr2vec() function hexstr2vec(str: string; hi: integer; lo: integer) return vlbit_1d is variable vtmp: vlbit_1d((hi-lo+1)*4-1 downto 0); variable index: integer; begin for i in lo to hi loop index := i - lo + 1; if(str(i) = '0') then vtmp(index*4 -1 downto (index-1)*4) := "0000"; elsif(str(i) = '1') then vtmp(index*4 -1 downto (index-1)*4) := "0001"; elsif(str(i) = '2') then vtmp(index*4 -1 downto (index-1)*4) := "0010"; elsif(str(i) = '3') then vtmp(index*4 -1 downto (index-1)*4) := "0011"; elsif(str(i) = '4') then vtmp(index*4 -1 downto (index-1)*4) := "0100"; elsif(str(i) = '5') then vtmp(index*4 -1 downto (index-1)*4) := "0101"; elsif(str(i) = '6') then vtmp(index*4 -1 downto (index-1)*4) := "0110"; elsif(str(i) = '7') then vtmp(index*4 -1 downto (index-1)*4) := "0111"; elsif(str(i) = '8') then vtmp(index*4 -1 downto (index-1)*4) := "1000"; elsif(str(i) = '9') then vtmp(index*4 -1 downto (index-1)*4) := "1001"; elsif(str(i) = 'A') then vtmp(index*4 -1 downto (index-1)*4) := "1010"; elsif(str(i) = 'B') then vtmp(index*4 -1 downto (index-1)*4) := "1011"; elsif(str(i) = 'C') then vtmp(index*4 -1 downto (index-1)*4) := "1100"; elsif(str(i) = 'D') then vtmp(index*4 -1 downto (index-1)*4) := "1101"; elsif(str(i) = 'E') then vtmp(index*4 -1 downto (index-1)*4) := "1110"; elsif(str(i) = 'F') then vtmp(index*4 -1 downto (index-1)*4) := "1111"; end if; end loop; return vtmp; end; begin -- This process applies stimulus to the design inputs, then it waits -- for some amount of time so we can observe the results during simulation stimulus:process file test_file: text is in "behv\bptest.txt"; variable output_line : line; variable file_line: line; variable str_in: string(58 downto 1); variable pc_i: vlbit_1d(31 downto 0); variable instr_i: vlbit_1d(31 downto 0); variable update_addr_i: vlbit_1d(31 downto 0); variable pred_validate_i: vlbit_1d(0 downto 0); variable branch_valid_i: vlbit_1d(0 downto 0); variable branch_e: vlbit_1d(0 downto 0); variable new_branch_addr_e: vlbit_1d(31 downto 0); variable untaken_addr_e: vlbit_1d(31 downto 0); variable name: string(8 downto 1); variable error_num: integer; begin error_num := 0; -- Hack to skip 2 comment lines --# Must be tab separated, except line number --#linenum, PC, INSTR, UPDATEAD, pval, bval, Exp Out RESET <= '1'; PRED_VALIDATE <= '0'; wait until pfalling(clk); wait for 20 ns; RESET <= '0'; while not endfile(test_file) loop wait until pfalling(clk); wait for 20 ns; readline(test_file, file_line); read(file_line, str_in); -- See bpred_test.txt for file layout name := str_in(58 downto 51); pc_i := hexstr2vec(str_in, 50, 43); instr_i := hexstr2vec(str_in, 41, 34); update_addr_i := hexstr2vec(str_in, 32, 25); pred_validate_i := str2vec(str_in, 23, 23); branch_valid_i := str2vec(str_in, 21, 21); branch_e := str2vec(str_in, 19, 19); new_branch_addr_e := hexstr2vec(str_in, 17, 10); untaken_addr_e := hexstr2vec(str_in, 8, 1); -- END bpred_test.txt parsing PC <= pc_i; INSTR <= instr_i; UPDATE_ADDR <= update_addr_i; PRED_VALIDATE <= pred_validate_i(0); BRANCH_VALID <= branch_valid_i(0); wait for 20 ns; write(output_line, toString("** Test: ")); write(output_line, name); writeline(output, output_line); write(output_line, toString("** Input PC: ")); write(output_line, vec32tohex(pc_i)); writeline(output, output_line); write(output_line, toString("** Input INSTR: ")); write(output_line, vec32tohex(instr_i)); writeline(output, output_line); write(output_line, toString("** Input UPDATE_ADDR: ")); write(output_line, vec32tohex(update_addr_i)); writeline(output, output_line); write(output_line, toString("** Input PRED_VALIDATE: ")); write(output_line, vec2str(pred_validate_i)); writeline(output, output_line); write(output_line, toString("** Input BRANCH_VALID: ")); write(output_line, vec2str(branch_valid_i)); writeline(output, output_line); write(output_line, toString("** Expected BRANCH: ")); write(output_line, vec2str(branch_e)); writeline(output, output_line); write(output_line, toString("** Actual BRANCH: write(output_line, vlb2str(BRANCH)); writeline(output, output_line); ")); write(output_line, toString("** Expected NEW_BRANCH_ADDR: ")); write(output_line, vec32tohex(new_branch_addr_e)); writeline(output, output_line); write(output_line, toString("** Actual NEW_BRANCH_ADDR: ")); write(output_line, vec32tohex(NEW_BRANCH_ADDR)); writeline(output, output_line); write(output_line, toString("** Expected UNTAKEN_ADDR: ")); write(output_line, vec32tohex(untaken_addr_e)); writeline(output, output_line); write(output_line, toString("** Actual UNTAKEN_ADDR: ")); write(output_line, vec32tohex(UNTAKEN_ADDR)); writeline(output, output_line); if (branch_e /= int2v1d(vlb2int(BRANCH))(0 downto 0)) or (new_branch_addr_e /= NEW_BRANCH_ADDR) or (untaken_addr_e /= UNTAKEN_ADDR) then assert false report "!!ERROR in testcase!!" & lf severity error; error_num := error_num + 1; end if; end loop; if (error_num = 0) then assert false report lf & "** All test passed" severity note; end if; wait; end process; end behavior; Branch Prediction testbench2 ------------------------------------------------------------------- VHDL Model of Branch Predictor Testbench -----------------------------------------------------------------library pack1076; use pack1076.pack1076.all; library ieee; use std.textio.all; entity bpred_testbench is end bpred_testbench; architecture behavior of bpred_testbench is component branch_pred port(PC, INSTR, UPDATE_ADDR: CLK, RESET, BRANCH_VALID, PRED_VALIDATE: TAKEN, BRANCH_INSTR: BRANCH: end component; in vlbit_1d(31 downto 0); in vlbit; out vlbit; out vlbit); signal PC, INSTR, UPDATE_ADDR: vlbit_1d(31 downto 0); signal TAKEN, BRANCH_INSTR: vlbit; signal BRANCH_VALID, PRED_VALIDATE, BRANCH, CLK, RESET: vlbit; function toString(dumb: string) return string is begin return dumb; end; function vlb2str(bit_in : vlbit) return string is variable stmp: string(1 downto 1); begin if(bit_in = '1') then stmp(1) := '1'; elsif(bit_in = '0') then stmp(1) := '0'; else stmp(1) := 'X'; end if; return stmp; end; function vec32tohex(vec: vlbit_1d) return string is variable str: string(10 downto 1); variable lo: integer; variable hi: integer; begin for i in 1 to 8 loop lo := (i-1)*4; hi := ((i-1)*4)+3; if(vec(hi downto lo) = "0000") then str(i) := '0'; elsif(vec(hi downto lo) = "0001") then str(i) := '1'; elsif(vec(hi downto lo) = "0010") then str(i) := '2'; elsif(vec(hi downto lo) = "0011") then str(i) := '3'; elsif(vec(hi downto lo) = "0100") then str(i) := '4'; elsif(vec(hi downto lo) = "0101") then str(i) := '5'; elsif(vec(hi downto lo) = "0110") then str(i) := '6'; elsif(vec(hi downto lo) = "0111") then str(i) := '7'; elsif(vec(hi downto lo) = "1000") then str(i) := '8'; elsif(vec(hi downto lo) = "1001") then str(i) := '9'; elsif(vec(hi downto lo) = "1010") then str(i) := 'A'; elsif(vec(hi downto lo) = "1011") then str(i) := 'B'; elsif(vec(hi downto lo) = "1100") then str(i) := 'C'; elsif(vec(hi downto lo) = "1101") then str(i) := 'D'; elsif(vec(hi downto lo) = "1110") then str(i) := 'E'; elsif(vec(hi downto lo) = "1111") then str(i) := 'F'; else str(i) := 'X'; end if; end loop; str(9) := 'x'; str(10) := '0'; return str; end; -- Function definition of vec2str() function vec2str(vec: vlbit_1d) return string is variable stmp: string(vec'left+1 downto 1); begin for i in vec'reverse_range loop if(vec(i) = '1') then stmp(i+1) := '1'; elsif(vec(i) = '0') then stmp(i+1) := '0'; else stmp(i+1) := 'X'; end if; end loop; return stmp; end; -- Function definition of str2vec() function str2vec(str: string; hi: integer; lo: integer) return vlbit_1d is variable vtmp: vlbit_1d((hi-lo) downto 0); begin for i in lo to hi loop--str'range loop if(str(i) = '1') then vtmp(i-lo) := '1'; elsif(str(i) = '0') then vtmp(i-lo) := '0'; else vtmp(i-lo) := 'X'; end if; end loop; return vtmp; end; -- Function definition of hexstr2vec() function hexstr2vec(str: string; hi: integer; lo: integer) return vlbit_1d is variable vtmp: vlbit_1d((hi-lo+1)*4-1 downto 0); variable index: integer; begin for i in lo to hi loop index := i - lo + 1; if(str(i) = '0') then vtmp(index*4 -1 downto (index-1)*4) := "0000"; elsif(str(i) = '1') then vtmp(index*4 -1 downto (index-1)*4) := "0001"; elsif(str(i) = '2') then vtmp(index*4 -1 downto (index-1)*4) := "0010"; elsif(str(i) = '3') then vtmp(index*4 -1 downto (index-1)*4) := "0011"; elsif(str(i) = '4') then vtmp(index*4 -1 downto (index-1)*4) := "0100"; elsif(str(i) = '5') then vtmp(index*4 -1 downto (index-1)*4) := "0101"; elsif(str(i) = '6') then vtmp(index*4 -1 downto (index-1)*4) := "0110"; elsif(str(i) = '7') then vtmp(index*4 -1 downto (index-1)*4) := "0111"; elsif(str(i) = '8') then vtmp(index*4 -1 downto (index-1)*4) := "1000"; elsif(str(i) = '9') then vtmp(index*4 -1 downto (index-1)*4) := "1001"; elsif(str(i) = 'A') then vtmp(index*4 -1 downto elsif(str(i) = 'B') then vtmp(index*4 -1 downto elsif(str(i) = 'C') then vtmp(index*4 -1 downto elsif(str(i) = 'D') then vtmp(index*4 -1 downto elsif(str(i) = 'E') then vtmp(index*4 -1 downto elsif(str(i) = 'F') then vtmp(index*4 -1 downto end if; end loop; return vtmp; (index-1)*4) := "1010"; (index-1)*4) := "1011"; (index-1)*4) := "1100"; (index-1)*4) := "1101"; (index-1)*4) := "1110"; (index-1)*4) := "1111"; end; begin -- Instantiate a Device Under Test (DUT) and map its I/O to the top -- level signals DUT: branch_pred port map (PC, INSTR, UPDATE_ADDR, CLK, RESET, BRANCH_VALID, PRED_VALIDATE, TAKEN, BRANCH_INSTR, BRANCH); -- This process applies stimulus to the design inputs, then it waits -- for some amount of time so we can observe the results during simulation stimulus:process file test_file: text is in "behv\bpredtest2.txt"; variable output_line : line; variable file_line: line; variable str_in: string(40 downto 1); variable pc_i: vlbit_1d(31 downto 0); variable instr_i: vlbit_1d(31 downto 0); variable update_addr_i: vlbit_1d(31 downto 0); variable pred_validate_i: vlbit_1d(0 downto 0); variable branch_valid_i: vlbit_1d(0 downto 0); variable branch_e: vlbit_1d(0 downto 0); variable name: string(8 downto 1); variable error_num: integer; begin error_num := 0; -- Hack to skip 2 comment lines --# Must be tab separated, except line number --#linenum, PC, INSTR, UPDATEAD, pval, bval, Exp Out RESET <= '1'; PRED_VALIDATE <= '0'; wait until pfalling(clk); wait for 5 ns; RESET <= '0'; while not endfile(test_file) loop wait until pfalling(clk); wait for 5 ns; readline(test_file, file_line); read(file_line, str_in); -- See bpred_test.txt for file layout name := str_in(40 downto 33); pc_i := hexstr2vec(str_in, 32, 25); instr_i := hexstr2vec(str_in, 23, 16); update_addr_i := hexstr2vec(str_in, 14, 7); pred_validate_i := str2vec(str_in, 5, 5); branch_valid_i := str2vec(str_in, 3, 3); branch_e := str2vec(str_in, 1, 1); -- END bpred_test.txt parsing PC <= pc_i; INSTR <= instr_i; UPDATE_ADDR <= update_addr_i; PRED_VALIDATE <= pred_validate_i(0); BRANCH_VALID <= branch_valid_i(0); wait for 5 ns; write(output_line, toString("** Test: ")); write(output_line, name); writeline(output, output_line); write(output_line, toString("** Input PC: ")); write(output_line, vec32tohex(pc_i)); writeline(output, output_line); write(output_line, toString("** Input INSTR: ")); write(output_line, vec32tohex(instr_i)); writeline(output, output_line); write(output_line, toString("** Input UPDATE_ADDR: ")); write(output_line, vec32tohex(update_addr_i)); writeline(output, output_line); write(output_line, toString("** Input PRED_VALIDATE: ")); write(output_line, vec2str(pred_validate_i)); writeline(output, output_line); write(output_line, toString("** Input BRANCH_VALID: ")); write(output_line, vec2str(branch_valid_i)); writeline(output, output_line); write(output_line, toString("** Expected BRANCH: ")); write(output_line, vec2str(branch_e)); writeline(output, output_line); write(output_line, toString("** Actual BRANCH: write(output_line, vlb2str(BRANCH)); writeline(output, output_line); ")); if (branch_e /= int2v1d(vlb2int(BRANCH))(0 downto 0)) then assert false report "!!ERROR in testcase!!" & lf severity error; error_num := error_num + 1; end if; end loop; if (error_num = 0) then assert false report lf & "** All test passed" severity note; end if; wait; end process; end behavior; Cache command file stepsize 24ns loadm foolio\odd\dram < test_files\seq.mem loadm foolio\even\dram < test_files\seq.mem vector vector vector vector vector vector vector vector vector data_in data_in[31:0] data_out data_out[31:0] address address[9:0] am address_to_mem[8:0] data_in_to_mem data_in_to_mem[63:0] do do[63:0] odd_address foolio\a_oo[4:0] even_address foolio\a_oe[4:0] data_even foolio\D_IOE[31:0] vector data_odd foolio\D_IOO[31:0] vector phoebus_is_a_fool foolio\data_out[63:0] vector vector vector vector vector vector vector vector vector vector vector vector vector vector vector vector vector vector vector vector vector vector vector vector vector tag0 koichi\tag_out0[8:0] tag1 koichi\tag_out1[8:0] tag2 koichi\tag_out2[8:0] tag3 koichi\tag_out3[8:0] tag4 koichi\tag_out4[8:0] tag5 koichi\tag_out5[8:0] tag6 koichi\tag_out6[8:0] tag7 koichi\tag_out7[8:0] victim koichi\victim[2:0] zero_zero koichi\block0_word0[31:0] zero_one koichi\block0_word1[31:0] one_zero koichi\block1_word0[31:0] one_one koichi\block1_word1[31:0] two_zero koichi\block2_word0[31:0] two_one koichi\block2_word1[31:0] three_zero koichi\block3_word0[31:0] three_one koichi\block3_word1[31:0] four_zero koichi\block4_word0[31:0] four_one koichi\block4_word1[31:0] five_zero koichi\block5_word0[31:0] five_one koichi\block5_word1[31:0] six_zero koichi\block6_word0[31:0] six_one koichi\block6_word1[31:0] seven_zero koichi\block7_word0[31:0] seven_one koichi\block7_word1[31:0] wave cachetest_v2.wfm clk reset address data_in am data_in_to_mem do data_out read write pipeline_stall request r_w wait even_address data_even odd_address data_odd foolio\RAS_L foolio\CAS_L foolio\OE_L foolio\WE_L tag0 tag1 tag2 tag3 tag4 tag5 tag6 tag7 victim zero_zero zero_one one_zero one_one two_zero two_one three_zero three_one four_zero four_one five_zero five_one six_zero six_one seven_zero seven_one phoebus_is_a_fool In Out test library pack1076; use pack1076.pack1076.all; use std.textio.all; entity inout_test is generic ( delay : time := 6 ns); port ( --Interface to Pipeline signal clk : in vlbit; signal r_w : in vlbit; --1 when processor is doing a write signal d_ioo : inout vlbit_1d(31 downto 0); signal d_ioe : inout vlbit_1d(31 downto 0); signal d64out : out vlbit_1d(63 downto 0)); end inout_test; architecture behavior of inout_test is function toString(dumb: string) return string is begin return dumb; end; function vec32tohex(vec: vlbit_1d; inlo:integer) return string is variable str: string(8 downto 1); variable lo: integer; variable hi: integer; begin for i in 1 to 8 loop lo := inlo+(i-1)*4; hi := inlo+((i-1)*4)+3; if(vec(hi downto lo) = "0000") then str(i) := '0'; elsif(vec(hi downto lo) = "0001") str(i) := '1'; elsif(vec(hi downto lo) = "0010") str(i) := '2'; elsif(vec(hi downto lo) = "0011") str(i) := '3'; elsif(vec(hi downto lo) = "0100") str(i) := '4'; elsif(vec(hi downto lo) = "0101") str(i) := '5'; elsif(vec(hi downto lo) = "0110") str(i) := '6'; elsif(vec(hi downto lo) = "0111") str(i) := '7'; elsif(vec(hi downto lo) = "1000") str(i) := '8'; elsif(vec(hi downto lo) = "1001") str(i) := '9'; elsif(vec(hi downto lo) = "1010") str(i) := 'A'; elsif(vec(hi downto lo) = "1011") str(i) := 'B'; elsif(vec(hi downto lo) = "1100") str(i) := 'C'; elsif(vec(hi downto lo) = "1101") str(i) := 'D'; elsif(vec(hi downto lo) = "1110") str(i) := 'E'; elsif(vec(hi downto lo) = "1111") str(i) := 'F'; elsif((vec(hi downto hi) = "X") or (vec(hi-1 downto hi-1) = or (vec(hi-2 downto hi-2) = or (vec(hi-3 downto hi-3) = str(i) := 'X'; else str(i) := 'Z'; end if; end loop; return str; end; begin then then then then then then then then then then then then then then then "X") "X") "X")) then -- behavior inout_test: process variable d64in : vlbit_1d(63 downto 0); begin wait until pfalling(clk); if r_w = '1' then wait for 5 ns; d_ioo <= "11111111111111111111111111111111"; d_ioe <= "01010101010101010101010101010101"; wait for 5 ns; else wait for 5 ns; d64in(63 downto 32) := d_ioo; d64in(31 downto 0) := d_ioe; d64out <= d64in after delay; wait for 5 ns; end if; d_ioo <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"; d_ioe <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"; wait for 5 ns; end process; end behavior; JR Unit command file stepsize 50ns clock clk 0 1 vector vector vector vector ROB_IN ROB_IN[3:0] CDB CDB[35:0] JR_PC JR_PC[31:0] REG_OUT REG_OUT[31:0] wave jr_unit_test.vwf CLK ISSUE_JR VALUE_READY REG_OUT ROB_IN SQUISH JR_CAN_WRITE ~CDB_WRITE_VALUE CDB ENABLE_JR_PC JR_PC l ISSUE_JR VALUE_READY ROB_IN SQUISH JR_CAN_WRITE CDB REG_OUT h ~CDB_WRITE_VALUE c 10 | first check the case where it's going to do a JR and the value is ready immediately (i.e., the value is in the register or the ROB) sim 10ns h ISSUE_JR h VALUE_READY assign REG_OUT a55face\h |case if JR_CAN_WRITE is high h JR_CAN_WRITE c assign REG_OUT f00\h |case if JR_CAN_WRITE is low l JR_CAN_WRITE c l ISSUE_JR c 3 h JR_CAN_WRITE c l JR_CAN_WRITE | now check if the value is not ready, and it comes from the CDB. h ISSUE_JR l VALUE_READY assign ROB_IN c\h c l ISSUE_JR c c assign CDB cffffffff\h l ~CDB_WRITE_VALUE | case if JR_CAN_WRITE is high h JR_CAN_WRITE c h ~CDB_WRITE_VALUE l JR_CAN_WRITE c 4 h ISSUE_JR assign ROB_IN b\h c l ISSUE_JR c 3 l ~CDB_WRITE_VALUE | wrong value c assign CDB bffff0000\h | case if JR_CAN_WRITE is low l JR_CAN_WRITE c h ~CDB_WRITE_VALUE c 3 h JR_CAN_WRITE c l JR_CAN_WRITE c 4 | Squish version h ISSUE_JR h VALUE_READY h SQUISH assign REG_OUT a55face\h |case if JR_CAN_WRITE is high h JR_CAN_WRITE c l SQUISH assign REG_OUT f00\h |case if JR_CAN_WRITE is low l JR_CAN_WRITE c l ISSUE_JR c h SQUISH c 3 | now check if the value is not ready, and it comes from the CDB. h ISSUE_JR l VALUE_READY assign ROB_IN c\h c l ISSUE_JR c h SQUISH c l SQUISH assign CDB cffffffff\h l ~CDB_WRITE_VALUE c h ~CDB_WRITE_VALUE c 4 h ISSUE_JR assign ROB_IN b\h c l ISSUE_JR c 3 l ~CDB_WRITE_VALUE | wrong value c assign CDB bffff0000\h | case if JR_CAN_WRITE is low h SQUISH c h ~CDB_WRITE_VALUE c 3 c c 4 Op Queue command file stepsize 50ns clock clk 0 1 vector vector vector vector vector vector vector vector vector din din[31:0] dout dout[31:0] pcin pcin[31:0] mri mri[31:0] br_in br_in[31:0] pcout pcout[31:0] br_out br_out[31:0] head op\head[4:0] tail op\tail[4:0] wave opQtest.wfm clk din pcin br_in predict_in squash insert send dout pcout br_out predict_out full empty head tail mri l din pcin br_in predict_in l send squash insert c 5 h din0 pcin0 br_in0 predict_in |sim 25ns h insert c l insert c 5 l h c l c din0 pcin0 br_in0 din1 insert pcin1 br_in1 insert 5 h send c l send c 5 h din0 insert pcin0 br_in0 c l insert c 5 l h c l c din0 din1 pcin0 pcin1 br_in0 br_in1 din2 insert pcin2 br_in2 insert 5 h din0 insert pcin0 br_in0 c l insert c 5 l h c l c din0 pcin0 br_in0 din1 insert pcin1 br_in1 insert 5 h din0 insert pcin0 br_in0 c l insert c 5 l h c l c din0 din1 din2 pcin0 pcin1 pcin2 br_in0 br_in1 br_in2 din3 insert pcin3 br_in3 insert 5 h din0 insert pcin0 br_in0 c l insert c 5 l h c l c din0 pcin0 br_in0 din1 insert pcin1 br_in1 insert 5 h din0 insert pcin0 br_in0 c l insert c 5 l h c l c din0 din1 pcin0 pcin1 br_in0 br_in1 din2 insert pcin2 br_in2 insert 5 h din0 insert pcin0 br_in0 c l insert c 5 l h c l c din0 pcin0 br_in0 din1 insert pcin1 br_in1 insert 5 h din0 insert pcin0 br_in0 c l insert c 5 l h c l c din0 din1 din2 din3 pcin0 pcin1 pcin2 pcin3 br_in0 br_in1 br_in2 br_in3 din4 insert pcin4 br_in4 insert 5 h send c l send c 5 h din0 insert pcin0 br_in0 c l insert c 5 h send c l send c 5 Reservation Station Squish command file stepsize 30ns |clock clk 1 0 clock clk 0 1 vector nr nr[15:0] vector fuinsel fuinsel[3:0] vector listen listen[3:0] vector issue issue[84:0] vector aluina aluina[31:0] vector aluinb aluinb[31:0] vector aluout aluout[31:0] vector cdb cdb[37:0] vector dout dout[31:0] vector doutb doutb[31:0] vector fakecdb fakecdb[37:0] vector res res[3:0] vector reset reset[15:0] vector func func[8:0] vector cdb_upper[3:0] vector branch_rob_plus_two branch_rob_plus_two[3:0] vector front front[3:0] wave RStester.wfm clk is clk reset res full nr fuinsel listen issue aluina aluinb aluout cdb dout doutb fakecdb launch grant func branch_rob_plus_two front squish sq broadcast cdbreq l is sim 30ns |(half a cycle) l grant l squish c 2 r aluina aluinb aluout reset grant |First, try a few instructions that have all their arguments h is assign issue "1603111111112222222200\h" c |add 0x11111111 0x22222222 = 0x33333333 assign issue "0744ffffffff0000000100\h" c |slt 0xFFFFFFFF 0x00000001 = 0x00000001 |Now, try some instructions that require reservations to listen to the cdb, before executing assign issue "041577777777xxxxxxxxxa\h" |Qk needs to wait for ROB 10 |and 0x77777777 0xcccccccc = 0x44444444 c l is assign cdb "0bdddddddd\h" |wrong ROB - RS should ignore this c assign cdb "0acccccccc\h" |right ROB - RS should take this c |Now issue an instruction WHILE another RS is waiting for its value h is assign issue "0236xxxxxxxx01234567fx\h" |xor 0x11111111 0x01234567 = 0x10325476 |Qj needs to wait for ROB 15 c assign issue "162766666666aaaaaaaaxx\h" |or 0x66666666 0xaaaaaaaa = 0xeeeeeeee c l is c 2 h is assign issue "xe08ffffffff00000003xx\h" assign cdb "0bcccccccc\h" |add 0xffffffff 0x00000003 = 0x00000002 c l is assign branch_rob_plus_two "4\h" assign front "9\h" |h squish |add 0xffffffff 0x00000003 = 0x00000002 c l squish h is assign issue "x6c9ffffffff00000001xx\h" |sltu 0xFFFFFFFF 0x00000001 = 0x00000000 assign cdb "0bcccccccc\h" |wrong ROB - RS should ignore this c assign cdb "0f11111111\h" |right ROB - RS should take this l is c 16 Reservation Station command file stepsize 30ns |clock clk 1 0 clock clk 0 1 vector nr nr[15:0] vector fuinsel fuinsel[3:0] vector listen listen[3:0] vector issue issue[84:0] vector aluina aluina[31:0] vector aluinb aluinb[31:0] vector aluout aluout[31:0] vector cdb cdb[37:0] vector dout dout[31:0] vector doutb doutb[31:0] vector fakecdb fakecdb[37:0] vector res res[3:0] vector reset reset[15:0] vector func func[8:0] vector cdb_upper[3:0] wave RStester.wfm clk is clk reset res full nr fuinsel listen issue aluina aluinb aluout cdb dout doutb fakecdb launch grant func l is h grant sim 30ns |(half a cycle) c r grant c r aluina aluinb aluout reset |First, try a few instructions that have all their arguments h is assign issue "1603111111112222222200\h" c |add 0x11111111 0x22222222 = 0x33333333 assign issue "0744ffffffff0000000100\h" c |slt 0xFFFFFFFF 0x00000001 = 0x00000001 |Now, try some instructions that require reservations to listen to the cdb, before executing assign issue "041577777777xxxxxxxxxa\h" |Qk needs to wait for ROB 10 |and 0x77777777 0xcccccccc = 0x44444444 c l is assign cdb "0bdddddddd\h" |wrong ROB - RS should ignore this c assign cdb "0acccccccc\h" |right ROB - RS should take this c |Now issue an instruction WHILE another RS is waiting for its value h is assign issue "0236xxxxxxxx01234567fx\h" |xor 0x11111111 0x01234567 = 0x10325476 |Qj needs to wait for ROB 15 c assign issue "162766666666aaaaaaaaxx\h" |or 0x66666666 0xaaaaaaaa = 0xeeeeeeee c l is c 2 h is assign issue "xe09ffffffff00000003xx\h" assign cdb "0bcccccccc\h" |add 0xffffffff 0x00000003 = 0x00000002 c assign issue "x6c8ffffffff00000001xx\h" |sltu 0xFFFFFFFF 0x00000001 = 0x00000000 assign cdb "0bcccccccc\h" |wrong ROB - RS should ignore this c assign cdb "0f11111111\h" |right ROB - RS should take this l is c 16 Source to ROB tester ------------------------------------------------- source2rob test bench version 3.1415926535897 -----------------------------------------------library pack1076; use pack1076.pack1076.all; library ieee; use std.textio.all; entity source2rob_tester is generic ( delay : time := 25 ns; prop_delay : time := 1 ns); port(signal signal signal signal signal signal signal signal signal CLK : out vlbit; REG_DEST : out vlbit_1d(4 downto 0); NEW_ROB : out vlbit_1d(3 downto 0); ISSUE : out vlbit; ROB_TO_COMMIT: out vlbit_1d(3 downto 0); COMMIT : out vlbit; REG_SOURCE : out vlbit_1d(4 downto 0); ROB_OUT : in vlbit_1d(3 downto 0); VALID : in vlbit); end source2rob_tester; architecture behavior of source2rob_tester is -- Function definition of str2vec() function str2vec(str: string; hi: integer; lo: integer) return vlbit_1d is variable vtmp: vlbit_1d((hi-lo) downto 0); variable index: integer; begin for i in lo to hi loop--str'range loop index := i - lo; if(str(i) = '1') then vtmp(index) := '1'; elsif(str(i) = '0') then vtmp(index) := '0'; else vtmp(index) := 'X'; end if; end loop; return vtmp; end; function toString (str : string) return string is begin return str; end; begin main: process constant zero : vlbit_1d := "00000000000000000000000000000000"; variable file_line : line; variable outputline : line; file test_file : text is in "behv\source2rob_tester.txt"; variable str_in : string(32 downto 1); variable reg_dest_in : vlbit_1d(4 downto 0); variable new_rob_in : vlbit_1d(3 downto 0); variable issue_in : vlbit; variable rob_to_commit_in : vlbit_1d(3 downto 0); variable commit_in : vlbit; variable reg_source_in : vlbit_1d(4 downto 0); variable rob_out_in : vlbit_1d(3 downto 0); variable valid_in : vlbit; variable error_num : integer; begin error_num := 0; while not endfile(test_file) loop readline(test_file, file_line); read(file_line, str_in); reg_dest_in := str2vec(str_in, 32, 28); new_rob_in := str2vec(str_in, 26, 23); issue_in := int2vlb(v1d2int(str2vec(str_in, 21, 21))); rob_to_commit_in := str2vec(str_in, 19, 16); commit_in := int2vlb(v1d2int(str2vec(str_in, 14, 14))); reg_source_in := str2vec(str_in, 12, 8); rob_out_in := str2vec(str_in, 6, 3); valid_in := int2vlb(v1d2int(str2vec(str_in, 1, 1))); REG_DEST <= reg_dest_in after prop_delay; NEW_ROB <= new_rob_in after prop_delay; ISSUE <= issue_in after prop_delay; ROB_TO_COMMIT <= rob_to_commit_in after prop_delay; COMMIT <= commit_in after prop_delay; REG_SOURCE <= reg_source_in after prop_delay; CLK <= '0'; wait for delay; CLK <= '1'; wait for delay; if ROB_OUT /= rob_out_in or VALID /= valid_in then write(outputline, toString("ROB or VALID does not agree: ")); write(outputline, toString("ROB->")); write(outputline, v1d2int(ROB_OUT)); write(outputline, toString(" ?= ")); write(outputline, v1d2int(rob_out_in)); write(outputline, toString(", VALID->")); write(outputline, vlb2int(VALID)); write(outputline, toString(" ?= ")); write(outputline, vlb2int(valid_in)); error_num := error_num + 1; else write(outputline, toString("ROB and VALID agrees: ")); write(outputline, toString("ROB->")); write(outputline, v1d2int(ROB_OUT)); write(outputline, toString(" = ")); write(outputline, v1d2int(rob_out_in)); write(outputline, toString(", VALID->")); write(outputline, vlb2int(VALID)); write(outputline, toString(" = ")); write(outputline, vlb2int(valid_in)); end if; writeline(output, outputline); end loop; write(outputline, write(outputline, write(outputline, writeline(output, wait; end process main; end behavior; toString("Test ended with ")); error_num); toString(" errors.")); outputline);