diff --git a/wally-pipelined/config/buildroot/wally-config.vh b/wally-pipelined/config/buildroot/wally-config.vh
index cb59bb69e..3a834ab09 100644
--- a/wally-pipelined/config/buildroot/wally-config.vh
+++ b/wally-pipelined/config/buildroot/wally-config.vh
@@ -46,7 +46,7 @@
 `define MEM_DCACHE 0
 `define MEM_DTIM 1
 `define MEM_ICACHE 0
-`define MEM_VIRTMEM 0
+`define MEM_VIRTMEM 1
 `define VECTORED_INTERRUPTS_SUPPORTED 1 // Domenico Ottolia 4/15: Support for vectored interrupts in _tvec csrs. Just implemented in src/privileged/trap.sv around line 75. Pretty sure this should be 1.
 
 `define ITLB_ENTRIES 32
diff --git a/wally-pipelined/config/busybear/wally-config.vh b/wally-pipelined/config/busybear/wally-config.vh
index 26e37fa6c..d38228634 100644
--- a/wally-pipelined/config/busybear/wally-config.vh
+++ b/wally-pipelined/config/busybear/wally-config.vh
@@ -47,7 +47,7 @@
 `define MEM_DCACHE 0
 `define MEM_DTIM 1
 `define MEM_ICACHE 0
-`define MEM_VIRTMEM 0
+`define MEM_VIRTMEM 1
 `define VECTORED_INTERRUPTS_SUPPORTED 1 // Domenico Ottolia 4/15: Support for vectored interrupts in _tvec csrs. Just implemented in src/privileged/trap.sv around line 75. Pretty sure this should be 1.
 
 `define ITLB_ENTRIES 32
diff --git a/wally-pipelined/config/rv64imc/wally-config.vh b/wally-pipelined/config/rv64imc/wally-config.vh
index a554a612b..925e98659 100644
--- a/wally-pipelined/config/rv64imc/wally-config.vh
+++ b/wally-pipelined/config/rv64imc/wally-config.vh
@@ -45,7 +45,7 @@
 `define MEM_DCACHE 0
 `define MEM_DTIM 1
 `define MEM_ICACHE 0
-`define MEM_VIRTMEM 0
+`define MEM_VIRTMEM 1
 `define VECTORED_INTERRUPTS_SUPPORTED 1
 
 `define ITLB_ENTRIES 32
diff --git a/wally-pipelined/src/mmu/mmu.sv b/wally-pipelined/src/mmu/mmu.sv
index 4faac7bc1..288fb9314 100644
--- a/wally-pipelined/src/mmu/mmu.sv
+++ b/wally-pipelined/src/mmu/mmu.sv
@@ -81,8 +81,20 @@ module mmu #(parameter TLB_ENTRIES = 8, // nuber of TLB Entries
   logic Cacheable, Idempotent, AtomicAllowed; // *** here so that the pmachecker has somewhere to put these outputs. *** I'm leaving them as outputs to pma checker, but I'm stopping them here.
   // Translation lookaside buffer
 
-  tlb #(.TLB_ENTRIES(TLB_ENTRIES), .ITLB(IMMU)) tlb(.*);
-
+  // only instantiate TLB if Virtual Memory is supported
+  generate
+    if (`MEM_VIRTMEM)
+      tlb #(.TLB_ENTRIES(TLB_ENTRIES), .ITLB(IMMU)) tlb(.*);
+    else begin // just pass address through as physical
+      logic [`XLEN+1:0]     VAExt;
+      assign VAExt = {2'b00, VirtualAddress}; // extend length of virtual address if necessary for RV32
+      assign PhysicalAddress = VAExt[`PA_BITS-1:0];
+      assign TLBMiss = 0;
+      assign TLBHit = 1;
+      assign TLBPageFault = 0;
+     end
+  endgenerate
+  
   ///////////////////////////////////////////
   // Check physical memory accesses
   ///////////////////////////////////////////
diff --git a/wally-pipelined/src/privileged/csr.sv b/wally-pipelined/src/privileged/csr.sv
index 7162263c2..48e4f4ef0 100644
--- a/wally-pipelined/src/privileged/csr.sv
+++ b/wally-pipelined/src/privileged/csr.sv
@@ -76,6 +76,7 @@ module csr #(parameter
   logic [31:0]     MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW;
   logic            WriteMSTATUSM, WriteSSTATUSM, WriteUSTATUSM;
   logic            CSRMWriteM, CSRSWriteM, CSRUWriteM;
+  logic            STATUS_TVM;
 
   logic [`XLEN-1:0] UnalignedNextEPCM, NextEPCM, NextCauseM, NextMtvalM;
 
@@ -109,7 +110,7 @@ module csr #(parameter
       assign NextCauseM = TrapM ? CauseM : CSRWriteValM;
       assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValM;
       assign CSRMWriteM = CSRWriteM && (PrivilegeModeW == `M_MODE);
-      assign CSRSWriteM = CSRWriteM && (PrivilegeModeW[0]);
+      assign CSRSWriteM = CSRWriteM && (|PrivilegeModeW);
       assign CSRUWriteM = CSRWriteM;  
 
       csri  csri(.*);
diff --git a/wally-pipelined/src/privileged/csrs.sv b/wally-pipelined/src/privileged/csrs.sv
index ca64b053a..5a6fb96f1 100644
--- a/wally-pipelined/src/privileged/csrs.sv
+++ b/wally-pipelined/src/privileged/csrs.sv
@@ -51,7 +51,9 @@ module csrs #(parameter
     input  logic             CSRSWriteM, STrapM,
     input  logic [11:0]      CSRAdrM,
     input  logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, SSTATUS_REGW, 
+    input  logic             STATUS_TVM,
     input  logic [`XLEN-1:0] CSRWriteValM,
+    input  logic [1:0]       PrivilegeModeW,
     output logic [`XLEN-1:0] CSRSReadValM, SEPC_REGW, STVEC_REGW, 
     output logic [31:0]      SCOUNTEREN_REGW,     
     output logic [`XLEN-1:0]      SEDELEG_REGW, SIDELEG_REGW, 
@@ -79,7 +81,7 @@ module csrs #(parameter
       assign WriteSEPCM = STrapM | (CSRSWriteM && (CSRAdrM == SEPC)) && ~StallW;
       assign WriteSCAUSEM = STrapM | (CSRSWriteM && (CSRAdrM == SCAUSE)) && ~StallW;
       assign WriteSTVALM = STrapM | (CSRSWriteM && (CSRAdrM == STVAL)) && ~StallW;
-      assign WriteSATPM = CSRSWriteM && (CSRAdrM == SATP) && ~StallW;
+      assign WriteSATPM = CSRSWriteM && (CSRAdrM == SATP) && (PrivilegeModeW == `M_MODE || ~STATUS_TVM) && ~StallW;
       assign WriteSCOUNTERENM = CSRSWriteM && (CSRAdrM == SCOUNTEREN) && ~StallW;
 
       // CSRs
@@ -88,7 +90,10 @@ module csrs #(parameter
       flopenr #(`XLEN) SEPCreg(clk, reset, WriteSEPCM, NextEPCM, SEPC_REGW); 
       flopenl #(`XLEN) SCAUSEreg(clk, reset, WriteSCAUSEM, NextCauseM, `XLEN'b0, SCAUSE_REGW); 
       flopenr #(`XLEN) STVALreg(clk, reset, WriteSTVALM, NextMtvalM, STVAL_REGW);
-      flopenr #(`XLEN) SATPreg(clk, reset, WriteSATPM, CSRWriteValM, SATP_REGW);
+      if (`MEM_VIRTMEM)
+        flopenr #(`XLEN) SATPreg(clk, reset, WriteSATPM, CSRWriteValM, SATP_REGW);
+      else
+        assign SATP_REGW = 0;
       if (`BUSYBEAR == 1)
         flopenl #(32)   SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, {CSRWriteValM[31:2],1'b0,CSRWriteValM[0]}, 32'b0, SCOUNTEREN_REGW);
       else if (`BUILDROOT == 1)
@@ -122,7 +127,11 @@ module csrs #(parameter
           SEPC:      CSRSReadValM = SEPC_REGW;
           SCAUSE:    CSRSReadValM = SCAUSE_REGW;
           STVAL:     CSRSReadValM = STVAL_REGW;
-          SATP:      CSRSReadValM = SATP_REGW;
+          SATP:      if (`MEM_VIRTMEM && (PrivilegeModeW == `M_MODE || ~STATUS_TVM)) CSRSReadValM = SATP_REGW;
+                     else begin
+                       CSRSReadValM = 0;
+                       IllegalCSRSAccessM = 1;
+                     end
           SCOUNTEREN:CSRSReadValM = {{(`XLEN-32){1'b0}}, SCOUNTEREN_REGW};
           default: begin
                      CSRSReadValM = 0; 
diff --git a/wally-pipelined/src/privileged/csrsr.sv b/wally-pipelined/src/privileged/csrsr.sv
index 0b36df491..b02baeb98 100644
--- a/wally-pipelined/src/privileged/csrsr.sv
+++ b/wally-pipelined/src/privileged/csrsr.sv
@@ -38,10 +38,10 @@ module csrsr (
   output logic             STATUS_SPP, STATUS_TSR,
   output logic             STATUS_MIE, STATUS_SIE,
   output logic             STATUS_MXR, STATUS_SUM,
-  output logic             STATUS_MPRV
+  output logic             STATUS_MPRV, STATUS_TVM
 );
 
-  logic STATUS_SD, STATUS_TW, STATUS_TVM, STATUS_SUM_INT, STATUS_MPRV_INT;
+  logic STATUS_SD, STATUS_TW, STATUS_SUM_INT, STATUS_MPRV_INT;
   logic [1:0] STATUS_SXL, STATUS_UXL, STATUS_XS, STATUS_FS, STATUS_FS_INT, STATUS_MPP_NEXT;
   logic STATUS_MPIE, STATUS_SPIE, STATUS_UPIE, STATUS_UIE;
 
@@ -96,7 +96,7 @@ module csrsr (
   assign STATUS_SD = (STATUS_FS == 2'b11) || (STATUS_XS == 2'b11); // dirty state logic
   assign STATUS_TSR = 0; // Trap SRET not supported; revisit whether this is necessary for an OS
   assign STATUS_TW = 0; // Timeout Wait not supported
-  assign STATUS_TVM = 0; // Trap Virtual Memory not supported (revisit if supporting virtualizations)
+  assign STATUS_TVM = 0; // Trap Virtual Memory not supported (revisit if supporting virtualizations, but hooks in place for it in satp)
   assign STATUS_MXR = 0; // Make Executable Readable (may need to add support for VM later)
   assign STATUS_XS = 2'b00; // No additional user-mode state to be dirty