mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-02 09:45:18 +00:00
7a4218788c
If the instruction address spilled across two pages and the second page misses the TLB, the HPTW received a tlb miss at the address of the first page rather than the second. After the walk the TLB was updated with the PTE from the first page at the address of the second page. Example bug Instruction PCF = 0x2ffe First page in 0x2ffe and second page in 0x3000. The second page misses the TLB and generates HPTW request at 0x2ffe rather than 0x3000. TLB is updated with PTE from 0x2ffe at 0x3000.
176 lines
5.9 KiB
Systemverilog
176 lines
5.9 KiB
Systemverilog
///////////////////////////////////////////
|
|
// datapath.sv
|
|
//
|
|
// Written: Ross Thompson
|
|
// email: ross1728@gmail.com
|
|
// Created: November 9, 2019
|
|
// Modified: March 04, 2021
|
|
//
|
|
// Purpose: Finds the current function or global assembly label based on PCE.
|
|
//
|
|
// A component of the Wally configurable RISC-V project.
|
|
//
|
|
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
|
//
|
|
// MIT LICENSE
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
|
// software and associated documentation files (the "Software"), to deal in the Software
|
|
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
|
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
|
// to whom the Software is furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in all copies or
|
|
// substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
|
// OR OTHER DEALINGS IN THE SOFTWARE.
|
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
`include "wally-config.vh"
|
|
|
|
module FunctionName(reset, clk, ProgramAddrMapFile, ProgramLabelMapFile);
|
|
|
|
input logic reset;
|
|
input logic clk;
|
|
input string ProgramAddrMapFile;
|
|
input string ProgramLabelMapFile;
|
|
|
|
logic [`XLEN-1:0] ProgramAddrMapMemory [];
|
|
string ProgramLabelMapMemory [integer];
|
|
string FunctionName;
|
|
|
|
|
|
logic [`XLEN-1:0] PCF, PCD, PCE, FunctionAddr;
|
|
logic StallD, StallE, FlushD, FlushE;
|
|
integer ProgramAddrIndex, ProgramAddrIndexQ;
|
|
|
|
assign PCF = testbench.dut.core.ifu.PCF;
|
|
assign StallD = testbench.dut.core.StallD;
|
|
assign StallE = testbench.dut.core.StallE;
|
|
assign FlushD = testbench.dut.core.FlushD;
|
|
assign FlushE = testbench.dut.core.FlushE;
|
|
|
|
// copy from ifu
|
|
// when the F and D stages are flushed we need to ensure the PCE is held so that the function name does not
|
|
// erroneously change.
|
|
flopenrc #(`XLEN) PCDReg(clk, reset, 1'b0, ~StallD, FlushE & FlushD ? PCE : PCF, PCD);
|
|
flopenr #(`XLEN) PCEReg(clk, reset, ~StallE, FlushE ? PCE : PCD, PCE);
|
|
|
|
|
|
|
|
task automatic bin_search_min;
|
|
input logic [`XLEN-1:0] pc;
|
|
input logic [`XLEN-1:0] length;
|
|
ref logic [`XLEN-1:0] array [];
|
|
output logic [`XLEN-1:0] minval;
|
|
output logic [`XLEN-1:0] mid;
|
|
|
|
logic [`XLEN-1:0] left, right;
|
|
|
|
begin
|
|
if ( pc == 0 ) begin
|
|
// *** want to keep the old value for mid and minval
|
|
mid = 0;
|
|
return;
|
|
end
|
|
left = 0;
|
|
right = length;
|
|
while (left <= right) begin
|
|
mid = left + ((right - left) / 2);
|
|
if (array[mid] == pc) begin
|
|
minval = array[mid];
|
|
return;
|
|
end
|
|
if (array[mid] < pc) begin
|
|
left = mid + 1;
|
|
end else if( array[mid] > pc) begin
|
|
right = mid -1;
|
|
end else begin
|
|
//$display("Critical Error in FunctionName. PC, %x not found.", pc);
|
|
return;
|
|
//$stop();
|
|
end
|
|
end // while (left <= right)
|
|
// if the element pc is now found, right and left will be equal at this point.
|
|
// we need to check if pc is less than the array at left or greather.
|
|
// if it is less than pc, then we select left as the index.
|
|
// if it is greather we want 1 less than left.
|
|
if (array[left] < pc) begin
|
|
minval = array[left];
|
|
mid = left;
|
|
return;
|
|
end else begin
|
|
minval = array[left-1];
|
|
mid = left - 1;
|
|
return;
|
|
end
|
|
end
|
|
endtask // bin_search_min
|
|
|
|
integer ProgramAddrMapFP, ProgramLabelMapFP;
|
|
integer ProgramAddrMapLineCount, ProgramLabelMapLineCount;
|
|
longint ProgramAddrMapLine;
|
|
string ProgramLabelMapLine;
|
|
integer status;
|
|
|
|
|
|
// preload
|
|
// initial begin
|
|
always @ (posedge reset) begin
|
|
$readmemh(ProgramAddrMapFile, ProgramAddrMapMemory);
|
|
// we need to count the number of lines in the file so we can set FunctionRadixLineCount.
|
|
|
|
ProgramAddrMapLineCount = 0;
|
|
ProgramAddrMapFP = $fopen(ProgramAddrMapFile, "r");
|
|
|
|
// read line by line to count lines
|
|
if (ProgramAddrMapFP) begin
|
|
while (! $feof(ProgramAddrMapFP)) begin
|
|
status = $fscanf(ProgramAddrMapFP, "%h\n", ProgramAddrMapLine);
|
|
|
|
ProgramAddrMapLineCount = ProgramAddrMapLineCount + 1;
|
|
end
|
|
end else begin
|
|
$display("Cannot open file %s for reading.", ProgramAddrMapFile);
|
|
end
|
|
$fclose(ProgramAddrMapFP);
|
|
|
|
// ProgramIndexFile maps the program name to the compile index.
|
|
// The compile index is then used to inditify the application
|
|
// in the custom radix.
|
|
// Build an associative array to convert the name to an index.
|
|
ProgramLabelMapLineCount = 0;
|
|
ProgramLabelMapFP = $fopen(ProgramLabelMapFile, "r");
|
|
|
|
if (ProgramLabelMapFP) begin
|
|
while (! $feof(ProgramLabelMapFP)) begin
|
|
status = $fscanf(ProgramLabelMapFP, "%s\n", ProgramLabelMapLine);
|
|
ProgramLabelMapMemory[ProgramLabelMapLineCount] = ProgramLabelMapLine;
|
|
ProgramLabelMapLineCount = ProgramLabelMapLineCount + 1;
|
|
end
|
|
end else begin
|
|
$display("Cannot open file %s for reading.", ProgramLabelMapFile);
|
|
end
|
|
$fclose(ProgramLabelMapFP);
|
|
|
|
end
|
|
|
|
always @(PCE) begin
|
|
bin_search_min(PCE, ProgramAddrMapLineCount, ProgramAddrMapMemory, FunctionAddr, ProgramAddrIndex);
|
|
end
|
|
|
|
logic OrReducedAdr, AnyUnknown;
|
|
assign OrReducedAdr = |ProgramAddrIndex;
|
|
assign AnyUnknown = (OrReducedAdr === 1'bx) ? 1'b1 : 1'b0;
|
|
initial ProgramAddrIndex = '0;
|
|
|
|
assign FunctionName = AnyUnknown ? "Unknown!" : ProgramLabelMapMemory[ProgramAddrIndex];
|
|
|
|
|
|
endmodule // function_radix
|
|
|