diff --git a/wally-pipelined/testgen/privileged/testgen-IE.py b/wally-pipelined/testgen/privileged/testgen-IE.py
new file mode 100644
index 000000000..5195006ee
--- /dev/null
+++ b/wally-pipelined/testgen/privileged/testgen-IE.py
@@ -0,0 +1,225 @@
+#!/usr/bin/python3
+##################################
+# testgen-IE.py
+#
+# ushakya@hmc.edu 24 Mar 2021
+#
+# Generate tests for mie CSR for RISC-V Design Validation.
+##################################
+
+##################################
+# libraries
+##################################
+from datetime import datetime
+from random import randint 
+from random import seed
+from enum import Enum
+from random import getrandbits
+
+##################################
+# functions
+##################################
+
+def randRegs():
+  reg1 = randint(1,30)
+  reg2 = randint(1,30)
+  reg3 = randint(1,30)
+  if (reg1 == 6 or reg2 == 6 or reg3 == 6 or reg1 == reg2):
+    return randRegs()
+  else:
+      return reg1, reg2, reg3
+
+def writeVectors(storecmd):  
+  global testnum
+  reg1, reg2, reg3 = randRegs()
+
+  # Set interupt enable bit in mstatus
+  lines = """
+  li x2, 0x8
+  csrrs x3, mstatus, x2
+  """
+
+  f.write(lines)
+
+ # Save and set trap handler address for machine mode timer interrupt
+  lines += """
+  la x1, _timer_trap_handler
+  csrrw x31, mtvec, x1
+  """
+  f.write(lines)
+
+  # Machine Mode Timer Interrupt (when interupt is enabled)
+  # is this not working because mtimecmp isn't implemented????
+  write(f"""
+    li x2, 0x0
+
+    li x4, 0x80
+    csrrs x0, mie, x4
+
+    {storecmd} x2, {str(wordsize*testnum)}(x6)
+
+    la x2, 0x2004000
+    
+    li x3, 0x0
+    lw x5, 0(x2)
+    sd x3, 0(x2)
+    wfi
+  """, storecmd, True, 4, "m")
+
+  # Supervisor Timer Interrupt
+  # user timer interupt
+
+  # Machine mode external interrupt (hasn't been connected yet)
+
+  # User external interrupt True, 8
+  # Supervisor external interrupt True, 9
+
+  # Save and set trap handler address for machine mode software interrupt
+ # lines = """
+ # la x1, _interupt_trap_handler
+ # csrrw x31, mtvec, x1
+ # """
+ # f.write(lines)
+ 
+  # Machine Mode software interupt (write to the CLINT)
+  #write(f"""
+  #  li x6, 0x0
+#
+#    li x4, 0x8
+#    csrrs x0, mie, x4
+#    
+#    li x3, 0x1
+#    lw x4, clint
+#    or x3, x4, x3
+#    {storecmd} x3, clint
+#  """, storecmd, True, 3, "m")
+
+  # supervisor mode software interupt
+  # user mode software interupt
+  
+  # timer interupt trap handler
+  lines = f"""
+  _timer_trap_handler:
+  li x2, 0x2A
+  {storecmd} x2, {str(wordsize*testnum)}(x6)
+  la x3, 0x2004000
+  {storecmd} x2, 0(x3)
+  mret
+  """
+
+  # software interupt trap handler
+  #lines += f"""
+  #_interupt_trap_handler:
+  #li x6, 0x2A
+  #li x3, 0x0
+  #lw x4, clint
+  #xor x3, x4, x3
+  #{storecmd} x3, 0(clint)
+ #mret
+  #"""
+  lines += storecmd + " x" + str(reg3) + ", " + str(wordsize*testnum) + "(x6)\n"
+
+  f.write(lines)
+
+def write(lines, storecmd, interrupt, code, mode = "m"):
+  global testnum
+
+  # generate expected interrupt code
+  expected = 0
+  #(0 if not interrupt else (2**31 if xlen == 32 else 2**63)) + code
+  # go back and fix expected
+
+  lines = f"""
+    # Testcase {testnum}
+    li x31, 0
+    {lines}
+
+    {storecmd} x31, {str(wordsize*testnum)}(x6)
+    # RVTEST_IO_ASSERT_GPR_EQ(x0, 0, {formatstr.format(expected)})
+  """
+
+  #if mode == "s":
+    # go to supervisor mode
+  #elif mode == "u":
+    # go to user mode
+
+  f.write(lines)
+
+  if (xlen == 32):
+    line = formatrefstr.format(expected)+"\n"
+  else:
+    line = formatrefstr.format(expected % 2**32)+"\n" + formatrefstr.format(expected >> 32) + "\n"
+  r.write(line)
+  testnum = testnum+1
+
+##################################
+# main body
+##################################
+
+# name: (interrupt?, code)
+# tests = {
+#  'User software interrupt': (1, '0'),
+#  'Supervisor software interrupt': (1, '1'),
+#  'Machine software interrupt': (1, '3'),
+#  'User timer interrupt': (1, '4'),
+#  'Supervisor timer interrupt': (1, '5'),
+#  'Machine timer interrupt': (1, '7'),
+#  'User external interrupt': (1, '8'),
+#  'Supervisor external interrupt': (1, '9'),
+#  'Machine external interrupt': (1, '11'),
+# }
+author = "Udeema Shakya (ushakya@hmc.edu)"
+xlens = [64, 32]
+numrand = 60;
+
+# setup
+seed(0xC395DDEB9173AD42) # make tests reproducible
+
+# generate files for each test
+for xlen in xlens:
+  formatstrlen = str(int(xlen/4))
+  formatstr = "0x{:0" + formatstrlen + "x}" # format as xlen-bit hexadecimal number
+  formatrefstr = "{:08x}" # format as xlen-bit hexadecimal number with no leading 0x
+  if (xlen == 32):
+    storecmd = "sw"
+    wordsize = 4
+  else:
+    storecmd = "sd"
+    wordsize = 8
+
+  imperaspath = f"""../../../imperas-riscv-tests/riscv-test-suite/rv{xlen}p/"""
+  basename = "WALLY-IE"
+  fname = imperaspath + "src/" + basename + ".S"
+  refname = imperaspath + "references/" + basename + ".reference_output"
+  testnum = 0
+
+  # print custom header part
+  f = open(fname, "w")
+  r = open(refname, "w")
+  line = "///////////////////////////////////////////\n"
+  f.write(line)
+  lines="// "+fname+ "\n// " + author + "\n"
+  f.write(lines)
+  line ="// Created " + str(datetime.now()) 
+  f.write(line)
+
+  # insert generic header
+  h = open("../testgen_header.S", "r")
+  for line in h:  
+    f.write(line)
+
+  # print directed and random test vectors
+  writeVectors(storecmd)
+
+
+  # print footer
+  h = open("../testgen_footer.S", "r")
+  for line in h:  
+    f.write(line)
+
+  # Finish
+  lines = ".fill " + str(testnum) + ", " + str(wordsize) + ", -1\n"
+  lines = lines + "\nRV_COMPLIANCE_DATA_END\n" 
+   f.write(lines)
+  f.close()
+  r.close()