Lab 1b: Fetch Unit - Datapath
CSE 141L, Spring 2007, Donghwan Jeon
Due 4/18(W) before the beginning of the class
This is an individual lab.
Overview
In Lab 1b, you will implement the datapath part of a decoupled fetch unit on "front end" we covered in the class. You will complete the implementation of the fetch unit in Lab 1c by adding controls, and use it as part of your future labs.
Deliverables
- No lab interview is required for lab 1b.
- Submit your source files(*.v, zipped) via e-mail to TA by 10:00am, Wednesday 4/18. Your email title should be "[CSE141L] lab 1b, SID, yourname" . No late submission will be accepted.
- Also submit your hardcopy report to TA at the beginning of the class on 4/18. Like Lab 1a, your report consists of answers to the questions(Q1 ~ Q5).
Getting Started
Starter Files
- Download lab1b.zip file, and unzip it.
- Make a project with all the *.v files. As you did in Lab 1a, we will use 'Virtex4 - XC4VLX15' as a target device.
- ram17_1024.v and fifo27_16.v files are behavioral verilog files for RAM and FIFO. You will use them for only simulations. They are not synthesizable.
- ram17_1024.ngc and fifo27_16.ngc files are implmentation files for RAM and FIFO. It is enough to put them in your project directory. Xilinx ISE will automatically use them for synthesis and implementation.
- ram17_1024.mif specifies the contents of the RAM. For address 0x00 - 0x3f, RAM is filled with its address for the debugging purposes. For other locations, they are all 0s.
- You are required to implement other *.v files in this lab.
- Throughout the lab, you will need to refer datapath.pdf file.
Fetch Unit Interface
module fetch#(parameter I_WIDTH = 17, A_WIDTH = 10, O_WIDTH = 5)
(
input clk,
// inputs from the exec unit
input deque,
input restart,
input [A_WIDTH-1 : 0] restart_addr,
// memory interface
input load_store_valid,
input store_en,
input [A_WIDTH-1 : 0] load_store_addr,
input [I_WIDTH-1 : 0] store_data,
output [I_WIDTH-1 : 0] load_data,
output load_data_valid,
// ouputs to the exec unit
output [I_WIDTH-1 : 0] instruction_data,
output [A_WIDTH-1 : 0] instruction_addr,
output instruction_valid
);
Fetch Unit Specification
- The width of an instruction is 17 bits. The MSB(most significant bit) is 'P(prediction)' bit; if P bit is 0, the instruction is not a branch or a branch predicted not taken; otherwise, it is a branch predicted taken or an unconditional branch. 5 LSBs are used as offset bits for branch instructions. The branch target address can be calculated as "pc + sign extended offset". Note that the offset is 2's complement and can be negative. The other bits are not used in this lab.
- The SRAM has 1024 * 17bits = 17408 bits, and uses 10bits for addressing. So you can access SRAM from address 0 to 1,023. You will be using provided ram_17_1024.v(for simulation), and ram_17_1024.ngc(for implementation) files. It is a highly optimized module generated from the coregen utility provided by Xilinx, and each memory location is pre-initialized to contain its own address. For example, the data stored in the address 0x1 is 17'b1.
- The FIFO has 16 * 27 bit entries. Each FIFO entry consists of an address part(10 bits) and an instruction part(17 bits). It is also generated from the coregen utility.
- 'restart' and 'restart_addr' inputs are used to change the current 'pc' of the fetch unit. If they are asserted, the fetch unit should clear the fifo, and change the current 'pc' as specified by 'restart_addr'. Note that the reset of the fetch unit is also implemented by this mechanism. To reset the fetch unit, the backend of the processor would assert the 'restart' signal with 'restart_addr' as '0x0'. Then the fetch unit should start fetching instructions from 0x0.
- To manage the contents of the SRAM, the fetch unit supports 'load' and 'store' operations. Upon a load, the fetch unit returns a 17 bit instruction(as data) via 'load_data' port. With a store, the fetch unit write 'store_data' to the location specified by 'store_addr'. The following signals trigger load and store instructions.
- load: load_store_valid = 1, store_en = 0
- store: load_store_valid = 1, store_en = 1
- 'memory' operations(load or store) always have higher priority than the usual 'fetch' operations(including restart and fetching instructions, and then inserting into the FIFO). Memory operations have higher priority because the backend implementation may be dependent on timely execution of these operations.
Datapath Implementation
You need to thoroughly understand the specification of the fetch unit and the provided datapath schematic to answer the following questions. To do so, you think about all of the scenarios that could happen in the fetch unit datapath, and a reasonable way to handle it. Your answers will be judged according to the degree with which they are both complete and concise. In these exerices except Q5, assume the fifo never fills up.
Q1. (10p) Suppose that the address of the last fetched instruction (pc_prev_r) is 0x12. If the P bit of the last fetched instruction is 0, what is the address of the next fetched instruction? Assume that restart signal is not asserted. This functionality uses an adder, as shown in the datapath schematic. To implement it, complete the adder.v file according to the given interface using RTL verilog. Also complete mux.v file to implement connected muxes.
Q2. (10p) What is the binary encoding of an instruction which branches to the instruction located right before the current instruction? If the address of the current instruction is 0x13, it should branch to 0x12. Use 'x' for don't care bits. Explain briefly how this case would be handled in the given datapath. Complete signext.v according to the given interface to implement this part of the datapath. (Hint: You can duplicate a bit N times by {N{1'bx}} in verilog. For example, 5'b11111 can be briefly expressed by {5{1'b1}}. )
Q3. (10p) Envision the following scenario. Unfortunately, the exec unit found that the branch prediction in the fetch unit was wrong. How can it generate the 'right' address for the fetch unit? If the exec unit sent 'restart' and 'restart_addr' at cycle 10, when can the exec unit get the 'right' instruction in the best case? Explain.
Q4. (10p) Look at the datapath. You can see 'pc_prev_r' can be used for the 'pc' and can be fed to the SRAM. Considering that 'pc_prev_r' saves the "previous pc", it looks strange to use the same address for 2 cycles in a row. Why is this path needed? Explain.
Q5. (10p) Envision the following scenario.
- In cycle 0: an instruction 0x10003 with address 0x10 is fed to the FIFO. (assume that sel_mux[2] is 1 at cycle 0.)
- In cycle 1: no external input is asserted. However, the insertion of a new instruction causes fifo_full to 1.
- In cycle 2: load_store_valid is asserted with {store_en=0, load_store_addr = 0x40}. 'restart' signal is not asserted.
- In cycle 3: no external input is asserted.
- In cycle 4: the following signals are asserted - {restart = 1, restart_addr = 0x0, load_store_valid = 1, store_en = 0, load_addr = 0x50}.
- In cycle 5: no external input is asserted.
- In cycle 6: 'deque' signal is asserted.
- In cycle 7: no external input is asserted. Due to the 'deque' signal in cycle 6, 'fifo_full' changes to 0, and the fetch unit can insert a new instruction to the FIFO. Finally, assume that the 'p' bit of the instruction at 0x0 is 0.
List all the address values fed to the address port of the SRAM from cycle 0 to cycle 7 with explaination.
Q6. (50p) Complete the datapath in fetch.v using the following guidelines.
- Use structural verilog, not a behavioral verilog or RTL verilog. To see the differences between them, see Krste's slides.
You should instantiate mux, adder, and signext modules in the fetch.v file. RAM and FIFO are already instantiated for the reference.
- You may use non-blocking assignments("a <= b") for flip flops.
- If possible, always use signal names in the provided datapath schematic. Otherwise, use consistent and readable naming style. The naming convention, proper indentation, and style will be graded (10p). Make sure your verilog file is readable in the Xilinx ISE editor.
- Your verilog files should be synthesizable and implementable in Xilinx ISE.
- Given that you have not implemented control signals yet, why does it make sense that there is no frequency check question for this lab? (5p)
- Include the complete verilog source files in your report.
Usefule Resources