Merge changes from main

This commit is contained in:
Jarred Allen 2021-03-18 18:58:10 -04:00
commit 279c09b27c
34 changed files with 644 additions and 252 deletions

View File

@ -63,16 +63,21 @@
// Peripheral memory space extends from BASE to BASE+RANGE // Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits // Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits
`define TIMBASE 32'h80000000
`define TIMRANGE 32'h07FFFFFF
`define BOOTTIMBASE 32'h00000000 //only needs to go from 0x1000 to 0x2FFF, extending to a power of 2 `define BOOTTIMBASE 32'h00000000 //only needs to go from 0x1000 to 0x2FFF, extending to a power of 2
`define BOOTTIMRANGE 32'h00003FFF `define BOOTTIMRANGE 32'h00003FFF
`define CLINTBASE 32'h02000000 `define CLINTBASE 32'h02000000
`define CLINTRANGE 32'h0000BFFF `define CLINTRANGE 32'h0000FFFF
//`define GPIOBASE 32'h10012000 // no GPIO in linux for now `define PLICBASE 32'h0C000000
//`define GPIORANGE 32'h000000FF `define PLICRANGE 32'h0FFFFFFF
`define UARTBASE 32'h10000000 `define UARTBASE 32'h10000000
`define UARTRANGE 32'h00000007 `define UARTRANGE 32'h00000007
`define VBD0BASE 32'h10001000
`define VBD0RANGE 32'h000001FF
// differing from Imperas' OVPSim by not having a VND0
`define GPIOBASE 32'h20000000
`define GPIORANGE 32'h000000FF
`define TIMBASE 32'h80000000
`define TIMRANGE 32'h07FFFFFF
// Bus Interface width // Bus Interface width
`define AHBW 64 `define AHBW 64
@ -81,6 +86,8 @@
// Tie GPIO outputs back to inputs // Tie GPIO outputs back to inputs
`define GPIO_LOOPBACK_TEST 0 `define GPIO_LOOPBACK_TEST 0
// Busybear special CSR config to match OVPSim
`define OVPSIM_CSR_CONFIG 1
// Hardware configuration // Hardware configuration
`define UART_PRESCALE 1 `define UART_PRESCALE 1
@ -90,3 +97,4 @@
`define TWO_BIT_PRELOAD "../config/busybear/twoBitPredictor.txt" `define TWO_BIT_PRELOAD "../config/busybear/twoBitPredictor.txt"
`define BTB_PRELOAD "../config/busybear/BTBPredictor.txt" `define BTB_PRELOAD "../config/busybear/BTBPredictor.txt"
`define BPTYPE "BPGSHARE" // BPGLOBAL or BPTWOBIT or BPGSHARE

View File

@ -66,6 +66,8 @@
// Peripheral memory space extends from BASE to BASE+RANGE // Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits // Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits
`define BOOTTIMBASE 32'h00000000
`define BOOTTIMRANGE 32'h00003FFF
`define TIMBASE 32'h00000000 `define TIMBASE 32'h00000000
`define TIMRANGE 32'hFFFFFFFF `define TIMRANGE 32'hFFFFFFFF
`define CLINTBASE 32'h02000000 `define CLINTBASE 32'h02000000
@ -80,6 +82,8 @@
// Tie GPIO outputs back to inputs // Tie GPIO outputs back to inputs
`define GPIO_LOOPBACK_TEST 0 `define GPIO_LOOPBACK_TEST 0
// Busybear special CSR config to match OVPSim
`define OVPSIM_CSR_CONFIG 0
// Hardware configuration // Hardware configuration
`define UART_PRESCALE 1 `define UART_PRESCALE 1
@ -91,3 +95,4 @@
`define TWO_BIT_PRELOAD "../config/coremark/twoBitPredictor.txt" `define TWO_BIT_PRELOAD "../config/coremark/twoBitPredictor.txt"
`define BTB_PRELOAD "../config/coremark/BTBPredictor.txt" `define BTB_PRELOAD "../config/coremark/BTBPredictor.txt"
`define BPTYPE "BPGSHARE" // BPGLOBAL or BPTWOBIT or BPGSHARE

View File

@ -66,6 +66,8 @@
// Peripheral memory space extends from BASE to BASE+RANGE // Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits // Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits
`define BOOTTIMBASE 32'h00000000
`define BOOTTIMRANGE 32'h00003FFF
`define TIMBASE 32'h80000000 `define TIMBASE 32'h80000000
`define TIMRANGE 32'h000FFFFF `define TIMRANGE 32'h000FFFFF
`define CLINTBASE 32'h02000000 `define CLINTBASE 32'h02000000
@ -80,6 +82,8 @@
// Tie GPIO outputs back to inputs // Tie GPIO outputs back to inputs
`define GPIO_LOOPBACK_TEST 0 `define GPIO_LOOPBACK_TEST 0
// Busybear special CSR config to match OVPSim
`define OVPSIM_CSR_CONFIG 0
// Hardware configuration // Hardware configuration
`define UART_PRESCALE 1 `define UART_PRESCALE 1

View File

@ -62,6 +62,8 @@
// Peripheral memory space extends from BASE to BASE+RANGE // Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits // Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits
`define BOOTTIMBASE 32'h00000000
`define BOOTTIMRANGE 32'h00003FFF
`define TIMBASE 32'h80000000 `define TIMBASE 32'h80000000
`define TIMRANGE 32'h0007FFFF `define TIMRANGE 32'h0007FFFF
`define CLINTBASE 32'h02000000 `define CLINTBASE 32'h02000000
@ -79,6 +81,8 @@
// Tie GPIO outputs back to inputs // Tie GPIO outputs back to inputs
`define GPIO_LOOPBACK_TEST 0 `define GPIO_LOOPBACK_TEST 0
// Busybear special CSR config to match OVPSim
`define OVPSIM_CSR_CONFIG 0
// Hardware configuration // Hardware configuration
`define UART_PRESCALE 1 `define UART_PRESCALE 1
@ -88,3 +92,4 @@
`define TWO_BIT_PRELOAD "../config/rv32ic/twoBitPredictor.txt" `define TWO_BIT_PRELOAD "../config/rv32ic/twoBitPredictor.txt"
`define BTB_PRELOAD "../config/rv32ic/BTBPredictor.txt" `define BTB_PRELOAD "../config/rv32ic/BTBPredictor.txt"
`define BPTYPE "BPGSHARE" // BPGLOBAL or BPTWOBIT or BPGSHARE

View File

@ -66,6 +66,8 @@
// Peripheral memory space extends from BASE to BASE+RANGE // Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits // Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits
`define BOOTTIMBASE 32'h00000000
`define BOOTTIMRANGE 32'h00003FFF
`define TIMBASE 32'h80000000 `define TIMBASE 32'h80000000
`define TIMRANGE 32'h0007FFFF `define TIMRANGE 32'h0007FFFF
`define CLINTBASE 32'h02000000 `define CLINTBASE 32'h02000000
@ -80,6 +82,8 @@
// Tie GPIO outputs back to inputs // Tie GPIO outputs back to inputs
`define GPIO_LOOPBACK_TEST 0 `define GPIO_LOOPBACK_TEST 0
// Busybear special CSR config to match OVPSim
`define OVPSIM_CSR_CONFIG 0
// Hardware configuration // Hardware configuration
`define UART_PRESCALE 1 `define UART_PRESCALE 1
@ -91,3 +95,4 @@
`define TWO_BIT_PRELOAD "../config/rv64ic/twoBitPredictor.txt" `define TWO_BIT_PRELOAD "../config/rv64ic/twoBitPredictor.txt"
`define BTB_PRELOAD "../config/rv64ic/BTBPredictor.txt" `define BTB_PRELOAD "../config/rv64ic/BTBPredictor.txt"
`define BPTYPE "BPGSHARE" // BPGLOBAL or BPTWOBIT or BPGSHARE

View File

@ -66,6 +66,8 @@
// Peripheral memory space extends from BASE to BASE+RANGE // Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits // Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits
`define BOOTTIMBASE 32'h00000000
`define BOOTTIMRANGE 32'h00003FFF
`define TIMBASE 32'h80000000 `define TIMBASE 32'h80000000
`define TIMRANGE 32'h0007FFFF `define TIMRANGE 32'h0007FFFF
`define CLINTBASE 32'h02000000 `define CLINTBASE 32'h02000000
@ -80,6 +82,8 @@
// Tie GPIO outputs back to inputs // Tie GPIO outputs back to inputs
`define GPIO_LOOPBACK_TEST 0 `define GPIO_LOOPBACK_TEST 0
// Busybear special CSR config to match OVPSim
`define OVPSIM_CSR_CONFIG 0
// Hardware configuration // Hardware configuration
`define UART_PRESCALE 1 `define UART_PRESCALE 1
@ -91,3 +95,4 @@
`define TWO_BIT_PRELOAD "../config/rv64icfd/twoBitPredictor.txt" `define TWO_BIT_PRELOAD "../config/rv64icfd/twoBitPredictor.txt"
`define BTB_PRELOAD "../config/rv64icfd/BTBPredictor.txt" `define BTB_PRELOAD "../config/rv64icfd/BTBPredictor.txt"
`define BPTYPE "BPGSHARE" // BPGLOBAL or BPTWOBIT or BPGSHARE

View File

@ -111,6 +111,6 @@ set DefaultRadix hexadecimal
-- Run the Simulation -- Run the Simulation
#run 7402000 #run 7402000
#run 12750 #run 12750
#run -all run -all
run 5000 #run 21400
#quit #quit

View File

@ -1,7 +1,8 @@
add wave /testbench/clk add wave /testbench/clk
add wave /testbench/reset add wave /testbench/reset
add wave -divider add wave -divider
#add wave /testbench/dut/hart/ebu/IReadF
add wave /testbench/dut/hart/DataStall add wave /testbench/dut/hart/DataStall
add wave /testbench/dut/hart/InstrStall add wave /testbench/dut/hart/InstrStall
add wave /testbench/dut/hart/StallF add wave /testbench/dut/hart/StallF
@ -44,6 +45,8 @@ add wave -hex /testbench/dut/hart/ifu/PCM
add wave -hex /testbench/dut/hart/ifu/InstrM add wave -hex /testbench/dut/hart/ifu/InstrM
add wave /testbench/InstrMName add wave /testbench/InstrMName
add wave /testbench/dut/uncore/dtim/memwrite add wave /testbench/dut/uncore/dtim/memwrite
add wave -hex /testbench/dut/uncore/HADDR
add wave -hex /testbench/dut/uncore/HWDATA
add wave -divider add wave -divider
add wave -hex /testbench/dut/hart/ebu/MemReadM add wave -hex /testbench/dut/hart/ebu/MemReadM
@ -60,9 +63,12 @@ add wave -hex /testbench/dut/hart/ebu/CaptureDataM
add wave -hex /testbench/dut/hart/ebu/InstrStall add wave -hex /testbench/dut/hart/ebu/InstrStall
add wave -divider add wave -divider
<<<<<<< HEAD
add wave -hex /testbench/dut/uncore/dtim/* add wave -hex /testbench/dut/uncore/dtim/*
add wave -divider add wave -divider
=======
>>>>>>> origin/main
add wave -hex /testbench/dut/hart/ifu/PCW add wave -hex /testbench/dut/hart/ifu/PCW
add wave -hex /testbench/dut/hart/ifu/InstrW add wave -hex /testbench/dut/hart/ifu/InstrW
add wave /testbench/InstrWName add wave /testbench/InstrWName
@ -72,4 +78,11 @@ add wave -hex /testbench/dut/hart/ieu/dp/ResultW
add wave -hex /testbench/dut/hart/ieu/dp/RdW add wave -hex /testbench/dut/hart/ieu/dp/RdW
add wave -divider add wave -divider
<<<<<<< HEAD
add wave -hex -r /testbench/* add wave -hex -r /testbench/*
=======
add wave -hex /testbench/dut/uncore/dtim/*
add wave -divider
add wave -hex -r /testbench/*
>>>>>>> origin/main

View File

@ -36,11 +36,9 @@ add wave -noupdate -group HDU -expand -group Flush -color Yellow /testbench/dut/
add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallF add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallF
add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallD add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallD
add wave -noupdate -group Bpred -expand -group direction -divider Update add wave -noupdate -group Bpred -expand -group direction -divider Update
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/DirPredictor/UpdatePC add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/Predictor/DirPredictor/UpdatePC
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/DirPredictor/UpdateEN add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/Predictor/DirPredictor/UpdateEN
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/DirPredictor/UpdatePCIndex add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/Predictor/DirPredictor/UpdatePrediction
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/DirPredictor/UpdatePrediction
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/DirPredictor/memory/memory
add wave -noupdate -group Bpred -group {bp wrong} /testbench/dut/hart/ifu/bpred/TargetWrongE add wave -noupdate -group Bpred -group {bp wrong} /testbench/dut/hart/ifu/bpred/TargetWrongE
add wave -noupdate -group Bpred -group {bp wrong} /testbench/dut/hart/ifu/bpred/FallThroughWrongE add wave -noupdate -group Bpred -group {bp wrong} /testbench/dut/hart/ifu/bpred/FallThroughWrongE
add wave -noupdate -group Bpred -group {bp wrong} /testbench/dut/hart/ifu/bpred/PredictionDirWrongE add wave -noupdate -group Bpred -group {bp wrong} /testbench/dut/hart/ifu/bpred/PredictionDirWrongE
@ -144,7 +142,7 @@ add wave -noupdate -group {function radix debug} /testbench/functionRadix/functi
add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/ProgramAddrIndex add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/ProgramAddrIndex
add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/FunctionName add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/FunctionName
TreeUpdate [SetDefaultTree] TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 2} {181681 ns} 0} {{Cursor 3} {20231927 ns} 0} WaveRestoreCursors {{Cursor 2} {3758805 ns} 0}
quietly wave cursor active 1 quietly wave cursor active 1
configure wave -namecolwidth 250 configure wave -namecolwidth 250
configure wave -valuecolwidth 229 configure wave -valuecolwidth 229
@ -160,4 +158,4 @@ configure wave -griddelta 40
configure wave -timeline 0 configure wave -timeline 0
configure wave -timelineunits ns configure wave -timelineunits ns
update update
WaveRestoreZoom {11339470 ns} {14752202 ns} WaveRestoreZoom {1644110 ns} {15262484 ns}

View File

@ -50,19 +50,20 @@ module dmem (
output logic LoadMisalignedFaultM, LoadAccessFaultM, output logic LoadMisalignedFaultM, LoadAccessFaultM,
output logic StoreMisalignedFaultM, StoreAccessFaultM, output logic StoreMisalignedFaultM, StoreAccessFaultM,
// TLB management // TLB management
//input logic [`XLEN-1:0] PageTableEntryM, input logic [1:0] PrivilegeModeW,
input logic [`XLEN-1:0] PageTableEntryM,
input logic [`XLEN-1:0] SATP_REGW, input logic [`XLEN-1:0] SATP_REGW,
//input logic DTLBWriteM, DTLBFlushM, input logic DTLBWriteM, // DTLBFlushM,
output logic DTLBMissM, DTLBHitM output logic DTLBMissM, DTLBHitM
); );
logic SquashSCM; logic SquashSCM;
// *** temporary hack until walker is hooked up -- Thomas F // *** temporary hack until walker is hooked up -- Thomas F
logic [`XLEN-1:0] PageTableEntryM = '0; // logic [`XLEN-1:0] PageTableEntryM = '0;
logic DTLBFlushM = '0; logic DTLBFlushM = '0;
logic DTLBWriteM = '0; // logic DTLBWriteM = '0;
tlb #(3) dtlb(clk, reset, SATP_REGW, MemAdrM, PageTableEntryM, DTLBWriteM, tlb #(3) dtlb(clk, reset, SATP_REGW, PrivilegeModeW, MemAdrM, PageTableEntryM, DTLBWriteM,
DTLBFlushM, MemPAdrM, DTLBMissM, DTLBHitM); DTLBFlushM, MemPAdrM, DTLBMissM, DTLBHitM);
// Determine if an Unaligned access is taking place // Determine if an Unaligned access is taking place

View File

@ -46,8 +46,11 @@ module ahblite (
input logic MemReadM, MemWriteM, input logic MemReadM, MemWriteM,
input logic [`XLEN-1:0] WriteDataM, input logic [`XLEN-1:0] WriteDataM,
input logic [1:0] MemSizeM, input logic [1:0] MemSizeM,
// Signals from MMU *** // Signals from MMU
// MMUPAdr; input logic [`XLEN-1:0] MMUPAdr,
input logic MMUTranslate,
output logic [`XLEN-1:0] MMUReadPTE,
output logic MMUReady,
// Return from bus // Return from bus
output logic [`XLEN-1:0] ReadDataW, output logic [`XLEN-1:0] ReadDataW,
// AHB-Lite external signals // AHB-Lite external signals

View File

@ -0,0 +1,143 @@
///////////////////////////////////////////
// pagetablewalker.sv
//
// Written: tfleming@hmc.edu 2 March 2021
// Modified:
//
// Purpose: Page Table Walker
// Part of the Memory Management Unit (MMU)
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// 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"
`include "wally-constants.vh"
module pagetablewalker (
input logic clk, reset,
input logic [`XLEN-1:0] SATP_REGW,
input logic ITLBMissF, DTLBMissM,
input logic [`XLEN-1:0] PCF, MemAdrM,
output logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM,
output logic ITLBWriteF, DTLBWriteM,
// *** handshake to tlbs probably not needed, since stalls take effect
// output logic TranslationComplete
// Signals from and to ahblite
input logic [`XLEN-1:0] MMUReadPTE,
input logic MMUReady,
output logic [`XLEN-1:0] MMUPAdr,
output logic MMUTranslate
);
logic SvMode;
logic [`PPN_BITS-1:0] BasePageTablePPN;
logic [`XLEN-1:0] DirectInstrPTE, DirectMemPTE;
logic [9:0] DirectPTEFlags = {2'b0, 8'b00001111};
// rv32 temp case
logic [`VPN_BITS-1:0] PCPageNumber;
logic [`VPN_BITS-1:0] MemAdrPageNumber;
assign BasePageTablePPN = SATP_REGW[`PPN_BITS-1:0];
assign PCPageNumber = PCF[`VPN_BITS+11:12];
assign MemAdrPageNumber = MemAdrM[`VPN_BITS+11:12];
generate
if (`XLEN == 32) begin
assign DirectInstrPTE = {PCPageNumber, DirectPTEFlags};
assign DirectMemPTE = {MemAdrPageNumber, DirectPTEFlags};
end else begin
assign DirectInstrPTE = {10'b0, PCPageNumber, DirectPTEFlags};
assign DirectMemPTE = {10'b0, MemAdrPageNumber, DirectPTEFlags};
end
endgenerate
flopenr #(`XLEN) instrpte(clk, reset, ITLBMissF, DirectInstrPTE, PageTableEntryF);
flopenr #(`XLEN) datapte(clk, reset, DTLBMissM, DirectMemPTE, PageTableEntryM);
flopr #(1) iwritesignal(clk, reset, ITLBMissF, ITLBWriteF);
flopr #(1) dwritesignal(clk, reset, DTLBMissM, DTLBWriteM);
/*
generate
if (`XLEN == 32) begin
assign SvMode = SATP_REGW[31];
logic VPN1 [9:0] = TranslationVAdr[31:22];
logic VPN0 [9:0] = TranslationVAdr[21:12]; // *** could optimize by not passing offset?
logic TranslationPAdr [33:0];
typedef enum {IDLE, DATA_LEVEL1, DATA_LEVEL0, DATA_LEAF, DATA FAULT} statetype;
statetype WalkerState, NextWalkerState;
always_ff @(posedge HCLK, negedge HRESETn)
if (~HRESETn) WalkerState <= #1 IDLE;
else WalkerState <= #1 NextWalkerState;
always_comb begin
NextWalkerState = 'X;
case (WalkerState)
IDLE: if (TLBMissM) NextWalkerState = LEVEL1;
else NextWalkerState = IDLE;
LEVEL1: if (HREADY && ValidEntry) NextWalkerState = LEVEL0;
else if (HREADY) NextWalkerState = FAULT;
else NextWalkerState = LEVEL1;
LEVEL2: if (HREADY && ValidEntry) NextWalkerState = LEAF;
else if (HREADY) NextWalkerState = FAULT;
else NextWalkerState = LEVEL2;
LEAF: NextWalkerState = IDLE;
endcase
end
always_ff @(posedge HCLK, negedge HRESETn)
if (~HRESETn) begin
TranslationPAdr <= '0;
PageTableEntryF <= '0;
TranslationComplete <= '0;
end else begin
// default values
case (NextWalkerState)
LEVEL1: TranslationPAdr <= {BasePageTablePPN, VPN1, 2'b00};
LEVEL2: TranslationPAdr <= {CurrentPPN, VPN0, 2'b00};
LEAF: begin
PageTableEntryF <= CurrentPageTableEntry;
TranslationComplete <= '1;
end
endcase
end
assign #1 Translate = (NextWalkerState == LEVEL1);
end else begin
// sv39 not yet implemented
assign SvMode = SATP_REGW[63];
end
endgenerate
// rv32 case
*/
endmodule

View File

@ -1,106 +0,0 @@
///////////////////////////////////////////
// pagetablewalker.sv
//
// Written: tfleming@hmc.edu 2 March 2021
// Modified:
//
// Purpose: Page Table Walker
// Part of the Memory Management Unit (MMU)
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// 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 pagetablewalker (
input logic clk, reset,
input logic [`XLEN-1:0] SATP_REGW,
input logic ITLBMissF, DTLBMissM,
input logic [`XLEN-1:0] TranslationVAdr,
input logic HCLK, HRESETn,
input logic HREADY,
output logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM,
output logic ITLBWriteF, DTLBWriteM,
output logic TranslationComplete
);
/*
generate
if (`XLEN == 32) begin
logic Sv_Mode = satp[31]
end else begin
logic Sv_Mode [3:0] = satp[63:60]
end
endgenerate
*/
logic Sv_Mode = SATP_REGW[31];
logic BasePageTablePPN [21:0] = SATP_REGW[21:0];
logic VPN1 [9:0] = TranslationVAdr[31:22];
logic VPN0 [9:0] = TranslationVAdr[21:12]; // *** could optimize by not passing offset?
logic TranslationPAdr [33:0];
typedef enum {IDLE, DATA_LEVEL1, DATA_LEVEL0, DATA_LEAF, DATA FAULT} statetype;
statetype WalkerState, NextWalkerState;
always_ff @(posedge HCLK, negedge HRESETn)
if (~HRESETn) WalkerState <= #1 IDLE;
else WalkerState <= #1 NextWalkerState;
always_comb begin
NextWalkerState = 'X;
case (WalkerState)
IDLE: if (TLBMissM) NextWalkerState = LEVEL1;
else NextWalkerState = IDLE;
LEVEL1: if (HREADY && ValidEntry) NextWalkerState = LEVEL0;
else if (HREADY) NextWalkerState = FAULT;
else NextWalkerState = LEVEL1;
LEVEL2: if (HREADY && ValidEntry) NextWalkerState = LEAF;
else if (HREADY) NextWalkerState = FAULT;
else NextWalkerState = LEVEL2;
LEAF: NextWalkerState = IDLE;
endcase
end
always_ff @(posedge HCLK, negedge HRESETn)
if (~HRESETn) begin
TranslationPAdr <= '0;
PageTableEntryF <= '0;
TranslationComplete <= '0;
end else begin
// default values
case (NextWalkerState)
LEVEL1: TranslationPAdr <= {BasePageTablePPN, VPN1, 2'b00};
LEVEL2: TranslationPAdr <= {CurrentPPN, VPN0, 2'b00};
LEAF: begin
PageTableEntryF <= CurrentPageTableEntry;
TranslationComplete <= '1;
end
endcase
end
assign #1 Translate = (NextWalkerState == LEVEL1);
endmodule

View File

@ -117,7 +117,7 @@ module controller(
if (InstrD[31:27] == 5'b00010) if (InstrD[31:27] == 5'b00010)
ControlsD = `CTRLW'b1_000_00_10_001_0_00_0_0_0_0_0_0_01_0; // lr ControlsD = `CTRLW'b1_000_00_10_001_0_00_0_0_0_0_0_0_01_0; // lr
else if (InstrD[31:27] == 5'b00011) else if (InstrD[31:27] == 5'b00011)
ControlsD = `CTRLW'b1_101_01_01_101_0_00_0_0_0_0_0_0_01_0; // sc ControlsD = `CTRLW'b1_101_01_01_100_0_00_0_0_0_0_0_0_01_0; // sc
else else
ControlsD = `CTRLW'b1_101_01_11_001_0_00_0_0_0_0_0_0_10_0;; // amo ControlsD = `CTRLW'b1_101_01_11_001_0_00_0_0_0_0_0_0_10_0;; // amo
end else end else
@ -125,23 +125,23 @@ module controller(
7'b0110011: if (Funct7D == 7'b0000000 || Funct7D == 7'b0100000) 7'b0110011: if (Funct7D == 7'b0000000 || Funct7D == 7'b0100000)
ControlsD = `CTRLW'b1_000_00_00_000_0_10_0_0_0_0_0_0_00_0; // R-type ControlsD = `CTRLW'b1_000_00_00_000_0_10_0_0_0_0_0_0_00_0; // R-type
else if (Funct7D == 7'b0000001 && `M_SUPPORTED) else if (Funct7D == 7'b0000001 && `M_SUPPORTED)
ControlsD = `CTRLW'b1_000_00_00_100_0_00_0_0_0_0_0_1_00_0; // Multiply/Divide ControlsD = `CTRLW'b1_000_00_00_011_0_00_0_0_0_0_0_1_00_0; // Multiply/Divide
else else
ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // non-implemented instruction ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // non-implemented instruction
7'b0110111: ControlsD = `CTRLW'b1_100_01_00_000_0_11_0_0_0_0_0_0_00_0; // lui 7'b0110111: ControlsD = `CTRLW'b1_100_01_00_000_0_11_0_0_0_0_0_0_00_0; // lui
7'b0111011: if ((Funct7D == 7'b0000000 || Funct7D == 7'b0100000) && `XLEN == 64) 7'b0111011: if ((Funct7D == 7'b0000000 || Funct7D == 7'b0100000) && `XLEN == 64)
ControlsD = `CTRLW'b1_000_00_00_000_0_10_0_0_1_0_0_0_00_0; // R-type W instructions for RV64i ControlsD = `CTRLW'b1_000_00_00_000_0_10_0_0_1_0_0_0_00_0; // R-type W instructions for RV64i
else if (Funct7D == 7'b0000001 && `M_SUPPORTED && `XLEN == 64) else if (Funct7D == 7'b0000001 && `M_SUPPORTED && `XLEN == 64)
ControlsD = `CTRLW'b1_000_00_00_100_0_00_0_0_1_0_0_1_00_0; // W-type Multiply/Divide ControlsD = `CTRLW'b1_000_00_00_011_0_00_0_0_1_0_0_1_00_0; // W-type Multiply/Divide
else else
ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // non-implemented instruction ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // non-implemented instruction
7'b1100011: ControlsD = `CTRLW'b0_010_00_00_000_1_01_0_0_0_0_0_0_00_0; // beq 7'b1100011: ControlsD = `CTRLW'b0_010_00_00_000_1_01_0_0_0_0_0_0_00_0; // beq
7'b1100111: ControlsD = `CTRLW'b1_000_00_00_010_0_00_1_1_0_0_0_0_00_0; // jalr 7'b1100111: ControlsD = `CTRLW'b1_000_00_00_000_0_00_1_1_0_0_0_0_00_0; // jalr
7'b1101111: ControlsD = `CTRLW'b1_011_00_00_010_0_00_1_0_0_0_0_0_00_0; // jal 7'b1101111: ControlsD = `CTRLW'b1_011_00_00_000_0_00_1_0_0_0_0_0_00_0; // jal
7'b1110011: if (Funct3D == 3'b000) 7'b1110011: if (Funct3D == 3'b000)
ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_1_0_00_0; // privileged; decoded further in priveleged modules ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_1_0_00_0; // privileged; decoded further in priveleged modules
else else
ControlsD = `CTRLW'b1_000_00_00_011_0_00_0_0_0_1_0_0_00_0; // csrs ControlsD = `CTRLW'b1_000_00_00_010_0_00_0_0_0_1_0_0_00_0; // csrs
default: ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // non-implemented instruction default: ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // non-implemented instruction
endcase endcase
endgenerate endgenerate

View File

@ -51,7 +51,7 @@ module datapath (
input logic RegWriteW, input logic RegWriteW,
input logic SquashSCW, input logic SquashSCW,
input logic [2:0] ResultSrcW, input logic [2:0] ResultSrcW,
input logic [`XLEN-1:0] PCLinkW, // input logic [`XLEN-1:0] PCLinkW,
input logic [`XLEN-1:0] CSRReadValW, ReadDataW, MulDivResultW, input logic [`XLEN-1:0] CSRReadValW, ReadDataW, MulDivResultW,
// Hazard Unit signals // Hazard Unit signals
output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E,
@ -126,7 +126,7 @@ module datapath (
assign SCResultW = 0; assign SCResultW = 0;
endgenerate endgenerate
mux6 #(`XLEN) resultmux(ALUResultW, ReadDataW, PCLinkW, CSRReadValW, MulDivResultW, SCResultW, ResultSrcW, ResultW); mux5 #(`XLEN) resultmux(ALUResultW, ReadDataW, CSRReadValW, MulDivResultW, SCResultW, ResultSrcW, ResultW);
/* -----\/----- EXCLUDED -----\/----- /* -----\/----- EXCLUDED -----\/-----
// This mux4:1 no longer needs to include PCLinkW. This is set correctly in the execution stage. // This mux4:1 no longer needs to include PCLinkW. This is set correctly in the execution stage.
// *** need to look at how the decoder is coded to fix. // *** need to look at how the decoder is coded to fix.

View File

@ -49,7 +49,7 @@ module ieu (
output logic [2:0] Funct3M, output logic [2:0] Funct3M,
// Writeback stage // Writeback stage
input logic [`XLEN-1:0] CSRReadValW, ReadDataW, MulDivResultW, input logic [`XLEN-1:0] CSRReadValW, ReadDataW, MulDivResultW,
input logic [`XLEN-1:0] PCLinkW, // input logic [`XLEN-1:0] PCLinkW,
output logic InstrValidW, output logic InstrValidW,
// hazards // hazards
input logic StallE, StallM, StallW, input logic StallE, StallM, StallW,

View File

@ -66,14 +66,44 @@ module bpred
// Part 1 branch direction prediction // Part 1 branch direction prediction
twoBitPredictor DirPredictor(.clk(clk), generate
.reset(reset), if (`BPTYPE == "BPTWOBIT") begin:Predictor
.LookUpPC(PCNextF), twoBitPredictor DirPredictor(.clk(clk),
.Prediction(BPPredF), .reset(reset),
// update .LookUpPC(PCNextF),
.UpdatePC(PCE), .Prediction(BPPredF),
.UpdateEN(InstrClassE[0]), // update
.UpdatePrediction(UpdateBPPredE)); .UpdatePC(PCE),
.UpdateEN(InstrClassE[0]),
.UpdatePrediction(UpdateBPPredE));
end else if (`BPTYPE == "BPGLOBAL") begin:Predictor
globalHistoryPredictor DirPredictor(.clk(clk),
.reset(reset),
.*, // Stalls and flushes
.LookUpPC(PCNextF),
.Prediction(BPPredF),
// update
.UpdatePC(PCE),
.UpdateEN(InstrClassE[0]),
.PCSrcE(PCSrcE),
.UpdatePrediction(UpdateBPPredE));
end else if (`BPTYPE == "BPGSHARE") begin:Predictor
gsharePredictor DirPredictor(.clk(clk),
.reset(reset),
.*, // Stalls and flushes
.LookUpPC(PCNextF),
.Prediction(BPPredF),
// update
.UpdatePC(PCE),
.UpdateEN(InstrClassE[0]),
.PCSrcE(PCSrcE),
.UpdatePrediction(UpdateBPPredE));
end
endgenerate
// this predictor will have two pieces of data, // this predictor will have two pieces of data,
// 1) A direction (1 = Taken, 0 = Not Taken) // 1) A direction (1 = Taken, 0 = Not Taken)

View File

@ -0,0 +1,109 @@
///////////////////////////////////////////
// globalHistoryPredictor.sv
//
// Written: Shreya Sanghai
// Email: ssanghai@hmc.edu
// Created: March 16, 2021
// Modified:
//
// Purpose: Global History Branch predictor with parameterized global history register
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// 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 globalHistoryPredictor
#(parameter int k = 10
)
(input logic clk,
input logic reset,
input logic StallF, StallD, StallE, FlushF, FlushD, FlushE,
input logic [`XLEN-1:0] LookUpPC,
output logic [1:0] Prediction,
// update
input logic [`XLEN-1:0] UpdatePC,
input logic UpdateEN, PCSrcE, /// *** need to add as input from bpred.sv
input logic [1:0] UpdatePrediction
);
logic [k-1:0] GHRF, GHRD, GHRE;
flopenr #(k) GlobalHistoryRegister(.clk(clk),
.reset(reset),
.en(UpdateEN),
.d({PCSrcE, GHRF[k-1:1] }),
.q(GHRF));
logic [1:0] PredictionMemory;
logic DoForwarding, DoForwardingF;
logic [1:0] UpdatePredictionF;
// for gshare xor the PC with the GHR
// TODO: change in sram memory2 module
// assign UpdatePCIndex = GHRE ^ UpdatePC;
// assign LookUpPCIndex = LookUpPC ^ GHR;
// Make Prediction by reading the correct address in the PHT and also update the new address in the PHT
// GHR referes to the address that the past k branches points to in the prediction stage
// GHRE refers to the address that the past k branches points to in the exectution stage
SRAM2P1R1W #(k, 2) PHT(.clk(clk),
.reset(reset),
.RA1(GHRF),
.RD1(PredictionMemory),
.REN1(1'b1),
.WA1(GHRE),
.WD1(UpdatePrediction),
.WEN1(UpdateEN),
.BitWEN1(2'b11));
// need to forward when updating to the same address as reading.
// first we compare to see if the update and lookup addreses are the same
assign DoForwarding = GHRF == GHRE;
// register the update value and the forwarding signal into the Fetch stage
// TODO: add stall logic ***
flopr #(1) DoForwardingReg(.clk(clk),
.reset(reset),
.d(DoForwarding),
.q(DoForwardingF));
flopr #(2) UpdatePredictionReg(.clk(clk),
.reset(reset),
.d(UpdatePrediction),
.q(UpdatePredictionF));
assign Prediction = DoForwardingF ? UpdatePredictionF : PredictionMemory;
//pipeline for GHR
flopenrc #(k) GHRDReg(.clk(clk),
.reset(reset),
.en(~StallD),
.clear(FlushD),
.d(GHRF),
.q(GHRD));
flopenrc #(k) GHREReg(.clk(clk),
.reset(reset),
.en(~StallE),
.clear(FlushE),
.d(GHRD),
.q(GHRE));
endmodule

View File

@ -0,0 +1,109 @@
///////////////////////////////////////////
// gshare.sv
//
// Written: Shreya Sanghai
// Email: ssanghai@hmc.edu
// Created: March 16, 2021
// Modified:
//
// Purpose: Gshare predictor with parameterized global history register
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// 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 gsharePredictor
#(parameter int k = 10
)
(input logic clk,
input logic reset,
input logic StallF, StallD, StallE, FlushF, FlushD, FlushE,
input logic [`XLEN-1:0] LookUpPC,
output logic [1:0] Prediction,
// update
input logic [`XLEN-1:0] UpdatePC,
input logic UpdateEN, PCSrcE,
input logic [1:0] UpdatePrediction
);
logic [k-1:0] GHRF, GHRD, GHRE;
logic [k-1:0] LookUpPCIndexD, LookUpPCIndexE;
logic [k-1:0] LookUpPCIndex, UpdatePCIndex;
logic [1:0] PredictionMemory;
logic DoForwarding, DoForwardingF;
logic [1:0] UpdatePredictionF;
flopenr #(k) GlobalHistoryRegister(.clk(clk),
.reset(reset),
.en(UpdateEN),
.d({PCSrcE, GHRF[k-1:1] }),
.q(GHRF));
// for gshare xor the PC with the GHR
assign UpdatePCIndex = GHRE ^ UpdatePC[k:1];
assign LookUpPCIndex = GHRF ^ LookUpPC[k:1];
// Make Prediction by reading the correct address in the PHT and also update the new address in the PHT
// GHR referes to the address that the past k branches points to in the prediction stage
// GHRE refers to the address that the past k branches points to in the exectution stage
SRAM2P1R1W #(k, 2) PHT(.clk(clk),
.reset(reset),
.RA1(LookUpPCIndex),
.RD1(PredictionMemory),
.REN1(1'b1),
.WA1(UpdatePCIndex),
.WD1(UpdatePrediction),
.WEN1(UpdateEN),
.BitWEN1(2'b11));
// need to forward when updating to the same address as reading.
// first we compare to see if the update and lookup addreses are the same
assign DoForwarding = LookUpPCIndex == UpdatePCIndex;
// register the update value and the forwarding signal into the Fetch stage
// TODO: add stall logic ***
flopr #(1) DoForwardingReg(.clk(clk),
.reset(reset),
.d(DoForwarding),
.q(DoForwardingF));
flopr #(2) UpdatePredictionReg(.clk(clk),
.reset(reset),
.d(UpdatePrediction),
.q(UpdatePredictionF));
assign Prediction = DoForwardingF ? UpdatePredictionF : PredictionMemory;
//pipeline for GHR
flopenrc #(k) LookUpDReg(.clk(clk),
.reset(reset),
.en(~StallD),
.clear(FlushD),
.d(LookUpPCIndex),
.q(LookUpPCIndexD));
flopenrc #(k) LookUpEReg(.clk(clk),
.reset(reset),
.en(~StallE),
.clear(FlushE),
.d(LookUpPCIndexD),
.q(LookUpPCIndexE));
endmodule

View File

@ -49,17 +49,17 @@ module ifu (
output logic [31:0] InstrD, InstrM, output logic [31:0] InstrD, InstrM,
output logic [`XLEN-1:0] PCM, output logic [`XLEN-1:0] PCM,
// Writeback // Writeback
output logic [`XLEN-1:0] PCLinkW, // output logic [`XLEN-1:0] PCLinkW,
// Faults // Faults
input logic IllegalBaseInstrFaultD, input logic IllegalBaseInstrFaultD,
output logic IllegalIEUInstrFaultD, output logic IllegalIEUInstrFaultD,
output logic InstrMisalignedFaultM, output logic InstrMisalignedFaultM,
output logic [`XLEN-1:0] InstrMisalignedAdrM, output logic [`XLEN-1:0] InstrMisalignedAdrM,
// TLB management // TLB management
//input logic [`XLEN-1:0] PageTableEntryF, input logic [1:0] PrivilegeModeW,
input logic [`XLEN-1:0] PageTableEntryF,
input logic [`XLEN-1:0] SATP_REGW, input logic [`XLEN-1:0] SATP_REGW,
//input logic ITLBWriteF, ITLBFlushF, input logic ITLBWriteF, // ITLBFlushF,
// input logic [`XLEN-1:0] SATP,
output logic ITLBMissF, ITLBHitF output logic ITLBMissF, ITLBHitF
); );
@ -74,10 +74,10 @@ module ifu (
logic [`XLEN-1:0] ITLBInstrPAdrF, ICacheInstrPAdrF; logic [`XLEN-1:0] ITLBInstrPAdrF, ICacheInstrPAdrF;
// *** temporary hack until walker is hooked up -- Thomas F // *** temporary hack until walker is hooked up -- Thomas F
logic [`XLEN-1:0] PageTableEntryF = '0; // logic [`XLEN-1:0] PageTableEntryF = '0;
logic ITLBFlushF = '0; logic ITLBFlushF = '0;
logic ITLBWriteF = '0; // logic ITLBWriteF = '0;
tlb #(3) itlb(clk, reset, SATP_REGW, PCF, PageTableEntryF, ITLBWriteF, ITLBFlushF, tlb #(3) itlb(clk, reset, SATP_REGW, PrivilegeModeW, PCF, PageTableEntryF, ITLBWriteF, ITLBFlushF,
ITLBInstrPAdrF, ITLBMissF, ITLBHitF); ITLBInstrPAdrF, ITLBMissF, ITLBHitF);
// branch predictor signals // branch predictor signals
@ -203,8 +203,8 @@ module ifu (
// *** redo this // *** redo this
flopenr #(`XLEN) PCPDReg(clk, reset, ~StallD, PCPlus2or4F, PCLinkD); flopenr #(`XLEN) PCPDReg(clk, reset, ~StallD, PCPlus2or4F, PCLinkD);
flopenr #(`XLEN) PCPEReg(clk, reset, ~StallE, PCLinkD, PCLinkE); flopenr #(`XLEN) PCPEReg(clk, reset, ~StallE, PCLinkD, PCLinkE);
flopenr #(`XLEN) PCPMReg(clk, reset, ~StallM, PCLinkE, PCLinkM); // flopenr #(`XLEN) PCPMReg(clk, reset, ~StallM, PCLinkE, PCLinkM);
flopenr #(`XLEN) PCPWReg(clk, reset, ~StallW, PCLinkM, PCLinkW); // /flopenr #(`XLEN) PCPWReg(clk, reset, ~StallW, PCLinkM, PCLinkW);
endmodule endmodule

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// tlb_toy.sv // tlb.sv
// //
// Written: jtorrey@hmc.edu 16 February 2021 // Written: jtorrey@hmc.edu 16 February 2021
// Modified: // Modified:
@ -60,6 +60,9 @@ module tlb #(parameter ENTRY_BITS = 3) (
// Current value of satp CSR (from privileged unit) // Current value of satp CSR (from privileged unit)
input [`XLEN-1:0] SATP_REGW, input [`XLEN-1:0] SATP_REGW,
// Current privilege level of the processeor
input [1:0] PrivilegeModeW,
// Virtual address input // Virtual address input
input [`XLEN-1:0] VirtualAddress, input [`XLEN-1:0] VirtualAddress,
@ -77,6 +80,7 @@ module tlb #(parameter ENTRY_BITS = 3) (
); );
logic SvMode; logic SvMode;
logic Translate;
generate generate
if (`XLEN == 32) begin if (`XLEN == 32) begin
@ -85,6 +89,11 @@ module tlb #(parameter ENTRY_BITS = 3) (
assign SvMode = SATP_REGW[63]; // currently just a boolean whether translation enabled assign SvMode = SATP_REGW[63]; // currently just a boolean whether translation enabled
end end
endgenerate endgenerate
// *** Currently fake virtual memory being on for testing purposes
// *** DO NOT ENABLE UNLESS TESTING
// assign SvMode = 1;
assign Translate = SvMode & (PrivilegeModeW != `M_MODE);
// *** If we want to support multiple virtual memory modes (ie sv39 AND sv48), // *** If we want to support multiple virtual memory modes (ie sv39 AND sv48),
// we could have some muxes that control which parameters are current. // we could have some muxes that control which parameters are current.
@ -134,13 +143,13 @@ module tlb #(parameter ENTRY_BITS = 3) (
generate generate
if (`XLEN == 32) begin if (`XLEN == 32) begin
mux2 #(`XLEN) addressmux(VirtualAddress, PhysicalAddressFull[31:0], SvMode, PhysicalAddress); mux2 #(`XLEN) addressmux(VirtualAddress, PhysicalAddressFull[31:0], Translate, PhysicalAddress);
end else begin end else begin
mux2 #(`XLEN) addressmux(VirtualAddress, {8'b0, PhysicalAddressFull}, SvMode, PhysicalAddress); mux2 #(`XLEN) addressmux(VirtualAddress, {8'b0, PhysicalAddressFull}, Translate, PhysicalAddress);
end end
endgenerate endgenerate
assign TLBMiss = ~TLBHit & ~(TLBWrite | TLBFlush) & SvMode; assign TLBMiss = ~TLBHit & ~(TLBWrite | TLBFlush) & Translate;
endmodule endmodule
module tlb_ram #(parameter ENTRY_BITS = 3) ( module tlb_ram #(parameter ENTRY_BITS = 3) (

View File

@ -33,7 +33,7 @@ module csr (
input logic [`XLEN-1:0] PCM, SrcAM, input logic [`XLEN-1:0] PCM, SrcAM,
input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, uretM, input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, uretM,
input logic TimerIntM, ExtIntM, SwIntM, input logic TimerIntM, ExtIntM, SwIntM,
input logic InstrValidW, FloatRegWriteW, LoadStallD, input logic InstrValidW, FloatRegWriteW, LoadStallD, BPPredWrongE,
input logic [1:0] NextPrivilegeModeM, PrivilegeModeW, input logic [1:0] NextPrivilegeModeM, PrivilegeModeW,
input logic [`XLEN-1:0] CauseM, NextFaultMtvalM, input logic [`XLEN-1:0] CauseM, NextFaultMtvalM,
output logic [1:0] STATUS_MPP, output logic [1:0] STATUS_MPP,

View File

@ -29,7 +29,7 @@
module csrc ( module csrc (
input logic clk, reset, input logic clk, reset,
input logic InstrValidW, LoadStallD, CSRMWriteM, input logic InstrValidW, LoadStallD, CSRMWriteM, BPPredWrongE,
input logic [11:0] CSRAdrM, input logic [11:0] CSRAdrM,
input logic [1:0] PrivilegeModeW, input logic [1:0] PrivilegeModeW,
input logic [`XLEN-1:0] CSRWriteValM, input logic [`XLEN-1:0] CSRWriteValM,
@ -62,7 +62,8 @@ module csrc (
assign MCOUNTEN[1] = 1'b0; assign MCOUNTEN[1] = 1'b0;
assign MCOUNTEN[2] = InstrValidW; assign MCOUNTEN[2] = InstrValidW;
assign MCOUNTEN[3] = LoadStallD; assign MCOUNTEN[3] = LoadStallD;
assign MCOUNTEN[`COUNTERS:4] = 0; assign MCOUNTEN[4] = BPPredWrongE;
assign MCOUNTEN[`COUNTERS:5] = 0;
genvar j; genvar j;
generate generate

View File

@ -125,11 +125,12 @@ module csrm #(parameter
flopenr #(`XLEN) MEPCreg(clk, reset, WriteMEPCM, NextEPCM, MEPC_REGW); flopenr #(`XLEN) MEPCreg(clk, reset, WriteMEPCM, NextEPCM, MEPC_REGW);
flopenr #(`XLEN) MCAUSEreg(clk, reset, WriteMCAUSEM, NextCauseM, MCAUSE_REGW); flopenr #(`XLEN) MCAUSEreg(clk, reset, WriteMCAUSEM, NextCauseM, MCAUSE_REGW);
flopenr #(`XLEN) MTVALreg(clk, reset, WriteMTVALM, NextMtvalM, MTVAL_REGW); flopenr #(`XLEN) MTVALreg(clk, reset, WriteMTVALM, NextMtvalM, MTVAL_REGW);
`ifndef BUSYBEAR generate
flopenl #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], allones, MCOUNTEREN_REGW); if (`OVPSIM_CSR_CONFIG)
`else flopenl #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, {CSRWriteValM[31:2],1'b0,CSRWriteValM[0]}, 32'b0, MCOUNTEREN_REGW);
flopenl #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, {CSRWriteValM[31:2],1'b0,CSRWriteValM[0]}, 32'b0, MCOUNTEREN_REGW); else
`endif flopenl #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], allones, MCOUNTEREN_REGW);
endgenerate
flopenl #(32) MCOUNTINHIBITreg(clk, reset, WriteMCOUNTINHIBITM, CSRWriteValM[31:0], allones, MCOUNTINHIBIT_REGW); flopenl #(32) MCOUNTINHIBITreg(clk, reset, WriteMCOUNTINHIBITM, CSRWriteValM[31:0], allones, MCOUNTINHIBIT_REGW);
flopenr #(`XLEN) PMPADDR0reg(clk, reset, WritePMPADDR0M, CSRWriteValM, PMPADDR0_REGW); flopenr #(`XLEN) PMPADDR0reg(clk, reset, WritePMPADDR0M, CSRWriteValM, PMPADDR0_REGW);
// PMPCFG registers are a pair of 64-bit in RV64 and four 32-bit in RV32 // PMPCFG registers are a pair of 64-bit in RV64 and four 32-bit in RV32

View File

@ -82,11 +82,10 @@ module csrs #(parameter
flopenl #(`XLEN) SCAUSEreg(clk, reset, WriteSCAUSEM, NextCauseM, zero, SCAUSE_REGW); flopenl #(`XLEN) SCAUSEreg(clk, reset, WriteSCAUSEM, NextCauseM, zero, SCAUSE_REGW);
flopenr #(`XLEN) STVALreg(clk, reset, WriteSTVALM, NextMtvalM, STVAL_REGW); flopenr #(`XLEN) STVALreg(clk, reset, WriteSTVALM, NextMtvalM, STVAL_REGW);
flopenr #(`XLEN) SATPreg(clk, reset, WriteSATPM, CSRWriteValM, SATP_REGW); flopenr #(`XLEN) SATPreg(clk, reset, WriteSATPM, CSRWriteValM, SATP_REGW);
`ifndef BUSYBEAR if (`OVPSIM_CSR_CONFIG)
flopenl #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, CSRWriteValM[31:0], allones, SCOUNTEREN_REGW); flopenl #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, {CSRWriteValM[31:2],1'b0,CSRWriteValM[0]}, 32'b0, SCOUNTEREN_REGW);
`else else
flopenl #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, {CSRWriteValM[31:2],1'b0,CSRWriteValM[0]}, 32'b0, SCOUNTEREN_REGW); flopenl #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, CSRWriteValM[31:0], allones, SCOUNTEREN_REGW);
`endif
if (`N_SUPPORTED) begin if (`N_SUPPORTED) begin
logic WriteSEDELEGM, WriteSIDELEGM; logic WriteSEDELEGM, WriteSIDELEGM;
assign WriteSEDELEGM = CSRSWriteM && (CSRAdrM == SEDELEG); assign WriteSEDELEGM = CSRSWriteM && (CSRAdrM == SEDELEG);

View File

@ -36,7 +36,7 @@ module privileged (
output logic [`XLEN-1:0] CSRReadValW, output logic [`XLEN-1:0] CSRReadValW,
output logic [`XLEN-1:0] PrivilegedNextPCM, output logic [`XLEN-1:0] PrivilegedNextPCM,
output logic RetM, TrapM, output logic RetM, TrapM,
input logic InstrValidW, FloatRegWriteW, LoadStallD, input logic InstrValidW, FloatRegWriteW, LoadStallD, BPPredWrongE,
input logic PrivilegedM, input logic PrivilegedM,
input logic InstrMisalignedFaultM, InstrAccessFaultF, IllegalIEUInstrFaultD, input logic InstrMisalignedFaultM, InstrAccessFaultF, IllegalIEUInstrFaultD,
input logic LoadMisalignedFaultM, LoadAccessFaultM, input logic LoadMisalignedFaultM, LoadAccessFaultM,
@ -44,12 +44,13 @@ module privileged (
input logic TimerIntM, ExtIntM, SwIntM, input logic TimerIntM, ExtIntM, SwIntM,
input logic [`XLEN-1:0] InstrMisalignedAdrM, MemAdrM, input logic [`XLEN-1:0] InstrMisalignedAdrM, MemAdrM,
input logic [4:0] SetFflagsM, input logic [4:0] SetFflagsM,
output logic [1:0] PrivilegeModeW,
output logic [`XLEN-1:0] SATP_REGW, output logic [`XLEN-1:0] SATP_REGW,
output logic [2:0] FRM_REGW, output logic [2:0] FRM_REGW,
input logic FlushD, FlushE, FlushM, StallD, StallW input logic FlushD, FlushE, FlushM, StallD, StallW
); );
logic [1:0] NextPrivilegeModeM, PrivilegeModeW; logic [1:0] NextPrivilegeModeM;
logic [`XLEN-1:0] CauseM, NextFaultMtvalM; logic [`XLEN-1:0] CauseM, NextFaultMtvalM;
logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, UEPC_REGW, UTVEC_REGW, STVEC_REGW, MTVEC_REGW; logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, UEPC_REGW, UTVEC_REGW, STVEC_REGW, MTVEC_REGW;

View File

@ -33,9 +33,7 @@ module imem (
/* verilator lint_off UNDRIVEN */ /* verilator lint_off UNDRIVEN */
logic [`XLEN-1:0] RAM[`TIMBASE>>(1+`XLEN/32):(`TIMRANGE+`TIMBASE)>>(1+`XLEN/32)]; logic [`XLEN-1:0] RAM[`TIMBASE>>(1+`XLEN/32):(`TIMRANGE+`TIMBASE)>>(1+`XLEN/32)];
`ifdef BOOTTIMBASE
logic [`XLEN-1:0] bootram[`BOOTTIMBASE>>(1+`XLEN/32):(`BOOTTIMRANGE+`BOOTTIMBASE)>>(1+`XLEN/32)]; logic [`XLEN-1:0] bootram[`BOOTTIMBASE>>(1+`XLEN/32):(`BOOTTIMRANGE+`BOOTTIMBASE)>>(1+`XLEN/32)];
`endif
/* verilator lint_on UNDRIVEN */ /* verilator lint_on UNDRIVEN */
logic [31:0] adrbits; // needs to be 32 bits to index RAM logic [31:0] adrbits; // needs to be 32 bits to index RAM
logic [`XLEN-1:0] rd; logic [`XLEN-1:0] rd;
@ -46,21 +44,13 @@ module imem (
else assign adrbits = AdrF[31:3]; else assign adrbits = AdrF[31:3];
endgenerate endgenerate
`ifndef BOOTTIMBASE
assign #2 rd = RAM[adrbits]; // word aligned
`else
assign #2 rd = (AdrF < (`TIMBASE >> 1)) ? bootram[adrbits] : RAM[adrbits]; // busybear: 2 memory options assign #2 rd = (AdrF < (`TIMBASE >> 1)) ? bootram[adrbits] : RAM[adrbits]; // busybear: 2 memory options
`endif
// hack right now for unaligned 32-bit instructions // hack right now for unaligned 32-bit instructions
// eventually this will need to cause a stall like a cache miss // eventually this will need to cause a stall like a cache miss
// when the instruction wraps around a cache line // when the instruction wraps around a cache line
// could be optimized to only stall when the instruction wrapping is 32 bits // could be optimized to only stall when the instruction wrapping is 32 bits
`ifndef BOOTTIMBASE
assign #2 rd2 = RAM[adrbits+1][15:0];
`else
assign #2 rd2 = (AdrF < (`TIMBASE >> 1)) ? bootram[adrbits+1][15:0] : RAM[adrbits+1][15:0]; //busybear: 2 memory options assign #2 rd2 = (AdrF < (`TIMBASE >> 1)) ? bootram[adrbits+1][15:0] : RAM[adrbits+1][15:0]; //busybear: 2 memory options
`endif
generate generate
if (`XLEN==32) begin if (`XLEN==32) begin
assign InstrF = AdrF[1] ? {rd2[15:0], rd[31:16]} : rd; assign InstrF = AdrF[1] ? {rd2[15:0], rd[31:16]} : rd;
@ -68,9 +58,11 @@ module imem (
end else begin end else begin
assign InstrF = AdrF[2] ? (AdrF[1] ? {rd2[15:0], rd[63:48]} : rd[63:32]) assign InstrF = AdrF[2] ? (AdrF[1] ? {rd2[15:0], rd[63:48]} : rd[63:32])
: (AdrF[1] ? rd[47:16] : rd[31:0]); : (AdrF[1] ? rd[47:16] : rd[31:0]);
`ifndef BOOTTIMBASE `ifndef BUSYBEAR
assign InstrAccessFaultF = |AdrF[`XLEN-1:32] | ~&({AdrF[31:1],1'b0} ~^ `TIMBASE | `TIMRANGE); assign InstrAccessFaultF = |AdrF[`XLEN-1:32] | ~&({AdrF[31:1],1'b0} ~^ `TIMBASE | `TIMRANGE);
`else `else
// *** this is just a hack since the logic above seems scary ***
// TODO: this should be removed when InstrAccessFaultF works with bootram also
assign InstrAccessFaultF = 0; //busybear: for now, i know we're not doing this assign InstrAccessFaultF = 0; //busybear: for now, i know we're not doing this
`endif `endif
end end

View File

@ -64,23 +64,17 @@ module uncore (
logic HSELTimD, HSELCLINTD, HSELGPIOD, HSELUARTD; logic HSELTimD, HSELCLINTD, HSELGPIOD, HSELUARTD;
logic HRESPTim, HRESPCLINT, HRESPGPIO, HRESPUART; logic HRESPTim, HRESPCLINT, HRESPGPIO, HRESPUART;
logic HREADYTim, HREADYCLINT, HREADYGPIO, HREADYUART; logic HREADYTim, HREADYCLINT, HREADYGPIO, HREADYUART;
`ifdef BOOTTIMBASE
logic [`XLEN-1:0] HREADBootTim; logic [`XLEN-1:0] HREADBootTim;
logic HSELBootTim, HSELBootTimD, HRESPBootTim, HREADYBootTim; logic HSELBootTim, HSELBootTimD, HRESPBootTim, HREADYBootTim;
logic [1:0] MemRWboottim; logic [1:0] MemRWboottim;
`endif
logic UARTIntr;// *** will need to tie INTR to an interrupt handler logic UARTIntr;// *** will need to tie INTR to an interrupt handler
// AHB Address decoder // AHB Address decoder
adrdec timdec(HADDR, `TIMBASE, `TIMRANGE, HSELTim); adrdec timdec(HADDR, `TIMBASE, `TIMRANGE, HSELTim);
`ifdef BOOTTIMBASE
adrdec boottimdec(HADDR, `BOOTTIMBASE, `BOOTTIMRANGE, HSELBootTim); adrdec boottimdec(HADDR, `BOOTTIMBASE, `BOOTTIMRANGE, HSELBootTim);
`endif
adrdec clintdec(HADDR, `CLINTBASE, `CLINTRANGE, HSELCLINT); adrdec clintdec(HADDR, `CLINTBASE, `CLINTRANGE, HSELCLINT);
`ifdef GPIOBASE
adrdec gpiodec(HADDR, `GPIOBASE, `GPIORANGE, HSELGPIO); adrdec gpiodec(HADDR, `GPIOBASE, `GPIORANGE, HSELGPIO);
`endif
adrdec uartdec(HADDR, `UARTBASE, `UARTRANGE, PreHSELUART); adrdec uartdec(HADDR, `UARTBASE, `UARTRANGE, PreHSELUART);
assign HSELUART = PreHSELUART && (HSIZE == 3'b000); // only byte writes to UART are supported assign HSELUART = PreHSELUART && (HSIZE == 3'b000); // only byte writes to UART are supported
@ -89,15 +83,11 @@ module uncore (
// tightly integrated memory // tightly integrated memory
dtim #(.BASE(`TIMBASE), .RANGE(`TIMRANGE)) dtim (.*); dtim #(.BASE(`TIMBASE), .RANGE(`TIMRANGE)) dtim (.*);
`ifdef BOOTTIMBASE
dtim #(.BASE(`BOOTTIMBASE), .RANGE(`BOOTTIMRANGE)) bootdtim(.HSELTim(HSELBootTim), .HREADTim(HREADBootTim), .HRESPTim(HRESPBootTim), .HREADYTim(HREADYBootTim), .*); dtim #(.BASE(`BOOTTIMBASE), .RANGE(`BOOTTIMRANGE)) bootdtim(.HSELTim(HSELBootTim), .HREADTim(HREADBootTim), .HRESPTim(HRESPBootTim), .HREADYTim(HREADYBootTim), .*);
`endif
// memory-mapped I/O peripherals // memory-mapped I/O peripherals
clint clint(.HADDR(HADDR[15:0]), .*); clint clint(.HADDR(HADDR[15:0]), .*);
`ifdef GPIOBASE
gpio gpio(.HADDR(HADDR[7:0]), .*); // *** may want to add GPIO interrupts gpio gpio(.HADDR(HADDR[7:0]), .*); // *** may want to add GPIO interrupts
`endif
uart uart(.HADDR(HADDR[2:0]), .TXRDYb(), .RXRDYb(), .INTR(UARTIntr), .SIN(UARTSin), .SOUT(UARTSout), uart uart(.HADDR(HADDR[2:0]), .TXRDYb(), .RXRDYb(), .INTR(UARTIntr), .SIN(UARTSin), .SOUT(UARTSout),
.DSRb(1'b1), .DCDb(1'b1), .CTSb(1'b0), .RIb(1'b1), .DSRb(1'b1), .DCDb(1'b1), .CTSb(1'b0), .RIb(1'b1),
.RTSb(), .DTRb(), .OUT1b(), .OUT2b(), .*); .RTSb(), .DTRb(), .OUT1b(), .OUT2b(), .*);
@ -105,50 +95,22 @@ module uncore (
// mux could also include external memory // mux could also include external memory
// AHB Read Multiplexer // AHB Read Multiplexer
assign HRDATA = ({`XLEN{HSELTimD}} & HREADTim) | ({`XLEN{HSELCLINTD}} & HREADCLINT) | assign HRDATA = ({`XLEN{HSELTimD}} & HREADTim) | ({`XLEN{HSELCLINTD}} & HREADCLINT) |
`ifdef GPIOBASE ({`XLEN{HSELGPIOD}} & HREADGPIO) | ({`XLEN{HSELBootTimD}} & HREADBootTim) |
({`XLEN{HSELGPIOD}} & HREADGPIO) |
`endif
`ifdef BOOTTIMBASE
({`XLEN{HSELBootTimD}} & HREADBootTim) |
`endif
({`XLEN{HSELUARTD}} & HREADUART); ({`XLEN{HSELUARTD}} & HREADUART);
assign HRESP = HSELTimD & HRESPTim | HSELCLINTD & HRESPCLINT | assign HRESP = HSELTimD & HRESPTim | HSELCLINTD & HRESPCLINT | HSELGPIOD & HRESPGPIO |
`ifdef GPIOBASE HSELBootTimD & HRESPBootTim | HSELUARTD & HRESPUART;
HSELGPIOD & HRESPGPIO | assign HREADY = HSELTimD & HREADYTim | HSELCLINTD & HREADYCLINT | HSELGPIOD & HREADYGPIO |
`endif HSELBootTimD & HREADYBootTim | HSELUARTD & HREADYUART;
`ifdef BOOTTIMBASE
HSELBootTimD & HRESPBootTim |
`endif
HSELUARTD & HRESPUART;
assign HREADY = HSELTimD & HREADYTim | HSELCLINTD & HREADYCLINT |
`ifdef GPIOBASE
HSELGPIOD & HREADYGPIO |
`endif
`ifdef BOOTTIMBASE
HSELBootTimD & HREADYBootTim |
`endif
HSELUARTD & HREADYUART;
// Faults // Faults
assign DataAccessFaultM = ~(HSELTimD | HSELCLINTD | assign DataAccessFaultM = ~(HSELTimD | HSELCLINTD | HSELGPIOD | HSELBootTimD | HSELUARTD);
`ifdef GPIOBASE
HSELGPIOD |
`endif
`ifdef BOOTTIMBASE
HSELBootTimD |
`endif
HSELUARTD);
// Address Decoder Delay (figure 4-2 in spec) // Address Decoder Delay (figure 4-2 in spec)
flopr #(1) hseltimreg(HCLK, ~HRESETn, HSELTim, HSELTimD); flopr #(1) hseltimreg(HCLK, ~HRESETn, HSELTim, HSELTimD);
flopr #(1) hselclintreg(HCLK, ~HRESETn, HSELCLINT, HSELCLINTD); flopr #(1) hselclintreg(HCLK, ~HRESETn, HSELCLINT, HSELCLINTD);
`ifdef GPIOBASE
flopr #(1) hselgpioreg(HCLK, ~HRESETn, HSELGPIO, HSELGPIOD); flopr #(1) hselgpioreg(HCLK, ~HRESETn, HSELGPIO, HSELGPIOD);
`endif
flopr #(1) hseluartreg(HCLK, ~HRESETn, HSELUART, HSELUARTD); flopr #(1) hseluartreg(HCLK, ~HRESETn, HSELUART, HSELUARTD);
`ifdef BOOTTIMBASE
flopr #(1) hselboottimreg(HCLK, ~HRESETn, HSELBootTim, HSELBootTimD); flopr #(1) hselboottimreg(HCLK, ~HRESETn, HSELBootTim, HSELBootTimD);
`endif
endmodule endmodule

View File

@ -93,11 +93,14 @@ module wallypipelinedhart (
logic ITLBMissF, ITLBHitF; logic ITLBMissF, ITLBHitF;
logic DTLBMissM, DTLBHitM; logic DTLBMissM, DTLBHitM;
logic [`XLEN-1:0] SATP_REGW; logic [`XLEN-1:0] SATP_REGW;
logic [1:0] PrivilegeModeW;
logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM; logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM;
// ICache stalls // IMem stalls
logic ICacheStallF; logic ICacheStallF;
logic [`XLEN-1:0] MMUPAdr, MMUReadPTE;
logic MMUTranslate, MMUReady;
// bus interface to dmem // bus interface to dmem
logic MemReadM, MemWriteM; logic MemReadM, MemWriteM;
@ -109,7 +112,7 @@ module wallypipelinedhart (
logic InstrReadF; logic InstrReadF;
logic DataStall, InstrStall; logic DataStall, InstrStall;
logic InstrAckD, MemAckW; logic InstrAckD, MemAckW;
logic BPPredWrongE; logic BPPredWrongE;
ifu ifu(.InstrInF(InstrRData), .*); // instruction fetch unit: PC, branch prediction, instruction cache ifu ifu(.InstrInF(InstrRData), .*); // instruction fetch unit: PC, branch prediction, instruction cache
@ -124,7 +127,7 @@ module wallypipelinedhart (
.Funct7M(InstrM[31:25]), .Funct7M(InstrM[31:25]),
.*); .*);
// walker walker(.*); *** // can send addresses to ahblite, send out pagetablestall pagetablewalker pagetablewalker(.*); // can send addresses to ahblite, send out pagetablestall
// *** can connect to hazard unit // *** can connect to hazard unit
// changing from this to the line above breaks the program. auipc at 104 fails; seems to be flushed. // changing from this to the line above breaks the program. auipc at 104 fails; seems to be flushed.
// Would need to insertinstruction as InstrD, not InstrF // Would need to insertinstruction as InstrD, not InstrF

View File

@ -101,7 +101,7 @@ module testbench_busybear();
$readmemh("/courses/e190ax/busybear_boot/ram.txt", dut.uncore.dtim.RAM); $readmemh("/courses/e190ax/busybear_boot/ram.txt", dut.uncore.dtim.RAM);
$readmemh("/courses/e190ax/busybear_boot/bootmem.txt", dut.imem.bootram, 'h1000 >> 3); $readmemh("/courses/e190ax/busybear_boot/bootmem.txt", dut.imem.bootram, 'h1000 >> 3);
$readmemh("/courses/e190ax/busybear_boot/ram.txt", dut.imem.RAM); $readmemh("/courses/e190ax/busybear_boot/ram.txt", dut.imem.RAM);
$readmemb(`TWO_BIT_PRELOAD, dut.hart.ifu.bpred.DirPredictor.memory.memory); $readmemb(`TWO_BIT_PRELOAD, dut.hart.ifu.bpred.Predictor.DirPredictor.PHT.memory);
$readmemb(`BTB_PRELOAD, dut.hart.ifu.bpred.TargetPredictor.memory.memory); $readmemb(`BTB_PRELOAD, dut.hart.ifu.bpred.TargetPredictor.memory.memory);
end end

View File

@ -48,7 +48,7 @@ module testbench();
// pick tests based on modes supported // pick tests based on modes supported
initial initial
tests = {"../../imperas-riscv-tests/riscv-ovpsim-plus/examples/CoreMark/coremark.RV64I.bare.elf.memfile", "1000"}; tests = {"../../imperas-riscv-tests/riscv-ovpsim-plus/examples/CoreMark/coremark.RV64IM.bare.elf.memfile", "1000"};
string signame, memfilename; string signame, memfilename;
logic [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn; logic [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn;
logic UARTSin, UARTSout; logic UARTSin, UARTSout;
@ -74,10 +74,10 @@ module testbench();
memfilename = tests[0]; memfilename = tests[0];
$readmemh(memfilename, dut.imem.RAM); $readmemh(memfilename, dut.imem.RAM);
$readmemh(memfilename, dut.uncore.dtim.RAM); $readmemh(memfilename, dut.uncore.dtim.RAM);
for(j=2371; j < 65535; j = j+1) for(j=268437829; j < 268566528; j = j+1)
dut.uncore.dtim.RAM[j] = 64'b0; dut.uncore.dtim.RAM[j] = 64'b0;
// ProgramAddrMapFile = "../../imperas-riscv-tests/riscv-ovpsim-plus/examples/CoreMark/coremark.RV64I.bare.elf.objdump.addr"; // ProgramAddrMapFile = "../../imperas-riscv-tests/riscv-ovpsim-plus/examples/CoreMark/coremark.RV64IM.bare.elf.objdump.addr";
// ProgramAddrMapFile = "../../imperas-riscv-tests/riscv-ovpsim-plus/examples/CoreMark/coremark.RV64I.bare.elf.objdump.lab"; // ProgramAddrMapFile = "../../imperas-riscv-tests/riscv-ovpsim-plus/examples/CoreMark/coremark.RV64IM.bare.elf.objdump.lab";
reset = 1; # 22; reset = 0; reset = 1; # 22; reset = 0;
end end
// generate clock to sequence tests // generate clock to sequence tests
@ -95,7 +95,7 @@ module testbench();
end end
initial begin initial begin
$readmemb(`TWO_BIT_PRELOAD, dut.hart.ifu.bpred.DirPredictor.memory.memory); $readmemb(`TWO_BIT_PRELOAD, dut.hart.ifu.bpred.Predictor.DirPredictor.PHT.memory);
$readmemb(`BTB_PRELOAD, dut.hart.ifu.bpred.TargetPredictor.memory.memory); $readmemb(`BTB_PRELOAD, dut.hart.ifu.bpred.TargetPredictor.memory.memory);
end end

View File

@ -483,7 +483,7 @@ string tests32i[] = {
// initialize the branch predictor // initialize the branch predictor
initial begin initial begin
$readmemb(`TWO_BIT_PRELOAD, dut.hart.ifu.bpred.DirPredictor.memory.memory); $readmemb(`TWO_BIT_PRELOAD, dut.hart.ifu.bpred.Predictor.DirPredictor.PHT.memory);
$readmemb(`BTB_PRELOAD, dut.hart.ifu.bpred.TargetPredictor.memory.memory); $readmemb(`BTB_PRELOAD, dut.hart.ifu.bpred.TargetPredictor.memory.memory);
end end

View File

@ -27,9 +27,13 @@ PTE_W = 1 << 2
PTE_R = 1 << 1 PTE_R = 1 << 1
PTE_V = 1 << 0 PTE_V = 1 << 0
PTE_PTR_MASK = ~(PTE_W | PTE_R | PTE_X)
pgdir = [] pgdir = []
pages = {}
testcase_num = 0 testcase_num = 0
signature_len = 2000 signature_len = 2000
signature = [0xff for _ in range(signature_len)] signature = [0xff for _ in range(signature_len)]
@ -41,6 +45,7 @@ class Architecture:
def __init__(self, xlen): def __init__(self, xlen):
if (xlen == 32): if (xlen == 32):
self.PTESIZE = 4 self.PTESIZE = 4
self.PTE_BITS = 32
self.VPN_BITS = 20 self.VPN_BITS = 20
self.VPN_SEGMENT_BITS = 10 self.VPN_SEGMENT_BITS = 10
@ -50,6 +55,7 @@ class Architecture:
self.LEVELS = 2 self.LEVELS = 2
elif (xlen == 64): elif (xlen == 64):
self.PTESIZE = 8 self.PTESIZE = 8
self.PTE_BITS = 54
self.VPN_BITS = 27 self.VPN_BITS = 27
self.VPN_SEGMENT_BITS = 9 self.VPN_SEGMENT_BITS = 9
@ -62,9 +68,9 @@ class Architecture:
self.PGSIZE = 2**12 self.PGSIZE = 2**12
self.NPTENTRIES = self.PGSIZE // self.PTESIZE self.NPTENTRIES = self.PGSIZE // self.PTESIZE
self.PTE_BITS = 8 * self.PTESIZE
self.OFFSET_BITS = 12 self.OFFSET_BITS = 12
self.FLAG_BITS = 8 self.FLAG_BITS = 8
self.VA_BITS = self.VPN_BITS + self.OFFSET_BITS
class PageTableEntry: class PageTableEntry:
def __init__(self, ppn, flags, arch): def __init__(self, ppn, flags, arch):
@ -85,41 +91,127 @@ class PageTableEntry:
class PageTable: class PageTable:
""" """
Represents a single level of the page table, with Represents a single level of the page table, located at some physical page
number `ppn` with symbol `name`, using a specified architecture `arch`.
""" """
def __init__(self, name, arch): def __init__(self, name, ppn, arch):
self.table = {} self.table = {}
self.name = name self.name = name
self.ppn = ppn
self.arch = arch self.arch = arch
def add_entry(self, vpn_segment, ppn_segment, flags, linked_table = None): self.children = 0
pages[ppn] = self
def add_entry(self, vpn_segment, ppn, flags):
if not (0 <= vpn_segment < 2**self.arch.VPN_SEGMENT_BITS): if not (0 <= vpn_segment < 2**self.arch.VPN_SEGMENT_BITS):
raise ValueError("Invalid virtual page segment number") raise ValueError("Invalid virtual page segment number")
self.table[vpn_segment] = (PageTableEntry(ppn_segment, flags, self.arch), linked_table) self.table[vpn_segment] = PageTableEntry(ppn, flags, self.arch)
def add_mapping(self, va, pa, flags): def add_mapping(self, va, pa, flags):
if not (0 <= va < 2**self.arch.VPN_BITS): """
Maps a virtual address `va` to a physical address `pa` with given `flags`,
creating missing page table levels as needed.
"""
if not (0 <= va < 2**self.arch.VA_BITS):
raise ValueError("Invalid virtual page number") raise ValueError("Invalid virtual page number")
vpn = virtual_to_vpn(va, self.arch)
ppn = pa >> self.arch.OFFSET_BITS
current_level = self
pathname = self.name
for level in range(self.arch.LEVELS - 1, -1, -1): for level in range(self.arch.LEVELS - 1, -1, -1):
if level == 0:
current_level.add_entry(vpn[level], ppn, flags)
elif vpn[level] in current_level.table:
current_level = pages[current_level.table[vpn[level]].ppn]
pathname += f"_{current_level.name}"
else:
next_level_ppn = next_ppn()
current_level.add_entry(vpn[level], next_level_ppn, flags & PTE_PTR_MASK)
pathname += f"_t{current_level.children}"
current_level.children += 1
pages[next_level_ppn] = PageTable(pathname, next_level_ppn, self.arch)
current_level = pages[next_level_ppn]
def assembly(self): def assembly(self):
# Sort the page table
entries = list(sorted(self.table.items(), key=lambda item: item[0])) entries = list(sorted(self.table.items(), key=lambda item: item[0]))
current_index = 0 current_index = 0
# Align the table
asm = f".balign {self.arch.PGSIZE}\n{self.name}:\n" asm = f".balign {self.arch.PGSIZE}\n{self.name}:\n"
for entry in entries: for entry in entries:
vpn_index, (pte, _) = entry vpn_index, pte = entry
if current_index < vpn_index: if current_index < vpn_index:
asm += f" .fill {vpn_index - current_index}, {self.arch.PTESIZE}, 0\n" asm += f" .fill {vpn_index - current_index}, {self.arch.PTESIZE}, 0\n"
asm += f" .4byte {str(pte)}\n" asm += f" .{self.arch.PTESIZE}byte {str(pte)}\n"
current_index = vpn_index + 1 current_index = vpn_index + 1
if current_index < self.arch.NPTENTRIES: if current_index < self.arch.NPTENTRIES:
asm += f" .fill {self.arch.NPTENTRIES - current_index}, {self.arch.PTESIZE}, 0\n" asm += f" .fill {self.arch.NPTENTRIES - current_index}, {self.arch.PTESIZE}, 0\n"
return asm return asm
def __str__(self):
return self.assembly()
def __repr__(self):
return f"<table: {self.table}>"
################################## ##################################
# functions # functions
################################## ##################################
def virtual_to_vpn(vaddr, arch):
if not (0 <= vaddr < 2**arch.VA_BITS):
raise ValueError("Invalid physical address")
page_number = [0 for _ in range(arch.LEVELS)]
vaddr = vaddr >> arch.OFFSET_BITS
mask = 2**arch.VPN_SEGMENT_BITS - 1
for level in range(arch.LEVELS):
page_number[level] = vaddr & mask
vaddr = vaddr >> arch.VPN_SEGMENT_BITS
return page_number
INITIAL_PPN = 0x80002
next_free_ppn = INITIAL_PPN
def next_ppn():
global next_free_ppn
ppn = next_free_ppn
next_free_ppn += 1
return ppn
def print_pages():
for page in pages:
print(pages[page])
##################################
# helper variables
##################################
rv32 = Architecture(32)
rv64 = Architecture(64)
if __name__ == "__main__":
arch = rv64
pgdir = PageTable("page_directory", next_ppn(), arch)
# Directly map the first 20 pages of RAM
for page in range(20):
vaddr = 0x80000000 + (arch.PGSIZE * page)
paddr = 0x80000000 + (arch.PGSIZE * page)
pgdir.add_mapping(vaddr, paddr, PTE_R | PTE_W | PTE_U | PTE_X | PTE_V)
"""
supervisor_pgdir = PageTable("sdir", next_ppn(), rv64)
supervisor_pgdir.add_mapping(0x80000000, 0x80000000, PTE_R | PTE_W | PTE_X)
supervisor_pgdir.add_mapping(0x80000001, 0x80000001, PTE_R | PTE_W | PTE_X)
supervisor_pgdir.add_mapping(0x80001000, 0x80000000, PTE_R | PTE_W | PTE_X)
supervisor_pgdir.add_mapping(0xffff0000, 0x80000000, PTE_R | PTE_W | PTE_X)
"""
print_pages()