diff --git a/tools/rtl-coding/RTL-Coding-Guidelines.md b/tools/rtl-coding/RTL-Coding-Guidelines.md
index 2e7efe194cf0ee2144039aa8801100f7851a2253..a396b55e31464b8c609d7c40fb6f024ad2addf33 100644
--- a/tools/rtl-coding/RTL-Coding-Guidelines.md
+++ b/tools/rtl-coding/RTL-Coding-Guidelines.md
@@ -1,5 +1,112 @@
 # CHIPKIT RTL Coding Guidelines
 
+Research test chip projects are typically severely time constrained.
+Therefore, it is important to use an RTL development approach that is 1) efficient, 2) minimizes bugs, and 3) is supported by front-to-back EDA tool flows.
+While less verbose than VHDL, the earlier Verilog RTL standards such as Verilog'95 and Verilog-2001 offer very limited compile-time checking, which can lead to a large number of trivial bugs.
+Although this can be overcome by the use of lining tools and strict coding guidlines, it is generally slow.
+
+In recent years, there has been a significant research effort exploring new hardware design languages, such as Chisel, PyMTL, MyHDL etc, as well as high-level synthesis (HLS) from C++/SystemC languages.
+However, in either case, there is a translation step of varying complexity required to generate Verilog for the EDA tools to consume.
+We use SystemVerilog (SV) for most of our RTL design, which is mature, natively supported by EDA tools, and relatively well supported in open source projects.
+SV includes a number of more advanced language features that prevent a whole class of common issues with older Verilog standards.
+
+This document outlines some coding guidelines for writing bug-free RTL in SV.
+More generally, we offer advice for arranging RTL projects.
+
+## SystemVerilog Coding Style
+
+SV is a very large language with many verification-oriented features that are not relevant to writing synthesizable RTL.
+Therefore, we use a strict RTL coding style, which can be summarized in the following directives:
+
+* **Separate logic and registers.**
+Makes RTL easier to parse and pipelining easier to modify.
+Forces designers to think about where registers exist in the design.
+Also typically also  it easier to modify pipelines.
+
+* **Use rising-edge registers with active-low async reset.**
+Simplifies functional debug, validation and timing constraint development.
+
+* **Only one clock and reset signal in a module.**
+This guideline drastically reduces bugs related to clocking and reset.
+The vast majority of RTL modules do not require more than one clock and reset.
+Any logic that *requires* multiple clocks should be careful contained in a special module.
+
+* **Use the `logic` type exclusively.**
+Replaces both the older \texttt{wire} and (very confusing) \texttt{reg} types.
+Provides compile-time checking for multiple drivers.
+
+* **Use the `always_comb` keyword for logic.**
+Provides compile-time checking for unintended latches or registers.
+
+* **Use the ``always_ff`` keyword to infer registers.**
+Provides compile-time checking for unintentional latches.
+
+* **Use automatic module instantiation connections (`.*`).**
+These significantly reduce the verbosity of connecting modules and provide additional compile-time checking.
+
+* **Lower-case signal names with underscores (`_`).**
+
+* **Use all-caps for top-level module port signals.**
+
+
+The following tiny RTL example module `my_counter` demonstrates some of these guidelines in a compact example.
+
+```systemverilog
+`include RTL.svh
+
+module my_counter (
+  input  logic       clock,
+  input  logic       reset_n,
+  
+  input  logic       enable,
+  output logic[31:0] count
+);
+
+// "logic" type replaces "wire" and "reg"
+logic[31:0] count_next;
+
+// Use "always_comb" keyword for logic
+always_comb count_next = count + 32'd1;
+
+// Use a macro to infer registers
+`FF(count_next, count, clock, enable, reset_n, '0); 
+
+endmodule  // my_counter
+```
+
+In addition to these guidelines, we also recommend the strict use of a pre-processor macro for register inference.
+This has a number of advantages, including: 1) significant reduction in lines of code, 2) removes the risk of poor inference style, e.g. embedded logic, 3) enforces use of a rising-edge, async active-low reset, 4) allows the register inference template to be changed to suit ASIC or FPGA.
+A macro is used instead of a module to reduce simulation overhead.
+The CHIPKIT RTL header file (`RTL.svh`) includes a macro definition `\`FF()` for this purpose, which replaces the traditional inference template, as shown in the snippet below.  
+When using FPGAs with an RTL codebase, this macro can be easily redefined to infer a synchronous reset, which is more common.
+
+```systemverilog
+// Include file contains flip-flop inference macro
+`include RTL.svh
+
+// Traditional flip-flop inference template
+always_ff @(posedge clock, negedge reset_n) begin
+  if(!reset_n) q_out <= ‘0;
+  else
+    if(enable) q_out <= d_in;
+end
+
+// Example of flip-flop macro
+// (Final term ('0) is the reset state)
+`FF(count_next, count, clock, enable, reset_n, '0); 
+```
+
+
+
+\subsection{Instantiated Library Components}
+Physical IP such as SRAMs, IO cells, clock oscillators, and synchronizers need to be instantiated in the RTL.
+It's worth remembering that various versions of these cells may be required over the lifetime of the IP or full-chip, including RTL functional models as well as various ASIC and FPGA libraries.
+Therefore, it is helpful to wrap instantiated components inside a module, which can then be easily switched.
+Each set of wrapped component instantiation modules is stored in a different directory for each library, with the correct directory included at compile time.
+%This allows the developer to swap out RTL models with ASIC or FPGA models or inference templates at both simulation and implementation time.
+
+
+
 TODO 
 add intro on importance of coding guidelines and explain not much currently around
 add examples of common gotchas, especially with Verilog (and how SV helps)