From 41497c647fc4367f078172c17854538ed690a649 Mon Sep 17 00:00:00 2001 From: Stafford Horne Date: Fri, 25 Jun 2021 02:15:05 +0900 Subject: [PATCH] immu: Fix issue with multiple mtspr insns Issue #122 Writing to the tlb rams was dependent on the spr_bus_ack as a means to only write during the first cycle after a spr_bus_stb_i. This works fine for a single write, but if we have a write to itlb_match_spr followed by itlb_trans_spr the spr_bus_ack never goes low so the write to itlb_trans_spr is skipped. Fix this by using the itlb_match_spr_cs_r and itlb_trans_spr_cs_r signals to control the "first cycle after spr_bus_stb_i" condition. This way writes can happen independently. Note, there may still be issues with a write to itlb_match followed by another write to itlb_match. Fixing that requires changing the "first cycle after spr_bus_stb_i" policy, which is similar to dmmu. --- rtl/verilog/mor1kx_immu.v | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rtl/verilog/mor1kx_immu.v b/rtl/verilog/mor1kx_immu.v index d05537d0..c284ef6f 100644 --- a/rtl/verilog/mor1kx_immu.v +++ b/rtl/verilog/mor1kx_immu.v @@ -174,13 +174,13 @@ endgenerate if (itlb_match_reload_we & !tlb_reload_huge) itlb_match_we[j] = 1; if (j[WAYS_WIDTH-1:0] == spr_way_idx) - itlb_match_we[j] = itlb_match_spr_cs & spr_bus_we_i & !spr_bus_ack; + itlb_match_we[j] = itlb_match_spr_cs & spr_bus_we_i & !itlb_match_spr_cs_r; itlb_trans_we[j] = 0; if (itlb_trans_reload_we & !tlb_reload_huge) itlb_trans_we[j] = 1; if (j[WAYS_WIDTH-1:0] == spr_way_idx) - itlb_trans_we[j] = itlb_trans_spr_cs & spr_bus_we_i & !spr_bus_ack; + itlb_trans_we[j] = itlb_trans_spr_cs & spr_bus_we_i & !itlb_trans_spr_cs_r; end end @@ -231,16 +231,16 @@ endgenerate assign itlb_trans_spr_cs = spr_bus_stb_i & (spr_bus_addr_i[15:11] == 5'd2) & |spr_bus_addr_i[10:9] & spr_bus_addr_i[7]; - assign itlb_match_addr = itlb_match_spr_cs & !spr_bus_ack ? + assign itlb_match_addr = itlb_match_spr_cs & !itlb_match_spr_cs_r ? spr_bus_addr_i[OPTION_IMMU_SET_WIDTH-1:0] : virt_addr_i[13+(OPTION_IMMU_SET_WIDTH-1):13]; - assign itlb_trans_addr = itlb_trans_spr_cs & !spr_bus_ack ? + assign itlb_trans_addr = itlb_trans_spr_cs & !itlb_trans_spr_cs_r ? spr_bus_addr_i[OPTION_IMMU_SET_WIDTH-1:0] : virt_addr_i[13+(OPTION_IMMU_SET_WIDTH-1):13]; - assign itlb_match_din = itlb_match_spr_cs & spr_bus_we_i & !spr_bus_ack ? + assign itlb_match_din = itlb_match_spr_cs & spr_bus_we_i & !itlb_match_spr_cs_r ? spr_bus_dat_i : itlb_match_reload_din; - assign itlb_trans_din = itlb_trans_spr_cs & spr_bus_we_i & !spr_bus_ack ? + assign itlb_trans_din = itlb_trans_spr_cs & spr_bus_we_i & !itlb_trans_spr_cs_r ? spr_bus_dat_i : itlb_trans_reload_din; assign itlb_match_huge_addr = virt_addr_i[24+(OPTION_IMMU_SET_WIDTH-1):24];