[sw] Move device code into sw/device folder

This change addresses issue #27. All device code is being moved to the
`sw/device` folder. Makefiles and Meson build files had been updated to
support the new directory structure.

Documentation, and top level and DV dependencies have been updated as
well.

Manual tests:

* ci/run_sw_build.sh
* ./meson_init.sh && ninja -C build-fpga && ninja -C build-verilator
diff --git a/ci/run_sw_build.sh b/ci/run_sw_build.sh
index 63f19a2..e94a36f 100755
--- a/ci/run_sw_build.sh
+++ b/ci/run_sw_build.sh
@@ -38,7 +38,7 @@
 PASS_TARGETS=()
 for target in "${BUILD_TARGETS[@]}"; do
   echo "Building target ${target}"
-  if make -C sw "SW_DIR=${target}" "SW_BUILD_DIR=build/${target}"; then
+  if make -C sw "SW_DIR=device/${target}" "SW_BUILD_DIR=build/${target}"; then
     PASS_TARGETS=("${PASS_TARGETS[@]}" "${target}")
   else
     FAIL_TARGETS=("${FAIL_TARGETS[@]}" "${target}")
diff --git a/doc/ug/getting_started_fpga.md b/doc/ug/getting_started_fpga.md
index 83e13f3..c7562dd 100644
--- a/doc/ug/getting_started_fpga.md
+++ b/doc/ug/getting_started_fpga.md
@@ -22,7 +22,7 @@
 Synthesizing a design for a FPGA board is done with the following commands.
 
 The FPGA build will pull in a program to act as the boot ROM.
-This is pulled in from the `sw/boot_rom` directory (see the `parameters:` section of the `hw/top_earlgrey/top_earlgrey_nexysvideo.core` file).
+This is pulled in from the `sw/device/boot_rom` directory (see the `parameters:` section of the `hw/top_earlgrey/top_earlgrey_nexysvideo.core` file).
 At the moment there is no check that the `rom.vmem` file is up to date, so it is best to follow the instructions to [Build software](getting_started_sw.md) and understand the FPGA's overall software flow
 
 In the following example we synthesize the Earl Grey design for the Nexys Video board using Xilinx Vivado 2018.3.
@@ -157,7 +157,7 @@
 
 ```console
 $ cd $REPO_TOP
-$ riscv32-unknown-elf-gdb -ex "target extended-remote :3333" -ex "info reg" sw/boot_rom/boot_rom.elf
+$ riscv32-unknown-elf-gdb -ex "target extended-remote :3333" -ex "info reg" sw/device/boot_rom/boot_rom.elf
 ```
 
 #### Common operations with GDB
@@ -190,7 +190,7 @@
 It is especially useful in the context of our `boot_rom.elf`, which resides in the ROM region, which will eventually jump to a different executable as part of the flash region.
 
 ```console
-(gdb) file sw/examples/hello_world/hello_world.elf
+(gdb) file sw/device/examples/hello_world/hello_world.elf
 (gdb) disassemble 0x200005c0,0x200005c0+16*4
 ```
 
diff --git a/doc/ug/getting_started_verilator.md b/doc/ug/getting_started_verilator.md
index 0d503af..1831e65 100644
--- a/doc/ug/getting_started_verilator.md
+++ b/doc/ug/getting_started_verilator.md
@@ -184,6 +184,6 @@
 
 ```console
 $ cd $REPO_TOP
-$ build/lowrisc_systems_top_earlgrey_verilator_0.1/sim-verilator/Vtop_earlgrey_verilator --meminit=sw/examples/hello_world/hello_world.vmem --trace
+$ build/lowrisc_systems_top_earlgrey_verilator_0.1/sim-verilator/Vtop_earlgrey_verilator --meminit=sw/device/examples/hello_world/hello_world.vmem --trace
 $ gtkwave sim.fst
 ```
diff --git a/doc/ug/quickstart.md b/doc/ug/quickstart.md
index cf47c78..90cdacd 100644
--- a/doc/ug/quickstart.md
+++ b/doc/ug/quickstart.md
@@ -11,10 +11,10 @@
 ```console
 $ cd $REPO_TOP
 $ fusesoc --cores-root . run --target=sim --setup --build lowrisc:systems:top_earlgrey_verilator
-$ make SIM=1 -C sw/boot_rom clean all
-$ make SIM=1 -C sw/examples/hello_world clean all
-$ build/lowrisc_systems_top_earlgrey_verilator_0.1/sim-verilator/Vtop_earlgrey_verilator --rominit=sw/boot_rom/boot_rom.vmem \
-$ --flashinit=sw/examples/hello_world/hello_world.vmem
+$ make SIM=1 -C sw/device/boot_rom clean all
+$ make SIM=1 -C sw/device/examples/hello_world clean all
+$ build/lowrisc_systems_top_earlgrey_verilator_0.1/sim-verilator/Vtop_earlgrey_verilator --rominit=sw/device/boot_rom/boot_rom.vmem \
+$ --flashinit=sw/device/examples/hello_world/hello_world.vmem
 ```
 
 See the [Getting Started with Verilator Guide](getting_started_verilator.md) for more information.
diff --git a/hw/dv/tools/rules.mk b/hw/dv/tools/rules.mk
index bed89c2..b6e6454 100644
--- a/hw/dv/tools/rules.mk
+++ b/hw/dv/tools/rules.mk
@@ -49,7 +49,7 @@
 	rm -rf ${SW_BUILD_DIR}
 	mkdir -p ${SW_BUILD_DIR}
 	$(MAKE) -C $(SW_ROOT_DIR) \
-	  SW_DIR=boot_rom \
+	  SW_DIR=device/boot_rom \
 	  SW_BUILD_DIR=$(SW_BUILD_DIR)/rom \
 	  MAKEFLAGS="$(SW_OPTS)"
 	$(MAKE) -C $(SW_ROOT_DIR) \
diff --git a/hw/top_earlgrey/dv/Makefile b/hw/top_earlgrey/dv/Makefile
index fb166e8..09f49fd 100644
--- a/hw/top_earlgrey/dv/Makefile
+++ b/hw/top_earlgrey/dv/Makefile
@@ -27,30 +27,30 @@
 UVM_TEST_SEQ    ?= chip_base_vseq
 
 ifeq (${TEST_NAME},chip_sanity)
-  SW_DIR         = examples/hello_world
+  SW_DIR         = device/examples/hello_world
   SW_NAME        = hello_world
 endif
 
 ifeq (${TEST_NAME},chip_flash_test)
-  SW_DIR         = tests/flash_ctrl
+  SW_DIR         = device/tests/flash_ctrl
   SW_NAME        = flash_test
   RUN_OPTS      += +cpu_test_timeout_ns=15000000
 endif
 
 ifeq (${TEST_NAME},chip_sha256_test)
-  SW_DIR         = tests/hmac
+  SW_DIR         = device/tests/hmac
   SW_NAME        = sha256_test
   RUN_OPTS      += +cpu_test_timeout_ns=4000000
 endif
 
 ifeq (${TEST_NAME},chip_rv_timer_test)
-  SW_DIR         = tests/rv_timer
+  SW_DIR         = device/tests/rv_timer
   SW_NAME        = rv_timer_test
   RUN_OPTS      += +cpu_test_timeout_ns=4000000
 endif
 
 ifeq (${TEST_NAME},coremark)
-  SW_DIR           = benchmarks/coremark
+  SW_DIR           = device/benchmarks/coremark
   SW_NAME          = coremark
   RUN_OPTS        += +cpu_test_timeout_ns=20000000
   SW_OPTS         += ITERATIONS=1
diff --git a/hw/top_earlgrey/top_earlgrey_artys7-50.core b/hw/top_earlgrey/top_earlgrey_artys7-50.core
index 9864d41..64e1631 100644
--- a/hw/top_earlgrey/top_earlgrey_artys7-50.core
+++ b/hw/top_earlgrey/top_earlgrey_artys7-50.core
@@ -21,14 +21,14 @@
 parameters:
   # XXX: This parameter needs to be absolute, or relative to the *.runs/synth_1
   # directory. It's best to pass it as absolute path when invoking fusesoc, e.g.
-  # --SRAM_INIT_FILE=$PWD/sw/examples/hello_world/hello_world.vmem
+  # --SRAM_INIT_FILE=$PWD/sw/device/examples/hello_world/hello_world.vmem
   # XXX: The VMEM file should be added to the sources of the Vivado project to
   # make the Vivado dependency tracking work. However this requires changes to
   # fusesoc first.
   SRAM_INIT_FILE:
     datatype: str
     description: SRAM initialization file in vmem hex format
-    default: "../../../../../sw/examples/hello_world/hello_world.vmem"
+    default: "../../../../../sw/device/examples/hello_world/hello_world.vmem"
     paramtype: vlogdefine
   # For value definition, please see ip/prim/rtl/prim_pkg.sv
   PRIM_DEFAULT_IMPL:
diff --git a/hw/top_earlgrey/top_earlgrey_nexysvideo.core b/hw/top_earlgrey/top_earlgrey_nexysvideo.core
index f0e5ca6..2c6eb6c 100644
--- a/hw/top_earlgrey/top_earlgrey_nexysvideo.core
+++ b/hw/top_earlgrey/top_earlgrey_nexysvideo.core
@@ -29,14 +29,14 @@
 parameters:
   # XXX: This parameter needs to be absolute, or relative to the *.runs/synth_1
   # directory. It's best to pass it as absolute path when invoking fusesoc, e.g.
-  # --SRAM_INIT_FILE=$PWD/sw/examples/hello_world/hello_world.vmem
+  # --SRAM_INIT_FILE=$PWD/sw/device/examples/hello_world/hello_world.vmem
   # XXX: The VMEM file should be added to the sources of the Vivado project to
   # make the Vivado dependency tracking work. However this requires changes to
   # fusesoc first.
   ROM_INIT_FILE:
     datatype: str
     description: SRAM initialization file in vmem hex format
-    default: "../../../../../sw/boot_rom/rom.vmem"
+    default: "../../../../../sw/device/boot_rom/rom.vmem"
     paramtype: vlogdefine
   # For value definition, please see ip/prim/rtl/prim_pkg.sv
   PRIM_DEFAULT_IMPL:
diff --git a/hw/top_earlgrey/top_earlgrey_usb_nexysvideo.core b/hw/top_earlgrey/top_earlgrey_usb_nexysvideo.core
index edbc907..49aaff9 100644
--- a/hw/top_earlgrey/top_earlgrey_usb_nexysvideo.core
+++ b/hw/top_earlgrey/top_earlgrey_usb_nexysvideo.core
@@ -21,14 +21,14 @@
 parameters:
   # XXX: This parameter needs to be absolute, or relative to the *.runs/synth_1
   # directory. It's best to pass it as absolute path when invoking fusesoc, e.g.
-  # --SRAM_INIT_FILE=$PWD/sw/examples/hello_world/hello_world.vmem
+  # --SRAM_INIT_FILE=$PWD/sw/device/examples/hello_world/hello_world.vmem
   # XXX: The VMEM file should be added to the sources of the Vivado project to
   # make the Vivado dependency tracking work. However this requires changes to
   # fusesoc first.
   SRAM_INIT_FILE:
     datatype: str
     description: SRAM initialization file in vmem hex format
-    default: "../../../../../sw/examples/hello_usbdev/hello_usbdev.vmem"
+    default: "../../../../../sw/device/examples/hello_usbdev/hello_usbdev.vmem"
     paramtype: vlogdefine
   PRIM_DEFAULT_IMPL:
     datatype: str
diff --git a/meson.build b/meson.build
index ef32c46..1df4b00 100644
--- a/meson.build
+++ b/meson.build
@@ -46,12 +46,12 @@
 prog_git = find_program('git')
 
 # RISCV linker parameters.
-riscv_linkfile = files(['sw/exts/common/link.ld'])
+riscv_linkfile = files(['sw/device/exts/common/link.ld'])
 riscv_link_args = ['-Wl,-T,@0@/@1@'.format('..', riscv_linkfile[0])]
 riscv_link_deps = [riscv_linkfile]
 
 # RISCV CRT parameters
-startup_files = files(['sw/exts/common/_crt.c'])
+startup_files = files(['sw/device/exts/common/_crt.c'])
 
 # Additional arguments for utility in charge of generating bin and vmem outputs
 # These variables are expected to be used in custom_target rules.
diff --git a/sw/Makefile b/sw/Makefile
index 57d0b31..1c55359 100644
--- a/sw/Makefile
+++ b/sw/Makefile
@@ -24,13 +24,13 @@
 
 # Generate a baremetal application for the microcontroller
 SW_ROOT_DIR   := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
-SW_DIR        ?= examples/hello_world
+SW_DIR        ?= device/examples/hello_world
 
 # sources
 STANDALONE_SW ?= 0
 include ${SW_DIR}/srcs.mk
-include exts/common/srcs.mk
-include lib/srcs.mk
+include device/exts/common/srcs.mk
+include device/lib/srcs.mk
 
 # common options and rules
 include opts.mk
diff --git a/sw/benchmarks/coremark/README.md b/sw/device/benchmarks/coremark/README.md
similarity index 100%
rename from sw/benchmarks/coremark/README.md
rename to sw/device/benchmarks/coremark/README.md
diff --git a/sw/benchmarks/coremark/srcs.mk b/sw/device/benchmarks/coremark/srcs.mk
similarity index 100%
rename from sw/benchmarks/coremark/srcs.mk
rename to sw/device/benchmarks/coremark/srcs.mk
diff --git a/sw/benchmarks/coremark/top_earlgrey/core_portme.c b/sw/device/benchmarks/coremark/top_earlgrey/core_portme.c
similarity index 100%
rename from sw/benchmarks/coremark/top_earlgrey/core_portme.c
rename to sw/device/benchmarks/coremark/top_earlgrey/core_portme.c
diff --git a/sw/benchmarks/coremark/top_earlgrey/core_portme.h b/sw/device/benchmarks/coremark/top_earlgrey/core_portme.h
similarity index 98%
rename from sw/benchmarks/coremark/top_earlgrey/core_portme.h
rename to sw/device/benchmarks/coremark/top_earlgrey/core_portme.h
index 2ddaf8f..caa9dc1 100644
--- a/sw/benchmarks/coremark/top_earlgrey/core_portme.h
+++ b/sw/device/benchmarks/coremark/top_earlgrey/core_portme.h
@@ -14,8 +14,8 @@
 
 #include <sys/types.h>
 
-#include "sw/lib/common.h"
-#include "sw/lib/uart.h"
+#include "sw/device/lib/common.h"
+#include "sw/device/lib/uart.h"
 
 extern unsigned int _stack_start;
 
diff --git a/sw/benchmarks/coremark/top_earlgrey/core_portme.mak b/sw/device/benchmarks/coremark/top_earlgrey/core_portme.mak
similarity index 100%
rename from sw/benchmarks/coremark/top_earlgrey/core_portme.mak
rename to sw/device/benchmarks/coremark/top_earlgrey/core_portme.mak
diff --git a/sw/benchmarks/coremark/top_earlgrey/cvt.c b/sw/device/benchmarks/coremark/top_earlgrey/cvt.c
similarity index 100%
rename from sw/benchmarks/coremark/top_earlgrey/cvt.c
rename to sw/device/benchmarks/coremark/top_earlgrey/cvt.c
diff --git a/sw/benchmarks/coremark/top_earlgrey/ee_printf.c b/sw/device/benchmarks/coremark/top_earlgrey/ee_printf.c
similarity index 100%
rename from sw/benchmarks/coremark/top_earlgrey/ee_printf.c
rename to sw/device/benchmarks/coremark/top_earlgrey/ee_printf.c
diff --git a/sw/boot_rom/boot_rom.c b/sw/device/boot_rom/boot_rom.c
similarity index 72%
rename from sw/boot_rom/boot_rom.c
rename to sw/device/boot_rom/boot_rom.c
index 91cd210..d0ac43f 100644
--- a/sw/boot_rom/boot_rom.c
+++ b/sw/device/boot_rom/boot_rom.c
@@ -2,14 +2,14 @@
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
 
-#include "sw/boot_rom/chip_info.h"  // Generated.
+#include "sw/device/boot_rom/chip_info.h"  // Generated.
 
-#include "sw/boot_rom/bootstrap.h"
-#include "sw/lib/common.h"
-#include "sw/lib/flash_ctrl.h"
-#include "sw/lib/gpio.h"
-#include "sw/lib/spi_device.h"
-#include "sw/lib/uart.h"
+#include "sw/device/boot_rom/bootstrap.h"
+#include "sw/device/lib/common.h"
+#include "sw/device/lib/flash_ctrl.h"
+#include "sw/device/lib/gpio.h"
+#include "sw/device/lib/spi_device.h"
+#include "sw/device/lib/uart.h"
 
 static inline void try_launch(void) {
   __asm__ volatile(
diff --git a/sw/boot_rom/bootstrap.c b/sw/device/boot_rom/bootstrap.c
similarity index 91%
rename from sw/boot_rom/bootstrap.c
rename to sw/device/boot_rom/bootstrap.c
index e56e748..e4f5f29 100644
--- a/sw/boot_rom/bootstrap.c
+++ b/sw/device/boot_rom/bootstrap.c
@@ -2,14 +2,14 @@
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
 
-#include "sw/boot_rom/bootstrap.h"
+#include "sw/device/boot_rom/bootstrap.h"
 
-#include "sw/lib/common.h"
-#include "sw/lib/flash_ctrl.h"
-#include "sw/lib/gpio.h"
-#include "sw/lib/hw_sha256.h"
-#include "sw/lib/spi_device.h"
-#include "sw/lib/uart.h"  // TODO: Wrap uart in DEBUG macros.
+#include "sw/device/lib/common.h"
+#include "sw/device/lib/flash_ctrl.h"
+#include "sw/device/lib/gpio.h"
+#include "sw/device/lib/hw_sha256.h"
+#include "sw/device/lib/spi_device.h"
+#include "sw/device/lib/uart.h"  // TODO: Wrap uart in DEBUG macros.
 
 /* Checks if flash is blank to determine if bootstrap is needed. */
 /* TODO: Update this to check bootstrap pin instead in Verilator. */
diff --git a/sw/boot_rom/bootstrap.h b/sw/device/boot_rom/bootstrap.h
similarity index 93%
rename from sw/boot_rom/bootstrap.h
rename to sw/device/boot_rom/bootstrap.h
index fd0b1bf..ace2692 100644
--- a/sw/boot_rom/bootstrap.h
+++ b/sw/device/boot_rom/bootstrap.h
@@ -5,7 +5,7 @@
 #ifndef _F_BOOTSTRAP_H__
 #define _F_BOOTSTRAP_H__
 
-#include "sw/boot_rom/bootstrap_msgs.h"
+#include "sw/device/boot_rom/bootstrap_msgs.h"
 
 /**
  * Bootstrap Flash with payload received on SPI device.
diff --git a/sw/boot_rom/bootstrap_msgs.h b/sw/device/boot_rom/bootstrap_msgs.h
similarity index 100%
rename from sw/boot_rom/bootstrap_msgs.h
rename to sw/device/boot_rom/bootstrap_msgs.h
diff --git a/sw/boot_rom/crt0.S b/sw/device/boot_rom/crt0.S
similarity index 100%
rename from sw/boot_rom/crt0.S
rename to sw/device/boot_rom/crt0.S
diff --git a/sw/boot_rom/meson.build b/sw/device/boot_rom/meson.build
similarity index 100%
rename from sw/boot_rom/meson.build
rename to sw/device/boot_rom/meson.build
diff --git a/sw/boot_rom/rom_link.ld b/sw/device/boot_rom/rom_link.ld
similarity index 100%
rename from sw/boot_rom/rom_link.ld
rename to sw/device/boot_rom/rom_link.ld
diff --git a/sw/boot_rom/srcs.mk b/sw/device/boot_rom/srcs.mk
similarity index 100%
rename from sw/boot_rom/srcs.mk
rename to sw/device/boot_rom/srcs.mk
diff --git a/sw/examples/hello_usbdev/hello_usbdev.c b/sw/device/examples/hello_usbdev/hello_usbdev.c
similarity index 95%
rename from sw/examples/hello_usbdev/hello_usbdev.c
rename to sw/device/examples/hello_usbdev/hello_usbdev.c
index 2dbff9a..24c1c0c 100644
--- a/sw/examples/hello_usbdev/hello_usbdev.c
+++ b/sw/device/examples/hello_usbdev/hello_usbdev.c
@@ -2,12 +2,12 @@
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
 
-#include "sw/lib/common.h"
-#include "sw/lib/gpio.h"
-#include "sw/lib/uart.h"
-#include "sw/lib/usb_controlep.h"
-#include "sw/lib/usb_simpleserial.h"
-#include "sw/lib/usbdev.h"
+#include "sw/device/lib/common.h"
+#include "sw/device/lib/gpio.h"
+#include "sw/device/lib/uart.h"
+#include "sw/device/lib/usb_controlep.h"
+#include "sw/device/lib/usb_simpleserial.h"
+#include "sw/device/lib/usbdev.h"
 
 // These just for the '/' printout
 #define USBDEV_BASE_ADDR 0x40020000
diff --git a/sw/examples/hello_usbdev/meson.build b/sw/device/examples/hello_usbdev/meson.build
similarity index 100%
rename from sw/examples/hello_usbdev/meson.build
rename to sw/device/examples/hello_usbdev/meson.build
diff --git a/sw/examples/hello_usbdev/srcs.mk b/sw/device/examples/hello_usbdev/srcs.mk
similarity index 100%
rename from sw/examples/hello_usbdev/srcs.mk
rename to sw/device/examples/hello_usbdev/srcs.mk
diff --git a/sw/examples/hello_world/hello_world.c b/sw/device/examples/hello_world/hello_world.c
similarity index 96%
rename from sw/examples/hello_world/hello_world.c
rename to sw/device/examples/hello_world/hello_world.c
index 8f44872..a02158d 100644
--- a/sw/examples/hello_world/hello_world.c
+++ b/sw/device/examples/hello_world/hello_world.c
@@ -2,10 +2,10 @@
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
 
-#include "sw/lib/common.h"
-#include "sw/lib/gpio.h"
-#include "sw/lib/spi_device.h"
-#include "sw/lib/uart.h"
+#include "sw/device/lib/common.h"
+#include "sw/device/lib/gpio.h"
+#include "sw/device/lib/spi_device.h"
+#include "sw/device/lib/uart.h"
 
 #define SPI_MAX 32
 
diff --git a/sw/examples/hello_world/meson.build b/sw/device/examples/hello_world/meson.build
similarity index 100%
rename from sw/examples/hello_world/meson.build
rename to sw/device/examples/hello_world/meson.build
diff --git a/sw/examples/hello_world/srcs.mk b/sw/device/examples/hello_world/srcs.mk
similarity index 100%
rename from sw/examples/hello_world/srcs.mk
rename to sw/device/examples/hello_world/srcs.mk
diff --git a/sw/examples/meson.build b/sw/device/examples/meson.build
similarity index 100%
rename from sw/examples/meson.build
rename to sw/device/examples/meson.build
diff --git a/sw/exts/common/_crt.c b/sw/device/exts/common/_crt.c
similarity index 88%
rename from sw/exts/common/_crt.c
rename to sw/device/exts/common/_crt.c
index e06889f..109a92d 100644
--- a/sw/exts/common/_crt.c
+++ b/sw/device/exts/common/_crt.c
@@ -4,8 +4,8 @@
 
 #include <string.h>
 
-#include "sw/lib/common.h"
-#include "sw/lib/irq.h"
+#include "sw/device/lib/common.h"
+#include "sw/device/lib/irq.h"
 
 extern int main(void);
 
diff --git a/sw/exts/common/link.ld b/sw/device/exts/common/link.ld
similarity index 100%
rename from sw/exts/common/link.ld
rename to sw/device/exts/common/link.ld
diff --git a/sw/exts/common/srcs.mk b/sw/device/exts/common/srcs.mk
similarity index 83%
rename from sw/exts/common/srcs.mk
rename to sw/device/exts/common/srcs.mk
index e50b681..a585a52 100644
--- a/sw/exts/common/srcs.mk
+++ b/sw/device/exts/common/srcs.mk
@@ -2,7 +2,7 @@
 # Licensed under the Apache License, Version 2.0, see LICENSE for details.
 # SPDX-License-Identifier: Apache-2.0
 
-EXT_COMMON_DIR        ?= $(SW_ROOT_DIR)/exts/common
+EXT_COMMON_DIR        ?= $(SW_ROOT_DIR)/device/exts/common
 INCS                  += -I$(EXT_COMMON_DIR)
 
 EXT_COMMON_LOC_SRCS   +=
diff --git a/sw/lib/common.h b/sw/device/lib/common.h
similarity index 100%
rename from sw/lib/common.h
rename to sw/device/lib/common.h
diff --git a/sw/lib/flash_ctrl.c b/sw/device/lib/flash_ctrl.c
similarity index 98%
rename from sw/lib/flash_ctrl.c
rename to sw/device/lib/flash_ctrl.c
index 24e6559..8d8f7a1 100644
--- a/sw/lib/flash_ctrl.c
+++ b/sw/device/lib/flash_ctrl.c
@@ -1,11 +1,11 @@
 // Copyright lowRISC contributors.
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
-#include "sw/lib/flash_ctrl.h"
+#include "sw/device/lib/flash_ctrl.h"
 
 #include "flash_ctrl_regs.h"  // Generated.
 
-#include "sw/lib/common.h"
+#include "sw/device/lib/common.h"
 
 #define FLASH_CTRL0_BASE_ADDR 0x40030000
 
diff --git a/sw/lib/flash_ctrl.h b/sw/device/lib/flash_ctrl.h
similarity index 100%
rename from sw/lib/flash_ctrl.h
rename to sw/device/lib/flash_ctrl.h
diff --git a/sw/lib/gpio.c b/sw/device/lib/gpio.c
similarity index 92%
rename from sw/lib/gpio.c
rename to sw/device/lib/gpio.c
index aed2247..a7ddf74 100644
--- a/sw/lib/gpio.c
+++ b/sw/device/lib/gpio.c
@@ -2,11 +2,11 @@
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
 
-#include "sw/lib/gpio.h"
+#include "sw/device/lib/gpio.h"
 
 #include <assert.h>
 
-#include "sw/lib/common.h"
+#include "sw/device/lib/common.h"
 
 void gpio_init(uint32_t oe) { REG32(GPIO_DIRECT_OE(0)) = oe; }
 
diff --git a/sw/lib/gpio.h b/sw/device/lib/gpio.h
similarity index 100%
rename from sw/lib/gpio.h
rename to sw/device/lib/gpio.h
diff --git a/sw/lib/handler.c b/sw/device/lib/handler.c
similarity index 97%
rename from sw/lib/handler.c
rename to sw/device/lib/handler.c
index f882750..b344415 100644
--- a/sw/lib/handler.c
+++ b/sw/device/lib/handler.c
@@ -4,8 +4,8 @@
 
 #include "handler.h"
 
-#include "sw/lib/common.h"
-#include "sw/lib/uart.h"
+#include "sw/device/lib/common.h"
+#include "sw/device/lib/uart.h"
 
 /**
  * Default exception handler. Can be overidden.
diff --git a/sw/lib/handler.h b/sw/device/lib/handler.h
similarity index 100%
rename from sw/lib/handler.h
rename to sw/device/lib/handler.h
diff --git a/sw/lib/hmac.c b/sw/device/lib/hmac.c
similarity index 98%
rename from sw/lib/hmac.c
rename to sw/device/lib/hmac.c
index 59d954f..bfad441 100644
--- a/sw/lib/hmac.c
+++ b/sw/device/lib/hmac.c
@@ -6,7 +6,7 @@
 
 #include "hmac_regs.h"  // Generated.
 
-#include "sw/lib/common.h"
+#include "sw/device/lib/common.h"
 
 #define HMAC0_BASE_ADDR 0x40120000
 #define HMAC_FIFO_MAX 16
diff --git a/sw/lib/hmac.h b/sw/device/lib/hmac.h
similarity index 100%
rename from sw/lib/hmac.h
rename to sw/device/lib/hmac.h
diff --git a/sw/lib/hw_sha256.c b/sw/device/lib/hw_sha256.c
similarity index 96%
rename from sw/lib/hw_sha256.c
rename to sw/device/lib/hw_sha256.c
index 67731bd..af67cae 100644
--- a/sw/lib/hw_sha256.c
+++ b/sw/device/lib/hw_sha256.c
@@ -2,7 +2,7 @@
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
 
-#include "sw/lib/hw_sha256.h"
+#include "sw/device/lib/hw_sha256.h"
 
 #include "hmac.h"
 
diff --git a/sw/lib/hw_sha256.h b/sw/device/lib/hw_sha256.h
similarity index 100%
rename from sw/lib/hw_sha256.h
rename to sw/device/lib/hw_sha256.h
diff --git a/sw/lib/irq.c b/sw/device/lib/irq.c
similarity index 94%
rename from sw/lib/irq.c
rename to sw/device/lib/irq.c
index 0ecf2dc..f57f5e7 100644
--- a/sw/lib/irq.c
+++ b/sw/device/lib/irq.c
@@ -2,9 +2,9 @@
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
 
-#include "sw/lib/irq.h"
+#include "sw/device/lib/irq.h"
 
-#include "sw/lib/common.h"
+#include "sw/device/lib/common.h"
 
 static const uint32_t IRQ_EXT_ENABLE_OFFSET = 11;
 static const uint32_t IRQ_TIMER_ENABLE_OFFSET = 7;
diff --git a/sw/lib/irq.h b/sw/device/lib/irq.h
similarity index 100%
rename from sw/lib/irq.h
rename to sw/device/lib/irq.h
diff --git a/sw/lib/irq_vectors.S b/sw/device/lib/irq_vectors.S
similarity index 100%
rename from sw/lib/irq_vectors.S
rename to sw/device/lib/irq_vectors.S
diff --git a/sw/lib/meson.build b/sw/device/lib/meson.build
similarity index 100%
rename from sw/lib/meson.build
rename to sw/device/lib/meson.build
diff --git a/sw/lib/rv_timer.c b/sw/device/lib/rv_timer.c
similarity index 94%
rename from sw/lib/rv_timer.c
rename to sw/device/lib/rv_timer.c
index 98c7dd1..caa8f24 100644
--- a/sw/lib/rv_timer.c
+++ b/sw/device/lib/rv_timer.c
@@ -2,11 +2,11 @@
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
 
-#include "sw/lib/rv_timer.h"
+#include "sw/device/lib/rv_timer.h"
 
 #include "rv_timer_regs.h"  // Generated.
 
-#include "sw/lib/common.h"
+#include "sw/device/lib/common.h"
 
 #define RV_TIMER0_BASE_ADDR 0x40080000
 #define HART_CFG_ADDR_GAP 0x100
diff --git a/sw/lib/rv_timer.h b/sw/device/lib/rv_timer.h
similarity index 100%
rename from sw/lib/rv_timer.h
rename to sw/device/lib/rv_timer.h
diff --git a/sw/lib/spi_device.c b/sw/device/lib/spi_device.c
similarity index 98%
rename from sw/lib/spi_device.c
rename to sw/device/lib/spi_device.c
index 9e02f89..04caa34 100644
--- a/sw/lib/spi_device.c
+++ b/sw/device/lib/spi_device.c
@@ -2,11 +2,11 @@
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
 
-#include "sw/lib/spi_device.h"
+#include "sw/device/lib/spi_device.h"
 
 #include "spi_device_regs.h"  // Generated.
 
-#include "sw/lib/common.h"
+#include "sw/device/lib/common.h"
 
 #define SPI_DEVICE0_BASE_ADDR 0x40020000
 #define SPID_SRAM_ADDR SPI_DEVICE_BUFFER(0)
diff --git a/sw/lib/spi_device.h b/sw/device/lib/spi_device.h
similarity index 100%
rename from sw/lib/spi_device.h
rename to sw/device/lib/spi_device.h
diff --git a/sw/lib/srcs.mk b/sw/device/lib/srcs.mk
similarity index 82%
rename from sw/lib/srcs.mk
rename to sw/device/lib/srcs.mk
index eada8f0..3431149 100644
--- a/sw/lib/srcs.mk
+++ b/sw/device/lib/srcs.mk
@@ -2,7 +2,7 @@
 # Licensed under the Apache License, Version 2.0, see LICENSE for details.
 # SPDX-License-Identifier: Apache-2.0
 
-GEN_HEADERS       += $(LIB_LOC_DIF_SRCS:.c=_regs.h) sw/boot_rom/chip_info.h
+GEN_HEADERS       += $(LIB_LOC_DIF_SRCS:.c=_regs.h) sw/device/boot_rom/chip_info.h
 LIB_LOC_DIF_SRCS  += uart.c gpio.c spi_device.c flash_ctrl.c hmac.c usbdev.c rv_timer.c
 LIB_LOC_EXT_SRCS  += usb_controlep.c usb_simpleserial.c irq.c handler.c irq_vectors.S
 
diff --git a/sw/lib/uart.c b/sw/device/lib/uart.c
similarity index 95%
rename from sw/lib/uart.c
rename to sw/device/lib/uart.c
index f3b10d1..f184916 100644
--- a/sw/lib/uart.c
+++ b/sw/device/lib/uart.c
@@ -2,9 +2,9 @@
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
 
-#include "sw/lib/uart.h"
+#include "sw/device/lib/uart.h"
 
-#include "sw/lib/common.h"
+#include "sw/device/lib/common.h"
 
 inline void uart_init(unsigned int baud) {
   // nco = 2^20 * baud / fclk
diff --git a/sw/lib/uart.h b/sw/device/lib/uart.h
similarity index 100%
rename from sw/lib/uart.h
rename to sw/device/lib/uart.h
diff --git a/sw/lib/usb_consts.h b/sw/device/lib/usb_consts.h
similarity index 100%
rename from sw/lib/usb_consts.h
rename to sw/device/lib/usb_consts.h
diff --git a/sw/lib/usb_controlep.c b/sw/device/lib/usb_controlep.c
similarity index 99%
rename from sw/lib/usb_controlep.c
rename to sw/device/lib/usb_controlep.c
index 064b9b2..5ff370a 100644
--- a/sw/lib/usb_controlep.c
+++ b/sw/device/lib/usb_controlep.c
@@ -7,7 +7,7 @@
 
 #include <stddef.h>
 
-#include "sw/lib/common.h"
+#include "sw/device/lib/common.h"
 #include "usb_consts.h"
 #include "usbdev.h"
 
diff --git a/sw/lib/usb_controlep.h b/sw/device/lib/usb_controlep.h
similarity index 98%
rename from sw/lib/usb_controlep.h
rename to sw/device/lib/usb_controlep.h
index 1046083..9e9e218 100644
--- a/sw/lib/usb_controlep.h
+++ b/sw/device/lib/usb_controlep.h
@@ -6,7 +6,7 @@
 #define __USB_CONTROLEP_H__
 #include <stddef.h>
 
-#include "sw/lib/common.h"
+#include "sw/device/lib/common.h"
 #include "usbdev.h"
 
 typedef enum ctstate {
diff --git a/sw/lib/usb_simpleserial.c b/sw/device/lib/usb_simpleserial.c
similarity index 98%
rename from sw/lib/usb_simpleserial.c
rename to sw/device/lib/usb_simpleserial.c
index 66da987..46229b1 100644
--- a/sw/lib/usb_simpleserial.c
+++ b/sw/device/lib/usb_simpleserial.c
@@ -7,7 +7,7 @@
 
 #include <stddef.h>
 
-#include "sw/lib/common.h"
+#include "sw/device/lib/common.h"
 #include "usbdev.h"
 
 #define MAX_GATHER 16
diff --git a/sw/lib/usb_simpleserial.h b/sw/device/lib/usb_simpleserial.h
similarity index 96%
rename from sw/lib/usb_simpleserial.h
rename to sw/device/lib/usb_simpleserial.h
index c1cc51a..dbb994a 100644
--- a/sw/lib/usb_simpleserial.h
+++ b/sw/device/lib/usb_simpleserial.h
@@ -5,7 +5,7 @@
 #ifndef __USB_SIMPLESERIAL_H__
 #define __USB_SIMPLESERIAL_H__
 
-#include "sw/lib/common.h"
+#include "sw/device/lib/common.h"
 #include "usbdev.h"
 
 // This is only here because caller of _init needs it
diff --git a/sw/lib/usbdev.c b/sw/device/lib/usbdev.c
similarity index 99%
rename from sw/lib/usbdev.c
rename to sw/device/lib/usbdev.c
index 1b95688..eb47297 100644
--- a/sw/lib/usbdev.c
+++ b/sw/device/lib/usbdev.c
@@ -7,7 +7,7 @@
 
 #include <stddef.h>
 
-#include "sw/lib/common.h"
+#include "sw/device/lib/common.h"
 
 #define USBDEV_BASE_ADDR 0x40020000
 #include "usbdev_regs.h"  // Generated.
diff --git a/sw/lib/usbdev.h b/sw/device/lib/usbdev.h
similarity index 99%
rename from sw/lib/usbdev.h
rename to sw/device/lib/usbdev.h
index f93784a..4f769f1 100644
--- a/sw/lib/usbdev.h
+++ b/sw/device/lib/usbdev.h
@@ -175,7 +175,7 @@
 void usbdev_init(usbdev_ctx_t *ctx);
 
 // Used for tracing what is going on
-#include "sw/lib/uart.h"
+#include "sw/device/lib/uart.h"
 #define TRC_S(s) uart_send_str(s)
 #define TRC_I(i, b) uart_send_uint(i, b)
 #define TRC_C(c) uart_send_char(c)
diff --git a/sw/device/meson.build b/sw/device/meson.build
new file mode 100644
index 0000000..052b2db
--- /dev/null
+++ b/sw/device/meson.build
@@ -0,0 +1,9 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+subdir('lib')
+
+subdir('boot_rom')
+subdir('examples')
+subdir('tests')
diff --git a/sw/tests/flash_ctrl/flash_test.c b/sw/device/tests/flash_ctrl/flash_test.c
similarity index 97%
rename from sw/tests/flash_ctrl/flash_test.c
rename to sw/device/tests/flash_ctrl/flash_test.c
index 391fd8a..db92381 100644
--- a/sw/tests/flash_ctrl/flash_test.c
+++ b/sw/device/tests/flash_ctrl/flash_test.c
@@ -2,10 +2,10 @@
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
 
-#include "sw/lib/common.h"
-#include "sw/lib/flash_ctrl.h"
-#include "sw/lib/gpio.h"
-#include "sw/lib/uart.h"
+#include "sw/device/lib/common.h"
+#include "sw/device/lib/flash_ctrl.h"
+#include "sw/device/lib/gpio.h"
+#include "sw/device/lib/uart.h"
 
 /**
  * Delay loop executing within 8 cycles on ibex
diff --git a/sw/tests/flash_ctrl/meson.build b/sw/device/tests/flash_ctrl/meson.build
similarity index 100%
rename from sw/tests/flash_ctrl/meson.build
rename to sw/device/tests/flash_ctrl/meson.build
diff --git a/sw/tests/flash_ctrl/srcs.mk b/sw/device/tests/flash_ctrl/srcs.mk
similarity index 100%
rename from sw/tests/flash_ctrl/srcs.mk
rename to sw/device/tests/flash_ctrl/srcs.mk
diff --git a/sw/tests/hmac/meson.build b/sw/device/tests/hmac/meson.build
similarity index 100%
rename from sw/tests/hmac/meson.build
rename to sw/device/tests/hmac/meson.build
diff --git a/sw/tests/hmac/sha256_test.c b/sw/device/tests/hmac/sha256_test.c
similarity index 89%
rename from sw/tests/hmac/sha256_test.c
rename to sw/device/tests/hmac/sha256_test.c
index 58ec263..8b5d7ea 100644
--- a/sw/tests/hmac/sha256_test.c
+++ b/sw/device/tests/hmac/sha256_test.c
@@ -5,10 +5,10 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "sw/lib/common.h"
-#include "sw/lib/flash_ctrl.h"
-#include "sw/lib/hw_sha256.h"
-#include "sw/lib/uart.h"
+#include "sw/device/lib/common.h"
+#include "sw/device/lib/flash_ctrl.h"
+#include "sw/device/lib/hw_sha256.h"
+#include "sw/device/lib/uart.h"
 
 typedef struct test_data {
   uint32_t digest[8];
diff --git a/sw/tests/hmac/srcs.mk b/sw/device/tests/hmac/srcs.mk
similarity index 100%
rename from sw/tests/hmac/srcs.mk
rename to sw/device/tests/hmac/srcs.mk
diff --git a/sw/tests/meson.build b/sw/device/tests/meson.build
similarity index 100%
rename from sw/tests/meson.build
rename to sw/device/tests/meson.build
diff --git a/sw/tests/rv_timer/meson.build b/sw/device/tests/rv_timer/meson.build
similarity index 100%
rename from sw/tests/rv_timer/meson.build
rename to sw/device/tests/rv_timer/meson.build
diff --git a/sw/tests/rv_timer/rv_timer_test.c b/sw/device/tests/rv_timer/rv_timer_test.c
similarity index 86%
rename from sw/tests/rv_timer/rv_timer_test.c
rename to sw/device/tests/rv_timer/rv_timer_test.c
index 4be8142..76721f7 100644
--- a/sw/tests/rv_timer/rv_timer_test.c
+++ b/sw/device/tests/rv_timer/rv_timer_test.c
@@ -5,10 +5,10 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "sw/lib/common.h"
-#include "sw/lib/irq.h"
-#include "sw/lib/rv_timer.h"
-#include "sw/lib/uart.h"
+#include "sw/device/lib/common.h"
+#include "sw/device/lib/irq.h"
+#include "sw/device/lib/rv_timer.h"
+#include "sw/device/lib/uart.h"
 
 static uint32_t intr_handling_success = 0;
 static const uint32_t hart = 0;
diff --git a/sw/tests/rv_timer/srcs.mk b/sw/device/tests/rv_timer/srcs.mk
similarity index 100%
rename from sw/tests/rv_timer/srcs.mk
rename to sw/device/tests/rv_timer/srcs.mk
diff --git a/sw/doc/sw_build_flow.md b/sw/doc/sw_build_flow.md
index c2f8566..5ff186b 100644
--- a/sw/doc/sw_build_flow.md
+++ b/sw/doc/sw_build_flow.md
@@ -24,13 +24,13 @@
   from the `SW_ROOT_DIR`. It is **mandatory** to set this variable on the command
   line.
 
-- **SW_NAME**: A `SW_DIR` could cotain one or more unique SW build targets.
+- **SW_NAME**: A `SW_DIR` could contain one or more unique SW build targets.
   This variable is used to indicate which one is to be built, on the command
   line.
 
 - **lib**: This refers to the library code generated from the shared common
-  sources. These sources are currently placed in `sw/lib`, `sw/util` and
-  `sw/exts` directories. More such directories can be added in future.
+  sources. These sources are currently placed in `sw/device/lib`, `sw/device/util` and
+  `sw/device/exts` directories. More such directories can be added in future.
   Also, this is one of the goals of the make flow.
 
 - **LIB_SRCS**: This is a list of all common / shared sources compiled into the
@@ -68,11 +68,11 @@
 within that directory. These `srcs.mk` files are then required to be added to the
 top level SW build Makefile.
 
-- **`exts/common/srcs.mk`**: Additional extended common sources. This includes
+- **`device/exts/common/srcs.mk`**: Additional extended common sources. This includes
     the default `CRT_SRCS` and the `LINKER_SCRIPT` which can be overridden for
     sw specific requirements.
 
-- **`lib/srcs.mk`**: Directory containing sources to compile the lib elements and
+- **`device/lib/srcs.mk`**: Directory containing sources to compile the lib elements and
   its dependencies.
 
 - **`$(SW_DIR)/srcs.mk`**: This sub-make file contains sources for building a SW
@@ -85,7 +85,7 @@
   same name as the directory and the C source) in this file. In that case, indicating
   `SW_NAME` on the command line is not required.
 
-- **`exts/common/srcs.mk`**: Additional extended common sources. This includes
+- **`device/exts/common/srcs.mk`**: Additional extended common sources. This includes
     the default `CRT_SRCS` and the `LINKER_SCRIPT` which can be overridden for
     sw specific requirements.
 
@@ -98,24 +98,24 @@
 
 Build boot_rom:
 ```console
-$ make SW_DIR=boot_rom SW_NAME=boot_rom
+$ make SW_DIR=device/boot_rom SW_NAME=boot_rom
 ```
 
-This will build the boot_rom image in the boot_rom directly itself. SW_NAME in
-boot_rom/srcs.mk is already set to boot_rom, so there is no need to specify it
+This will build the boot_rom image in the device/boot_rom directly itself. SW_NAME in
+device/boot_rom/srcs.mk is already set to boot_rom, so there is no need to specify it
 on the command line.
 
 - Build the boot_rom in a separate build directory:
 ```console
-$ make SW_DIR=boot_rom SW_BUILD_DIR=path/to/scratch
+$ make SW_DIR=device/boot_rom SW_BUILD_DIR=path/to/scratch
 ```
 
 - Build hello_world test:
 ```console
-$ make SW_DIR=examples/hello_world SW_NAME=hello_world SW_BUILD_DIR=path/to/scratch
+$ make SW_DIR=device/examples/hello_world SW_NAME=hello_world SW_BUILD_DIR=path/to/scratch
 ```
 
 - Build sha256 test:
 ```console
-$ make SW_DIR=tests/hmac SW_NAME=sha256_test
+$ make SW_DIR=device/tests/hmac SW_NAME=sha256_test
 ```
diff --git a/sw/examples/hello_world/README.md b/sw/examples/hello_world/README.md
index 97735fb..d2e22c3 100644
--- a/sw/examples/hello_world/README.md
+++ b/sw/examples/hello_world/README.md
@@ -12,7 +12,7 @@
 All data input over SPI is echo'd on UART in a word aligned fashion.
 The sample output below is hello_world run on a verilator model.
 ```shell
-$ ./Vtop_earlgrey_verilator --rominit=sw/boot_rom/rom.vmem --flashinit=sw/examples/hello_world/sw.vmem
+$ ./Vtop_earlgrey_verilator --rominit=sw/device/boot_rom/rom.vmem --flashinit=sw/device/examples/hello_world/sw.vmem
 ```
 
 Output:
diff --git a/sw/host/spiflash/README.md b/sw/host/spiflash/README.md
index b1aea5d..e85c361 100644
--- a/sw/host/spiflash/README.md
+++ b/sw/host/spiflash/README.md
@@ -49,7 +49,7 @@
 ```console
 $ cd ${REPO_TOP}
 $ build/lowrisc_systems_top_earlgrey_verilator_0.1/sim-verilator/Vtop_earlgrey_verilator \
-  --rominit=sw/boot_rom/rom.vmem
+  --rominit=sw/device/boot_rom/rom.vmem
 ```
 
 Run spiflash. In this example we use SPI device `/dev/pts/3` as an example.
@@ -57,7 +57,7 @@
 
 ```console
 $ cd ${REPO_TOP}
-$ ./sw/host/spiflash/spiflash --input=sw/examples/hello_world/sw.bin --verilator=/dev/pts/3
+$ ./sw/host/spiflash/spiflash --input=sw/device/examples/hello_world/sw.bin --verilator=/dev/pts/3
 ```
 
 ## Run the tool in FPGA
@@ -69,5 +69,5 @@
 
 ```console
 $ cd ${REPO_TOP}
-$ ./sw/host/spiflash/spiflash --input=sw/examples/hello_world/sw.bin
+$ ./sw/host/spiflash/spiflash --input=sw/device/examples/hello_world/sw.bin
 ```
diff --git a/sw/meson.build b/sw/meson.build
index 9d70a8e..142c20f 100644
--- a/sw/meson.build
+++ b/sw/meson.build
@@ -2,10 +2,5 @@
 # Licensed under the Apache License, Version 2.0, see LICENSE for details.
 # SPDX-License-Identifier: Apache-2.0
 
-subdir('lib')
-
-subdir('boot_rom')
-subdir('examples')
-subdir('tests')
-
+subdir('device')
 subdir('host')
diff --git a/sw/opts.mk b/sw/opts.mk
index 18e1663..d0d21d8 100644
--- a/sw/opts.mk
+++ b/sw/opts.mk
@@ -24,7 +24,7 @@
 SW_BUILD_DIR  ?= $(SW_ROOT_DIR)/$(SW_DIR)
 
 LIB_NAME      ?= ot
-LIB_DIR       ?= $(SW_ROOT_DIR)/lib
+LIB_DIR       ?= $(SW_ROOT_DIR)/device/lib
 LIB_TARGET    ?= $(LIB_BUILD_DIR)/lib${LIB_NAME}.a
 LIB_SRCS      +=
 LIB_OBJS      += $(addprefix $(LIB_BUILD_DIR)/, $(addsuffix .o, $(basename $(notdir $(LIB_SRCS)))))
@@ -56,7 +56,7 @@
 
 # defaults
 CRT_SRCS      ?= $(EXT_COMMON_DIR)/_crt.c
-LINKER_SCRIPT ?= $(SW_ROOT_DIR)/exts/common/link.ld
+LINKER_SCRIPT ?= $(SW_ROOT_DIR)/device/exts/common/link.ld
 
 # tools and opts
 REGTOOL       ?= $(SW_ROOT_DIR)/../util/regtool.py
diff --git a/sw/rules.mk b/sw/rules.mk
index 662208b..3c3e029 100644
--- a/sw/rules.mk
+++ b/sw/rules.mk
@@ -121,8 +121,8 @@
 	$(REGTOOL) -D -o $@ $<
 
 # chip_info
-$(LIB_BUILD_DIR)/sw/boot_rom/chip_info.h: $(INFOTOOL)
-	$(INFOTOOL) -o $(LIB_BUILD_DIR)/sw/boot_rom
+$(LIB_BUILD_DIR)/sw/device/boot_rom/chip_info.h: $(INFOTOOL)
+	$(INFOTOOL) -o $(LIB_BUILD_DIR)/sw/device/boot_rom
 
 -include $(DEPS)
 
diff --git a/test/systemtest/functional_fpga_test.py b/test/systemtest/functional_fpga_test.py
index ea8383c..507700a 100644
--- a/test/systemtest/functional_fpga_test.py
+++ b/test/systemtest/functional_fpga_test.py
@@ -18,7 +18,7 @@
 
 $ cd ${REPO_TOP}
 $ pytest -s -v test/systemtest/functional_fpga_test.py \
-  --test_bin sw/tests/hmac/sw.bin \
+  --test_bin sw/device/tests/hmac/sw.bin \
   --fpga_uart /dev/ttyUSB2 \
   --spiflash sw/host/spiflash/spiflash
 """
diff --git a/test/systemtest/functional_verilator_test.py b/test/systemtest/functional_verilator_test.py
index 657091e..27fb63c 100644
--- a/test/systemtest/functional_verilator_test.py
+++ b/test/systemtest/functional_verilator_test.py
@@ -7,13 +7,13 @@
 Failing to write either will result in a timeout.
 
 This test requires some configuration options. Use the following steps to
-run the test manually after building Verilator and the sw/boot_rom and
-sw/examples/hello_world targets.
+run the test manually after building Verilator and the sw/device/boot_rom and
+sw/device/examples/hello_world targets.
 
 $ cd ${REPO_TOP}
 $ pytest -s -v test/systemtest/functional_verilator_test.py \
-  --test_bin sw/tests/hmac/sw.vmem \
-  --rom_bin sw/boot_rom/rom.vmem \
+  --test_bin sw/device/tests/hmac/sw.vmem \
+  --rom_bin sw/device/boot_rom/rom.vmem \
   --verilator_model build/lowrisc_systems_top_earlgrey_verilator_0.1/sim-verilator/Vtop_earlgrey_verilator
 """
 
diff --git a/test/systemtest/openocd_verilator_test.py b/test/systemtest/openocd_verilator_test.py
index ae4f6c1..a66f2c5 100644
--- a/test/systemtest/openocd_verilator_test.py
+++ b/test/systemtest/openocd_verilator_test.py
@@ -5,13 +5,13 @@
 r"""Runs OpenOCD compliance test against Verilator target.
 
 This test requires some configuration options. Use the following steps to
-run the test manually after building Verilator and the sw/boot_rom and
-sw/examples/hello_world targets.
+run the test manually after building Verilator and the sw/device/boot_rom and
+sw/device/examples/hello_world targets.
 
 $ cd ${REPO_TOP}
 $ pytest -s -v test/systemtest/openocd_verilator_test.py \
-  --test_bin sw/examples/hello_world/sw.vmem \
-  --rom_bin sw/boot_rom/rom.vmem \
+  --test_bin sw/device/examples/hello_world/sw.vmem \
+  --rom_bin sw/device/boot_rom/rom.vmem \
   --verilator_model build/lowrisc_systems_top_earlgrey_verilator_0.1/sim-verilator/Vtop_earlgrey_verilator
 
 In some cases the pytest environment may not be able to find the openocd binary.