2. Verilog

a)

  • a “two-bit” flip-flop does not exist. It’s just two flip-flops.
  • do not forget to state “active-low as the code resets if the reset signal is low”

b)

Sequential circuit “as all the left-hand side signals are not assigned in every possible condition”. For ex, data_out[0] not assigned foor mask = 0.

c)

State “NOT syntactically correct”

  • if something has multtiple assigns, it has multiple drivers, which is wrong.

3. FSMs

b), c)

DO NOT forget to give an equation for O[0] = ... the output!!!!

→ make sure to clearly state what NS, S are, etc…

ISA vs. uArch

physical page size not in ISA! only the layout of the entries, for the page table walkers…

5. Performance Eval

b)

MIPS = million instructions per second.

so for 600MHz with CPI = 3 .

c)

Make sure to properly account for the +50% of instrs needed to encode it into processor B code.

Then .

6. Pipeline Rev. Eng.

c)

No, we cannot reduce exec. time with more ports → more ports does not mean that we can have multiple instrs. in W or M at the same time.
→ no stall cycle reduction.

d)

say “any other forwarding is unkown”.

e)

Possible to run using more forwarding paths?

State → “No. All instructions that stall due to data dependency already use the best possible forwarding.”

f)

Internal register forwarding?

Yes W→ ID (or W → EX for delay 2).
“Instruction 6 can finish decode by reading R4 in the second half of the cycle in the same cycle that it’s written.”

g)

→ Make sure to explain the changes in the box, not only put the new instructions in!

7. Tomasulo’s

Latency of ALU and memory unit:

  • This refers to the Execution time, so how many cycles EX takes!
    • 2 not 5, 10 not 13 (without the F, D, W)

Numbers of entries in each RS:

  • the decode is only executed (before it stalls) once the second instruction goes into W → two entries per RS
  • make sure to count this separately for each instruction type

Data forwarding?

  • NO!

8. Systolic Arrays

Notice the shape 3x4

  • Each element of the convolution kernel is multiplied with 4 of the matrix
    ⇒ Matrix is fed block-wise into the top
    ⇒ convolution kernels each get one row

We have to stagger them, so all data is available when they arrive.

9. GPUs and SIMD

for (i = 0; i < 1026; i++) {
	if (A[i] < 33) // instr 1
		B[i] = A[i] << 1; // instr 2
	if (A[i] > 33) // instr 3
		B[i] = A[i] >> 1; // instr 4
}

a)

Warps =

33 warps = 32 with 32 threads, 1 with 2 threads.

b)

Maximum possible → we want the fraction “threads doing shit”/“threads * warps * instructions” to be maximal.

so we want to have the

  • 32 full warps to do as much as possible
  • 1 warp with 2 to do as little as possible

this is split by instruction, counting threads:

  • isntr 1:
    • 1026 = 32*32+2 → all 1026 threads execute the first
  • instr 2 / 4:
    • 1024 = 32*32 → only the 32 first warps to 2 or 4
  • instr 3:
    • 1026 = 32*32 + 2 → all 1026 do the last instr
      and this is out of a maximum of:
  • instr 1, 3:
    • 1056 = 32*33 i.e. 33 full warps
  • instr 2 or 4:
    • 1024 = 32*32 as only the first 32 warps actually get there
      • so no cycles wasted for the last warp

the 32 warps execute 1, 3 and either 2 or 4 as a block (so for each warp choose either 2 or 4, i.e. A[i] < / > 33, but no mix).
The final warp should do as little as possible, so only execute 1 and 4 → A[i] = 33.

c)

What needs to be true about A for this to happen: (3 cases)

  • for the first 1024, every consecutive 32 elements of A
    • every element either < 33 OR > 33 (not mixed)
  • for the last two:
    • A[i] = 33

d)

Minimum utilisation:

  • each warp executes all 4
    • so mix of < 33, > 33.
  • last warp executes all 4:
    • exactly 1 < 33 and 1 > 33

this gives

e)

for every consecutive 32 elements of A for the first 1024:

  • A[i] < 33 for one, > 33 for another, the rest should be = 33.
    last 2 elements:
  • A[1024] > 33, A[1025] < 33 so exactly a mix.

10. Rev. Eng. Caches

Note: the 1 means 1.0 cache hit rate, so 8/8.

a) Block Size

(8. 16,32, 64 or 128B)

Notice that seq. 1 has 3/8.

Compute the hit rate for all different block sizes, then see which matches.

b) Cache Associativity

(1,2,3,4 or 8 way assoc.)

Block number = bytes address / block size.

Notice that regardless of cache-size or assoc. 0, 8192 16384 and 32768 map to set 0. Let .

  • .

  • 64 does not map to set 0 (set 1)

  • 4096 maps to either 0 or 1 depending on # sets.

    • for cache-size 8192B and 1-way, it maps to set 64
    • for all other configs, it’s set 0.

>= 3:

  • 16384 is a hit at end of seq. 1 so it must contain {0, 8192, 16384} at least (4096 is open)
    ⇐ 4:
  • Because 8192 is not a hit at the end of seq. 2, 4096 must have been set 0 and it’s associativity has to be >= 3, so it’s 4 but ⇐ 4.

c)

(4KB or 8KB)

We now know block size = 64B and 4-way assoc.

Look at Seq. 3.

  • 4096 is a hit, so 3072 and 1024 could not have been mapped to → set 0.

for 4-way and 64B block size, we would have

  • 4KB cache size →
    • sets
    • sets

So 3072 and 1024 would map to →

  • , mod 32 = 16
  • , mod 32 = 16.
    As 4096 is a hit, they must have mapped to set 16 → thus size = 8192KB.

d)

(LRU or FIFO)

8192 is a miss in seq. 2, so let’s look at FIFO vs. LRU:

FIFO for set 0

  • seq. 1 end
  • then seq. 2 :
    • on insertion of 32768:
    • 0 is inserted back
  • thus it’s consistent with 8192 miss

LRU for set 0:

  • seq 1. end from LRU, MRU
  • seq 2.
  • but then 8192 would not have been a miss!

Thus the cache must be FIFO.

Branch Prediction

a)

Lead-In

There is always a NN lead-in to take into account.
This makes sure we have something to index the first branch with.

We have TTT…NT, so prepend the NN lead in. Then we have NN → T, NT → T, etc…

b)

We don’t have to give a value for all entries of the PHT → only those actually taken in the steady state branch history.