Hello,
Perhaps there is something I am missing here, but part of the code in the maptable logic appears redundant. Specifically the handling of remap requests appears to be unecessary as the logic is duplicated elsewhere. The code in question:
for (i <- 0 until plWidth) {
io.map_resps(i).prs1 := (0 until i).foldLeft(map_table(io.map_reqs(i).lrs1)) ((p,k) =>
Mux(bypass.B && io.remap_reqs(k).valid && io.remap_reqs(k).ldst === io.map_reqs(i).lrs1, io.remap_reqs(k).pdst, p))
Specifically, this creates says that for k = 0 until i, where i goes from 0 until plWidth, check to see if a remap requests logical destination matches one of the source operands of this operation. However, the check only checks the i-1 inputs for remap requests, which is strange, as this comes from the previous cycle and all of them should be checked.
The reason why rename still works is because at the end of the ren1_uop, the register r_uop (the intermediary register step in the 2-cycle rename) receives input through
r_uop := GetNewUopAndBrMask(BypassAllocations(next_uop, ren2_uops, ren2_alloc_reqs), io.brupdate)
This results in the incoming uop explicitly handling all dependencies from the second cycle renames that have not yet appeared in the map table, and therefore ensures remapping correctness.
My question is, have I misunderstood something or is this just an unfortunate case of leftover code?
Kind regards,
Amund