mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge changes from main
This commit is contained in:
commit
279c09b27c
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
143
wally-pipelined/src/ebu/pagetablewalker.sv
Normal file
143
wally-pipelined/src/ebu/pagetablewalker.sv
Normal 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
|
@ -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
|
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
|
109
wally-pipelined/src/ifu/globalHistoryPredictor.sv
Normal file
109
wally-pipelined/src/ifu/globalHistoryPredictor.sv
Normal 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
|
109
wally-pipelined/src/ifu/gshare.sv
Normal file
109
wally-pipelined/src/ifu/gshare.sv
Normal 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
|
@ -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
|
||||||
|
|
||||||
|
@ -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) (
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
Loading…
Reference in New Issue
Block a user