diff --git a/.readthedocs.yaml b/.readthedocs.yaml
new file mode 100644
index 00000000..81a18992
--- /dev/null
+++ b/.readthedocs.yaml
@@ -0,0 +1,35 @@
+# Read the Docs configuration file for Sphinx projects
+# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
+
+# Required
+version: 2
+
+# Set the OS, Python version and other tools you might need
+build:
+ os: ubuntu-22.04
+ tools:
+ python: "3.12"
+ # You can also specify other tool versions:
+ # nodejs: "20"
+ # rust: "1.70"
+ # golang: "1.20"
+
+# Build documentation in the "docs/" directory with Sphinx
+sphinx:
+ configuration: docs/conf.py
+ # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs
+ # builder: "dirhtml"
+ # Fail on all warnings to avoid broken references
+ # fail_on_warning: true
+
+# Optionally build your docs in additional formats such as PDF and ePub
+formats:
+ - pdf
+# - epub
+
+# Optional but recommended, declare the Python requirements required
+# to build your documentation
+# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
+python:
+ install:
+ - requirements: docs/requirements.txt
\ No newline at end of file
diff --git a/Makefile b/Makefile
index e41bb750..8f5095f1 100644
--- a/Makefile
+++ b/Makefile
@@ -56,89 +56,89 @@ all : doxy-pdf default #t# Build default with docs
.PHONY : sim
sim: boot #t# Build atomsim for given soctarget
$(call print_msg_root,Building AtomSim)
- make $(MKFLAGS) -C $(sim_dir) soctarget=$(soctarget) DEBUG=$(debug)
+ $(MAKE) $(MKFLAGS) -C $(sim_dir) soctarget=$(soctarget) DEBUG=$(debug)
.PHONY: clean-sim
clean-sim: #t# Clean atomsim build files
$(call print_msg_root,Cleaning AtomSim build files)
- make $(MKFLAGS) -C $(sim_dir) soctarget=$(soctarget) clean
+ $(MAKE) $(MKFLAGS) -C $(sim_dir) soctarget=$(soctarget) clean
.PHONY: test
test: sim lib #t# Test the build using banner example
$(call print_msg_root,Running example on Atomsim)
- make $(MKFLAGS) -C $(RVATOM)/sw/examples soctarget=$(soctarget) ex=banner sim=1 clean compile run
+ $(MAKE) $(MKFLAGS) -C $(RVATOM)/sw/examples soctarget=$(soctarget) ex=banner sim=1 clean compile run
# ======== Bootloader ========
.PHONY : boot
boot: lib #t# Build bootloader for given target
$(call print_msg_root,Building bootloader)
- make $(MKFLAGS) -C $(bootloader_dir) soctarget=$(soctarget) sim=$(sim)
+ $(MAKE) $(MKFLAGS) -C $(bootloader_dir) soctarget=$(soctarget) sim=$(sim)
.PHONY: clean-boot
clean-boot: #t# Clean bootloader build files
$(call print_msg_root,Cleaning bootloader build files)
- make $(MKFLAGS) -C $(bootloader_dir) soctarget=$(soctarget) clean
+ $(MAKE) $(MKFLAGS) -C $(bootloader_dir) soctarget=$(soctarget) clean
# ======== SCAR ========
.PHONY: scar
scar: sim #t# Verify target using scar
$(call print_msg_root,Running SCAR)
- make $(MKFLAGS) -C $(scar_dir)
+ $(MAKE) $(MKFLAGS) -C $(scar_dir)
.PHONY: clean-scar
clean-scar: #t# Clean scar directory
$(call print_msg_root,Cleaning SCAR working directory)
- make $(MKFLAGS) -C $(scar_dir) clean
+ $(MAKE) $(MKFLAGS) -C $(scar_dir) clean
# ======== ElfDump ========
.PHONY: elfdump
elfdump: #t# Build elfdump utility
$(call print_msg_root,Building ELFDump)
- make $(MKFLAGS) -C $(elfdump_dir)
+ $(MAKE) $(MKFLAGS) -C $(elfdump_dir)
.PHONY: clean-elfdump
clean-elfdump: #t# Clean elfdump directory
$(call print_msg_root,Cleaning ELFDump build files)
- make $(MKFLAGS) -C $(elfdump_dir) clean
+ $(MAKE) $(MKFLAGS) -C $(elfdump_dir) clean
# ======== SW libs ========
.PHONY: lib
lib: #t# compile software libraries
$(call print_msg_root,Building libcatom)
- make $(MKFLAGS) -C $(lib_dir) soctarget=$(soctarget) sim=$(sim)
+ $(MAKE) $(MKFLAGS) -C $(lib_dir) soctarget=$(soctarget) sim=$(sim)
.PHONY: clean-lib
clean-lib: #t# Clean software libs
$(call print_msg_root,Cleaning libcatom build files)
- make $(MKFLAGS) -C $(lib_dir) clean
+ $(MAKE) $(MKFLAGS) -C $(lib_dir) clean
# ======== Documentation ========
.PHONY: doxy
doxy: #t# Generate atomsim C++ source documentation
$(call print_msg_root,Generating docs for AtomSim,LATEX & HTML)
- make $(MKFLAGS) -C $(doxy_dir)
+ $(MAKE) $(MKFLAGS) -C $(doxy_dir)
.PHONY: doxy-pdf
doxy-pdf: doxy #t# Generate atomsim C++ source documentation (pdf)
$(call print_msg_root,Generating docs for AtomSim,PDF)
- make $(MKFLAGS) -C $(doxy_dir) pdf
+ $(MAKE) $(MKFLAGS) -C $(doxy_dir) pdf
.PHONY: clean-doxy
clean-doxy: #t# Clean build files for Atomsim docs
$(call print_msg_root,Cleaning docs build files)
- make $(MKFLAGS) -C $(doxy_dir) clean
+ $(MAKE) $(MKFLAGS) -C $(doxy_dir) clean
# ======== clean ========
diff --git a/docs/conf.py b/docs/conf.py
index 8afcd2c4..b062bafc 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -30,7 +30,7 @@
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
-extensions = ['sphinx.ext.autosectionlabel', 'sphinx_panels', 'sphinx_copybutton', ]
+extensions = ['sphinx.ext.autosectionlabel', 'sphinx_design', 'sphinx_copybutton', 'sphinx.ext.graphviz']
copybutton_prompt_text = r">>> |\.\.\. |\$ |In \[\d*\]: | {2,5}\.\.\.: | {5,8}: "
copybutton_prompt_is_regexp = True
diff --git a/docs/diagrams/AtomBones.drawio b/docs/diagrams/AtomBones.drawio
new file mode 100644
index 00000000..89aaf8bc
--- /dev/null
+++ b/docs/diagrams/AtomBones.drawio
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/diagrams/AtomBones.png b/docs/diagrams/AtomBones.png
new file mode 100644
index 00000000..969aba99
Binary files /dev/null and b/docs/diagrams/AtomBones.png differ
diff --git a/docs/diagrams/HydrogenSoC.drawio b/docs/diagrams/HydrogenSoC.drawio
index c02cce34..cbd7a18c 100644
--- a/docs/diagrams/HydrogenSoC.drawio
+++ b/docs/diagrams/HydrogenSoC.drawio
@@ -1 +1,178 @@
-7Vrbcts2EP0aPSZDghdRj7IsN53W006cjt2nDkRAJGqIUEAokvL1BUWAN8C27JC2rPRFQxxcCJ7dPbugOPJmq90vHK7Ta4YwHQEH7Ube5QiAKIzkbwHsS8AfOyWQcIJKyK2BG/IdK1AP2xCE89ZAwRgVZN0GY5ZlOBYtDHLOtu1hS0bbd13DBBvATQypid4SJFL1WIFT458wSVJ9Z9dRPSuoBysgTyFi2wbkzUfejDMmyqvVboZpwZ3mpZx39UBvtTGOM3HMhN/+EIw7t5er++9zN5he4a/z9Qfgl8t8g3SjnljtVuw1BZxtMoSLVdyRd7FNicA3axgXvVtpc4mlYkVVN+SxMqInWwjmaTVT3QlzgXcPPoNbMSM9CrMVFnwvh+gJE0Wm8ibd3Nam8UOFpU2z6IFQuUNSLV0zJi8Uac8g0HsOf87T/C0JpTNGGT/M9ZbLJYhjieeCs3vc6EHhIgzCfmj1QJvWyokbvLpWXr2heHVNHjGSkamajIuUJSyDdF6jF22m6zG/M7ZW/P6LhdgrD4Ubwdrs4x0Rd43rv4ulPgaqdblTKx8ae93I5PPeNRuNWUWznnZo6Xm5gFxMC4mSQExhnpNYw1eE6i2VhtfaAyqDF2w8bm5JHtvwGD/GslJUyBMsHhkX2t2HYwoF+dbeR/+uYITYVLDVCIRUbvliweVVUlzNGMf9Bl8UY3vwLaLAD5yegi/sBB8wgy+yxF40VOiZKeGW5OmCZZJd51aStsbc4Fk+v2iT2SYtK6a3GVYQpCTJihCQfMmFvYuCTSIz8FR1rAhCh/C2Wa9t3z7M4bfNAWxaCCz2AINJoWuwfXZSOKDGBUdq3ANu8ToaFwxbRmAXBXhsU7JJOPZgX2WE21EyzwwdW+SEg0WOd/6R8/ZFRHhkgEVvWkT45+8KJ2DjyQ/a+DBV+jPcNwasGclE3lj5zwKodSfoHl/Czkn4ifEgcDr+Ve6g9rbqUV7ugOE5KHz19uZkFN4xWPw/rI8P6/GRYR28pXSPjcj59Xp+3Wv0IIijpfWkF8YRXiz7iZ7qKHEqJ73IYPbyfTIbBCfGrDs5HV0CjwtTq4RUZ/Jm/WiKkNuvCPVSMxhJPuykKpkIP0bOJACe+m0vWEqgWqNj/B6yPzihPDV+hj8ce6Q43CFDHTeSSMOJ3p/LdMuWgZ1kYsjxX9PPX8wXndcMbWi/rzpl8Rgh3ybTEVh4YU/lY1emgaV8tMm0P5RM60doUP7lziTcRD7fGfSfzRtQIwx800q+xUqDvQAFtrNTaZElOwRwbYbw64bpjg/5QRincoAbrHd1p2FXDXzaI84SnN2wme6TO150x0usvLGGT9IV+v7ztVu+2vzidd+MA/NoYKbZOivVycywTCuPveB012NuAw8ktwbLgYVkjf1gDnS7J3y3Y7xy/0YONBeaPLHQ0BWXebh5/77hOW/qG91/Krv10Yt9o/sZwdC+YVZaMb3/h/wkQu4e8bnHqyZ4bf6GPXgufl57WN5e9GQP2ay/OCvDqf5sz5v/Bw==
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/diagrams/HydrogenSoC.png b/docs/diagrams/HydrogenSoC.png
index b2c5aae4..548687af 100644
Binary files a/docs/diagrams/HydrogenSoC.png and b/docs/diagrams/HydrogenSoC.png differ
diff --git a/docs/diagrams/RISCVAtom_arch.drawio b/docs/diagrams/RISCVAtom_arch.drawio
new file mode 100644
index 00000000..0f2934d1
--- /dev/null
+++ b/docs/diagrams/RISCVAtom_arch.drawio
@@ -0,0 +1,635 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/diagrams/RISCVAtom_arch.png b/docs/diagrams/RISCVAtom_arch.png
new file mode 100644
index 00000000..32292edf
Binary files /dev/null and b/docs/diagrams/RISCVAtom_arch.png differ
diff --git a/docs/diagrams/memory_map.drawio b/docs/diagrams/memory_map.drawio
index 08ab7f92..32f6f010 100644
--- a/docs/diagrams/memory_map.drawio
+++ b/docs/diagrams/memory_map.drawio
@@ -1 +1,232 @@
-7Vptc5s4EP41nul1Jh1ABuOPjtNLO3O5dpoP9/JNRmujCSAq5Njurz8JhA2IujRB47RXZ8aRVmKRnmdZ7a6ZoGW6v+U4j+8YgWTiOWQ/QTcTzwuDUH4rwaESuP7MqSQbTomWnQT39AtoYT1tSwkUrYmCsUTQvC2MWJZBJFoyzDnbtaetWdK+a443YAjuI5yY0r8oEbHel++c5O+AbuL6zq6jR1JcT9aCIsaE7Roi9HaClpwxUbXS/RISBV6NS3Xd718ZPS6MQyaGXLC7XTLnLkeP+N8/0Z27+Lx4/8eV1vKIk63e8JuVWlG1YnGoYeBsmxFQmpwJut7FVMB9jiM1upPES1ks0kT2XNlc0yRZsoTx8lq09tWfkrNMNOTVR8rNndTLAi5g3xDpnd0CS0Hwg5xSjwYaZW1nKNT93Yk0t2YibhBWy7C2k81R9QlK2dBofgeynonsozRQufkxsQWX+DCzhGFwaQyRiaHcy7jWSTCE68gOgt58IIIzWwhOTQQ5I1jgcTH0ISRTSxj6AzGc2sLQNzEcHcH1GoLIkhW6Q59jawgGPadMUYwM4NqzBqB3aQBnBoAxSECeBSDBRVzOVZ0Nx4RC63ieAQ7AOeMwC8HZAzRGgiiE1doOB0M9KbJFQWhQUAgcPdjlYD4jzmx2xuEaHITeCgVBQ9sN5TLsoCyT4xnjCrxR+bkYIXODkPEcSsYysGPHV9OBuB0vHB24OrU6hxxkZKGyJ9mLElwUNGqDBXsq/la4vvF17x+Nsmrf7Judg+58Fc2CbXkE33Z/QFq5mol5A1O/B9JaxiHBgj62M7w+mPUdPjIqV3yk1HP6XVOtodqOvqiZkHX1eG093SBQYL4BYegpOT9u+hlmYOZ+I5mBa8kMwhdlBmjaps8fyQy6emybgZmoTrwgETpfb9lD8HnL6oGroqzVLOQE1833JbH1uGxt1H9n7+hPrVIusdJaTTAMrkzvWibWPuG0Y+7x1TihG3XGRdKsQMqvlY+mEU4WeiClhKjb9J4D7ZOidSyr9eq6lOuOcyjM24yjnuAm6DsSrJ0IZqI9tg24v2zgvA3MLm0DZqngSTbQbwDuD+4ExifcvfhDb2blYxI+/UV4J/J3L024WUU4F/BphFuodFLXj1hI1LNS4jnoyFv9Swn6Htf5QsK6bjhmFHWeGtcZxNoO7MyKBZWKmMH50ysWXW6NasQq9Kd+Tw1pHUZgq1o3OMO2Vq1DfZ61A3oR41w1oy1PDtccRw8gvo3+iaoS/oTm74ZSoeNwW3UO1EmKj0lyg4X+346ssTDA3f20LFwOddPrfFrcScErN3j47fULPfotxPcItR+InnBv2suMLWLMeumnDyUxwfT/RUz3XL40M/XNnhGIz/vicMmpU1EsJThV4FbfSl4+k0pBMVHvqih8VqBEKS5XTCCXsSDNNrK9zVmmNpHmCaQSeFz+nPBDxfY27GjI6xJ9geoT4g7ZPb0oVAWIp9et0Nv/AA==
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/diagrams/memory_map.png b/docs/diagrams/memory_map.png
index 42f00ad0..bd3613d1 100644
Binary files a/docs/diagrams/memory_map.png and b/docs/diagrams/memory_map.png differ
diff --git a/docs/index.rst b/docs/index.rst
index de60d188..9762f8e0 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -11,15 +11,24 @@
RISC-V Atom Documentation & User Manual
****************************************
+Welcome to RISC-V Atom Documentation and User Manual! Please follow the :doc:`getting started guide`
+to setup an environment to build and test the RISC-V Atom project. Please feel free file a bug report in github.
+
+.. grid:: 2
+
+ .. grid-item-card:: Github Repository
+ :link: https://github.com/saursin/riscv-atom
+
+ .. grid-item-card:: Website
+ :link: https://sites.google.com/view/saursin/projects/risc-v-atom?authuser=0
+
+
.. toctree::
:maxdepth: 1
:caption: Overview
pages/overview/introduction.rst
- pages/overview/components.rst
pages/overview/directory_structure.rst
- pages/overview/performance.rst
- pages/overview/fpga_results.rst
.. toctree::
@@ -28,18 +37,25 @@ RISC-V Atom Documentation & User Manual
pages/getting_started/prerequisites.rst
pages/getting_started/building.rst
+ pages/getting_started/docker.rst
pages/getting_started/examples.rst
.. toctree::
- :maxdepth: 2
+ :maxdepth: 1
:caption: Documentation & User Manual
- pages/documentation/riscv_atom/riscv_atom.rst
+ pages/documentation/riscv_atom.rst
pages/documentation/soc_targets.rst
+ pages/documentation/memory_map.rst
+ pages/documentation/bootloader.rst
pages/documentation/atomsim/atomsim.rst
pages/documentation/scar.rst
pages/documentation/convelf.rst
+ pages/documentation/libcatom.rst
+ pages/documentation/build_flow.rst
+ pages/documentation/performance.rst
+ pages/documentation/fpga_results.rst
Indices and tables
diff --git a/docs/pages/documentation/atomsim/adding_target.rst b/docs/pages/documentation/atomsim/adding_target.rst
deleted file mode 100644
index 020bb8b3..00000000
--- a/docs/pages/documentation/atomsim/adding_target.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-Adding a New Target to AtomSim
-###############################
-
-This is a placeholder
\ No newline at end of file
diff --git a/docs/pages/documentation/atomsim/atomsim.rst b/docs/pages/documentation/atomsim/atomsim.rst
index b000014b..2cd27ee5 100644
--- a/docs/pages/documentation/atomsim/atomsim.rst
+++ b/docs/pages/documentation/atomsim/atomsim.rst
@@ -2,26 +2,54 @@ AtomSim: A simulation tool for Atom based SoCs
###############################################
AtomSim is an interactive RTL simulator for Atom based SoCs. It provides an interface which is similar to the RISC-V
-Spike simulator, but simulates the actual RTL in the backend. Atomsim is a modular and flexible simulaion solution
-based on Verilator, due to which it can achieve a very high simulation rate. AtomSim is a feature rich tool which makes
-it very powerful for debugging code on the Atom CPU.
+Spike simulator, but simulates the actual RTL in the backend. AtomSim is a feature rich tool which makes it very powerful
+for debugging code on the Atom CPU.
Key Features of AtomSim are listed below:
#. Achieves a high simulation rate due to use of Verilator.
#. Target Configurable, can be easily extended for new SoC designs.
#. In-built debug mode similar to spike.
-#. External Debug Support using OpenOCD & GDB ``[TODO]``.
+#. External Debug Support using OpenOCD & GDB **[TODO]**.
#. Supports VCD trace generation.
#. Supports memory dumps.
#. Compatible with RISC-V compliance tests framework.
#. Compatible with SCAR framework.
-The following figure depicts the architecture of atomsim.
+.. tip::
+ See :doc:`../../getting_started/building` for info on how to build AtomSim.
+
+The following figure depicts the architecture of AtomSim.
.. image:: ../../../diagrams/atomsim_arch.png
-See :doc:`../../getting_started/building` for info on how to build atomsim.
+.. _atomsim_arch:
+
+AtomSim Architecture
+*********************
+AtomSim is designed in a modular fashion with a clear API between the layers. There are 3 main layers in AtomSim,
+1) frontend, 2) middle-end, and 3) backend.
+
+Frontend
+=========
+Frontend is the interactive part of the simulator. User can interact with AtomSim in the following two modes of operation.
+
+#. :ref:`Normal Mode `
+#. :ref:`Debug Mode `
+
+
+Middle-end
+===========
+Middle-end contains references to signals and states of the CPU. These states and signal values are set by the backend
+and read by the frontend to display information.
+
+
+Backend
+========
+Backend is the part which probes the signal values and CPU state from the RTL. All backends extend from the ``Backend``
+class.
+
+
To view available command line options, use:
@@ -30,15 +58,6 @@ To view available command line options, use:
$ atomsim --help
-Modes of Operation
-*******************
-Atomsim supports two modes of operation:
-
-.. toctree::
- :maxdepth: 1
-
- debug_mode.rst
- normal_mode.rst
AtomSim Topics
@@ -46,7 +65,6 @@ AtomSim Topics
.. toctree::
:maxdepth: 1
-
cli_args.rst
- code_structure.rst
- adding_target.rst
+ atomsim_modes.rst
+ atomsim_developers_guide.rst
diff --git a/docs/pages/documentation/atomsim/atomsim_developers_guide.rst b/docs/pages/documentation/atomsim/atomsim_developers_guide.rst
new file mode 100644
index 00000000..3a04a4d2
--- /dev/null
+++ b/docs/pages/documentation/atomsim/atomsim_developers_guide.rst
@@ -0,0 +1,31 @@
+AtomSim Developer's Guide
+##########################
+
+AtomSim Code Structure
+=======================
+
+AtomSim is designed in a modular fashion to allow portability across platforms not just limited to RISC-V Atom. Checkout
+:ref:`AtomSim architecture`. The source code for atomsim is located under ``RVATOM/sim`` folder. Atomsim
+comprises of an interactive frontend (implemented in ``interactive.cpp``), middle-end (implemented in ``simstate.cpp``)
+and a backends for different *soctargets* (implemened in ``backend_.cpp``). All AtomSim backends are
+implemented as a child-class of the *Backend* template class (implemented in ``backend.hpp``). The backend class
+implements the RTL facing side of AtomSim and is responsible for reading register values and driving any signals through
+the *Testbench* class (implemented in ``testbench.hpp``).
+
+Adding a New Backend to AtomSim
+================================
+
+- Adding new backend involves adding a new backend class that extends the *Backend* class (in ``backend.hpp``).
+- All soctarget backends must override all the methods marked with ``[** OVERRIDE **]`` comment in the *Backend* class
+ (parent) as bare-minimum.
+- The methods marked with ``[** MAY OVERRIDE **]`` can optionally be overriden in child classes depending on the intended
+ functionality.
+- To allow AtomSim to *peek* and *poke* into SoC memory, user must override the ``fetch()`` and ``store()`` methods.
+- The backend may optioanlly use the testbench class from (``testbench.hpp``) to implement the low-level RTL facing
+ functionality.
+- Users can use the *BitbangUART* class is provided in the ``bitbang_uart.cpp`` to emulate a UART device being connected
+ to SoC. Additioanlly, the *Vuart* class is provided in ``vuart.cpp`` can be used to interface with linux serial ports.
+- Users may intend to not simulate the whole SoC in RTL and therefore they can create their own C++ modules to emulate
+ some functionality and call them from their backends. One example of this is the :ref:`AtomBones`
+ soctarget which only simulates the processor in RTL, everything else like memories (implemented in ``memory.cpp``),
+ uart, etc. is emulated in C++.
\ No newline at end of file
diff --git a/docs/pages/documentation/atomsim/atomsim_modes.rst b/docs/pages/documentation/atomsim/atomsim_modes.rst
new file mode 100644
index 00000000..0192b70e
--- /dev/null
+++ b/docs/pages/documentation/atomsim/atomsim_modes.rst
@@ -0,0 +1,98 @@
+AtomSim Simulation Modes
+#########################
+
+.. _atomsim_normal_mode:
+
+AtomSim can be run in 2 modes, normal and interactive mode.
+
+Normal Mode
+************
+In this mode of simulation, no debug information is printed. Optionally user can enable printing of UART traffic to
+stdout using ``--enable-uart-dump / -u`` CLI option while invoking atomsim. Using ``--verbose / -v`` flag shows
+additional useful information. Checkout :doc:`cli_args` for information on CLI options.
+
+.. code-block:: bash
+
+ $ atomsim sw/examples/banner/banner.elf -v
+ ___ __ _____
+ / _ |/ /____ __ _ / __(_)_ _
+ / __ / __/ _ \/ ' \_\ \/ / ' \
+ /_/ |_\__/\___/_/_/_/___/_/_/_/_/ v2.2
+ soctarget: hydrogensoc
+ Initializing ram
+ Initialization complete!
+ EBreak hit at 0x2000007c
+ Exiting..
+
+
+.. _atomsim_debug_mode:
+
+Debug/Interactive Mode
+***********************
+Debug/Interactive mode of AtomSim presents a console interface to the user, allowing them to interact with the simulation
+in real-time. The console is similar to the GDB console and inherits many features from it like stepping, breakpoints etc.
+
+To invoke AtomSim in interactive debug mode, invoke atomsim with ``--debug / -d`` flag.
+
+.. code-block:: bash
+
+ ___ __ _____
+ / _ |/ /____ __ _ / __(_)_ _
+ / __ / __/ _ \/ ' \_\ \/ / ' \
+ /_/ |_\__/\___/_/_/_/___/_/_/_/_/ v2.2
+ [ 1] PC: 0x00000000, IR: 0x00000013, _
+ atomsim>
+
+
+As shown above, AtomSim will display the current cycle count, PC value, Instruction Register value and its disassembly
+respectively. To see register file contents, users can use the ``info / i`` command in the AtomSim console.
+
+Alternatively, If invoked with both ``--debug / -d`` and ``--verbose / -v`` CLI options, AtomSim presents a more verbose
+interface with register file contents in each cycle.
+
+.. code-block:: bash
+
+ ___ __ ____
+ / _ |/ /____ __ _ / __(_)_ _
+ / __ / __/ _ \/ ' \_\ \/ / ' \
+ /_/ |_\__/\___/_/_/_/___/_/_/_/_/ v2.2
+ soctarget: hydrogensoc
+ Initializing ram
+ Initialization complete!
+ ┌─[ 1]─────────────────────────────────────────────┐
+ │ PC: 0x00000000 PC_f: 0x00010000 ( +65536 ) │
+ │ IR: 0x00000013 _ │
+ └──────────────────────────────────────────────────────────┘
+ x0 (zero) : 0x00000000 x16 (a6) : 0x00000000
+ x1 (ra) : 0x00000000 x17 (a7) : 0x00000000
+ x2 (sp) : 0x00000000 x18 (s2) : 0x00000000
+ x3 (gp) : 0x00000000 x19 (s3) : 0x00000000
+ x4 (tp) : 0x00000000 x20 (s4) : 0x00000000
+ x5 (t0) : 0x00000000 x21 (s5) : 0x00000000
+ x6 (t1) : 0x00000000 x22 (s6) : 0x00000000
+ x7 (t2) : 0x00000000 x23 (s7) : 0x00000000
+ x8 (s0/fp): 0x00000000 x24 (s8) : 0x00000000
+ x9 (s1) : 0x00000000 x25 (s9) : 0x00000000
+ x10 (a0) : 0x00000000 x26 (s10) : 0x00000000
+ x11 (a1) : 0x00000000 x27 (s11) : 0x00000000
+ x12 (a2) : 0x00000000 x28 (t3) : 0x00000000
+ x13 (a3) : 0x00000000 x29 (t4) : 0x00000000
+ x14 (a4) : 0x00000000 x30 (t5) : 0x00000000
+ x15 (a5) : 0x00000000 x31 (t6) : 0x00000000
+ atomsim>
+
+Try the ``help`` command to checkout the commands available in AtomSim console.
+
+Tips for using AtomSim in interactive mode
+===========================================
+- If simulation is run in normal mode, pressing :kbd:`ctrl` + :kbd:`c` returns AtomSim to interactive mode and pressing
+ :kbd:`ctrl` + :kbd:`c` in interactive mode terminates the simulation.
+- AtomSim has shorter aliases for most of the command names which can be seen in command help.
+- AtomSim console is based on the linux readline library which allows user to press :kbd:`up` / :kbd:`down` arrow keys
+ to cycle between previously entered commands.
+- If user presses :kbd:`enter` without entering a command, AtomSim executes the last executed command.
+- When entering numeric values in console such as addresses, users can specify in decimal, hexadecimal (by prefixing
+ the value with **0x**), or binary (by prefixng the value with **0b**).
+- Register names can be specified as physical register names (*x0, x1, x2 ...*) or their ABI names (*zero, ra, sp...*)
+- Some of effects of CLI arguments can be overridden in the AtomSim console, like enabling/disabling trace, verbosity etc.
+- Lastly, refer to the ``help`` command to find most up-to-date information related to the AtomSim console.
diff --git a/docs/pages/documentation/atomsim/cli_args.rst b/docs/pages/documentation/atomsim/cli_args.rst
index 36137a07..a338ae6d 100644
--- a/docs/pages/documentation/atomsim/cli_args.rst
+++ b/docs/pages/documentation/atomsim/cli_args.rst
@@ -1,29 +1,66 @@
AtomSim CLI Argument Reference
###############################
-The following are the arguments that may be passed to the AtomSim executable.
+Following are the arguments that may be passed to the AtomSim executable.
-.. code-block:: text
-
- Usage:
- $ atomsim [OPTION...] input_file
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| Option | Long Option | Function | Default value |
++========+=====================+================================================+========================================+
+| **General Options** |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| -h | --help | Show this message | |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| | --version | Show version information | |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| | --soctarget | Show current AtomSim SoC target | |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| | --no-color | Don't show colored output | |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| | --no-banner | Don't show banner | |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| -i | --input arg | Specify an input file | |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| **Debugging Options** |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| -v | --verbose | Turn on verbose output | |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| -d | --debug | Start in debug mode | |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| -t | --trace | Enable VCD tracing | |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| | --trace-file arg | Specify trace file | trace.vcd |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| | --dump-file arg | Specify dump file | dump.txt |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| | --ebreak-dump | Enable processor state dump at hault | |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| | --signature arg | Enable signature dump at hault | |
+| | | (Used for riscv compliance tests) | "" |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| **Sim Config Options** |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| | --maxitr arg | Specify maximum simulation iterations | 1000000 |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| **Backend Config Options (Common)** |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| -u | --enable-uart-dump | Enable dumping UART data (from soc) to stdout | |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| -p | --vuart-port arg | serial port for virtual UART | "" |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| -b | --vuart-baud arg | serial baud rate for virtual UART | 115200 |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| **Backend Config Options (AtomBones)** |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| | --bootrom-size arg | Specify size of bootrom to simulate (in KB) | 8 |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| | --bootrom-image arg | Specify bootrom hex image | ${RVATOM}/sw/bootloader/bootloader.hex |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| | --ram-size arg | Specify size of RAM memory to simulate (in KB) | 81920 |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| **Backend Config Options (HydrogenSoC)** |
++--------+---------------------+------------------------------------------------+----------------------------------------+
+| | --bootmode arg | Specify bootmode signal | 1 |
++--------+---------------------+------------------------------------------------+----------------------------------------+
- Config options:
- --maxitr arg Specify maximum simulation iterations (default: 10000000)
- --vuart arg use provided virtual uart port (default: Null)
- --vuart-baud arg Specify virtual uart port baudrate (default: 9600)
- Debug options:
- -v, --verbose Turn on verbose output
- -d, --debug Start in debug mode
- -t, --trace Enable VCD tracing
- --trace-dir arg Specify trace directory (default: build/trace)
- --dump-dir arg Specify dump directory (default: build/trace)
- --ebreak-dump Enable processor state dump at hault
- --signature arg Enable signature sump at hault (Used for riscv
- compliance tests) (default: "")
-
- General options:
- -h, --help Show this message
- --version Show version information
- --simtarget Show current AtomSim Target
- -i, --input arg Specify an input file
+.. note::
+ For most up-to-date information, run ``atomsim --help`` command.
diff --git a/docs/pages/documentation/atomsim/code_structure.rst b/docs/pages/documentation/atomsim/code_structure.rst
deleted file mode 100644
index 927af680..00000000
--- a/docs/pages/documentation/atomsim/code_structure.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-AtomSim Code Structure
-#######################
-
-This is a Placeholder
\ No newline at end of file
diff --git a/docs/pages/documentation/atomsim/debug_mode.rst b/docs/pages/documentation/atomsim/debug_mode.rst
deleted file mode 100644
index 41237068..00000000
--- a/docs/pages/documentation/atomsim/debug_mode.rst
+++ /dev/null
@@ -1,149 +0,0 @@
-Debug/Interactive Mode
-#######################
-In this mode of simulation, Contents of Program counter (in both stages), Instruction register, instruction disassembly and contents of registers (if verbosity is set) are printed to stdout. A console with symbol ``:`` is also displayed at the bottom if screen for user to enter various commands to control the simulation. To step through one clock cycle, user can simply press :kbd:`enter` key (without entering anything in console).
-
-To invoke interactive debug mode, invoke atomsim with `-d` & `-v` flag:
-
-::
-
- $ ./build/bin/atomsim hello.elf -d -v
- Segments found : 2
- Loading Segment 0 @ 0x00000000 --- done
- Loading Segment 1 @ 0x00010000 --- done
- Entry point : 0x00000000
- Initialization complete!
- :
- -< 1 >--------------------------------------------
- F-STAGE | pc : 0x00000034 (+4) ()
- E-STAGE V pc : 0x00000000 ir : 0x00010517 [addi x1, 0x33f]
- ---------------------------------------------------
- x0 (zero) : 0x00000000 x16 (a6) : 0x00000000
- x1 (ra) : 0x00000000 x17 (a7) : 0x00000000
- x2 (sp) : 0x00000000 x18 (s2) : 0x00000000
- x3 (gp) : 0x00000000 x19 (s3) : 0x00000000
- x4 (tp) : 0x00000000 x20 (s4) : 0x00000000
- x5 (t0) : 0x00000000 x21 (s5) : 0x00000000
- x6 (t1) : 0x00033000 x22 (s6) : 0x00000400
- x7 (t2) : 0x00000000 x23 (s7) : 0x00000000
- x8 (s0/fp): 0x00000000 x24 (s8) : 0x00000000
- x9 (s1) : 0x00000000 x25 (s9) : 0x00000000
- x10 (a0) : 0x00000000 x26 (s10) : 0x00000000
- x11 (a1) : 0x00000000 x27 (s11) : 0x00000000
- x12 (a2) : 0x00000000 x28 (t3) : 0x00000000
- x13 (a3) : 0x00000000 x29 (t4) : 0x00000000
- x14 (a4) : 0x00000000 x30 (t5) : 0x00000000
- x15 (a5) : 0x00000000 x31 (t6) : 0x00000000
- :
-
-
-Interacting With Debug Console
-*******************************
-
-Displaying contents of a register
-==================================
-Contents of register can be displayed simply typing its name (abi names are also supported) on the
-console. ex:
-
-::
-
- : reg x0
- x0 = 0x000045cf
- : reg ra
- ra = 0x0000301e
-
-Use ':' to display a range of registers. ex:
-
-::
-
- : x0 : x1
-
-
-Displaying Contents of a memory location
-========================================
-::
-
- : m
-
-Address can be specified in hex or decimal.
-Use sizetag to specify the size of data to be fetched, b for byte, h for half-word and w for word
-(default is word).
-
-::
-
- : m 0x30 b
- mem[0x30] = 01
-
-Use ':' to display contents of memory in a range. ex:
-
-::
-
- : m 0x32:0x38 w
- mem[0x30] = 01 30 cf 21
- mem[0x38] = 11 70 ab cf
-
-
-Generating VCD traces
-=====================
-Tracing can be enabled by:
-
-::
-
- : trace out.vcd
- Trace enabled : "./out.vcd" opened for output.
-
-or by passing --trace option while invoking atomsim.
-
-Tracing can be disabled by:
-
-::
-
- :notrace
- Trace disabled
-
-
-Controlling execution
-=====================
-You can advance the simulation by one clock cycle by pressing the enter-key. You can also execute
-until a desired equality is reached:
-
-1. until value of a register becomes
- ::
-
- : until
-
-2. until value of a memory address becomes
- ::
-
- : until
-
-3. while is true
- ::
-
- : while
-
-4. Execute for specified number of ticks
- ::
-
- : for
-
-5. You can continue execution indefinitely by:
- ::
-
- : r
-
-6. To end the simulation from the debug prompt:
- ::
-
- : q
-
- or
-
- ::
-
- : quit
-
- .. note::
- At any point during execution (even without -d), you can enter the interactive debug mode with :kbd:`ctrl` + :kbd:`c`.
-
-7. Miscellaneous
- verbose-on & verbose off commands can be used to turn on /off verbosity.
diff --git a/docs/pages/documentation/atomsim/normal_mode.rst b/docs/pages/documentation/atomsim/normal_mode.rst
deleted file mode 100644
index 010341b6..00000000
--- a/docs/pages/documentation/atomsim/normal_mode.rst
+++ /dev/null
@@ -1,29 +0,0 @@
-Normal Mode
-############
-
-In this mode of simulation, no debug information is printed. Only serial data recieved from the system is printed to the stdout. Using ``--verbose / -v`` flag shows additional useful information.
-
-.. code-block:: bash
-
- $ atomsim sw/examples/banner/banner.elf -v
- Input File: hello-asm/hello.elf
- Resetting..
- Relaying uart-rx to stdout (Note: This mode does not support uart-tx)
- Initialization complete!
- Hello World!
- -- from Assembly
-
- Haulting @ tick 931
-
-Redierecting AtomSim Output
-****************************
-All verbose information is printed on **stderror** stream while the output of the program is printed on the **stdout**. Therefore one can easily redirect them to two different files if needed. This can be done as follows:
-
-.. code-block::
-
- $ atomsim sw/examples/banner/banner.elf -v 1> output.log 2> sim.log
-
-
-Reverting to Debug Mode from Normal Mode
-*****************************************
-During a program's execution on atomsim, if user presses :kbd:`ctrl` + :kbd:`c` atomsim quits by default. This behaviour can be changed by invoking AtomSim with ``___to_be_added____`` options. With this option, anytime during the simulation, it is possible to revert to debug mode from normal mode by pressing :kbd:`ctrl` + :kbd:`c`. To quit AtomSim, press :kbd:`ctrl` + :kbd:`c` twice or press :kbd:`ctrl` + :kbd:`c` once and then use the *quit* command on debug console.
\ No newline at end of file
diff --git a/docs/pages/documentation/bootloader.rst b/docs/pages/documentation/bootloader.rst
new file mode 100644
index 00000000..94228af8
--- /dev/null
+++ b/docs/pages/documentation/bootloader.rst
@@ -0,0 +1,66 @@
+RISC-V Atom Bootloader
+#######################
+
+The RISC-V Atom bootloader is a **stage-0** bootloader. It is loaded in the BootROM and executable as the first thing
+after reset. The source code for Atom bootloader is located in ``RVATOM/sw/bootloader`` subdirectory. The bootloader can
+be built manually using the following *make* command.
+
+.. code-block::
+
+ $ cd sw/bootloader
+ $ make soctarget=hydrogensoc
+
+During run-time, the bootloader uses RAM to implement stack. it includes code for platform initialization, loading
+executable and control transfer. Bootloader provides various *bootmodes* to the user allowing the user to control the
+boot process.
+
+Following is a list of actions that are performed step-by-step during the boot process:
+
+#. Upon reset the control is transferred to reset vector, which by default points to start of BootROM.
+#. CPU starts executing the stage-0 bootloader.
+ #. Bootloader performs common initialization.
+ #. Bootloader then performs any platform specific initializations.
+ #. Bootloader reads the *bootmode* pins and decides the bootmode.
+ #. Actions are performed according to bootmode, which includes loading the executable into RAM from correct source.
+ #. Finally, the control is transferred to User program.
+
+
+Bootmodes
+**********
+
+RISC-V Atom bootloader mainly supports 4 boot modes:
+
++----------+---------------+----------------------------------------------------------------------+
+| Pinval | Bootmode | Function |
++==========+===============+======================================================================+
+| ``0b00`` | FLASHBoot | Loads a binary image into RAM from FLASH memory using SPI |
++----------+---------------+----------------------------------------------------------------------+
+| ``0b01`` | Jump to RAM | Jumps to RAM, without memory initialization |
++----------+---------------+----------------------------------------------------------------------+
+| ``0b10`` | UARTBoot | Loads a binary image into RAM from UART stream using XMODEM protocol |
++----------+---------------+----------------------------------------------------------------------+
+| ``0b11`` | Infinite Loop | Executes an infinite loop |
++----------+---------------+----------------------------------------------------------------------+
+
+FLASHBoot
+==========
+In this bootmode, user must write the binary image for the program directly in FLASH memory at a predefined offset value.
+During boot, this binary image will be copied as it is to the RAM and will be executed. FLASHBoot requires the SPI IP to
+communicate with FLASH memory and will give an boot-panic error if its missing.
+
+UARTBoot
+=========
+In this mode, the bootloader obtains the program binary image from UART using the
+`XMODEM protocol `_. It supports XMODEM CRC16 with default packet size of 128 bytes.
+
+Transferring files over UART
+-----------------------------
+RISC-V Atom project provides the ``xmsend.py`` python script that can be used to transmit binary files over UART. *xmsend*
+can be used as follows.
+
+.. code-block:: bash
+
+ $ xmsend.py -b 115200 -p /dev/ttyUSB0 firmware.bin
+
+.. tip::
+ Make sure that no other process (like screen) is using the serial port before invoking the xmsend script.
diff --git a/docs/pages/documentation/build_flow.rst b/docs/pages/documentation/build_flow.rst
new file mode 100644
index 00000000..630b30ef
--- /dev/null
+++ b/docs/pages/documentation/build_flow.rst
@@ -0,0 +1,28 @@
+RISC-V Atom Build Flow
+#######################
+
+RISC-V Atom project uses a Make base build flow, assisted by the ``cfgparse.py`` script and JSON config files located
+under ``rtl/config`` directory. There exists a JSON config file for each / a group of RTL components which specifies
+how to compile them, any required flags, macros etc. This implies, each soctarget or a variation of an soctarget has a
+JSON which is used to build it.
+
+This approach has many advantages over a static approach of incorporating everything in the Makefiles. The ``cfgparse.py``
+is used to parse the json files and extract all the necessary information to build a target like compiler flags, source
+files etc. Not only that, cfgparse script allows JSON files to include dependency information on other JSON files, variable
+substitution and polymorphism.
+
+Some Information on the Structure of JSON config files
+*******************************************************
+
+#. One JSON file can depend on one or more JSON files (specified in ``includes`` attribute), allowing all of them to be
+ parsed together.
+#. A JSON file can specify parameters in the ``params`` attribute which can be used as variables in conditional statements
+ throughout the script.
+#. Parameters in the included JSON files can be overridden by the parameters in the JSON file which included it.
+#. A conditional statement can be specified as ``[?:]``, where if the condition is true, ``A`` is
+ substituted in the string, else ``B`` is substituted in the string. Users are free to omit A, B, or both depending on
+ the requirement.
+#. JSON config files support basic polymorphism. They can inherit attributes from the another JSON file using the
+ ``extends`` attribute. This is useful when users want to specify a special configuration of an existing configuration
+ without duplicating the contents of the original file.
+#. Parameters in the *child* config files override parameters in the parent *config* file.
diff --git a/docs/pages/overview/fpga_results.rst b/docs/pages/documentation/fpga_results.rst
similarity index 100%
rename from docs/pages/overview/fpga_results.rst
rename to docs/pages/documentation/fpga_results.rst
diff --git a/docs/pages/documentation/libcatom.rst b/docs/pages/documentation/libcatom.rst
new file mode 100644
index 00000000..9038d4fd
--- /dev/null
+++ b/docs/pages/documentation/libcatom.rst
@@ -0,0 +1,26 @@
+Libcatom: C standard library for RISC-V Atom
+#############################################
+
+Libcatom is a minimal C standard library for RISCV-Atom. It consists of startup code, basic stdio library, heap allocator,
+soc-specific libraries such as drivers for peripherals such as GPIO, UART, SPI etc. and linker scripts. The soc-specific
+sources (such as drivers) are located inside the corresponding folder. ``platform.h`` header defines most of the
+platform-specific macros for libcatom. Libcatom does not define the software multiply and soft floating point operations
+and therefore uses the standard library provided with the compiler.
+
+Building Libcatom
+******************
+Libcatom can be built as follows.
+
+
+.. code-block:: bash
+
+ $ make soctarget=hydrogensoc sim=1
+
+
+.. tip::
+ You don't need to build Libcatom separately in most cases as it will be built automatically (with correct soc target)
+ while building AtomSim.
+
+.. note::
+ You must use ``sim=1`` option to build the library for simulation. If you see framing errors in UART output during
+ simulation, most likely you haven't built the library and anything that uses it with ``sim=1``.
\ No newline at end of file
diff --git a/docs/pages/documentation/memory_map.rst b/docs/pages/documentation/memory_map.rst
new file mode 100644
index 00000000..86b73916
--- /dev/null
+++ b/docs/pages/documentation/memory_map.rst
@@ -0,0 +1,45 @@
+Memory Map and Boot Flow
+#########################
+
+Memory Map
+***********
+
+The following image shows the memory map of Atom-based SoCs.
+
+.. image:: /diagrams/memory_map.png
+
+The column **C** shows the memory map template for all RISC-V Atom based SoCs. Column **D** and **E** show the memory map
+for AtomBones and HydrogenSoC respectively.
+
+Boot Flow
+**********
+Upon reset, the core jumps to the reset vector (default: ``0x10000``) which points to the start of BootROM. RISC-V Atom
+BootROM includes a **stage-0 bootloader** that is automatically built and included when building the AtomSim or running FPGA
+builds. The stage-0 bootloader uses RAM for stack. It initializes the platform, loads the user program in RAM and finally
+transfers control to the user program. The user program often includes a **stage-1 bootloader** which sets up the runtime
+environment and standard library before executing the application.
+
+.. graphviz::
+
+ digraph G {
+ rankdir=LR;
+ reset_vec [label="Reset Vector", shape=rect, style=filled, fillcolor=white];
+ subgraph cluster_0 {
+ style=filled;
+ fillcolor=gray;
+ label="BootROM";
+ stage0_bl [label="Stage-0\nBootloader", shape=rect, style=filled, fillcolor=yellow];
+ }
+ subgraph cluster_1 {
+ style=filled;
+ fillcolor=gray;
+ label="RAM";
+ stage1_bl [label="Stage-1\nBootloader", shape=rect, style=filled, fillcolor=orange];
+ prog [shape=rect, label="User Program", style=filled, fillcolor=cyan];
+ stage1_bl -> prog [label="launch"];
+ }
+ reset_vec -> stage0_bl;
+ stage0_bl -> stage1_bl;
+ }
+
+To know more about the stage-0 bootloader, see :doc:`this` page.
\ No newline at end of file
diff --git a/docs/pages/overview/performance.rst b/docs/pages/documentation/performance.rst
similarity index 100%
rename from docs/pages/overview/performance.rst
rename to docs/pages/documentation/performance.rst
diff --git a/docs/pages/documentation/riscv_atom.rst b/docs/pages/documentation/riscv_atom.rst
new file mode 100644
index 00000000..cf785668
--- /dev/null
+++ b/docs/pages/documentation/riscv_atom.rst
@@ -0,0 +1,132 @@
+RISC-V Atom CPU
+################
+Atom is an open-source 32-bit soft-core processor written in Verilog. It is an embedded class processor
+architecture that implements the open-source RISC-V instruction set architecture (RV32IC), as described
+in the RISC-V unprivileged spec. Atom contains a two stage pipeline inspired from arm cortex m0+.
+
+The following diagram showcases the architecture of RISC-V Atom core.
+
+.. image:: /diagrams/RISCVAtom_arch.png
+
+Atom Pipeline Stages
+*********************
+The pipeline is divided into two stages. These are explained below.
+
+Stage-1: Fetch
+===============
+
+Fetch unit is responsible for fetching instructions from instruction memory through the IPort. It uses a 32-bit Program
+Counter (PC) to keep track of the address of the instruction being fetched. After the instruction is successfully fetched,
+Program counter is incremented by either 4 or 2 (in case of compressed instruction). Fetch stage also includes pipeline
+control logic which controls pipeline stalls and flushes. If compressed extension in enables, Fetch stage includes
+RISC-V Compressed Aligner which aligns all the memory requests to 4 byte boundary. It also includes RISC-V Compressed
+instruction decoder, which decodes 16-bit compressed instructions to their 32-bit equivalents.
+
+Stage-2: Decode, Execute & Write-back
+======================================
+
+In this stage, the instruction from Instruction Register (IR) is decoded and executed. First, the decode unit decodes the
+instruction and sets all the control signals in order to configure the data-path to execute the instruction. Parallelly,
+operand registers are fetched and 32-bit immediate value is generated. Next, ALU/Comparator does the necessary
+computation/comparison and the results are written back to register file. In case current instruction invokes a memory
+request, stage-2 is stalled until response is received. Memload module is used extract the correct data from the received
+memory response. If CSR extension is enabled, CSR Unit is included in this stage. CSR Unit provides Control and status
+registers which perform various special functions. SR Unit also includes exceptions and interrupt handling logic if Exceptions
+and interrupts are enabled. Branch calculation also happens in this stage and if branch is taken, a signal is sent to
+the pipeline control logic to flush the pipeline.
+
+Atom Interface
+***************
+Atom module is defined in the file ``RVATOM/rtl/core/atomRV.v``. It has has two independent ports (IPort & DPort)
+which it uses to access memory. Both the ports use a generic ready-valid handshaking protocol to transfer data. We also
+provide wrappers to the core to convert the generic handshaking protocol to standard bus protocols such as Wishbone.
+These wrappers are specified in the following files.
+
+#. Wishbone-B4 Wrapper with separate instruction and data port: ``RVATOM/rtl/core/atomRV_wb.v``
+
+
+Atom Configuration operations
+******************************
+
++----------------+------------------------------------------------------+
+| Macro | Function |
++================+======================================================+
+| ``EN_RVC`` | Enables support for RISC-V Compressed Extension |
++----------------+------------------------------------------------------+
+| ``EN_RVZICSR`` | Enables Control and Status Registers (CSRs) |
++----------------+------------------------------------------------------+
+| ``EN_EXCEPT`` | Enables support for RISC-V interrupts and exceptions |
++----------------+------------------------------------------------------+
+| ``DPI_LOGGER`` | Enable DPI Logger |
++----------------+------------------------------------------------------+
+
+
+RISC-V Atom RTL
+****************
+RISC-V Atom is written in Verilog. The RTL specification for Atom is divided into 3 categories, *core*, *uncore* and *soc*,
+all of which reside in the ``rtl`` directory.
+
+Core Directory
+==============
+The ``rtl/core`` subdirectory contains the the *core* components of the CPU such as register file, ALU, decode unit etc.
+It also contains Verilog header files like ``Defs.vh`` and ``Utils.vh``. ``Defs.vh`` contain various signal enumerations
+and other parameters internal to the processor. ``Utils.vh`` defines some useful utility macros.
+
+
+Uncore Directory
+================
+The ``rtl/uncore`` subdirectory contains the SoC peripheral components such as UART, GPIO, memories, etc. It also
+contains the wishbone wrappers of some non-wishbone components. SoC implementations of the Atom processor usually
+instantiate these hardware modules in their implementations.
+
+
+SoC directory
+==============
+The top level Verilog modules for SoCs (such as AtomBones & HydrogenSoC) are present in the ``rtl/soc`` directory in the
+corresponding subdirectories. Each of these top level modules are configured by their respective configuration headers
+(_Config.vh file). These configuration headers contain the macros used in the top-module definitions to control the
+generation of SoC, various sub-components and their parameters.
+
+
+RTL Features
+*************
+
+DPI Logger
+===========
+DPI Logger is a System Verilog DPI based logging mechanism provided with the RTL. It can be used to dump useful run-time
+debug information such as PC values, Jump addresses, Loads and Stores, etc. into a log file. This module is present in
+the ``rtl/dpi`` subdirectory.
+
+To enable DPI Logger simply define ``DPI_LOGGER`` macro in the top-module or in the CLI as ``-DDPI_LOGGER``. This will
+trigger the inclusion of the ``rtl/dpi/util_dpi.vh`` header in ``rtl/core/Utils.vh``. User is free include the
+``rtl/core/Utils.vh`` header file in any Verilog file that needs to be debugged.
+
+To log information, user first needs to call the ``dpi_trace_start()`` function somewhere in the rtl as following.
+
+.. code-block:: verilog
+
+ initial begin
+ dpi_trace_start();
+ end
+
+Then the ``dpi_trace()`` function can be used to dump information. Its syntax is exactly same as the Verilog ``$display``
+system function. Example of logging the jumps during code execution is provided in the ``AtomRV.v`` file and is also
+shown below.
+
+.. code-block:: verilog
+
+ `ifdef DPI_LOGGER
+ initial begin
+ dpi_logger_start(); // begin logging
+ end
+ `endif
+
+ `ifdef LOG_RVATOM_JUMP
+ always @(posedge clk_i) begin
+ if(jump_decision) // on some trigger condition
+ dpi_logger("Jump address=0x%x\n", {alu_out[31:1], 1'b0}); // dump information
+ end
+ `endif
+
+For logging the Jumps, user must also define the ``LOG_ATOMRV_JUMP`` macro in a similar way. This will generate a ``run.log``
+file in the current directory containing all the dumped information.
diff --git a/docs/pages/documentation/riscv_atom/riscv_atom.rst b/docs/pages/documentation/riscv_atom/riscv_atom.rst
deleted file mode 100644
index a953d167..00000000
--- a/docs/pages/documentation/riscv_atom/riscv_atom.rst
+++ /dev/null
@@ -1,56 +0,0 @@
-RISC-V Atom (Core)
-###################
-Atom is an open-source 32-bit soft-core processor written in Verilog. It is an embedded class processor
-architecture that implements the open-source RISC-V instruction set architecture (RV32I), as described
-in the RISC-V unprivileged spec. Atom contains a two stage pipeline inspired from arm cortex m0+.
-
-The following diagram showcases the architecture of RISC-V Atom core.
-
-.. image:: ../../../diagrams/atom_architecture_diagram.png
-
-Processor Pipeline Stages
-**************************
-The pipeline is divided into two stages. These are explained below.
-
-Stage-1: Fetch
-===============
-
-Fetch unit is responsible for fetching instructions from instruction memory through the IBUS. It uses a
-32-bit register called "Program counter" to keep track of the address of the instruction being fetched.
-After the instruction is successfully fetched, Program counter is incremented by 4.
-
-Stage-2: Decode, Execute & Write-back
-======================================
-
-In this stage, the instruction is decoded, all the signal are assigned in order to configure
-data-path to execute the instruction. & registers are fetched. A 32 bit immediate is generated by the
-ImmGen unit. ALU then execute the instruction which is followed by write-back into the register file.
-Branch calculation also happens in this stage and if branch is taken, the pipeline is flushed. Comparator
-module in this stage is used for all the instructions that involve comparison like slt, slti, beq, bltu etc.
-
-Processor Interface
-********************
-RISCV-Atom module is defined in the file ``RVATOM/rtl/core/atomRV.v``. It has has two independent ports
-which it uses to access memory.
-
-#. Instruction port &
-#. Data port
-
-Both the ports use a generic ready-valid handshaking protocol to transfer data.
-
-We also provide wrappers to the core to convert the generic handshaking protocol to standard bus protocols such
-as Wishbobne. These wrappers are specified in the following files.
-
-#. Wishbobne-B4 Wrapper with separate instruction and data port: ``RVATOM/rtl/core/atomRV_wb.v``
-
-
-
-
-
-
-.. toctree::
- :maxdepth: 1
- :caption: Related Topics
-
- rtl.rst
-
\ No newline at end of file
diff --git a/docs/pages/documentation/riscv_atom/rtl.rst b/docs/pages/documentation/riscv_atom/rtl.rst
deleted file mode 100644
index 10d6974c..00000000
--- a/docs/pages/documentation/riscv_atom/rtl.rst
+++ /dev/null
@@ -1,71 +0,0 @@
-RISC-V Atom RTL
-################
-RISC-V Atom is written in Verilog. Its RTL is divided into 2 categories, core and uncore,
-both of which reside in the `rtl` directory in `core` and `uncore` subdirectories respectively.
-
-Rtl directory
-**************
-The top level verilog modules (atombones & hydrogensoc) are present in the `rtl` directory. Each
-of these top level modules are configured by their respective configure headers (_Config.vh file).
-These configuration headers contain the macros used in the top-module definitions to control the
-generation of various sub-components and their parameters.
-
-
-Core directory
-==============
-`core` directory contains the the *core* components of the CPU such as register file, alu,
-decode unit etc. It also contains verilog header files like `Defs.vh` and `Utils.vh`. `Defs.vh`
-defines various signal eunumerations and other parameters internal to the processor. `Utils.vh`
-defines some useful utility macros.
-
-
-Uncore directory
-================
-The `uncore` subdirectory contains all the peripheral components such as uart, gpio, ram, rom etc.
-This also includes the wishbone wrappers of some non-wishbone components. SoC implementations of the
-Atom processor usually instantiate these hardware modules in their implementations.
-
-RTL Features
-*************
-
-DPI Logger
-===========
-DPI Logger is a SystemVerilog DPI based logging mechanism provided with the RTL. It can be used to
-dump useful run-time debug information such as PC values, Jump addresses, Loads and Stores, etc.
-into a log file. This module is present in the `rtl/dpi` subdirectory.
-
-To enable DPI Logger simply define `DPI_LOGGER` macro in the topmodule or in the Makefile VFLAGS variable
-as `-DDPI_LOGGER`. This will trigger the inclusion of the `rtl/dpi/util_dpi.vh` header in `rtl/core/Utils.vh`.
-User is free include the `rtl/core/Utils.vh` header file in any verilog file that needs to be debugged.
-
-To log information, user first needs to call the `dpi_trace_start()` function somewhere in the rtl as following.
-
-.. code-block:: verilog
-
- initial begin
- dpi_trace_start();
- end
-
-Then the `dpi_trace()` function can be used to dump information. Its syntax is exactly same as the verilog
-`$display` system funciton. Example of logging the jump is provided in the `AtomRV.v` file and is also shown
-below.
-
-.. code-block:: verilog
-
- `ifdef DPI_LOGGER
- initial begin
- dpi_logger_start(); // begin logging
- end
- `endif
-
- `ifdef LOG_RVATOM_JUMP
- always @(posedge clk_i) begin
- if(jump_decision) // on some trigger condition
- dpi_logger("Jump address=0x%x\n", {alu_out[31:1], 1'b0}); // dump information
- end
- `endif
-
-For logging the Jumps, user must also define the `LOG_ATOMRV_JUMP` macro in a similar way. This will generate a
-"run.log" file in the current directory containt all the dumped information.
-
-
diff --git a/docs/pages/documentation/scar.rst b/docs/pages/documentation/scar.rst
index 69f5cb9c..98319cca 100644
--- a/docs/pages/documentation/scar.rst
+++ b/docs/pages/documentation/scar.rst
@@ -1,62 +1,86 @@
SCAR: Search Compile Assert Run
################################
-SCAR is a processor verification framework in python. SCAR performs a set of assembly level tests to verify the processor implementation. Each assembly test checks for one particular functionality of the processor. SCAR does this by examining a state dump file after the processor is done with executing a test code. This state dump file then checked assuming a set of assertions in the form of expected register values. These assertions are provided in the assembly file itself. SCAR is also used to verify the ISA-compliance.
+SCAR is a processor verification framework in python. SCAR performs a set of assembly level tests to verify the processor
+implementation. Each assembly test checks for one particular functionality of the processor. SCAR does this by examining
+a state dump file after the processor is done with executing a test code. This state dump file then checked assuming a
+set of assertions in the form of expected register values. These assertions are provided in a separate assertion file.
+SCAR is also used to verify the ISA-compliance.
+
+SCAR is located in ``RVATOM/test/scar`` directory.
SCAR Workflow
**************
+As the name suggests:
+
+#. **Search:** SCAR searches for all the available assembly level tests specified in a config JSON file. The config JSON
+ file also specifies the corresponding assertion files.
+#. **Compile:** SCAR then compiles all the tests with a user-defined linker script.
+#. **Execute:** In this step, The elf files are executed on the target simulator with a special flag which creates a
+ state dump file after execution terminates. SCAR createsa ``work`` directory to store all the outputs.
+#. **Verify:** Finally, Assertions are read from the assertion file and are then used to verify the register values in
+ the generated state dump file.
+
+Once you're finished building the RISC-V Atom project, SCAR can be invoked from the ``RVATOM`` directory itself using the
+``scar`` target in the Makefile (see make help). Following is a demo output of a run of SCAR framework on hydrogensoc.
+
+.. code-block:: bash
+
+ +------------------------------------------------------------------------------+
+ | SCAR Verification Report |
+ +------------------------------------------------------------------------------+
+ Date: 2024-02-04 19:23:21
+
+ 0). add64 - Passed All Assertions Passed
+ 1). addi - Passed All Assertions Passed
+ 2). add - Passed All Assertions Passed
+ 3). andi - Passed All Assertions Passed
+ 4). and - Passed All Assertions Passed
+ 5). auipc - Passed All Assertions Passed
+ 6). beq - Passed All Assertions Passed
+ 7). bge - Passed All Assertions Passed
+ 8). bgeu - Passed All Assertions Passed
+ 9). blt - Passed All Assertions Passed
+ 10). bltu - Passed All Assertions Passed
+ 11). bne - Passed All Assertions Passed
+ 12). function_call - Passed All Assertions Passed
+ 13). jalr - Passed All Assertions Passed
+ 14). jal - Passed All Assertions Passed
+ 15). li - Passed All Assertions Passed
+ 16). load_store_byte - Passed All Assertions Passed
+ 17). load_store_hw - Passed All Assertions Passed
+ 18). lui - Passed All Assertions Passed
+ 19). lw - Passed All Assertions Passed
+ 20). mv - Passed All Assertions Passed
+ 21). ori - Passed All Assertions Passed
+ 22). or - Passed All Assertions Passed
+ 23). slli - Passed All Assertions Passed
+ 24). sll - Passed All Assertions Passed
+ 25). slti - Passed All Assertions Passed
+ 26). sltiu - Passed All Assertions Passed
+ 27). slt - Passed All Assertions Passed
+ 28). sltu - Passed All Assertions Passed
+ 29). srai - Passed All Assertions Passed
+ 30). sra - Passed All Assertions Passed
+ 31). srli - Passed All Assertions Passed
+ 32). srl - Passed All Assertions Passed
+ 33). stack - Passed All Assertions Passed
+ 34). storew - Passed All Assertions Passed
+ 35). sub - Passed All Assertions Passed
+ 36). sw - Passed All Assertions Passed
+ 37). xori - Passed All Assertions Passed
+ 38). xor - Passed All Assertions Passed
+ ================================================================================
+ Passed tests : 39 / 39
+ Ignored tests : 0 / 39
+ Failed tests : 0 / 39
-#. **Search:** SCAR searches for all the available assembly level test in the directory and makes a list
-#. **Compile:** It then compiles all the found tests with a user-defined linker script.
-#. **Execute:** In this step, The elf files are executed on the target simulator which creates a state dump file after execution.
-#. **Verify:** Finally, Assertions are read from the assembly file containing the test. These are then used to check for mismatches in the generated state dump file.
-
-
-Assembly test format
-*********************
-The assembly file must satisfy the following criteria:
-
-#. File must have a ``_start`` label before the start of code.
-#. File must have a ``ebreak`` instraction after the end of code.
-#. File must have an assertion section at the bottom with the following format.
-
-Assertion Section Format
-========================
-The assembly file must contain a set of assertions at the bottom in the following format:
-
-::
-
- .global _start
- _start:
-
- li t0, 0x00d01010
- li t1, 0x1ddc1044
- li t2, 0xdeadbeef
- li t3, 0x22101301
- li t4, 0xfaf01569
- li t5, 0x078b102a
- li t6, 0xdae013c0
-
- add a0, t0, t1
- add a1, t1, t2
- add a2, t2, t3
- add a3, t3, t4
- add a4, t4, t5
- add a5, t5, t6
-
- nop
- nop
- ebreak
-
- # $-ASSERTIONS-$
- # eq a0 0x1eac2054
- # eq a1 0xfc89cf33
- # eq a2 0x00bdd1f0
- # eq a3 0x1d00286a
- # eq a4 0x027b2593
- # eq a5 0xe26b23ea
-
-
-State-Dump file format
-=======================
-[TODO]
\ No newline at end of file
+How to Create Your Own Tests?
+******************************
+#. Assembly file containing the test source code must have a ``_start`` label before the start of code.
+#. Assembly file must have a ``ebreak`` instraction after the end of code, this triggers the simulation to terminate.
+#. Each test file must have a corresponding assertion file (``*.asrt``) both of which need to be specified in the JSON
+ config file.
+#. The assertion file uses a python like syntax to specify one expressions per line; which could use physical register
+ names (x0, x1, x2...) or ABI names (zero, ra, sp) as variables.
+#. State dump file generated by simulator must have one key value pair per line.
diff --git a/docs/pages/documentation/soc_targets.rst b/docs/pages/documentation/soc_targets.rst
index 2ccb4a04..dee36804 100644
--- a/docs/pages/documentation/soc_targets.rst
+++ b/docs/pages/documentation/soc_targets.rst
@@ -1,16 +1,38 @@
-RISC-V Atom SoC Targets
-########################
-SoC Targets are systems that use the RISC-V atom core alongside different peripherals. From a
-complexity and functionality point-of-view, SoC Targets can be as simple as a wrapper to the core
-interface (e.g. AtomBones) and as complex as multi-core fully-fledged SOCs.
+SoC Targets
+############
+
+SoC Targets are RISC-V Atom based SoCs. These contain one or more Atom cores, peripheral IPs, crossbars memories etc.
+From a complexity and functionality point-of-view, SoC Targets can be as simple as a wrapper to the core interface
+(e.g. AtomBones) and as complex as multi-core SOCs.
+
+.. _soctarget-atombones:
AtomBones
**********
+AtomBones is a stub-target that consists of a single atom core only. All other peripherals like memories and serial port
+are simulated in C++. It is meant to be used for simulation and debugging of the core because of its faster simulation
+rate. Unlike FPGA SoC targets, AtomBones provides larger memories for experimenting with the programs without being
+constrained by physical memory size.
+
+The following figure shows the architecture of AtomBones.
-.. image:: ../../../diagrams/AtomBones.png
+.. image:: /diagrams/AtomBones.png
+ :width: 600
+AtomBones backend implements the C++ simulation of SoC peripherals. In each cycle, the backend listens to IPort and DPort
+for any requests and responds to them by bit-banging. The backend provides the ``fetch()`` and ``store()`` API that are
+used to access these memory mapped peripherals.
+
+.. _soctarget-hydrogensoc:
HydrogenSoC
************
+HydrogenSoC is a full SoC implementation that contains a single Atom core along with Memories, and peripheral IPs like
+UART, GPIOs, timers, etc. All the peripherals are connected to the CPU using a Wishbone-B4 bus. Users have the flexibility
+to disable/enable core features, add/remove IPs, and set memory maps through a config JSON file. HydrogenSoC is proven on
+multiple FPGA platforms.
+
+The following diagram shows the architecture of HydrogenSoC.
-.. image:: ../../diagrams/HydrogenSoC.png
\ No newline at end of file
+.. image:: /diagrams/HydrogenSoC.png
+ :width: 600
diff --git a/docs/pages/getting_started/building.rst b/docs/pages/getting_started/building.rst
index da46ed09..59062d0d 100644
--- a/docs/pages/getting_started/building.rst
+++ b/docs/pages/getting_started/building.rst
@@ -3,6 +3,7 @@ Building RISC-V Atom
Clone the repository
*********************
+First let's clone the repository as follows.
.. code-block:: bash
@@ -10,55 +11,51 @@ Clone the repository
$ cd riscv-atom # switch to riscv-atom directory
-.. note:: All the commands are executed from the root directory unless explicitly mentioned. We'll refer to this root directory as ``RVATOM``.
+.. note::
+ All the commands are executed from the root directory unless explicitly mentioned. We'll refer to this root
+ directory as ``RVATOM``.
-Edit Config.mk
-***************
-Edit Config.mk file and provide paths appropriately
-
-
-RISC-V Atom environment variables
-**********************************
+Setting up the environment
+***************************
#. ``RVATOM`` environment variable must point to root of riscv-atom directory for the tools & scripts to work properly.
-#. ``RVATOM_LIB`` environment variable must point to the ``RVATOM/sw/lib`` folder. This variable is used by the compile scripts to locate *libcatom*.
+#. ``RVATOM_LIB`` environment variable must point to the ``RVATOM/sw/lib`` folder. This variable is used by the compile
+ scripts to locate *libcatom*.
-For convenience, ``RVATOM/sourceme`` script is provided that you can source everytime you work with the project.
-This can be done as follows:
+For convenience, ``RVATOM/sourceme`` script is provided that you can source as follows:
.. code-block:: bash
$ source sourceme
-With this method, everytime you open a new terminal, you have to source the ``sourceme`` file. You can optionally append the aforementioned
-to your ``.bashrc`` to source it automatically everytime you open a new terminl.
+.. tip::
+ With this method, every time you open a new terminal, you have to source the ``sourceme`` file. You can optionally
+ append the aforementioned to your ``.bashrc`` to source it automatically every time you open a new terminal.
-.. code-block:: bash
+ .. code-block:: bash
- $ echo "source /sourceme" >> ~/.bashrc
-
-In the above command replace ``rvatom-path`` with the path to your RISC-V atom directory.
+ $ echo "source /sourceme" >> ~/.bashrc
+
+ Replace ``rvatom-path`` with the path to your RISC-V atom directory.
-Building the Simulator
-***********************
-Let's build AtomSim simulator for ``atombones`` target.
+Building AtomSim
+*****************
+:doc:`AtomSim` is the interactive RTL simulator for RISC-V Atom. Let's build AtomSim for :ref:`AtomBones ` target.
.. code-block:: bash
- $ make soctarget=atombones
+ $ make soctarget=atombones sim=1
-This will create ``RVATOM/sim/build`` and ``RVATOM/sim/run`` directories for Atomsim build files and runtime files respectively.
-You can find the Atomsim executable in the former directory.
+Optionally, to speed up builds, you can specify the number of parallel jobs to run using ``-j `` flag in the above
+command. This will create ``RVATOM/sim/build`` directory for AtomSim build files. You can find the Atomsim executable in
+``RVATOM/sim/build/bin`` directory.
-Assuming you've sourced the ``RVATOM/sourceme`` file, try the following command to verify the build.
+Assuming you've sourced the ``RVATOM/sourceme`` file, try the following command to check if the build was successful.
.. code-block:: bash
- $ atomsim --help
- AtomSim v_._
- Interactive RTL Simulator for Atom based systems [ atombones ]
- Usage:
- atomsim [OPTION...] input
+ $ atomsim --version
+ v2.2 [ atombones ]
...
\ No newline at end of file
diff --git a/docs/pages/getting_started/docker.rst b/docs/pages/getting_started/docker.rst
new file mode 100644
index 00000000..392e94ad
--- /dev/null
+++ b/docs/pages/getting_started/docker.rst
@@ -0,0 +1,38 @@
+RISC-V Atom Development in Docker
+##################################
+
+Alternative to previous approach, you can also use the provided `Dockerfile `_
+to build a Docker image containing all the necessary tools to checkout the RISC-V Atom project. As a prerequisite, you
+must have Docker installed on your system. You can install Docker by following the `official Docker guide `_.
+
+Once you have installed Docker, you can clone the RISC-V Atom repository and build the Docker image as follows.
+
+.. code-block:: bash
+
+ $ git clone https://github.com/saursin/riscv-atom.git
+ $ cd riscv-atom # switch to riscv-atom directory
+ $ docker build . -t rvatom-dev # we'll name this image rvatom-dev
+
+Once the build is finished you should be able to see the image using the following command:
+
+.. code-block:: bash
+
+ $ docker images
+ REPOSITORY TAG IMAGE ID CREATED SIZE
+ rvatom-dev latest a9cab48034fc 24 hours ago 475MB
+
+To run an instance of this docker image (also called container), you can run the following command.
+
+.. code-block:: bash
+
+ $ docker run -it -v .:/home/riscv-atom rvatom-dev
+ > Setting environment variables...
+ *** Welcome to the riscv-atom container! ***
+ root@7110d3ddecd7:/home/riscv-atom#
+
+The above command should launch the container and attach to it, and you should have a familiar linux prompt! It will
+also mount the riscv-atom directory on host machine to ``/home/riscv-atom`` directory in the container, and
+automatically set-up the environment variables for RISC-V Atom development.
+
+.. tip::
+ Checkout this `cheatsheet `_ to learn more about Docker CLI syntax.
\ No newline at end of file
diff --git a/docs/pages/getting_started/examples.rst b/docs/pages/getting_started/examples.rst
index 4d2784e1..51d2eed9 100644
--- a/docs/pages/getting_started/examples.rst
+++ b/docs/pages/getting_started/examples.rst
@@ -1,8 +1,8 @@
Running Examples on AtomSim
############################
-The RISC-V Atom project consists of a wide range of examples programs out-of-the-box to test. These examples programs reside
-in `RVATOM/sw/examples` directory.
+The RISC-V Atom project consists of a wide range of examples programs out-of-the-box to test. These examples programs
+reside in `RVATOM/sw/examples` directory.
Switch to examples directory
@@ -14,22 +14,48 @@ Lets run the classical "hello World!" example first!
Hello World Example
********************
-The source code for the *hello-world* example resides in the ``hello-asm`` directory. You can have a look at the source code. First we need to compile the hello world example with our RISC-V gcc cross-compiler. For this purpose, use the provided makefile as following.
+The source code for the *hello-world* example resides in the ``hello-asm`` directory. You can have a look at the source
+code. First we need to compile the hello world example with our RISC-V gcc cross-compiler. For this purpose, use the
+provided makefile as following.
.. code-block:: bash
- $ make soctarget=atombones ex=hello-asm compile
+ $ make soctarget=atombones ex=hello-asm sim=1 compile
-The above command should generate a ``hello.elf`` file in the ``hello-asm`` directory. Now fire up atomsim and
-provide the generated elf file as argument.
+The above command should generate a ``hello.elf`` file in the ``hello-asm`` directory.
+
+.. tip::
+ ``soctarget=atombones`` in the above command can be skipped if AtomSim is already built. The SoC target will be automatically detected from
+ the AtomSim executable.
+
+Now fire up AtomSim and provide the generated elf file as argument.
.. code-block:: bash
- $ atomsim hello-asm/hello.elf
+ $ atomsim -u hello-asm/hello.elf
+ ___ __ _____
+ / _ |/ /____ __ _ / __(_)_ _
+ / __ / __/ _ \/ ' \_\ \/ / ' \
+ /_/ |_\__/\___/_/_/_/___/_/_/_/_/ v2.2
+ ----------8<-----------8<-----------8<-----------8<---------
+
+ **** RISC-V Atom Bootloader ****
+ bootmode: 0x1
+ Jumping to RAM
+ --------------------------------
Hello World!
- -- from Assembly
+ -- from Assembly
+
+ EBreak hit at 0x2000014a
+ Exiting..
-Alternatively, use make run to run the example.
+You should see *Hello world* message on the screen.
+
+.. note::
+ Make sure to use ``-u`` flag to direct UART output from SoC to stdout. You can also use ``-t`` flag to generate a VCD
+ trace of the simulation.
+
+Alternatively, use ``make run`` to run the example as follows
.. code-block:: bash
@@ -40,7 +66,7 @@ We can compile other examples also in the similar fashion by using the following
.. code-block:: bash
- $ make soctarget= ex= compile
+ $ make soctarget= ex= sim=1 compile
$ make soctarget= ex= run
.. note::
@@ -52,95 +78,133 @@ Banner Example
.. code-block:: bash
$ make target=atombones ex=banner compile
- $ atomsim banner/banner.elf
-
-
-Output:
-
-.. code-block:: text
-
- .';,. ....;;;.
- .ll,:o, ':c,.
- .dd;co' .cl,
- .:o:;,. 'o:
- co. .oc
- ,o' .coddoc. 'd,
- lc .lXMMMMMMXl. ll
- .o: ;KMMMMMMMMK, :o.
- .o: 'OMMMMMMMMO. :o.
- co. .o0XNNX0o. .oc
- .o: ..''.. :o.
- 'o: :o'
- .lc. .ll.
- ,lc' 'cl,
- 'cc:,.. ..,:c:'
- .;::::;;;;::::;.
- ....
- ____ _________ _______ __ __
- / __ \/ _/ ___// ____/ | / / ____ _/ /_____ ____ ___
- / /_/ // / \__ \/ / | | / / / __ `/ __/ __ \/ __ `__ \
- / _, _// / ___/ / /___ | |/ / / /_/ / /_/ /_/ / / / / / /
- /_/ |_/___//____/\____/ |___/ \__,_/\__/\____/_/ /_/ /_/
- /=========By: Saurabh Singh (saurabh.s99100@gmail.com)====/
-
- ROM size: xxxxx bytes (xx KB)
- RAM size: xxxxx bytes (xx KB)
- exiting...
-
-The Runexamples Script
-***********************
-Instead of testing all examples one-by-one, we can use the provided ``atomsim-runexamples`` script to
-automatically compile and simulate all examples.
-
-Simply invoke the script as following
-
-.. code-block:: bash
+.. code-block::
+
+ $ atomsim -u banner/banner.elf
+ ___ __ _____
+ / _ |/ /____ __ _ / __(_)_ _
+ / __ / __/ _ \/ ' \_\ \/ / ' \
+ /_/ |_\__/\___/_/_/_/___/_/_/_/_/ v2.2
+ ----------8<-----------8<-----------8<-----------8<---------
+
+ **** RISC-V Atom Bootloader ****
+ bootmode: 0x1
+ Jumping to RAM
+ --------------------------------
+
+ .';,. ....;;;.
+ .ll,:o, ':c,.
+ .dd;co' .cl,
+ .:o:;,. 'o:
+ co. .oc
+ ,o' .coddoc. 'd,
+ lc .lXMMMMMMXl. ll
+ .o: ;KMMMMMMMMK, :o.
+ .o: 'OMMMMMMMMO. :o.
+ co. .o0XNNX0o. .oc
+ .o: ..''.. :o.
+ 'o: :o'
+ .lc. .ll.
+ ,lc' 'cl,
+ 'cc:,.. ..,:c:'
+ .;::::;;;;::::;.
+ ....
+ ____ _________ _______ __ __
+ / __ \/ _/ ___// ____/ | / / ____ _/ /_____ ____ ___
+ / /_/ // / \__ \/ / | | / / / __ `/ __/ __ \/ __ `__ \
+ / _, _// / ___/ / /___ | |/ / / /_/ / /_/ /_/ / / / / / /
+ /_/ |_/___//____/\____/ |___/ \__,_/\__/\____/_/ /_/ /_/
+ /=========By: Saurabh Singh (saurabh.s99100@gmail.com)====/
+
+ CPU : RISC-V Atom @ 50000000 Hz
+ Arch : RV32IC - little endian
+ CODE RAM : 0x20000000 (40960 bytes)
+ DATA RAM : 0x2000a000 (8192 bytes)
+ Exiting...
+ EBreak hit at 0x2000007c
+ Exiting..
- $ atomsim-runexamples
-atomsim-runexamples script internally uses the same makefile that we used earlier, with the run-all target.
-Therefore we can alternatively get the same result by using the make command (in ``RVATOM/sw/examples`` directory).
+How to compile and run all examples?
+*************************************
+Instead of testing all examples one-by-one, we can compile and run all examples as follows.
.. code-block:: bash
$ make soctarget=atombones run-all
-
Using Atomsim Vuart
********************
-By default AtomSim relays the output of the running application on stdout. But, in this mode of operation, user cannot provide any input to the running program. Alternatively, Atomsim can estabilish a two-way communication with AtomSim through a linux serial port. This functionality is provided by the Vuart module in Atomsim.
+When using ``-u`` flag, AtomSim relays the output of the running application on stdout. But, in this mode of operation,
+user cannot provide any input to the running program. AtomSim provides Virtual UART to work around this problem. Virtual
+UART is an inbuilt class in AtomSim that can attach the stdin, stdout streams of the simulation to a linux serial port.
+
+
+.. graphviz::
+
+ digraph G {
+ rankdir=LR;
+ subgraph cluster_0 {
+ style=filled;
+ fillcolor=lightgrey;
+ label="Pair of pseudo serial ports using socat as relay";
+ Userport [shape=rect, style=filled, fillcolor=orange];
+ Simport [shape=rect, style=filled, fillcolor=orange];
+ Socat [shape=ellipse, style=filled, fillcolor=yellow];
+ Userport -> Socat -> Simport [dir=both];
+ }
+ subgraph cluster_1 {
+ style=filled;
+ fillcolor=cyan;
+ label="AtomSim";
+ VUART [shape=rect, style=filled, fillcolor=gray];
+ RTL [shape=rect, label="RTL\nSimulation", style=filled, fillcolor=gray];
+ VUART -> RTL [dir=both, label="UART traffic"];
+ }
+ Screen [shape=rect, style=filled, fillcolor=cyan];
+ ttyUSB [shape=rect, style=filled, fillcolor=orange];
+ FPGA [shape=box3d, style=filled, fillcolor=green];
+ Screen -> Userport [label=attach];
+ Simport -> VUART [dir=back, label=attach];
+ Screen -> ttyUSB [label=attach];
+ ttyUSB -> FPGA [label=USB];
+ }
-Generating virtual serial ports
+|
+
+Generating Pseudo Serial Ports
================================
-A pair of connected serial ports can be generated by usng the provided ``atomsim-gen-vports`` script as following.
+A pair of connected pseudo serial ports can be generated by using the provided ``atomsim-gen-vports`` script as following.
.. code-block:: bash
$ atomsim-gen-vports
-This will generate a pair of new virtual serial ports in ``/dev/pts`` and links them together using the
-``socat`` linux command. This means that whatever is sent to port-1 is recieved at port-2 and vice versa.
+This will generate a pair of new pseudo serial ports in ``/dev/pts`` and links them together using the
+``socat`` linux command. This means that whatever is sent to port-1 is received at port-2 and vice-versa.
Further, this script also generates symlinks to these generated ports in the ``RVATOM`` directory
as ``simport`` and ``userport``.
-Interacting with Stdout and Stdin over virtual ports
-=====================================================
+Interacting with Stdout and Stdin over Pseudo Serial Ports
+==========================================================
Open a new terminal (say terminal-2) and run the screen command as following
.. code-block:: bash
- $ screen $RVATOM/userport 9600
+ $ screen $RVATOM/userport 115200
And on the other terminal (terminal-1) run atomsim as following
.. code-block:: bash
- $ atomsim hello-asm/hello.s --vuart=$RVATOM/simport
+ $ atomsim hello-asm/hello.s -p $RVATOM/simport -b 115200
You should now be able to see the output on the terminal-2.
-To close the screen command press ``ctrl+a``, type ``:quit`` and press ``enter``.
+.. tip::
+ To close *screen* first press :kbd:`ctrl` + :kbd:`a`, then press :kbd:`k` followed by :kbd:`y`. To clear the *screen* window,
+ press :kbd:`ctrl` + :kbd:`a`, then press :kbd:`shift` + :kbd:`c`.
Adding New Examples
@@ -150,14 +214,14 @@ To add a new example to the existing framework, simply create a directory under
.. code-block:: bash
- $ mkdir newexample
+ $ mkdir myexample
Next, put your source files under this directory.
.. code-block:: c
- $ cat newexample.c
+ $ cat myexample.c
#include
void main()
{
@@ -174,10 +238,9 @@ executable file as follows.
.. code-block:: bash
$ cat Makefile.include
- src_files = newexample.c
- executable = newexample.elf
+ src_files = myexample.c
+ executable = myexample.elf
That's it! Now you can use the same compile and run commands as discussed earlier to run this example.
-
diff --git a/docs/pages/getting_started/prerequisites.rst b/docs/pages/getting_started/prerequisites.rst
index 3e725136..87d4ec36 100644
--- a/docs/pages/getting_started/prerequisites.rst
+++ b/docs/pages/getting_started/prerequisites.rst
@@ -1,60 +1,37 @@
Prerequisites
###############
-
-This page discusses how to set up your system in order to get riscv-atom up and running.
+This page discusses how to set up your system in order to get RISC-V Atom up and running.
Required Packages
******************
.. note::
- RISC-V Atom project has been developed and tested on ubuntu 20.04.
- However, It should work just fine on any other version of ubuntu with no or few additional packages.
-
-
-Run apt update
-================
-This step is needed to make sure the apt package list is up to date.
-
-.. code-block:: bash
-
- $ sudo apt update
-
+ RISC-V Atom project has been developed and tested on **Ubuntu 20.04**.
+ However, It should work just fine on any other linux based distribution with relevant packages.
Install git, make, python3, gcc & other tools
==============================================
-GNU C/C++ compilers and Make and other essential build tools are conveniently packaged as ``build-essential`` meta package.
+RISC-V Atom uses *Make* for all builds. *GNU C/C++ compilers*, *Make* and other essential build tools are conveniently
+packaged as ``build-essential`` meta package in Ubuntu. RISC-V Atom uses the GNU Readline library to implement the
+interactive console in AtomSim. We also want to install GTKWave to view VCD waveforms and screen to connect to serial ports.
.. code-block:: bash
- $ sudo apt install git python3 build-essential
+ $ sudo apt-get update
+ $ sudo apt-get install git python3 python3-pip build-essential libreadline8 libreadline-dev socat
+ $ sudo apt-get install gtkwave screen
+ $ pip install -r requirements.txt
Install Verilator
==================
-Verilator will be used By Atomsim to *Verilate* Verilog RTL into C++. We recommend installing latest stable verilator version using `git quick install method `_
-
-Install GTK Wave
-==================
-GTKwave is a GUI tool to view waveforms stored as Value Change Dump (VCD) files.
-
-.. code-block:: bash
-
- $ sudo apt install gtkwave
-
-
-Install Screen
-==================
-Screen is a command line utility that can be used to connect to serial ports on linux.
-It will be used to estabilish a two-way serial communication with the AtomSim.
-
-.. code-block:: bash
-
- $ sudo apt install screen
+Verilator will be used By AtomSim to *Verilate* Verilog RTL into C++. We recommend installing the latest stable
+Verilator version (>=5.006) using `git quick install method `_.
Install RISC-V GNU Toolchain
=============================
-We will be installing the RV64-Multilib toolchain
+We will be installing the **RISC-V 64-bit Multilib** toolchain
Further install instructions can be found `here `_.
We recommend using the provided ``install_toolchain.sh`` script to install the proper toolchain.
@@ -63,23 +40,41 @@ We recommend using the provided ``install_toolchain.sh`` script to install the p
$ chmod +x install_toolchain.sh
$ ./install_toolchain.sh
+Allow user to access serial ports
+=================================
+To allow current linux user to access serial ports and usb devices (such as JTAG), the user must be added to
+the ``dialout`` and ``plugdev`` groups respectively.
-----------------
+.. code-block:: bash
-|
+ $ sudo usermod -aG dialout $USER
+ $ sudo usermod -aG plugdev $USER
+
+.. note::
+ This takes effect after user logs out and logs back in.
+
+OpenFPGAloader
+==============
+We use openFPGAloader to load bitstreams on FPGA. you are free to use vendor tools instead. To install openFPGAloader
+follow `this `_ guide.
+
+----------------
Optional Packages
******************
-.. note:: The following packages are optional and are only required for generating documentation using doxygen & sphinx
+.. note::
+ The following packages are optional and are only required for generating documentation using
+ Doxygen & Sphinx
Install Doxygen
================
-Doxygen a tool is used to generate C++ cource code documentation from =documentation comments= inside the C++ source files.
+Doxygen a tool is used to generate C++ source code documentation from comments inside the C++ source files.
.. code-block:: bash
- $ sudo apt install doxygen
+ $ sudo apt-get install doxygen
+
Install Latex Related packages
===============================
@@ -92,10 +87,10 @@ These packages are essential for generating Latex documentation using Doxygen.
Install sphinx & other python dependencies
===========================================
-Sphinx is used to generate the RISC-V Atom Documentation and User-Manual in PDF & HTML.
+Sphinx is used to generate the RISC-V Atom Documentation and User-Manual in PDF & HTML. To install the packages to
+generate sphinx documentation, run the following command in ``docs`` directory under riscv-atom repository.
.. code-block:: bash
- $ cd docs/ && pip install -r requirements.txt
-
-
+ $ pip install -r docs/requirements.txt
+ $ sudo apt install graphviz # Graphviz is for flow diagrams in sphinx documentation
diff --git a/docs/pages/overview/components.rst b/docs/pages/overview/components.rst
deleted file mode 100644
index 8724c2b9..00000000
--- a/docs/pages/overview/components.rst
+++ /dev/null
@@ -1,61 +0,0 @@
-Components
-###########
-
-This page gives a high-level overview of various components of the RISC-V Atom project.
-
-RISC-V Atom Core
-*****************
-
-Atom is a 32-bit embedded-class softcore processor written in Verilog HDL. It is designed to cater to embedded class applications. It is fully compliant with the open-source RISC-V Instruction Set Architecture (RV32I) and passes all official RISC-V compliance tests. Atom is based on a two-stage pipelined architecture inspired by the ARM cortex m0+ processor. It is aimed towards implementation on FPGAs.
-
-
-.. link-button:: RISC-V Atom (Core)
- :type: ref
- :text: Click here for in-depth documentation
- :classes: btn-outline-primary btn-block
-
-
-SoC Targets
-************
-
-* **AtomBones**: It is a stub-target that consists of a single atom core only. The instruction memory, data memory, and serial port are simulated in C++. It is should be used for simulation and debugging purposes only.
-
-* **HydrogenSoC**: It is a basic SoC implementation that contains a single Atom core along with instruction memory, data memory, serial ports, GPIO pins, etc. All the peripherals are connected with the CPU using a Wishbone-B4 bus.
-
-.. link-button:: RISC-V Atom SoC Targets
- :type: ref
- :text: Click here for in-depth documentation
- :classes: btn-outline-primary btn-block
-
-
-AtomSim
-********
-
-AtomSim is a Spike-like simulator written in C++. In contrast to Spike, AtomSim Simulates the actual RTL in the backend. AtomSim provides a hardware-software co-simulation environment for developing applications and extensions on the Atom platform. It uses the Verilator tool to compile the RTL into a shared object which then gets linked with the C++ based simulator frontend to simulate the system. AtomSim also features a command-line interface to control various aspects of the simulation like start, stop, step, run indefinitely, run for a specified number of cycles, enable/disable vcd tracing, etc. It also supports run-time instruction disassembly with the help of the RISC-V objdump tool.
-
-.. link-button:: AtomSim: A simulation tool for Atom based SoCs
- :type: ref
- :text: Click here for in-depth documentation
- :classes: btn-outline-primary btn-block
-
-
-SCAR
-*****
-
-SCAR (Search, Compile Assert, and Run) is a processor verification framework written in python. It performs a set of assembly-level tests to verify the processor implementation. Each assembly test usually checks for one particular function of the processor. SCAR does this by examining a state dump after the processor is done with executing a test code. This state dump is then checked assuming a set of assertions in the form of expected register values. These assertions are provided in the assembly file itself. SCAR is also used to verify the RISC-V ISA compliance in this project.
-
-.. link-button:: SCAR: Search Compile Assert Run
- :type: ref
- :text: Click here for in-depth documentation
- :classes: btn-outline-primary btn-block
-
-
-ConvELF
-********
-
-ConvELF is a python script that is used to convert an ELF executable file to verilog friendly memory initialization files. These files can be in either `hex` or `bin` format and can be used to initialize a verilog memory with the help of `$readmemh` & `readmemb` functions. ConvELF is a flexible program configured by a memory map specified as a python dictionary. It can even fragment an elf file into multiple memory initialization files depending on the memory map provided.
-
-.. link-button:: ConvELF: A Utility Tool for ELF Conversion
- :type: ref
- :text: Click here for in-depth documentation
- :classes: btn-outline-primary btn-block
diff --git a/docs/pages/overview/directory_structure.rst b/docs/pages/overview/directory_structure.rst
index 0d9d79d0..a71f49a1 100644
--- a/docs/pages/overview/directory_structure.rst
+++ b/docs/pages/overview/directory_structure.rst
@@ -6,38 +6,41 @@ Directory Structure
riscv-atom : root directory
|
├─ docs : RISCV-Atom documentation & user manual
- | ├─ diagrams : executable binaries
- | └─ pages : reStructuredText sources
|
├─ rtl : RISCV-Atom Verilog Sources
+ | ├─ common : Common headers
+ | ├─ config : SoC target config files (JSON)
| ├─ core : RISCV-Atom core components
- | ├─ uncore : RISCV-Atom non-core components (SoC peripherals)
- | └─ dpi : SystemVerilog DPI sources
+ | ├─ dpi : SystemVerilog DPI sources
+ | ├─ soc : SoC RTL files
+ | ├─ tb : Verilog testbenches
+ | └─ uncore : RISCV-Atom non-core components (SoC peripherals)
|
- ├─ scripts : scripts for commonly used commands
+ ├─ scripts : Commonly used python and bash scripts
|
├─ sim : Atomsim source code
| ├─ build : AtomSim build files (autogenerated)
| ├─ docs : AtomSim Source Documentation (Doxygen)
- | ├─ include : Third party Libraries for AtomSim
- | └─ run : Atomsim run logs, dumps and VCD traces (autogenerated)
+ | └─ include : Third party Libraries for AtomSim
|
- ├─ sw : Atomsim source code
- | ├─ examples : example programs
- | └─ lib : libc for RISCV-Atom (libcatom)
- | ├─ include : libcatom headers
- | ├─ libcatom : libcatom sources
+ ├─ sw : Software sources
+ | ├─ bootloader : RISC-V Atom bootloader
+ | ├─ examples : Example programs
+ | └─ lib : Libc for RISCV-Atom (libcatom)
+ | ├─ include : Libcatom headers
+ | ├─ libcatom : Libcatom sources
| └─ link : Linker scripts
|
├─ synth : RISC-V Atom Synthesis
- | ├─ xilinx : Synthesis project for xilinx FPGAs
- | └─ yosys : Yosys synthesis scripts
+ | ├─ altera : Synthesis project for Altera FPGAs
+ | ├─ xilinx : Synthesis project for Xilinx FPGAs
+ | └─ yosys : Synthesis project for Yosys
|
├─ test : RISCV Atom tests
| ├─ riscv-target : Official RISC-V compliance test files
| └─ scar : SCAR tests directory
|
- └─ tools : utility tools
- └─ elfdump : elfdump utility
+ └─ tools : Utility tools
+ └─ elfdump : Elfdump utility
diff --git a/docs/pages/overview/introduction.rst b/docs/pages/overview/introduction.rst
index 70dd8903..bb0e67ab 100644
--- a/docs/pages/overview/introduction.rst
+++ b/docs/pages/overview/introduction.rst
@@ -12,23 +12,53 @@
Introduction
##############
-**RISC-V Atom** is an open-source soft-core processor platform targeted for FPGAs. It is based on the open-source loyality-free RISC-V ISA. It is complete hardware prototyping and software development environment based around the :doc:`Atom` CPU. RISC-V Atom is a customizable processor platform which is easy to learn, use and tinker even for a begineer. It also provides a wide variety of software examples for testing, a rich documentation and a comprehensive guide for getting stated.
+**RISC-V Atom** is an open-source soft-core processor platform targeted for FPGAs. It is complete hardware prototyping
+and software development environment based around **Atom**, which is a 32-bit embedded-class processor based on the
+`RISC-V `_ Instruction Set Architecture (ISA).
Key Highlights
***************
+Key highlights of the RISC-V Atom projects are are listed below:
-#. Based around :doc:`Atom`: A 32-bit 2-stage pipelined RISC-V CPU.
-#. Provides multiple SoC configurations.
-#. Provides an interactive feature-rich RTL simulation frontend called **AtomSim**.
-#. Features a python based processor verification framework called *SCAR*.
-#. RISC-V GCC is used as default toolchain (prebuilt toolchains are also provided)
-#. A rich documentation & getting started guide.
-#. An array of software examples to run & test.
-#. A rich software framework with a C library **libcatom** for all SoC peripherals.
-#. Customizable, Easy to learn and tinker.
-#. Open-Sources under MIT License.
-
-.. note::
- Although significant efforts have been and will be made towards optimizing the RTL for LUT consumption & timing on FPGAs, however, the **codebase is not recommended for any production use as of now**.
-
-To get started, Check out the getting started guide :doc:`/pages/getting_started/prerequisites`.
+#. Atom implements ``RV32IC_Zicsr`` ISA as defined in the `RISC-V unprivileged ISA manual `_.
+#. Simple 2-stage pipelined architecture, ideal for smaller FPGAs.
+#. Optional support for RISC-V exceptions and interrupts.
+#. Wishbone ready CPU interface.
+#. Interactive RTL simulator - :doc:`AtomSim`.
+#. In-house verification framework - :doc:`SCAR`.
+#. Multiple SoC configurations.
+#. Tiny libc like standard library - :doc:`Libcatom`.
+#. Wide range of example programs.
+#. Open source under `MIT License `_.
+
+.. tip::
+ To get started, Check out the :doc:`getting started guide`.
+
+
+Components
+***********
+Following is list of various components of the RISC-V Atom project.
+
+.. card:: RISC-V Atom CPU
+ :link-type: doc
+ :link: /pages/documentation/riscv_atom
+
+ A simple 32-bit RISC-V processor.
+
+.. card:: SoC Targets
+ :link-type: doc
+ :link: /pages/documentation/soc_targets
+
+ RISC-V Atom project provides several configurable SoC targets that can be built around the Atom CPU.
+
+.. card:: AtomSim
+ :link-type: doc
+ :link: /pages/documentation/atomsim/atomsim
+
+ AtomSim is the interactive RTL simulator for RISC-V Atom SoCs.
+
+.. card:: SCAR
+ :link-type: doc
+ :link: /pages/documentation/scar
+
+ SCAR (Search, Compile Assert, and Run) is an in-house processor verification framework written in python.
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 277e92d7..bbb8fcbb 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,4 +1,4 @@
-sphinx==4.5.0 # not using latest due to compatibility issues with with sphinx-panels
+sphinx==5.0 # not using latest due to compatibility issues with with sphinx-panels
sphinx-rtd-theme
sphinx-copybutton
-sphinx-panels
+sphinx-design
diff --git a/rtl/config/uart.json b/rtl/config/uart.json
index 804c4070..5a162fc7 100644
--- a/rtl/config/uart.json
+++ b/rtl/config/uart.json
@@ -4,7 +4,8 @@
"vdefines": [],
"vsrcs": [
"${RVATOM}/rtl/uncore/uart/UART.v",
- "${RVATOM}/rtl/uncore/uart/UART_core.v"
+ "${RVATOM}/rtl/uncore/uart/UART_core.v",
+ "${RVATOM}/rtl/uncore/uart/FIFO_sync.v"
],
"incdirs": [
"${RVATOM}/rtl/common"
diff --git a/rtl/soc/hydrogensoc/HydrogenSoC.v b/rtl/soc/hydrogensoc/HydrogenSoC.v
index 49d96c02..a9ead61c 100644
--- a/rtl/soc/hydrogensoc/HydrogenSoC.v
+++ b/rtl/soc/hydrogensoc/HydrogenSoC.v
@@ -334,7 +334,11 @@ module HydrogenSoC(
wire uart_wb_ack_o;
wire uart_wb_err_o = 0;
- UART uart (
+ UART #(
+ .DEFAULT_DIV(1),
+ .FIFO_EN (`SOC_UART_FIFO_EN),
+ .FIFO_DEPTH (`SOC_UART_FIFO_DEPTH)
+ ) uart (
.wb_clk_i (wb_clk_i),
.wb_rst_i (wb_rst_i),
diff --git a/rtl/soc/hydrogensoc/HydrogenSoC_Config.vh b/rtl/soc/hydrogensoc/HydrogenSoC_Config.vh
index c7d89cdf..9f65ad07 100644
--- a/rtl/soc/hydrogensoc/HydrogenSoC_Config.vh
+++ b/rtl/soc/hydrogensoc/HydrogenSoC_Config.vh
@@ -54,6 +54,8 @@
// `define SOC_EN_UART
`define SOC_UART_ADDR 32'h4000_0000
`define SOC_UART_SIZE 16 // 4 words
+`define SOC_UART_FIFO_EN 1
+`define SOC_UART_FIFO_DEPTH 4
/*
diff --git a/rtl/uncore/spi/README.md b/rtl/uncore/spi/README.md
index 01653e62..1dc948e0 100644
--- a/rtl/uncore/spi/README.md
+++ b/rtl/uncore/spi/README.md
@@ -70,7 +70,7 @@ SPI IP with Wishbone B-4 Interface.
| **Range** | **Access** | **RstVal** | **Name** | **Description**
|-----------|------------|------------|----------|-----------------
-| [31:24] | RW | - | ACS | Active Chip Select
+| [31:24] | RW | 0x1 | ACS | Active Chip Select
| [23:2] | - | - | - | Reserved
| [1:0] | RW | 0x0 | CSMODE | CS Mode
diff --git a/rtl/uncore/spi/SPI_wb.v b/rtl/uncore/spi/SPI_wb.v
index a9ada835..f63a7338 100644
--- a/rtl/uncore/spi/SPI_wb.v
+++ b/rtl/uncore/spi/SPI_wb.v
@@ -85,7 +85,7 @@ always @(posedge wb_clk_i) begin
rg_sctrl_pol <= 1'b0;
rg_sctrl_spien <= 1'b0;
- rg_csctrl_acs <= 0;
+ rg_csctrl_acs <= 1;
rg_csctrl_csmode <= 2'b00;
rg_dctrl_prcshd <= DEFAULT_DCTRL_PRECSHD;
diff --git a/rtl/uncore/uart/FIFO_sync.v b/rtl/uncore/uart/FIFO_sync.v
new file mode 100644
index 00000000..29f01316
--- /dev/null
+++ b/rtl/uncore/uart/FIFO_sync.v
@@ -0,0 +1,50 @@
+module FIFO_sync #(
+ parameter DEPTH = 32,
+ parameter DATAW = 8
+)(
+ input wire clk_i,
+ input wire rst_i,
+ input wire we_i,
+ input wire re_i,
+ input wire [DATAW-1:0] dat_i,
+ output wire [DATAW-1:0] dat_o,
+ output wire full_o,
+ output wire empty_o
+);
+ parameter ADDRW = $clog2(DEPTH);
+
+ reg [DATAW-1:0] mem [0: DEPTH-1];
+ reg [ADDRW:0] count;
+ reg [ADDRW-1:0] w_ptr;
+ reg [ADDRW-1:0] r_ptr;
+
+ wire enq_cond = we_i & !full_o;
+ wire deq_cond = re_i & !empty_o;
+
+ always@(posedge clk_i) begin
+ if(rst_i) begin
+ w_ptr <= 0;
+ r_ptr <= 0;
+ count <= 0;
+ end else begin
+ if(enq_cond)begin
+ mem[w_ptr] <= dat_i;
+ w_ptr <= w_ptr + 1;
+ count <= count +1;
+ end
+
+ if(deq_cond) begin
+ r_ptr <= r_ptr + 1;
+ count <= count - 1;
+ end
+
+ if(enq_cond && deq_cond) begin
+ count <= count;
+ end
+ end
+ end
+ assign dat_o = mem[r_ptr];
+
+ assign empty_o = (count == 0);
+ assign full_o = (count == DEPTH);
+endmodule
diff --git a/rtl/uncore/uart/UART.v b/rtl/uncore/uart/UART.v
index d3fedde8..c34bdb65 100644
--- a/rtl/uncore/uart/UART.v
+++ b/rtl/uncore/uart/UART.v
@@ -7,7 +7,9 @@
`default_nettype none
module UART#(
- parameter DEFAULT_DIV = 1
+ parameter DEFAULT_DIV = 1,
+ parameter FIFO_EN = 1,
+ parameter FIFO_DEPTH = 4
)(
// Wishbone Interface
input wire wb_clk_i,
@@ -15,7 +17,7 @@ module UART#(
input wire [3:2] wb_adr_i,
output reg [31:0] wb_dat_o,
- input wire [31:0] wb_dat_i /* verilator public */,
+ input wire [31:0] wb_dat_i,
input wire wb_we_i,
input wire [3:0] wb_sel_i,
@@ -23,20 +25,10 @@ module UART#(
output reg wb_ack_o,
// Serial Interface
- /* verilator lint_off UNUSED */
input wire rx_i,
- /* verilator lint_on UNUSED */
-
- /* verilator lint_off UNDRIVEN */
output wire tx_o
- /* verilator lint_on UNDRIVEN */
);
////////////////////////////////////////////////////////////////////////////////////////////////////
-/*
- if __ATOMSIM_SIMULATION__ is defined, this module behaves as a stub. simpleuart is not
- instantiated, instead reg_status, reg_data, and reg_div are converted to actual registers
- which are written externally by atomsim for the purpose of the simulation of uart communication.
-*/
// Set Ack_o
always @(posedge wb_clk_i) begin
@@ -55,6 +47,52 @@ reg [31:0] reg_div = 0;
wire reg_data_we = (wb_adr_i == 2'b00) && wb_we_i && wb_stb_i && wb_sel_i[0];
wire reg_data_re = (wb_adr_i == 2'b00) && !wb_we_i && wb_stb_i;
+wire rxfifo_empty_o;
+wire rxfifo_full_o;
+wire [7:0] rxfifo_data_o;
+
+wire txfifo_full_o;
+wire txfifo_empty_o;
+wire [7:0] txfifo_data_o;
+generate
+ if (FIFO_EN) begin
+ FIFO_sync #(
+ .DEPTH(FIFO_DEPTH),
+ .DATAW(8)
+ ) rxfifo (
+ .clk_i (wb_clk_i),
+ .rst_i (wb_rst_i),
+ .we_i (core_recv_buf_valid & reg_lcr[0]),
+ .re_i (reg_data_re & wb_ack_o),
+ .dat_i (core_reg_data),
+ .dat_o (rxfifo_data_o),
+ .full_o (rxfifo_full_o),
+ .empty_o (rxfifo_empty_o)
+ );
+
+ FIFO_sync #(
+ .DEPTH(FIFO_DEPTH),
+ .DATAW(8)
+ ) txfifo (
+ .clk_i (wb_clk_i),
+ .rst_i (wb_rst_i),
+ .we_i (reg_data_we & wb_ack_o),
+ .re_i (core_send_buf_empty & reg_lcr[1]),
+ .dat_i (wb_dat_i[7:0]),
+ .dat_o (txfifo_data_o),
+ .full_o (txfifo_full_o),
+ .empty_o (txfifo_empty_o)
+ );
+ end else begin
+ assign rxfifo_empty_o = 1'dx;
+ assign rxfifo_full_o = 1'dx;
+ assign rxfifo_data_o = 8'dx;
+ assign txfifo_full_o = 1'dx;
+ assign txfifo_empty_o = 1'dx;
+ assign txfifo_data_o = 8'dx;
+ end
+endgenerate
+
// Handle Writes
always @(posedge wb_clk_i) begin
if(wb_rst_i) begin
@@ -79,9 +117,12 @@ end
// Handle Reads
always @(*) /* COMBINATORIAL */ begin
case(wb_adr_i)
- 2'b00: /* THR-RBR */ wb_dat_o = {24'd0, core_reg_data};
+ 2'b00: /* THR-RBR */ wb_dat_o = {24'd0, FIFO_EN ? rxfifo_data_o: core_reg_data};
2'b01: /* LCR */ wb_dat_o = {24'd0, reg_lcr};
- 2'b10: /* LSR */ wb_dat_o = {27'd0, core_rx_parity_bit, core_err_parity, core_err_framing, core_send_buf_empty, core_recv_buf_valid};
+ 2'b10: /* LSR */ wb_dat_o = {27'd0, core_rx_parity_bit, core_err_parity, core_err_framing,
+ (FIFO_EN ? ~txfifo_full_o : core_send_buf_empty),
+ (FIFO_EN ? ~rxfifo_empty_o: core_recv_buf_valid)
+ };
2'b11: /* DIV */ wb_dat_o = reg_div;
endcase
end
@@ -101,9 +142,9 @@ UART_core uart_core_i
.ser_tx (tx_o),
.ser_rx (reg_lcr[7] ? tx_o : rx_i), // loopback
.divisor (reg_div),
- .reg_dat_we (reg_data_we),
- .reg_dat_re (reg_data_re),
- .reg_dat_di (wb_dat_i[7:0]),
+ .reg_dat_we (FIFO_EN ? ~txfifo_empty_o : reg_data_we),
+ .reg_dat_re (FIFO_EN ? ~rxfifo_full_o : reg_data_re),
+ .reg_dat_di (FIFO_EN ? txfifo_data_o : wb_dat_i[7:0]),
.reg_dat_do (core_reg_data),
.rx_en (reg_lcr[0]),
diff --git a/scripts/atomsim-gen-vports b/scripts/atomsim-gen-vports
index a4904002..c732e9a0 100755
--- a/scripts/atomsim-gen-vports
+++ b/scripts/atomsim-gen-vports
@@ -9,15 +9,8 @@ SIMPORT=$RVATOM/simport
if [[ $1 != -s ]]
then
- echo "simport : $SIMPORT"
- echo "userport: $USERPORT"
-
- echo -n "Generating Virtual UART Ports... "
+ printf "\033[0;36m$SIMPORT\033[0m <--\033[0;33m socat \033[0m--> \033[0;36m$USERPORT\033[0m\n"
fi
socat pty,link=$USERPORT,echo=0 pty,link=$SIMPORT,echo=0 &
-
-if [[ $1 != -s ]]
-then
- echo " Done!"
-fi
\ No newline at end of file
+echo "Socat PID: $!"
\ No newline at end of file
diff --git a/scripts/atomsim-runexamples b/scripts/atomsim-runexamples
deleted file mode 100755
index 62647a1a..00000000
--- a/scripts/atomsim-runexamples
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-
-# Detect current directory
-curr_dir=$(pwd)
-echo -e "current directory: $currdir"
-
-example_dir=$RVATOM/sw/examples/
-
-cd ${example_dir}
-make run-all $*
-cd ${curr_dir}
\ No newline at end of file
diff --git a/sim/Makefile b/sim/Makefile
index d83946a6..e5948257 100755
--- a/sim/Makefile
+++ b/sim/Makefile
@@ -117,7 +117,7 @@ $(VERILATED_DIR)/V$(VTOPMODULE)__ALL.a: $(VSRCS)
$(VC) $(VFLAGS) `$(RVATOM)/scripts/cfgparse.py $(JSONCFG) -f --tool=verilator`
$(call print_msgt,Generating library)
- make -s -C $(VERILATED_DIR) -f V$(VTOPMODULE).mk > /dev/null
+ $(MAKE) -s -C $(VERILATED_DIR) -f V$(VTOPMODULE).mk > /dev/null
$(call print_msg,Generating combined header,V$(VTOPMODULE)_headers.h)
printf "#ifndef __V$(VTOPMODULE)_headers__\n" > $(VERILATED_DIR)/V$(VTOPMODULE)_headers.h
diff --git a/sim/docs/Makefile b/sim/docs/Makefile
index d02536fa..f2ed6bc9 100644
--- a/sim/docs/Makefile
+++ b/sim/docs/Makefile
@@ -35,7 +35,7 @@ $(MAN_PDF): $(LATEX_DIR)/refman.pdf
mv $^ $@
$(LATEX_DIR)/refman.pdf:
- make -C build/latex/
+ $(MAKE) -C build/latex/
diff --git a/sourceme b/sourceme
index b4198ed2..236bc479 100644
--- a/sourceme
+++ b/sourceme
@@ -1,4 +1,4 @@
-########## RISCV-ATOM Environment Setup ##########
+echo "***** RISC-V Atom Environment Setup *****"
# Uncomment if using environment modules
# module load verilator/5.006
diff --git a/sw/examples/Makefile b/sw/examples/Makefile
index 14a48de4..8ecdce72 100644
--- a/sw/examples/Makefile
+++ b/sw/examples/Makefile
@@ -77,7 +77,7 @@ ifeq ($(__check_soctarget), true)
ABI:=$(shell $(RVATOM)/scripts/cfgparse.py $(RVATOM)/rtl/config/$(soctarget).json -a abi)
endif
-CFLAGS += -march=$(ISA) -mabi=$(ABI) -nostartfiles -ffreestanding -Os
+CFLAGS += -march=$(ISA) -mabi=$(ABI) -nostartfiles -ffreestanding -Os -fdata-sections -ffunction-sections
CFLAGS += -I $(RVATOM_LIB)/include -L $(RVATOM_LIB)
LFLAGS := -T $(LINKERSCRIPT) -lcatom -Wl,--gc-sections
diff --git a/sw/examples/sdcard/Makefile.include b/sw/examples/sdcard/Makefile.include
new file mode 100644
index 00000000..40a13b5e
--- /dev/null
+++ b/sw/examples/sdcard/Makefile.include
@@ -0,0 +1,2 @@
+src_files = sdcard.c
+executable = sdcard.elf
\ No newline at end of file
diff --git a/sw/examples/sdcard/sdcard.c b/sw/examples/sdcard/sdcard.c
new file mode 100644
index 00000000..af1d6e88
--- /dev/null
+++ b/sw/examples/sdcard/sdcard.c
@@ -0,0 +1,79 @@
+#include "platform.h"
+#include
+#include
+#include
+
+
+int main(){
+ serial_init(UART_BAUD_115200);
+
+ struct SPI_Config cfg = {
+ cfg.base_addr = SPI_ADDR,
+ cfg.enable = true,
+ cfg.pha = false,
+ cfg.pol = false,
+ cfg.lsb_first = false,
+ cfg.baudrate = 1000000,
+ cfg.device_num = 0,
+ cfg.cs_mode = CSMODE_DISABLE,
+ cfg.post_cs_low_delay = 1,
+ cfg.pre_cs_high_delay = 1,
+ cfg.loopback_enable=false
+ };
+
+ uint8_t rc = sd_init(&cfg);
+ if(rc != SD_SUCCESS)
+ return 1;
+
+ printf("read Sector 0\n");
+ uint8_t rbuf[512], res[5], token;
+
+ res[0] = sdc_read_block(&cfg, 0x00000000, rbuf, &token);
+
+
+ // print response
+ if(SD_RESP1_NO_ERROR(res[0]) && (token == SD_START_TOKEN)) {
+ dumphexbuf((char*)rbuf, 512, 0x00000000);
+ }
+ else {
+ puts("Error reading sector\n");
+ return 1;
+ }
+
+
+ // initialize buffer
+ uint8_t wbuf[512];
+ for(uint16_t i = 0; i < 512; i++) wbuf[i] = 0x55;
+
+ res[0] = sdc_write_block(&cfg, 0x00000000, wbuf, &token);
+ // print response
+ if(SD_RESP1_NO_ERROR(res[0]) && (token == SD_DATA_ACCEPTED)) {
+ puts("Write OK\n");
+ }
+ else {
+ puts("Error writing\n");
+ return 1;
+ }
+
+
+ // read again
+ res[0] = sdc_read_block(&cfg, 0x00000000, rbuf, &token);
+ if(SD_RESP1_NO_ERROR(res[0]) && (token == SD_START_TOKEN)) {
+ dumphexbuf((char*)rbuf, 512, 0x00000000);
+ }
+ else {
+ puts("Error reading sector\n");
+ return 1;
+ }
+
+ // verify
+ for(int i=0; i<512; i++){
+ if(rbuf[i] != wbuf[i]){
+ printf("TEST FAIL! @ i=%d\n", i);
+ return 1;
+ }
+ }
+
+ puts("TEST PASSED!\n");
+ return 0;
+}
\ No newline at end of file
diff --git a/sw/lib/include/assert.h b/sw/lib/include/assert.h
index 2e3a5563..5ab58475 100644
--- a/sw/lib/include/assert.h
+++ b/sw/lib/include/assert.h
@@ -6,6 +6,6 @@
#define assert(x) \
if(!(x)) { \
- puts("[ERROR]: Assert Failed:" EXPAND_AND_STRINGIFY(__FILE__) EXPAND_AND_STRINGIFY(__LINE__)); \
+ puts("[ERROR]: Assert Failed: " __FILE__ ":" EXPAND_AND_STRINGIFY(__LINE__) "\n"); \
exit(1); \
}
diff --git a/sw/lib/include/mmio.h b/sw/lib/include/mmio.h
index e439a3ab..bc47bdde 100644
--- a/sw/lib/include/mmio.h
+++ b/sw/lib/include/mmio.h
@@ -4,3 +4,4 @@
#define REG8(base, offset) *((volatile uint8_t*) (base + offset))
#define REG16(base, offset) *((volatile uint16_t*) (base + offset))
#define REG32(base, offset) *((volatile uint32_t*) (base + offset))
+#define REG64(base, offset) *((volatile uint64_t*) (base + offset))
diff --git a/sw/lib/include/sd.h b/sw/lib/include/sd.h
new file mode 100644
index 00000000..479b1289
--- /dev/null
+++ b/sw/lib/include/sd.h
@@ -0,0 +1,48 @@
+#pragma once
+#include
+#include
+
+// Error codes
+#define SD_SUCCESS 0
+#define SD_ERR_UNKNOWN_CARD 1
+#define SD_ERR_MAYBE_VER1CARD 2
+
+#define SD_DATA_ACCEPTED 0x05
+#define SD_DATA_REJECTED_CRC 0x0B
+#define SD_DATA_REJECTED_WRITE 0x0D
+
+#define SD_RESP1_NO_ERROR(x) ((x) == 0)
+
+#define SD_START_TOKEN 0xFE
+#define SD_ERROR_TOKEN 0x00
+#define SD_BLOCK_LEN 512
+
+/**
+ * @brief Initialize SDCARD
+ *
+ * @param cfg SPI config
+ * @return uint8_t resp1
+ */
+uint8_t sd_init(struct SPI_Config *cfg);
+
+/**
+ * @brief Read a block from SDCARD
+ *
+ * @param cfg SPI config
+ * @param addr block address
+ * @param buf buffer
+ * @param token response token
+ * @return uint8_t resp1
+ */
+uint8_t sdc_read_block(struct SPI_Config *cfg, uint32_t addr, uint8_t *buf, uint8_t *token);
+
+/**
+ * @brief Write a block to SDCard
+ *
+ * @param cfg SPI Config
+ * @param addr block address
+ * @param buf buffer
+ * @param token response token
+ * @return uint8_t resp1
+ */
+uint8_t sdc_write_block(struct SPI_Config *cfg, uint32_t addr, uint8_t *buf, uint8_t *token);
diff --git a/sw/lib/include/stdio.h b/sw/lib/include/stdio.h
index 3054f08d..afca3607 100644
--- a/sw/lib/include/stdio.h
+++ b/sw/lib/include/stdio.h
@@ -112,6 +112,14 @@ int fprintf (FILE * file, const char * fmt, ...)
int printf (const char * fmt, ...)
__attribute__((__format__ (__printf__, 1, 2)));
+/**
+ * @brief Writes formatted string to a char buffer
+ * @param str char buffer
+ * @param fmt format string
+ * @return int number of chars written
+ */
+int sprintf(char *str, const char *fmt, ...)
+ __attribute__((__format__ (__printf__, 2, 3)));
// ========== Non Standard Functions ==========
diff --git a/sw/lib/include/stdlib.h b/sw/lib/include/stdlib.h
index e7e43949..58017404 100644
--- a/sw/lib/include/stdlib.h
+++ b/sw/lib/include/stdlib.h
@@ -88,7 +88,7 @@ char *memset(char *dptr, int x, int len);
* @param block_size size of block to be allocated (in bytes)
* @return void* pointer to the allocated block of memory
*/
-void *malloc(size_t block_size);
+void *malloc(unsigned block_size);
/**
@@ -98,3 +98,14 @@ void *malloc(size_t block_size);
*/
void free(void* ptr);
+
+/**
+ * @brief Defragments heap
+ */
+void heap_defrag();
+
+
+/**
+ * @brief Displays heap blocks and overall status
+ */
+void heap_status();
diff --git a/sw/lib/libcatom/heap.c b/sw/lib/libcatom/heap.c
new file mode 100644
index 00000000..b21629ca
--- /dev/null
+++ b/sw/lib/libcatom/heap.c
@@ -0,0 +1,146 @@
+#include
+#include
+#include
+
+extern int _start_heap[2]; // specified as array to prevent a bounds warning
+
+#define HEAP_START &_start_heap
+#ifndef HEAP_SIZE
+ #define HEAP_SIZE 2048
+#endif
+
+struct heapblock{
+ struct heapblock * next;
+ unsigned size;
+};
+typedef struct heapblock HeapBlock;
+
+// Free list
+static HeapBlock * _freelist = NULL;
+
+
+void heap_init() {
+ _freelist = (HeapBlock *) HEAP_START;
+ _freelist->next = NULL;
+ _freelist->size = HEAP_SIZE - sizeof(HeapBlock);
+}
+
+
+void * malloc(unsigned nbytes) {
+ // First Fit
+ if(nbytes == 0 )
+ return NULL;
+
+ HeapBlock * curr = _freelist;
+ HeapBlock * prev = NULL;
+
+ while(curr != NULL){
+ if(curr->size >= nbytes){
+ if(curr->size > sizeof(HeapBlock) + nbytes){
+ // split
+ HeapBlock *newblk = (HeapBlock *)(((uint8_t*)curr) + sizeof(HeapBlock) + nbytes);
+ newblk->next = curr->next;
+ newblk->size = curr->size - (sizeof(HeapBlock) + nbytes);
+ curr->next = newblk;
+ curr->size = nbytes;
+ }
+
+ // allocate current block (remove from list & return chunk pointer)
+ if(prev == NULL) {
+ // first block
+ _freelist = curr->next;
+ }
+ else {
+ prev->next = curr->next;
+ }
+
+ // printf("Allocating [0x%08x: 0x%08x, 0x%d]\n", (uint32_t)curr, (uint32_t)curr->next, curr->size);
+ return (void *)(((uint8_t*)curr) + sizeof(HeapBlock));
+ }
+ prev = curr;
+ curr = curr->next;
+ }
+
+ // No suitable block found
+ return NULL;
+}
+
+
+void free(void * chunk){
+ if(chunk == NULL)
+ return;
+
+ HeapBlock * blk = (HeapBlock *)(((uint8_t*)chunk) - sizeof(HeapBlock));
+ // printf("Freeing [0x%08x: 0x%08x, 0x%d]\n", (uint32_t)blk, (uint32_t)blk->next, blk->size);
+
+ HeapBlock * curr = _freelist;
+ HeapBlock * prev = NULL;
+
+ // march till we reach location of blk
+ while(curr != NULL && curr < blk){
+ prev = curr;
+ curr = curr->next;
+ }
+
+ // Insert block
+ if (prev == NULL) {
+ _freelist = blk;
+ } else {
+ prev->next = blk;
+ }
+ blk->next = curr;
+
+ // // merge with previous
+ // // only if prev and current are adjascent (which means both are free)
+ // if(prev != NULL && ((uint8_t*)prev + sizeof(HeapBlock) + prev->size) == (uint8_t*)blk) {
+ // prev->size += sizeof(HeapBlock) + blk->size;
+ // prev->next = blk->next;
+ // }
+
+ // // merge with next
+ // // only if current and next are adjascent (which means both are free)
+ // if(curr != NULL && ((uint8_t*)blk + sizeof(HeapBlock) + blk->size) == (uint8_t*)curr) {
+ // blk->size += sizeof(HeapBlock) + curr->size;
+ // blk->next = curr->next;
+ // }
+}
+
+
+void heap_defrag(){
+ HeapBlock * curr = _freelist;
+ HeapBlock * prev = NULL;
+
+ while(curr != NULL){
+ // merge if prev blk & curr blk are contigous (both free)
+ if(prev != NULL && (uint8_t*)prev+sizeof(HeapBlock)+prev->size == (uint8_t*)curr){
+ prev->size += sizeof(HeapBlock) + curr->size;
+ prev->next = curr->next;
+ curr = prev->next;
+ continue;
+ }
+ prev = curr;
+ curr = curr->next;
+ }
+}
+
+
+void heap_status(){
+ unsigned total_sz = 0;
+ unsigned blk_cnt = 0;
+ unsigned largest_blk_sz = 0;
+ HeapBlock * currblk = _freelist;
+ while(currblk != NULL) {
+ printf("Block [addr=0x%08x: next=0x%08x, size=%d]\n", (uint32_t)currblk, (uint32_t)currblk->next, currblk->size);
+ total_sz += currblk->size;
+ if(currblk->size > largest_blk_sz){
+ largest_blk_sz = currblk->size;
+ }
+ currblk = currblk->next;
+ blk_cnt ++;
+ }
+ printf("Chunks: %d\n", blk_cnt);
+ printf("Avail: %d/%d bytes\n", total_sz, HEAP_SIZE);
+
+ // see: https://cpp4arduino.com/2018/11/06/what-is-heap-fragmentation.html
+ printf("Frag: %.2f %%\n", (1.0 - ((float)largest_blk_sz/(float)HEAP_SIZE)) * 100);
+}
diff --git a/sw/lib/libcatom/hydrogensoc/sd.c b/sw/lib/libcatom/hydrogensoc/sd.c
new file mode 100644
index 00000000..96747674
--- /dev/null
+++ b/sw/lib/libcatom/hydrogensoc/sd.c
@@ -0,0 +1,414 @@
+#include
+#include
+#include
+#include
+
+#include
+
+#ifdef SDCARD_SILENT_INIT
+ #define SD_DBG(x)
+#else
+ #define SD_DBG(x) x
+#endif
+
+// Configuration
+#define SD_NUM_ATTEMPTS 10
+#define SD_SPI_INIT_BAUD 200000
+
+//FIXME: change these to time based timeout values
+#define SD_MAX_READ_ATTEMPTS 1563
+#define SD_MAX_WRITE_ATTEMPTS 3907
+
+// Helper Macros
+#define R1_CHECK_CARD_RDY(X) ((X) == 0)
+#define R1_CHECK_MSB_ERROR(X) ((X) & 0b10000000)
+#define R1_CHECK_PARAM_ERROR(X) ((X) & 0b01000000)
+#define R1_CHECK_ADDR_ERROR(X) ((X) & 0b00100000)
+#define R1_CHECK_ERASE_SEQ_ERROR(X) ((X) & 0b00010000)
+#define R1_CHECK_CRC_ERROR(X) ((X) & 0b00001000)
+#define R1_CHECK_ILLEGAL_CMD(X) ((X) & 0b00000100)
+#define R1_CHECK_ERASE_RESET(X) ((X) & 0b00000010)
+#define R1_CHECK_IN_IDLE(X) ((X) & 0b00000001)
+
+#define R7_GET_CMD_VER(X) ((X >> 4) & 0xF0)
+#define R7_GET_VOL_ACC(X) (X & 0x1F)
+#define R7_VOLTAGE_ACC_27_33 0b00000001
+#define R7_VOLTAGE_ACC_LOW 0b00000010
+#define R7_VOLTAGE_ACC_RES1 0b00000100
+#define R7_VOLTAGE_ACC_RES2 0b00001000
+
+#define R3_POWER_UP_STATUS(X) ((X) & 0x40)
+#define R3_CCS_VAL(X) ((X) & 0x40)
+#define R3_VDD_2728(X) ((X) & 0b10000000)
+#define R3_VDD_2829(X) ((X) & 0b00000001)
+#define R3_VDD_2930(X) ((X) & 0b00000010)
+#define R3_VDD_3031(X) ((X) & 0b00000100)
+#define R3_VDD_3132(X) ((X) & 0b00001000)
+#define R3_VDD_3233(X) ((X) & 0b00010000)
+#define R3_VDD_3334(X) ((X) & 0b00100000)
+#define R3_VDD_3435(X) ((X) & 0b01000000)
+#define R3_VDD_3536(X) ((X) & 0b10000000)
+
+
+uint8_t sdc_read_res1(struct SPI_Config *cfg);
+void sdc_read_res3_or_7(struct SPI_Config *cfg, uint8_t *res);
+void sdc_powerup_seq(struct SPI_Config *cfg);
+
+///////////////////////////////////////////////////////////////////////////////
+static void __print_buf(uint8_t *buf, unsigned buflen) {
+ puts("{ ");
+ for(unsigned i=0; i 1) return;
+
+ printf("- Cmd Version: 0x%x\n", R7_GET_CMD_VER(res[1]));
+ puts("- Voltage Accepted: ");
+ switch(R7_GET_VOL_ACC(res[3])){
+ case R7_VOLTAGE_ACC_27_33: puts("2.7-3.6V"); break;
+ case R7_VOLTAGE_ACC_LOW: puts("Low Voltage"); break;
+ case R7_VOLTAGE_ACC_RES1:
+ case R7_VOLTAGE_ACC_RES2: puts("Reserved"); break;
+ default: puts("Not Defined"); break;
+ }
+ putchar('\n');
+ printf("- Check pattern: 0x%x\n", res[4]);
+}
+
+void sd_print_r3_resp(uint8_t *res) {
+ puts("Res3:"); __print_buf(res, 5); putchar('\n');
+
+ sd_print_r1_resp(res[0]);
+ if(res[0] > 1) return;
+
+ puts("- Card Power Up Status: ");
+ if(R3_POWER_UP_STATUS(res[1])) {
+ puts("Ready\n");
+ printf("- CCS Status: %c\n", R3_CCS_VAL(res[1]) ? '1' : '0');
+ }
+ else {
+ puts("Busy\n");
+ }
+
+ puts("- VDD Window: ");
+ if(R3_VDD_2728(res[3])) puts("2.7-2.8, ");
+ if(R3_VDD_2829(res[2])) puts("2.8-2.9, ");
+ if(R3_VDD_2930(res[2])) puts("2.9-3.0, ");
+ if(R3_VDD_3031(res[2])) puts("3.0-3.1, ");
+ if(R3_VDD_3132(res[2])) puts("3.1-3.2, ");
+ if(R3_VDD_3233(res[2])) puts("3.2-3.3, ");
+ if(R3_VDD_3334(res[2])) puts("3.3-3.4, ");
+ if(R3_VDD_3435(res[2])) puts("3.4-3.5, ");
+ if(R3_VDD_3536(res[2])) puts("3.5-3.6");
+ puts("\n");
+}
+
+enum SDRespType {
+ RESP1,
+ RESP3,
+ RESP7
+};
+
+typedef struct {
+ uint8_t cmd;
+ uint32_t arg;
+ uint8_t crc;
+ enum SDRespType resp_type;
+} SDCmd_attr;
+
+typedef enum {
+ SD_CMD0 = 0,
+ SD_CMD8 = 1,
+ SD_CMD17 = 2,
+ SD_CMD24 = 3,
+ SD_CMD41 = 4,
+ SD_CMD55 = 5,
+ SD_CMD58 = 6
+} SDCmd;
+
+const SDCmd_attr sdcmds[7] = {
+ /* SD_CMD0 */ {.cmd=0, .arg=0x00000000, .crc=0x94, .resp_type=RESP1},
+ /* SD_CMD8 */ {.cmd=8, .arg=0x000001AA, .crc=0x86, .resp_type=RESP7},
+ /* SD_CMD17 */ {.cmd=17, .arg=0x00000000, .crc=0x00, .resp_type=RESP1},
+ /* SD_CMD24 */ {.cmd=24, .arg=0x00000000, .crc=0x00, .resp_type=RESP1},
+ /* SD_CMD41 */ {.cmd=41, .arg=0x40000000, .crc=0x00, .resp_type=RESP1},
+ /* SD_CMD55 */ {.cmd=55, .arg=0x00000000, .crc=0x00, .resp_type=RESP1},
+ /* SD_CMD58 */ {.cmd=58, .arg=0x00000000, .crc=0x00, .resp_type=RESP3}
+};
+
+#define _spi_select(cfg) \
+ spi_transfer(cfg, 0xFF); \
+ spi_select(cfg); \
+ spi_transfer(cfg, 0xFF);
+
+#define _spi_deselect(cfg) \
+ spi_transfer(cfg, 0xFF); \
+ spi_deselect(cfg); \
+ spi_transfer(cfg, 0xFF); \
+
+void sdc_cmd(struct SPI_Config *cfg, SDCmd cmd, uint8_t * resp) {
+ // send command
+ spi_transfer(cfg, sdcmds[cmd].cmd | 0x40);
+
+ // send arg
+ spi_transfer(cfg, sdcmds[cmd].arg >> 24);
+ spi_transfer(cfg, sdcmds[cmd].arg >> 16);
+ spi_transfer(cfg, sdcmds[cmd].arg >> 8);
+ spi_transfer(cfg, sdcmds[cmd].arg);
+
+ // send CRC
+ spi_transfer(cfg, sdcmds[cmd].crc | 0x1);
+
+ // read response
+ switch(sdcmds[cmd].resp_type) {
+ case RESP1:
+ resp[0] = sdc_read_res1(cfg);
+ break;
+
+ case RESP3:
+ case RESP7:
+ sdc_read_res3_or_7(cfg, resp);
+ break;
+
+ default:
+ resp[0] = sdc_read_res1(cfg);
+ break;
+ }
+}
+
+uint8_t sdc_read_res1(struct SPI_Config *cfg) {
+ unsigned ntry = 8;
+ uint8_t resp;
+ do {
+ resp = spi_transfer(cfg, 0xFF);
+ } while((resp == 0xff) & (ntry-- > 0));
+ return resp;
+}
+
+void sdc_read_res3_or_7(struct SPI_Config *cfg, uint8_t *res) {
+ // read R1
+ res[0] = sdc_read_res1(cfg);
+
+ // if error reading R1, return
+ if(res[0] > 1) return;
+
+ // read remaining bytes
+ res[1] = spi_transfer(cfg, 0x0);
+ res[2] = spi_transfer(cfg, 0x0);
+ res[3] = spi_transfer(cfg, 0x0);
+ res[4] = spi_transfer(cfg, 0x0);
+}
+
+void sdc_powerup_seq(struct SPI_Config *cfg) {
+ // deselect SPI
+ spi_deselect(cfg);
+
+ // wait for some time
+ sleep_ms(1);
+
+ // send 80 clock cycles to synchronize
+ for(int i=0; i<80; i+=8)
+ spi_transfer(cfg, 0xff);
+}
+
+uint8_t sd_init(struct SPI_Config *cfg)
+{
+ cfg->cs_mode = CSMODE_DISABLE;
+ cfg->baudrate = SD_SPI_INIT_BAUD;
+ spi_init(cfg);
+
+ uint8_t res[5];
+ uint8_t ntries = 0;
+
+ // Step - 1: Power UP Sequence
+ SD_DBG(puts("SDC: Powering up\n");)
+ sdc_powerup_seq(cfg);
+
+
+ // Step - 2: goto IDLE
+ SD_DBG(puts("SDC: Sending CMD0..\n");)
+ ntries = SD_NUM_ATTEMPTS;
+ do {
+ _spi_select(cfg)
+ sdc_cmd(cfg, SD_CMD0, res);
+ _spi_deselect(cfg)
+ } while ((res[0] != 0x01) && (ntries-- > 0));
+
+ if(ntries==0)
+ return SD_ERR_UNKNOWN_CARD;
+
+
+ // Step - 3: Send interface conditions
+ SD_DBG(puts("SDC: Sending CMD8..\n");)
+ _spi_select(cfg)
+ sdc_cmd(cfg, SD_CMD8, res);
+ _spi_deselect(cfg)
+ SD_DBG(sd_print_r7_resp(res);)
+
+ // check idle
+ if(res[0] != 0x01)
+ return SD_ERR_MAYBE_VER1CARD;
+ // check echo pattern
+ if(res[4] != 0xAA)
+ return SD_ERR_UNKNOWN_CARD;
+
+
+ // Step - 4: Initialization
+ SD_DBG(puts("SDC: Initializing..\n");)
+ ntries = 0;
+ do {
+ if(ntries > SD_NUM_ATTEMPTS) {
+ return SD_ERR_UNKNOWN_CARD;
+ }
+
+ // send app cmd
+ SD_DBG(printf("SDC: Sending CMD55... (Try:%d)\n", ntries);)
+ _spi_select(cfg)
+ sdc_cmd(cfg, SD_CMD55, res);
+ _spi_deselect(cfg)
+ SD_DBG(sd_print_r1_resp(res[0]);)
+
+ // if no error in response
+ if(res[0] < 2)
+ {
+ SD_DBG(puts("SDC: Sending ACMD41...\n");)
+ _spi_select(cfg)
+ sdc_cmd(cfg, SD_CMD41, res);
+ _spi_deselect(cfg)
+ SD_DBG(sd_print_r1_resp(res[0]);)
+ }
+
+ // wait
+ sleep_ms(10);
+ ntries++;
+ } while(!R1_CHECK_CARD_RDY(res[0]));
+
+ // Step - 5: read OCR
+ SD_DBG(puts("SDC: Send CMD58 (Read OCR)..\n");)
+ _spi_select(cfg)
+ sdc_cmd(cfg, SD_CMD58, res);
+ _spi_deselect(cfg)
+ SD_DBG(sd_print_r3_resp(res);)
+
+ // check card is ready
+ SD_DBG(puts("SDC: Initialization ");)
+
+ if(!(res[1] & 0x80)) {
+ SD_DBG(puts("FAILED\n");)
+ return SD_ERR_UNKNOWN_CARD;
+ }
+
+ SD_DBG(puts("SUCCESS\n");)
+ return SD_SUCCESS;
+}
+
+uint8_t sdc_read_block(struct SPI_Config *cfg, uint32_t addr, uint8_t *buf, uint8_t *token) {
+ uint8_t res1, read;
+ uint16_t readAttempts;
+
+ // set token to none
+ *token = 0xFF;
+
+ _spi_select(cfg);
+
+ // send command 17
+ sdc_cmd(cfg, SD_CMD17, &res1);
+
+ // if response received from card
+ if(res1 != 0xFF)
+ {
+ // wait for a response token (timeout = 100ms)
+ readAttempts = 0;
+ while(++readAttempts != SD_MAX_READ_ATTEMPTS)
+ if((read = spi_transfer(cfg, 0xFF)) != 0xFF) break;
+
+ // if response token is 0xFE
+ if(read == SD_START_TOKEN)
+ {
+ // read 512 byte block
+ for(uint16_t i = 0; i < SD_BLOCK_LEN; i++)
+ *buf++ = spi_transfer(cfg, 0xFF);
+
+ // read (& discard) 16-bit CRC
+ spi_transfer(cfg, 0xFF);
+ spi_transfer(cfg, 0xFF);
+ }
+
+ // set token to card response
+ *token = read;
+ }
+
+ // deassert chip select
+ _spi_deselect(cfg);
+ return res1;
+}
+
+uint8_t sdc_write_block(struct SPI_Config *cfg, uint32_t addr, uint8_t *buf, uint8_t *token)
+{
+ uint8_t res1, readAttempts, read;
+
+ // set token to none
+ *token = 0xFF;
+
+ // assert chip select
+ _spi_select(cfg)
+
+ // send CMD24
+ sdc_cmd(cfg, SD_CMD24, &res1);
+
+ // if no error
+ if(R1_CHECK_CARD_RDY(res1))
+ {
+ // send start token
+ spi_transfer(cfg, SD_START_TOKEN);
+
+ // write buffer to card
+ for(uint16_t i = 0; i < SD_BLOCK_LEN; i++)
+ spi_transfer(cfg, buf[i]);
+
+ // wait for a response (timeout = 250ms)
+ readAttempts = 0;
+ while(++readAttempts != SD_MAX_WRITE_ATTEMPTS)
+ if((read = spi_transfer(cfg, 0xFF)) != 0xFF) { *token = 0xFF; break; }
+
+ // if data accepted
+ if((read & 0x1F) == 0x05)
+ {
+ // set token to data accepted
+ *token = 0x05;
+
+ // wait for write to finish (timeout = 250ms)
+ readAttempts = 0;
+ while(spi_transfer(cfg, 0xFF) == 0x00) {
+ if(++readAttempts == SD_MAX_WRITE_ATTEMPTS) {
+ *token = 0x00;
+ break;
+ }
+ }
+ }
+ }
+
+ // deassert chip select
+ _spi_deselect(cfg)
+ return res1;
+}
diff --git a/sw/lib/libcatom/hydrogensoc/serial.c b/sw/lib/libcatom/hydrogensoc/serial.c
index 0d149fd2..99ed084a 100644
--- a/sw/lib/libcatom/hydrogensoc/serial.c
+++ b/sw/lib/libcatom/hydrogensoc/serial.c
@@ -32,6 +32,8 @@
#define UART_REG_LCR_PERR 0b00001000
int __serial_read(char * bf, uint32_t sz){
+ assert(sz==1);
+ bf[0] = serial_read();
return 0;
}
@@ -47,7 +49,7 @@ void serial_init(uint32_t baud_rate)
uart_config.baud = baud_rate;
serial_set_config(&uart_config);
- stddev[DEV_STDOUT].read=__serial_read;
+ stddev[DEV_STDIN].read=__serial_read;
stddev[DEV_STDOUT].write=__serial_write;
}
diff --git a/sw/lib/libcatom/start.S b/sw/lib/libcatom/start.S
index ff9b57c4..d012e630 100644
--- a/sw/lib/libcatom/start.S
+++ b/sw/lib/libcatom/start.S
@@ -31,6 +31,9 @@ _start:
sub a2, t0, a0 // size = _sbss - _sbss
jal memset
+ // Initialize heap
+ jal heap_init
+
/* Disable and clear all interrupt sources */
li a3, -1
csrc mie, a3
diff --git a/sw/lib/libcatom/stdio.c b/sw/lib/libcatom/stdio.c
index b2826b6e..0b8ecaca 100644
--- a/sw/lib/libcatom/stdio.c
+++ b/sw/lib/libcatom/stdio.c
@@ -2,7 +2,7 @@
#include
#include
#include
-
+#include
#define BACKSPACE 0x7f
@@ -10,7 +10,7 @@
#define PRINTF_ENFMT_BIN
// Enable printf %f format specifer
-// #define PRINTF_ENFMT_FLOAT
+#define PRINTF_ENFMT_FLOAT
// Enable printf %n format specifer
#define PRINTF_ENFMT_N
@@ -85,6 +85,25 @@ static int __fprint_ull(FILE *f, unsigned long long n, unsigned base, char padc,
return ret;
}
+#ifdef PRINTF_ENFMT_FLOAT
+static int __fltprint(FILE *f, double flt, char padc, int padd, int padf)
+{
+ int ret = 0;
+ unsigned long long d = (unsigned long long) flt;
+ double frac = flt - (double) d;
+ ret = __fprint_ull(f, d, 10, padc, padd);
+ if(padf>0){
+ __fputc(f, '.');
+ ret++;
+ while(padf--) {
+ frac *= 10.0;
+ }
+ d = (unsigned long long) frac;
+ ret += __fprint_ull(f, d, 10, '0', 0);
+ }
+ return ret;
+}
+#endif
//////////////////////////////////////////////////////////////////////////
@@ -161,10 +180,12 @@ char * gets(char *str){
int vfprintf(FILE *f, const char * fmt, va_list args){
long long num_ll;
unsigned long long num_ull;
+ double num_f;
uintptr_t ptr;
char padc;
int padn;
+ int padf;
int lcount;
unsigned nwritten = 0;
@@ -174,17 +195,30 @@ int vfprintf(FILE *f, const char * fmt, va_list args){
if (*fmt == '%') {
fmt++; // skip over %
- // check for padc & padn
- padn = 0;
+ // Parse padchar (padc), width (padn) and precision (padf)
padc = ' ';
+ padn = 0;
+ padf = 6;
if (*fmt == '0') {
padc = '0';
fmt++;
+ }
+ while(1){
+ if(!__char_is_num(*fmt))
+ break;
+ padn = (*fmt-'0') + (padn << 3) + (padn << 1); // padn = padn*10 + digit
+ fmt++;
+ }
+ if(*fmt == '.') {
+ fmt++; // skip over .
+ padf = 0;
while(1){
if(!__char_is_num(*fmt))
break;
- padn = (*fmt-'0') + (padn << 3) + (padn << 1); // padn = padn*10 + digit
+ padf = (*fmt-'0') + (padf << 3) + (padf << 1); // padn = padn*10 + digit
fmt++;
+ if(padn > padf + 1)
+ padn -= (padf+1);
}
}
@@ -271,6 +305,14 @@ int vfprintf(FILE *f, const char * fmt, va_list args){
#ifdef PRINTF_ENFMT_FLOAT
// Float
case 'f':
+ // floats are always promoted to double in va_args
+ num_f = va_arg(args, double);
+ if(num_f < 0) {
+ __fputc(f, '-');
+ num_f *= -1.0;
+ padn--;
+ }
+ nwritten += __fltprint(f, num_f, padc, padn, padf);
break;
#endif // PRINTF_ENFMT_FLOAT
@@ -314,6 +356,39 @@ int printf(const char *fmt, ...)
}
+static char * __sstream_strbuf = NULL;
+static int __sstream_strbuf_writepos = -1;
+int __sstream_write(char * bf, uint32_t sz){
+ assert(__sstream_strbuf != NULL);
+ __sstream_strbuf[__sstream_strbuf_writepos++] = bf[0];
+ return 0;
+}
+
+int vsprintf(char *str, const char *fmt, va_list args) {
+ // setup a fake string stream that writes to a string buffer
+ FILE fake_sstream = {.read=NULL, .write=__sstream_write};
+ __sstream_strbuf = str;
+ __sstream_strbuf_writepos = 0;
+
+ int rv = vfprintf(&fake_sstream, fmt, args);
+
+ // terminate with nullchar
+ fake_sstream.write("\0", 1);
+
+ // cleanup after we're done
+ __sstream_strbuf = NULL;
+ __sstream_strbuf_writepos = -1;
+ return rv;
+}
+
+int sprintf(char *str, const char *fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ int rv = vsprintf(str, fmt, args);
+ va_end(args);
+ return rv;
+}
+
void dumphexbuf(char *buf, unsigned len, unsigned base_addr)
{
const int bpw = 4; // bytes per word
diff --git a/synth/altera/de0-cv/HydrogenSoC.tcl b/synth/altera/de0-cv/HydrogenSoC.tcl
index 57cf2c89..18daa27e 100644
--- a/synth/altera/de0-cv/HydrogenSoC.tcl
+++ b/synth/altera/de0-cv/HydrogenSoC.tcl
@@ -160,14 +160,26 @@ if {$make_assignments} {
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio_io[29]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio_io[30]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio_io[31]
- set_location_assignment PIN_G13 -to spi_cs_o[0]
- set_location_assignment PIN_G12 -to spi_mosi_o
- set_location_assignment PIN_J17 -to spi_miso_i
- set_location_assignment PIN_K16 -to spi_sck_o
+
+ # SDCARD Slot
+ set_location_assignment PIN_C11 -to spi_cs_o[0]
+ set_location_assignment PIN_H11 -to spi_sck_o
+ set_location_assignment PIN_B11 -to spi_mosi_o
+ set_location_assignment PIN_K9 -to spi_miso_i
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to spi_cs_o[0]
+ set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to spi_sck_o
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to spi_mosi_o
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to spi_miso_i
- set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to spi_sck_o
+
+ # GPIO - SDCARD ELA
+ # set_location_assignment PIN_G13 -to ela_spi_cs_o
+ # set_location_assignment PIN_G12 -to ela_spi_sck_o
+ # set_location_assignment PIN_J17 -to ela_spi_mosi_o
+ # set_location_assignment PIN_K16 -to ela_spi_miso_o
+ # set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ela_spi_cs_o[0]
+ # set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ela_spi_sck_o
+ # set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ela_spi_mosi_o
+ # set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ela_spi_miso_o
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
@@ -175,25 +187,6 @@ if {$make_assignments} {
export_assignments
}
-load_package flow
-
-# Synthesize the design
-puts "Synthesizing the design..."
-execute_module -tool map
-
-# Place and route
-puts "Performing place and route..."
-execute_module -tool fit
-
-# Generate programming files (Bitstream)
-puts "Generating bitstream..."
-execute_module -tool asm
-
-# Generate Timing Analysis Report
-puts "Generating timing analysis report..."
-execute_module -tool sta
-
-puts "Bitstream generation completed."
# Load necessary package
load_package flow
diff --git a/synth/altera/de0-cv/Makefile b/synth/altera/de0-cv/Makefile
index e21f84e5..774d6b07 100644
--- a/synth/altera/de0-cv/Makefile
+++ b/synth/altera/de0-cv/Makefile
@@ -18,8 +18,8 @@ default: build
$(build_dir)/bootloader.hex:
$(call print_msg_root,Rebuilding libcatom and bootloader)
- make $(MKFLAGS) -C $(RVATOM)/sw/lib soctarget=$(soctarget) sim=0 clean build
- make $(MKFLAGS) -C $(RVATOM)/sw/bootloader soctarget=$(soctarget) sim=0 clean build
+ $(MAKE) $(MKFLAGS) -C $(RVATOM)/sw/lib soctarget=$(soctarget) sim=0 clean build
+ $(MAKE) $(MKFLAGS) -C $(RVATOM)/sw/bootloader soctarget=$(soctarget) sim=0 clean build
cp $(RVATOM)/sw/bootloader/bootloader.hex $@
$(build_dir)/HydrogenSoC.v:
diff --git a/synth/xilinx/spartan6-mini/Makefile b/synth/xilinx/spartan6-mini/Makefile
index 15a87dcd..2a4bf23c 100644
--- a/synth/xilinx/spartan6-mini/Makefile
+++ b/synth/xilinx/spartan6-mini/Makefile
@@ -18,8 +18,8 @@ default: build
$(build_dir)/bootloader.hex:
$(call print_msg_root,Rebuilding libcatom and bootloader)
- make $(MKFLAGS) -C $(RVATOM)/sw/lib soctarget=$(soctarget) sim=0 clean build
- make $(MKFLAGS) -C $(RVATOM)/sw/bootloader soctarget=$(soctarget) sim=0 clean build
+ $(MAKE) $(MKFLAGS) -C $(RVATOM)/sw/lib soctarget=$(soctarget) sim=0 clean build
+ $(MAKE) $(MKFLAGS) -C $(RVATOM)/sw/bootloader soctarget=$(soctarget) sim=0 clean build
cp $(RVATOM)/sw/bootloader/bootloader.hex $@
$(build_dir)/HydrogenSoC.v:
diff --git a/synth/yosys/Makefile b/synth/yosys/Makefile
index f05339c9..ec05f477 100644
--- a/synth/yosys/Makefile
+++ b/synth/yosys/Makefile
@@ -39,8 +39,8 @@ default: fpga #t# alias for fpga target
$(build_dir)/bootloader.hex:
$(call print_msg_root,Rebuilding libcatom and bootloader)
- make $(MKFLAGS) -C $(RVATOM)/sw/lib soctarget=$(soctarget) sim=0 clean build
- make $(MKFLAGS) -C $(RVATOM)/sw/bootloader soctarget=$(soctarget) sim=0 clean build
+ $(MAKE) $(MKFLAGS) -C $(RVATOM)/sw/lib soctarget=$(soctarget) sim=0 clean build
+ $(MAKE) $(MKFLAGS) -C $(RVATOM)/sw/bootloader soctarget=$(soctarget) sim=0 clean build
cp $(RVATOM)/sw/bootloader/bootloader.hex $@
$(build_dir)/HydrogenSoC.v: