diff --git a/ci/ci-build.sh b/ci/ci-build.sh
index 2a6b7efed05ec7a1b9cc2969af633a888afa6010..621e455b1d030b90d438d98fd5ee8c500b7e3f7a 100644
--- a/ci/ci-build.sh
+++ b/ci/ci-build.sh
@@ -2,9 +2,13 @@
 
 set -e
 
+# Quad Hardware Tests
+source /remote/Xilinx/2018.2/Vivado/2018.2/settings64.sh
+(cd quad/ip_repo && make build-tests)
+
 # Quad Libraries and Boot image
-(cd quad && make deep-clean && make)
+#(cd quad && make deep-clean && make)
 
 # Ground station
-git submodule update --init --recursive
+#git submodule update --init --recursive
 #(cd groundStation && make vrpn && make) # QT is breaking things right now
diff --git a/ci/ci-test.sh b/ci/ci-test.sh
index 67e6ed1c6afc9968d791978dbdf4cfca8f9711eb..50bf206a6b2cd535792da85c7c82c293d765c3aa 100644
--- a/ci/ci-test.sh
+++ b/ci/ci-test.sh
@@ -2,5 +2,9 @@
 
 set -e
 
+# Quad HW
+source /remote/Xilinx/2018.2/Vivado/2018.2/settings64.sh
+(cd quad/ip_repo && make run-tests)
+
 # Quad
-(cd quad && make test)
+#(cd quad && make test)
diff --git a/quad/ip_repo/Makefile b/quad/ip_repo/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..8c1120a62e3eeabcb735581ebbb0b0c8a5f3a2c2
--- /dev/null
+++ b/quad/ip_repo/Makefile
@@ -0,0 +1,7 @@
+build-tests: 
+	(cd pwm_recorder_1.0/ && make build-tests)
+	(cd pwm_signal_out_1.0/ && make build-tests)
+
+run-tests:
+	(cd pwm_recorder_1.0/ && make run-tests)
+	(cd pwm_signal_out_1.0/ && make run-tests)
\ No newline at end of file
diff --git a/quad/ip_repo/get_simulation_result.tcl b/quad/ip_repo/get_simulation_result.tcl
new file mode 100644
index 0000000000000000000000000000000000000000..26a4eea8eab648e5155d3afc0d3dc255231cd46b
--- /dev/null
+++ b/quad/ip_repo/get_simulation_result.tcl
@@ -0,0 +1,7 @@
+#!/bin/bash
+set signal [get_objects /*_tester/passing]
+set fd [open "result.log" "w"]
+run all
+puts $fd [get_value $signal]
+flush $fd
+quit
\ No newline at end of file
diff --git a/quad/ip_repo/pwm_recorder_1.0/Makefile b/quad/ip_repo/pwm_recorder_1.0/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..a3981b29b189d71d9808cf315c4f59b67a395f17
--- /dev/null
+++ b/quad/ip_repo/pwm_recorder_1.0/Makefile
@@ -0,0 +1,10 @@
+build-tests:
+# The build products get removed if run in the build step.
+
+run-tests:
+	xelab --debug wave -prj kernel_test.prj -s run_kernel_test work.kernel_tester
+	xsim run_kernel_test -wdb kernel_test.wdb --t ../get_simulation_result.tcl
+	echo 1 > result.exp
+	cat result.log
+	cmp result.log result.exp
+	rm result.exp
\ No newline at end of file
diff --git a/quad/ip_repo/pwm_recorder_1.0/hdl/kernel_tester.vhd b/quad/ip_repo/pwm_recorder_1.0/hdl/kernel_tester.vhd
index a9f79d2e362ba57a57e3e6511c46a9ab2ef73e5b..aa3b53a64c1021f6ed1e8b3f1d5ce067f4df363e 100644
--- a/quad/ip_repo/pwm_recorder_1.0/hdl/kernel_tester.vhd
+++ b/quad/ip_repo/pwm_recorder_1.0/hdl/kernel_tester.vhd
@@ -53,6 +53,7 @@ architecture testbench of kernel_tester is
     signal count : std_logic_vector(31 downto 0);
     signal write : std_logic;
     signal done : std_logic := '0';
+    signal passing : std_logic := '0';
     
 begin
     UUT: pwm_rec
@@ -67,6 +68,8 @@ begin
         variable period : integer;
         
     begin
+        passing <='1';
+        
         reset_n <='0';
         wait for 2*CLK_HPER;
         reset_n <='1';
@@ -78,7 +81,10 @@ begin
         wait for period*2*CLK_HPER;
         pwm <= '0';
         wait until write='1';
-        ASSERT count=std_logic_vector(to_unsigned(period, 32)) REPORT "Incorrect COUNT result" SEVERITY FAILURE;
+        if (count /= std_logic_vector(to_unsigned(period, 32))) then
+          REPORT "Incorrect COUNT result" SEVERITY FAILURE;
+          passing <='0';
+        end if;
         
         period := 200;
         pwm <= '0';
@@ -87,8 +93,11 @@ begin
         wait for period*2*CLK_HPER;
         pwm <= '0';
         wait until write='1';
-        ASSERT count=std_logic_vector(to_unsigned(period, 32)) REPORT "Incorrect COUNT result" SEVERITY FAILURE;
-        
+        if (count /= std_logic_vector(to_unsigned(period, 32))) then
+          REPORT "Incorrect COUNT result" SEVERITY FAILURE;
+          passing <='0';
+        end if;
+                
         period := 300;
         pwm <= '0';
         wait for CLK_HPER*2*20;
@@ -96,7 +105,10 @@ begin
         wait for period*2*CLK_HPER;
         pwm <= '0';
         wait until write='1';
-        ASSERT count=std_logic_vector(to_unsigned(period, 32)) REPORT "Incorrect COUNT result" SEVERITY FAILURE;
+        if (count /= std_logic_vector(to_unsigned(period, 32))) then
+          REPORT "Incorrect COUNT result" SEVERITY FAILURE;
+          passing <='0';
+        end if;
         
         period := 400;
         pwm <= '0';
@@ -105,7 +117,10 @@ begin
         wait for period*2*CLK_HPER;
         pwm <= '0';
         wait until write='1';
-        ASSERT count=std_logic_vector(to_unsigned(period, 32)) REPORT "Incorrect COUNT result" SEVERITY FAILURE;
+        if (count /= std_logic_vector(to_unsigned(period, 32))) then
+          REPORT "Incorrect COUNT result" SEVERITY FAILURE;
+          passing <='0';
+        end if;
         
         period := 10;
         pwm <= '0';
@@ -115,7 +130,10 @@ begin
         pwm <= '0';
         for t in 0 to 100 loop
             wait for 2*CLK_HPER;
-            ASSERT write='0' REPORT "Glitch not Ignored" SEVERITY FAILURE;
+            if (write /= '0') then
+              REPORT "Glitch not Ignored" SEVERITY FAILURE;
+              passing <='0';
+            end if;
         end loop;
         
         -- Run for 45, glitch for 10, then run for 45, expect a result of 100
@@ -130,12 +148,20 @@ begin
         wait for 45*2*CLK_HPER;
         pwm <= '0';
         wait until write='1';
-        ASSERT count=std_logic_vector(to_unsigned(period, 32)) REPORT "Incorrect COUNT result" SEVERITY FAILURE;
+        if (count /= std_logic_vector(to_unsigned(period, 32))) then
+          REPORT "Incorrect COUNT result" SEVERITY FAILURE;
+          passing <='0';
+        end if;
         
         done <='1';
+                        
+        if (passing = '0') then
+            -- output test faulure?
+        end if;
+        
         wait;
     end process;
-    
+        
     clock_proc: process
     begin
         clk <= '0';
diff --git a/quad/ip_repo/pwm_recorder_1.0/kernel_test.prj b/quad/ip_repo/pwm_recorder_1.0/kernel_test.prj
new file mode 100644
index 0000000000000000000000000000000000000000..82dec23a23523cf562dad93dc93f00c6a153417b
--- /dev/null
+++ b/quad/ip_repo/pwm_recorder_1.0/kernel_test.prj
@@ -0,0 +1,2 @@
+vhdl work src/pwm_rec.vhd
+vhdl work hdl/kernel_tester.vhd
diff --git a/quad/ip_repo/pwm_signal_out_1.0/Makefile b/quad/ip_repo/pwm_signal_out_1.0/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..a3981b29b189d71d9808cf315c4f59b67a395f17
--- /dev/null
+++ b/quad/ip_repo/pwm_signal_out_1.0/Makefile
@@ -0,0 +1,10 @@
+build-tests:
+# The build products get removed if run in the build step.
+
+run-tests:
+	xelab --debug wave -prj kernel_test.prj -s run_kernel_test work.kernel_tester
+	xsim run_kernel_test -wdb kernel_test.wdb --t ../get_simulation_result.tcl
+	echo 1 > result.exp
+	cat result.log
+	cmp result.log result.exp
+	rm result.exp
\ No newline at end of file
diff --git a/quad/ip_repo/pwm_signal_out_1.0/component.xml b/quad/ip_repo/pwm_signal_out_1.0/component.xml
index c7a792f450b6002f66ae57ebdc1f899602050202..db7c5502aaa04b69b4320a9368c1ceb1b0af8066 100644
--- a/quad/ip_repo/pwm_signal_out_1.0/component.xml
+++ b/quad/ip_repo/pwm_signal_out_1.0/component.xml
@@ -247,7 +247,7 @@
       <spirit:parameters>
         <spirit:parameter>
           <spirit:name>POLARITY</spirit:name>
-          <spirit:value spirit:id="BUSIFPARAM_VALUE.S_AXI_ARESETN.POLARITY" spirit:choiceRef="choice_list_74b5137e">ACTIVE_LOW</spirit:value>
+          <spirit:value spirit:id="BUSIFPARAM_VALUE.S_AXI_ARESETN.POLARITY" spirit:choiceRef="choice_list_9d8b0d81">ACTIVE_LOW</spirit:value>
         </spirit:parameter>
       </spirit:parameters>
     </spirit:busInterface>
@@ -304,7 +304,7 @@
         <spirit:parameters>
           <spirit:parameter>
             <spirit:name>viewChecksum</spirit:name>
-            <spirit:value>83cf02e9</spirit:value>
+            <spirit:value>5c86c06b</spirit:value>
           </spirit:parameter>
         </spirit:parameters>
       </spirit:view>
@@ -320,7 +320,7 @@
         <spirit:parameters>
           <spirit:parameter>
             <spirit:name>viewChecksum</spirit:name>
-            <spirit:value>83cf02e9</spirit:value>
+            <spirit:value>e8071657</spirit:value>
           </spirit:parameter>
         </spirit:parameters>
       </spirit:view>
@@ -366,6 +366,20 @@
           </spirit:parameter>
         </spirit:parameters>
       </spirit:view>
+      <spirit:view>
+        <spirit:name>xilinx_testbench</spirit:name>
+        <spirit:displayName>Test Bench</spirit:displayName>
+        <spirit:envIdentifier>:vivado.xilinx.com:simulation.testbench</spirit:envIdentifier>
+        <spirit:fileSetRef>
+          <spirit:localName>xilinx_testbench_view_fileset</spirit:localName>
+        </spirit:fileSetRef>
+        <spirit:parameters>
+          <spirit:parameter>
+            <spirit:name>viewChecksum</spirit:name>
+            <spirit:value>4e801d27</spirit:value>
+          </spirit:parameter>
+        </spirit:parameters>
+      </spirit:view>
     </spirit:views>
     <spirit:ports>
       <spirit:port>
@@ -712,7 +726,7 @@
       <spirit:enumeration>32</spirit:enumeration>
     </spirit:choice>
     <spirit:choice>
-      <spirit:name>choice_list_74b5137e</spirit:name>
+      <spirit:name>choice_list_9d8b0d81</spirit:name>
       <spirit:enumeration>ACTIVE_HIGH</spirit:enumeration>
       <spirit:enumeration>ACTIVE_LOW</spirit:enumeration>
     </spirit:choice>
@@ -744,6 +758,10 @@
         <spirit:fileType>vhdlSource</spirit:fileType>
         <spirit:userFileType>CHECKSUM_45a2bd69</spirit:userFileType>
       </spirit:file>
+      <spirit:file>
+        <spirit:name>../../../../const.xdc</spirit:name>
+        <spirit:userFileType>xdc</spirit:userFileType>
+      </spirit:file>
     </spirit:fileSet>
     <spirit:fileSet>
       <spirit:name>xilinx_vhdlbehavioralsimulation_view_fileset</spirit:name>
@@ -759,6 +777,12 @@
         <spirit:name>hdl/pwm_signal_out_v1_0.vhd</spirit:name>
         <spirit:fileType>vhdlSource</spirit:fileType>
       </spirit:file>
+      <spirit:file>
+        <spirit:name>src/kernel_tester.vhd</spirit:name>
+        <spirit:fileType>vhdlSource</spirit:fileType>
+        <spirit:userFileType>USED_IN_ipstatic</spirit:userFileType>
+        <spirit:logicalName>xil_defaultlib</spirit:logicalName>
+      </spirit:file>
     </spirit:fileSet>
     <spirit:fileSet>
       <spirit:name>xilinx_softwaredriver_view_fileset</spirit:name>
@@ -808,6 +832,15 @@
         <spirit:fileType>tclSource</spirit:fileType>
       </spirit:file>
     </spirit:fileSet>
+    <spirit:fileSet>
+      <spirit:name>xilinx_testbench_view_fileset</spirit:name>
+      <spirit:file>
+        <spirit:name>src/kernel_tester.vhd</spirit:name>
+        <spirit:fileType>vhdlSource</spirit:fileType>
+        <spirit:userFileType>USED_IN_simulation</spirit:userFileType>
+        <spirit:userFileType>USED_IN_synthesis</spirit:userFileType>
+      </spirit:file>
+    </spirit:fileSet>
   </spirit:fileSets>
   <spirit:description>Produces the pwm signal out base on a register value</spirit:description>
   <spirit:parameters>
@@ -876,19 +909,19 @@
       </xilinx:taxonomies>
       <xilinx:displayName>pwm_signal_out_v1.0</xilinx:displayName>
       <xilinx:coreRevision>2</xilinx:coreRevision>
-      <xilinx:coreCreationDateTime>2017-12-09T23:09:40Z</xilinx:coreCreationDateTime>
+      <xilinx:coreCreationDateTime>2018-10-05T20:40:10Z</xilinx:coreCreationDateTime>
       <xilinx:tags>
         <xilinx:tag xilinx:name="user.org:user:pwm_signal_out:1.0_ARCHIVE_LOCATION">/local/ucart/MicroCART/quad/ip_repo/pwm_signal_out_1.0</xilinx:tag>
       </xilinx:tags>
     </xilinx:coreExtensions>
     <xilinx:packagingInfo>
-      <xilinx:xilinxVersion>2017.1</xilinx:xilinxVersion>
-      <xilinx:checksum xilinx:scope="busInterfaces" xilinx:value="cebbc925"/>
-      <xilinx:checksum xilinx:scope="memoryMaps" xilinx:value="59f5074b"/>
-      <xilinx:checksum xilinx:scope="fileGroups" xilinx:value="7d50a186"/>
-      <xilinx:checksum xilinx:scope="ports" xilinx:value="c99dab34"/>
-      <xilinx:checksum xilinx:scope="hdlParameters" xilinx:value="1826240f"/>
-      <xilinx:checksum xilinx:scope="parameters" xilinx:value="a6a514bf"/>
+      <xilinx:xilinxVersion>2018.2.1</xilinx:xilinxVersion>
+      <xilinx:checksum xilinx:scope="busInterfaces" xilinx:value="9a0bb3a5"/>
+      <xilinx:checksum xilinx:scope="memoryMaps" xilinx:value="c30980da"/>
+      <xilinx:checksum xilinx:scope="fileGroups" xilinx:value="29260a33"/>
+      <xilinx:checksum xilinx:scope="ports" xilinx:value="16b2dbf2"/>
+      <xilinx:checksum xilinx:scope="hdlParameters" xilinx:value="f9a38560"/>
+      <xilinx:checksum xilinx:scope="parameters" xilinx:value="28e39136"/>
     </xilinx:packagingInfo>
   </spirit:vendorExtensions>
 </spirit:component>
diff --git a/quad/ip_repo/pwm_signal_out_1.0/kernel_test.prj b/quad/ip_repo/pwm_signal_out_1.0/kernel_test.prj
new file mode 100644
index 0000000000000000000000000000000000000000..033f09e410e72a21fda32a35676ec41e47126071
--- /dev/null
+++ b/quad/ip_repo/pwm_signal_out_1.0/kernel_test.prj
@@ -0,0 +1,2 @@
+vhdl work src/pwm.vhd
+vhdl work src/kernel_tester.vhd
diff --git a/quad/ip_repo/pwm_signal_out_1.0/src/kernel_tester.vhd b/quad/ip_repo/pwm_signal_out_1.0/src/kernel_tester.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..67d98bfe415e94bbea31bb3f2ac4b4b48c433836
--- /dev/null
+++ b/quad/ip_repo/pwm_signal_out_1.0/src/kernel_tester.vhd
@@ -0,0 +1,120 @@
+----------------------------------------------------------------------------------
+-- Company: 
+-- Engineer: 
+-- 
+-- Create Date: 10/05/2018 02:27:32 PM
+-- Design Name: 
+-- Module Name: kernel_tester - Behavioral
+-- Project Name: 
+-- Target Devices: 
+-- Tool Versions: 
+-- Description: 
+-- 
+-- Dependencies: 
+-- 
+-- Revision:
+-- Revision 0.01 - File Created
+-- Additional Comments:
+-- 
+----------------------------------------------------------------------------------
+
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.numeric_std.all;
+
+-- Uncomment the following library declaration if using
+-- arithmetic functions with Signed or Unsigned values
+--use IEEE.NUMERIC_STD.ALL;
+
+-- Uncomment the following library declaration if instantiating
+-- any Xilinx leaf cells in this code.
+--library UNISIM;
+--use UNISIM.VComponents.all;
+
+entity kernel_tester is
+--  Port ( );
+end kernel_tester;
+
+architecture Behavioral of kernel_tester is
+  component pwm IS
+    PORT(clk       : IN  STD_LOGIC;        --system clock
+         reset_n   : IN  STD_LOGIC;        --reset
+         pwm_per   : IN  STD_LOGIC_VECTOR(31 DOWNTO 0);    -- Number of clock counts
+         pwm_puls  : IN  STD_LOGIC_VECTOR(31 DOWNTO 0);    -- Number of clock counts in puls
+         pwm_out   : OUT STD_LOGIC := '0');        
+  END component pwm;
+
+  signal passing : std_logic;
+  signal clk : std_logic;
+  signal period : std_logic_vector(31 downto 0);
+  signal pulse : std_logic_vector(31 downto 0);
+  signal reset_n : std_logic;
+  signal generated : std_logic;
+  signal done : std_logic;
+  
+  constant CLK_HPER : time := 20 us;
+begin
+  UUT: pwm
+    PORT map(clk => clk,
+             reset_n => reset_n,
+             pwm_per => period,
+             pwm_puls => pulse,
+             pwm_out => generated);
+  
+  testbench: process
+    variable period_desired : integer;
+    variable pulse_desired : integer;
+    variable period_measured : time;
+    variable pulse_measured : time;
+    variable period_count : integer;
+    variable pulse_count : integer;
+  begin
+    passing <= '1';
+    
+    reset_n <='0';
+    wait for 2*CLK_HPER;
+    reset_n <='1';
+    
+    for period_iter in 0 to 10 loop
+      for duty in 1 to 9 loop
+        period_desired := 100*(2**period_iter);
+        pulse_desired := period_desired*duty/10;
+        period <= std_logic_vector(to_unsigned(period_desired-1, 32));
+        pulse <= std_logic_vector(to_unsigned(pulse_desired-1, 32));
+        wait until generated = '1';
+        wait until generated = '0';
+        wait until generated = '1';
+        period_measured := now;
+        pulse_measured := now;
+        wait until generated = '0';
+        pulse_measured := now-pulse_measured;
+        wait until generated = '1';
+        period_measured := now-period_measured;
+        period_count := (period_measured/CLK_HPER)/2;
+        pulse_count := (pulse_measured/CLK_HPER)/2;
+        if (period_count /= period_desired OR pulse_count /= pulse_desired) then
+          passing <= '0';
+        end if;
+        ASSERT period_count = period_desired REPORT "Period was incorrect, expected: "&integer'image(period_desired)&" actual: "&integer'image(period_count) SEVERITY ERROR;
+        ASSERT pulse_count = pulse_desired REPORT "Pulse was incorrect, expected: "&integer'image(pulse_desired)&" actual: "&integer'image(pulse_count) SEVERITY ERROR;
+      end loop;
+    end loop;
+    
+    
+    done <= '1';
+    wait;
+  end process testbench;
+  
+  clock_gen: process
+  begin
+    if (done = '1') then
+      wait;
+    else
+      clk <= '0';
+      wait for CLK_HPER;
+      clk <= '1';
+      wait for CLK_HPER;
+    end if;
+  end process;
+end Behavioral;
diff --git a/quad/ip_repo/pwm_signal_out_1.0/src/pwm.vhd b/quad/ip_repo/pwm_signal_out_1.0/src/pwm.vhd
index 93ec9d2a5c0126c0a203ab7077a3d197224cb59e..e76fc7e634e0cafe05d64c136351b5288e5fdd5e 100644
--- a/quad/ip_repo/pwm_signal_out_1.0/src/pwm.vhd
+++ b/quad/ip_repo/pwm_signal_out_1.0/src/pwm.vhd
@@ -33,6 +33,7 @@ BEGIN
 			pwm_out <= '0';
 			counter <= std_logic_vector(unsigned(counter) + 1);
 		else
+		    pwm_out <= '1';
 			counter <= X"00000000";
 		end if;
     end if;