Problem 1, 2 and 3 must be done with your project partner. Names must be included in the partner.txt file included in the supplied tar file.
- Problems 1, 2 and 3
- Electronic submission of files: Submit to learn@UW, One submission per pair, titled hw3.tar
- Problems 4 - 10:
- These problems are optional and will not be graded but are recommended for a better understanding of the course material.
- Problem 1 is design of simple datapath component
- Problem 2 is a simple problem that stresses state machines
- Problem 3 is a more sophisticated problem focusing on state machines
- Homework is due at start of class on 03/03
- A tarball is provided that includes testbenches and top level module definitions for all verilog problems: hw3.tar
- Do not edit the provided *_hier.v files
- You must maintain the directory structure that exists in the provided tar file, i.e. each problem has its own subdirectory titled hw3_[1,2,3]
- All verilog files required to run your verilog must be in each problem's respective subdirectory. You may also need to have copies of some files in each directory.
- Once you are done with a problem, run the command
vcheck-all.sh in the problem directory to make sure that you adhere to the Verilog Rules. See Verilog rules check for more details.
- A legible schematic.pdf file must be in each problem's respective subdirectory with the schematics you drew.
- Any solution without a corresponding schematic drawing will NOT be graded
- A scanner is available for general use in Wendt Library
- The partner.txt file at the top level of the tarball must contain the names of yourself and your partner.
- Submit only this tar file named hw3.tar - only one partner needs to submit the file
- For each problem follow the steps below in sequence:
- Break down your design into sub-modules.
- Define interfaces between these modules
- Draw paper and pencil schematics for these modules (these will he handed in as scanned schematic.pdf file)
- Then start writing verilog
- Use the
wsrun.pl script to simulate your Verilog code. See wsrun.pl detailed usage instructions for more details.
Using Verilog, design an 8 -by -16- bit register file. See the verilog interface below. It has one write port, two read ports, three register select inputs (two for read and one for write,) a write enable, a reset and a clock input. All register state changes occur on the rising edge of the clock. As always, your basic building block must be the D-flipflop given in the Homework modules provided page. The read ports should be all combinational logic. Do not use tri-state logic in your design.
Design this register file such that changing the width to 32-bit or 64-bit is straightforward
The read and write data ports are 16 bits each. The select inputs (read and write) are 3 bits each. When the write enable is asserted (high) the selected register will be written with the data from the write port. The write occurs on the next rising clock edge; write data cannot flow through to a read port during the same cycle.
There is no read enable; data from the selected registers will always appear on to the corresponding read ports.
The reset signal is synchronous and when asserted (active high), resets all the register values to 0.
You must use a hierarchical design. Design a 16-bit register first, and then put 8 of them together with additional logic to build the register file.
Do not make any changes to the provided
You must verify your design using the testbench in the supplied tar file. Run the testbench in your hw3_1 directory using the command
wsrun.pl rf_bench *.v
The testbench for this problem (rf_bench.v) generates a random set of input signals to your module in each cycle, and compares outputs from your module with outputs that are expected from a perfect register file implementation.
If there are no errors in your design you will see a "TEST PASSED" message. If the testbench failed with a "TEST FAILED" message, look for error messages like "ERRORCHECK: Incorrect read data in cycle <cycle_number>" in the testbench output. Above each of these error messages you will see the inputs to your module, your outputs and the expected outputs for that cycle which can help you debug.
Using Verilog, write, compile and simulate a six state saturating counter. The counter should take as input a clock and a reset line (
ctr_rst), and output a 3-bit wide bus (and an err output). Reset is synchronous and sets the output to 0 at the rising edge of the clock.
ctr_rst is not the same as the global reset signal generated at the start of simulation. The output should increment every clock cycle until it reaches its saturation value (5, i.e. 101 in binary) and then continue to output the maximum value until reset. ctr_rst is different from the global rst signal which is set high at start for 2 cycles and then remains low. Use this global rst signal to initialize the state of the counter to zero. The "err" output is a standard way of indicating hardware errors or illegal states. Assert it (1'b1) for states which are supposed to be impossible to get into.
ctr_rst line is active high, i.e. a logical value of 1 will reset the counter, while a logical value of 0 will let the counter increment.
ctr_rst is high while the counter is still counting, the output should reset to 0. If it is held high, the counter should hold at 0. All state changes should occur on the clock's rising edge.
Do not make any changes to the provided
You must verify your design using the testbench in the supplied tar file. Run the testbench in your hw3_2 directory using the command
wsrun.pl sc_bench *.v
The testbench for this problem (sc_bench.v) randomly asserts
ctr_rst, and compares outputs from your module with outputs that are expected from a perfect saturating counter implementation.
If there are no errors in your design you will see a "TEST PASSED" message. If the testbench failed with a "TEST FAILED" message, look for error messages like "ERRORCHECK: ctr_rst = xx : out = xx : expected_out = xx" in the testbench output. These lines show the input to your module (
ctr_rst), your output and the expected output which can help you debug.
In this problem, you must design a FIFO that can hold 64-bit data values.
Design, simulate, and verify in Verilog, a 4-entry FIFO that can hold 64-bit data. The FIFO should implement the functionality of a conventional first-in-first-out data structure. You may assume the D-flip flop module provided. The FIFO accepts new input each cycle when the data_in_valid is asserted, unless it is full (indicated by fifo_full). Data that is inserted into a full FIFO is ignored. The data_out signal is always driven by the data at the head of the FIFO (the oldest data). The head of the FIFO is popped when pop_fifo is asserted. An empty FIFO drives zeros on data_out and asserts fifo_empty. Popping an empty FIFO has no effect. Asserting reset makes the FIFO empty. All outputs should change only in response to the clock edge.
The "err" output is a standard way of indicating hardware errors or illegal states. Assert it (1'b1) for states which are supposed to be impossible to get into.
- If the fifo is full, fifo_full should be held high (irrespective of whether data_in_valid is asserted or not)
- If the fifo is empty, fifo_empty should be held high (irrespective of whether pop_fifo is asserted or not)
- Handling the case when both data_in_valid and pop_fifo are asserted
- CASE I: The fifo is neither empty nor full
- Expected behavior: Both the requests should be serviced. ie, the appropriate elements should be inserted/popped to/from the fifo.
- CASE II: The fifo is empty.
- Accept the incoming element and write it into the fifo. Do not pop the element in the same cycle (continue to assert fifo_empty in that cycle). You should not bypass the element to fifo output directly.
- CASE III: The fifo is full.
- Ignore the data being inserted, pop the correct element from the FIFO and drive data_out. Again, do not insert anything into the FIFO in the same cycle.
Do not make any changes to the provided
You must verify your design using the testbench in the supplied tar file. Run the testbench in your hw3_3 directory using the command
wsrun.pl fifo_bench *.v
The testbench for this problem (fifo_bench.v) consists of 145 randomly generated test cases. Each test case asserts a set of input signals to your module, and after one cycle, compares outputs from your module with the outputs that are expected from a perfect FIFO implementation.
If there are no errors in your design you will see a "TEST PASSED" message. If the testbench failed with a "TEST FAILED" message, there are 3 possible reasons:
- Error in
fifo_empty signal: You will see an error message similar to "MINORCHECK : In cycle xx - EMPTY logic : empty = xx, expected empty = xx" in the testbench output.
- Error in
fifo_full signal: You will see an error message similar to "MINORCHECK : In cycle xx - FULL logic : full = xx, expected full = xx" in the testbench output.
- Error in
data_out signal: You will see an error message similar to "ERRORCHECK : In cycle xx - Data out error. data_out = xx, expcted data_out = xx" in the testbench output.
Above each of these error messages you will see the inputs to your module, your outputs and the expected outputs for that cycle which can help you debug. If you have only "MINORCHECK" errors in your submission, you will get a maximum of 85% for this problem.
The remaining problems will not be graded but are recommended for better understanding of the course material.
Do problem 4.7
Do problems 4.8
Do problem 4.9
Do problems 4.1.1 to 4.1.3 in page 357 of textbook.
For 4.1.1, In addition to the control signals RegWrite, ALU operation, MemWrite, MemRead and Branch, you should also report the control signals of the following two control signals:
- ALUMux: the control signal that controls the Mux at the ALU input, 0 (Reg) selects the output of the register file and 1 (Imm) selects the immediate from the instruction word as the second input to the ALU.
- RegMux: the control signal that controls the Mux at the data input to the register file, 0 (ALU) selects the output of the ALU, and 1 (Mem) selects the output of memory.
Consider a single-cycle computer design such as the one in Figure 4.15 of text (page 263). Assume a MIPS-like instruction set. Suppose you had just completed such a design, and now the compiler group has come to you with a small list of additional instructions they would like you to add. How would you respond? Order the list from easiest to most difficult to add, based on the number of things that would have to change in the datapath; briefly indicate for each one what those changes would be.
- "Split Register": This instruction would read an operand from $rs and move its lower half to $rd with the upper half set to zero. It would also take the upper half of $rs, shift it right 16 bits (with zero fill), and write it to $rt.
- "Bit Equal": This instruction does a bit-for-bit compare between two registers. For each bit i, if bit i of $rs is equal to bit i of $rt, set bit i of $rd; otherwise set bit i of $rd to zero.
- "Replace Under Mask": This I-Format instruction uses the 16-bit sign-extended immediate to select which bits of $rt should be replaced with the corresponding bits of $rs. For each bit of the sign-extended immediate that is a one, the result comes from the corresponding bit of $rs; for each bit that is a zero, the result comes from $rt. The result is written to $rt.
For this problem, you do not need to use mentor or Verilog; just draw the designs (neatly!) on paper.
First, design a 4-bit ripple-carry adder; as a building block use squares representing full adders. (You may use a printout from Homework 1.)
Next, draw an 8-bit carry-select adder, using as building blocks (three) 4-bit ripple-carry adders and 2:1 muxes.
Now, calculate the delay at output S5 of the carry-select adder. To do this, you will need to know the gate design of the full adder and the 2:1 mux (see below). You will also need to know the delay function:
AND, OR, NAND, NOR, NOT: delay = (8 + n2) τ
XOR: delay = (12 + n2) τ
where n is the number of inputs to the gate.
Assume that all inputs to your design are available at time zero. Calculate (and mark on your paper) the pertinent critical-path delays through the basic building blocks, through your ripple adder, and finally to S5 of the entire design.
This problem does not require verilog implementation. You should work to create a neatly drawn schematic.
Consider the division algorithm in Figure 3.10 (page 238) of the text and the accompanying high level diagram in Figure 3.9 (page 237). For this problem create a working and detail schematic with hierarchical design implementing this bit-wise divider. Simply reproducing Figure 3.9 will earn you negative points
If you feel there is ambiguity in the problem specification, make reasonable
assumptions and start your answer stating all your assumptions.
- Break your design into different blocks (Like in figure 3.9)
- The schematic should include
- The names and bit widths of external ports of the design
- Think about how the values of dividend and divisors are going to be initialized.
- Do you need any control signals for the inputs?
- Do you need any output ports?
- How would another module interact with the divider module? Do you need a control signal to notify that the divide operation is completed?
- The name for each block
- The names and bit widths of interfaces between blocks.
- You will be graded based on:
- the correctness of the design
- the completeness of the design
- If a team of 4-5 engineers were to implement (each person in charge of one block) the design in verilog, your design document would function as a reference for this team. They should be able to complete the implementation without talking to you or talking to each other. This requires that the interfaces are marked clearly, with meaningful names and bit widths.