diff --git a/wally-pipelined/src/mmu/cam_line.sv b/wally-pipelined/src/mmu/cam_line.sv index 4104976b..a7341bf9 100644 --- a/wally-pipelined/src/mmu/cam_line.sv +++ b/wally-pipelined/src/mmu/cam_line.sv @@ -29,7 +29,7 @@ `include "wally-config.vh" module cam_line #(parameter KEY_BITS = 20, - parameter HIGH_SEGMENT_BITS = 10) ( + parameter SEGMENT_BITS = 10) ( input clk, reset, // input to check which SvMode is running @@ -57,6 +57,36 @@ module cam_line #(parameter KEY_BITS = 20, // This entry has KEY_BITS for the key plus one valid bit. logic Valid; logic [KEY_BITS-1:0] Key; + + + // Split up key and VPN into sections for each page table level. + logic [SEGMENT_BITS-1:0] Key0, Key1, VPN0, VPN1; + logic MatchVPN0, MatchVPN1; + + generate + if (`XLEN == 32) begin + assign {Key1, Key0} = Key; + assign {VPN1, VPN0} = VirtualPageNumber; + + assign MatchVPN0 = (VPN0 == Key0) || (PageType[0]); // least signifcant section + assign MatchVPN1 = (VPN1 == Key1); + + assign Match = MatchVPN0 & MatchVPN1 & Valid; + end else begin + logic [SEGMENT_BITS-1:0] Key2, Key3, VPN2, VPN3; + logic MatchVPN2, MatchVPN3; + + assign {VPN3, VPN2, VPN1, VPN0} = VirtualPageNumber; + assign {Key3, Key2, Key1, Key0} = Key; + + assign MatchVPN0 = (VPN0 == Key0) || (PageType > 2'd0); // least signifcant section + assign MatchVPN1 = (VPN1 == Key1) || (PageType > 2'd1); + assign MatchVPN2 = (VPN2 == Key2) || (PageType > 2'd2); + assign MatchVPN3 = (VPN3 == Key3); // *** this should always match in sv39 since both vPN3 and key3 are zeroed by the pagetable walker before getting to the cam + + assign Match = MatchVPN0 & MatchVPN1 & MatchVPN2 & MatchVPN3 & Valid; + end + endgenerate // When determining a match for a superpage, we might use only a portion of // the input VirtualPageNumber. Unused parts of the VirtualPageNumber are @@ -77,8 +107,17 @@ module cam_line #(parameter KEY_BITS = 20, // Calculate the actual query key based on the input key and the page type. // For example, a megapage in SV39 only cares about VPN2 and VPN1, so VPN0 // should automatically match. - page_number_mixer #(KEY_BITS, HIGH_SEGMENT_BITS) mixer(VirtualPageNumber, Key, PageType, SvMode, VirtualPageNumberQuery); +// logic [KEY_BITS-1:0] PageNumberMask, MaskedKey, MaskedQuery; + // this is the max possible length of the vpn, as listed in wally-constants. + // for modes with a mode with fewer bits in the vpn, the extra levels in MaskedQuery + // and MaskedKey should have been zeroed out by the tlb before coming through the cam as VirtualPageNumber. + generate + if (`XLEN == 32) begin + + end else begin + + end + endgenerate - assign Match = ({1'b1, VirtualPageNumberQuery} == {Valid, Key}); endmodule diff --git a/wally-pipelined/src/mmu/page_number_mixer.sv b/wally-pipelined/src/mmu/page_number_mixer.sv index ea0e3d85..7f09dff5 100644 --- a/wally-pipelined/src/mmu/page_number_mixer.sv +++ b/wally-pipelined/src/mmu/page_number_mixer.sv @@ -51,7 +51,6 @@ module page_number_mixer #(parameter BITS = 20, generate if (`XLEN == 32) begin - always_comb logic [HIGH_SEGMENT_BITS-1:0] Segment1, MixSegment1, Segment1Combined; logic [LOW_SEGMENT_BITS-1:0] Segment0, MixSegment0, Segment0Combined; diff --git a/wally-pipelined/src/mmu/tlb_cam.sv b/wally-pipelined/src/mmu/tlb_cam.sv index 160e6155..5652d1ac 100644 --- a/wally-pipelined/src/mmu/tlb_cam.sv +++ b/wally-pipelined/src/mmu/tlb_cam.sv @@ -30,7 +30,7 @@ module tlb_cam #(parameter ENTRY_BITS = 3, parameter KEY_BITS = 20, - parameter HIGH_SEGMENT_BITS = 10) ( + parameter SEGMENT_BITS = 10) ( input clk, reset, input [KEY_BITS-1:0] VirtualPageNumber, input [1:0] PageTypeWrite, @@ -60,7 +60,7 @@ module tlb_cam #(parameter ENTRY_BITS = 3, generate genvar i; for (i = 0; i < NENTRIES; i++) begin - cam_line #(KEY_BITS, HIGH_SEGMENT_BITS) cam_line( + cam_line #(KEY_BITS, SEGMENT_BITS) cam_line( .CAMLineWrite(CAMLineWrite[i] && TLBWrite), .PageType(PageTypeList[i]), .Match(Matches[i]),