Merge remote-tracking branch 'origin/sjk/tk_rc61' into main
diff --git a/caravel.sh b/caravel.sh
index c144973..1fa93ee 100755
--- a/caravel.sh
+++ b/caravel.sh
@@ -8,6 +8,6 @@
 echo $PDK_ROOT
 echo $OPENLANE_ROOT
 cd openlane
-time make rapcore user_project_wrapper OPENLANE_IMAGE_NAME=openlane:rc5
-cd ../
-make ship
+time make rapcores user_project_wrapper OPENLANE_IMAGE_NAME=openlane:rc6 2>&1 | tee raprc6tk.log
+#cd ../
+#make ship
diff --git a/openlane/rapcore/pin_order.cfg b/openlane/rapcore/pin_order.cfg
deleted file mode 100644
index ccb7d40..0000000
--- a/openlane/rapcore/pin_order.cfg
+++ /dev/null
@@ -1,3 +0,0 @@
-#BUS_SORT
-
-#S
diff --git a/openlane/rapcore/config.tcl b/openlane/rapcores/config.tcl
similarity index 76%
rename from openlane/rapcore/config.tcl
rename to openlane/rapcores/config.tcl
index e0d8c8c..6edaf15 100644
--- a/openlane/rapcore/config.tcl
+++ b/openlane/rapcores/config.tcl
@@ -1,11 +1,11 @@
 set script_dir [file dirname [file normalize [info script]]]
 
-set ::env(DESIGN_NAME) rapcore
+set ::env(DESIGN_NAME) rapcores
 
 set ::env(VERILOG_FILES) "\
         $script_dir/../../verilog/rtl/defines.v \
         $script_dir/../../rapcores/src/constants.v \
-        $script_dir/../../rapcore_caravel_defines.v \
+        $script_dir/../../rapcores/boards/mpw_one_defines.v \
         $script_dir/../../rapcores/src/macro_params.v \
         $script_dir/../../rapcores/src/spi_state_machine.v \
         $script_dir/../../rapcores/src/dda_timer.v \
@@ -22,8 +22,10 @@
         $script_dir/../../rapcores/src/microstepper/mytimer.v \
         $script_dir/../../rapcores/src/microstepper/mytimer_8.v \
         $script_dir/../../rapcores/src/microstepper/mytimer_10.v \
-        $script_dir/../../rapcores/src/rapcore.v"
-set ::env(CLOCK_PORT) "CLK"
+        $script_dir/../../rapcores/src/rapcore.v \
+        $script_dir/../../verilog/rtl/rapcores.v"
+
+set ::env(CLOCK_PORT) "wb_clk_i"
 set ::env(CLOCK_PERIOD) "15"
 
 set ::env(FP_SIZING) absolute
@@ -44,6 +46,8 @@
 # We try to set the die size instead
 #set ::env(PL_BASIC_PLACEMENT) 40
 set ::env(PL_TARGET_DENSITY) 0.41
+#set ::env(CELL_PAD) 0
+
 
 # Routing
 # -------
@@ -52,14 +56,20 @@
 set ::env(ROUTING_CORES) 6
 #set ::env(GLB_RT_ALLOW_CONGESTION) 1
 
-# block met5 with obstruction
-set ::env(GLB_RT_OBS) "met5 0 0 800 800"
+set ::env(VDD_NETS) [list {vccd1} {vccd2} {vdda1} {vdda2}]
+set ::env(GND_NETS) [list {vssd1} {vssd2} {vssa1} {vssa2}]
 
-#set ::env(VDD_PIN) vccd1
-#set ::env(GND_PIN) vssd1
+# block met5 with obstruction
+set ::env(GLB_RT_OBS) "met5 0 0 1000 1000"
+set ::env(GLB_RT_MAXLAYER) 5
+set ::env(VDD_PIN) vccd1
+set ::env(GND_PIN) vssd1
 set ::env(FP_PDN_VOFFSET) "14"
 set ::env(FP_PDN_VPITCH) "180"
 set ::env(FP_PDN_HOFFSET) "14"
 set ::env(FP_PDN_HPITCH) "180"
 
+set ::env(SYNTH_USE_PG_PINS_DEFINES) "USE_POWER_PINS"
 
+# If you're going to use multiple power domains, then keep this disabled.
+#set ::env(RUN_CVC) 0
diff --git a/openlane/rapcores/pin_order.cfg b/openlane/rapcores/pin_order.cfg
new file mode 100644
index 0000000..6de1406
--- /dev/null
+++ b/openlane/rapcores/pin_order.cfg
@@ -0,0 +1,157 @@
+#BUS_SORT
+#NR
+analog_io\[15\]
+io_in\[15\]
+io_out\[15\]
+io_oeb\[15\]
+analog_io\[16\]
+io_in\[16\]
+io_out\[16\]
+io_oeb\[16\]
+analog_io\[17\]
+io_in\[17\]
+io_out\[17\]
+io_oeb\[17\]
+analog_io\[18\]
+io_in\[18\]
+io_out\[18\]
+io_oeb\[18\]
+analog_io\[19\]
+io_in\[19\]
+io_out\[19\]
+io_oeb\[19\]
+analog_io\[20\]
+io_in\[20\]
+io_out\[20\]
+io_oeb\[20\]
+analog_io\[21\]
+io_in\[21\]
+io_out\[21\]
+io_oeb\[21\]
+analog_io\[22\]
+io_in\[22\]
+io_out\[22\]
+io_oeb\[22\]
+analog_io\[23\]
+io_in\[23\]
+io_out\[23\]
+io_oeb\[23\]
+
+#S
+wb_.*
+wbs_.*
+la_.*
+user_clock2
+
+#E
+analog_io\[0\]
+io_in\[0\]
+io_out\[0\]
+io_oeb\[0\]
+analog_io\[1\]
+io_in\[1\]
+io_out\[1\]
+io_oeb\[1\]
+analog_io\[2\]
+io_in\[2\]
+io_out\[2\]
+io_oeb\[2\]
+analog_io\[3\]
+io_in\[3\]
+io_out\[3\]
+io_oeb\[3\]
+analog_io\[4\]
+io_in\[4\]
+io_out\[4\]
+io_oeb\[4\]
+analog_io\[5\]
+io_in\[5\]
+io_out\[5\]
+io_oeb\[5\]
+analog_io\[6\]
+io_in\[6\]
+io_out\[6\]
+io_oeb\[6\]
+analog_io\[7\]
+io_in\[7\]
+io_out\[7\]
+io_oeb\[7\]
+analog_io\[8\]
+io_in\[8\]
+io_out\[8\]
+io_oeb\[8\]
+analog_io\[9\]
+io_in\[9\]
+io_out\[9\]
+io_oeb\[9\]
+analog_io\[10\]
+io_in\[10\]
+io_out\[10\]
+io_oeb\[10\]
+analog_io\[11\]
+io_in\[11\]
+io_out\[11\]
+io_oeb\[11\]
+analog_io\[12\]
+io_in\[12\]
+io_out\[12\]
+io_oeb\[12\]
+analog_io\[13\]
+io_in\[13\]
+io_out\[13\]
+io_oeb\[13\]
+analog_io\[14\]
+io_in\[14\]
+io_out\[14\]
+io_oeb\[14\]
+
+#WR
+analog_io\[24\]
+io_in\[24\]
+io_out\[24\]
+io_oeb\[24\]
+analog_io\[25\]
+io_in\[25\]
+io_out\[25\]
+io_oeb\[25\]
+analog_io\[26\]
+io_in\[26\]
+io_out\[26\]
+io_oeb\[26\]
+analog_io\[27\]
+io_in\[27\]
+io_out\[27\]
+io_oeb\[27\]
+analog_io\[28\]
+io_in\[28\]
+io_out\[28\]
+io_oeb\[28\]
+analog_io\[29\]
+io_in\[29\]
+io_out\[29\]
+io_oeb\[29\]
+analog_io\[30\]
+io_in\[30\]
+io_out\[30\]
+io_oeb\[30\]
+io_in\[31\]
+io_out\[31\]
+io_oeb\[31\]
+io_in\[32\]
+io_out\[32\]
+io_oeb\[32\]
+io_in\[33\]
+io_out\[33\]
+io_oeb\[33\]
+io_in\[34\]
+io_out\[34\]
+io_oeb\[34\]
+io_in\[35\]
+io_out\[35\]
+io_oeb\[35\]
+io_in\[36\]
+io_out\[36\]
+io_oeb\[36\]
+io_in\[37\]
+io_out\[37\]
+io_oeb\[37\]
diff --git a/openlane/user_project_wrapper/config.tcl b/openlane/user_project_wrapper/config.tcl
index fc75c08..b0ef495 100644
--- a/openlane/user_project_wrapper/config.tcl
+++ b/openlane/user_project_wrapper/config.tcl
@@ -44,16 +44,13 @@
 
 set ::env(VERILOG_FILES_BLACKBOX) "\
     $script_dir/../../verilog/rtl/defines.v \
-    $script_dir/../../rapcore_caravel_defines.v \
-    $script_dir/../../rapcores/src/macro_params.v \
-    $script_dir/../../rapcores/src/constants.v \
-    $script_dir/../../rapcores/src/rapcore.v"
+    $script_dir/../../verilog/rtl/rapcores.v"
 
 set ::env(EXTRA_LEFS) "\
-	$script_dir/../../lef/rapcore.lef"
+	$script_dir/../../lef/rapcores.lef"
 
 set ::env(EXTRA_GDS_FILES) "\
-	$script_dir/../../gds/rapcore.gds"
+	$script_dir/../../gds/rapcores.gds"
 
 #set ::env(GLB_RT_OBS) "met4 1150 1700 1690 2240"
 
diff --git a/openlane/user_project_wrapper/macro.cfg b/openlane/user_project_wrapper/macro.cfg
new file mode 100644
index 0000000..bbd3189
--- /dev/null
+++ b/openlane/user_project_wrapper/macro.cfg
@@ -0,0 +1 @@
+rapcores0 1150 1700 N
diff --git a/rapcore_caravel_defines.v b/rapcore_caravel_defines.v
deleted file mode 100644
index c63166f..0000000
--- a/rapcore_caravel_defines.v
+++ /dev/null
@@ -1,31 +0,0 @@
-
-// Enable SPI Interface
-`define SPI_INTERFACE
-
-// Use PLL for higher SPI frequencies
-//`define SPIPLL
-
-// Enable Buffer DTR pin
-`define BUFFER_DTR
-
-// Enable Move Done Pin
-`define MOVE_DONE
-
-// Enable Halt Input
-`define HALT
-
-// Motor Definitions
-//`define DUAL_HBRIDGE 1
-`define ULTIBRIDGE 1
-
-// Encoder Count
-`define QUAD_ENC 1
-
-// External Step/DIR Input
-`define STEPINPUT
-
-// Output Step/DIR signals
-`define STEPOUTPUT
-
-// Change the Move Buffer Size. Should be power of two
-//`define MOVE_BUFFER_SIZE 4
diff --git a/rapcores b/rapcores
index 9e2fdd6..fb46da3 160000
--- a/rapcores
+++ b/rapcores
@@ -1 +1 @@
-Subproject commit 9e2fdd6f0df84aad3423d49cd4df8ae4801ae41c
+Subproject commit fb46da3de6c1b7a71acbfc1afee8f49c607eb6bf
diff --git a/verilog/dv/caravel/user_proj_example/io_ports/Makefile b/verilog/dv/caravel/user_proj_example/io_ports/Makefile
index 3ab6272..208084d 100644
--- a/verilog/dv/caravel/user_proj_example/io_ports/Makefile
+++ b/verilog/dv/caravel/user_proj_example/io_ports/Makefile
@@ -1,11 +1,14 @@
 FIRMWARE_PATH = ../..
 RTL_PATH = ../../../../rtl
 IP_PATH = ../../../../ip
-BEHAVIOURAL_MODELS = ../../ 
+BEHAVIOURAL_MODELS = ../../
+RAPCORES_PATH = ../../../../../rapcores
 
-GCC_PATH?=/ef/apps/bin
+GCC_PATH?=//opt/riscv32/bin
 GCC_PREFIX?=riscv32-unknown-elf
-PDK_PATH?=/ef/tech/SW/sky130A
+PDK_PATH?=$(PDK_ROOT)/sky130A
+
+SIM?=RTL
 
 .SUFFIXES:
 
@@ -16,9 +19,16 @@
 hex:  ${PATTERN:=.hex}
 
 %.vvp: %_tb.v %.hex
-	iverilog -DFUNCTIONAL -I $(BEHAVIOURAL_MODELS) \
-	-I $(PDK_PATH) -I $(IP_PATH) -I $(RTL_PATH) \
+ifeq ($(SIM),RTL)
+	iverilog -DFUNCTIONAL -DSIM -I $(BEHAVIOURAL_MODELS) \
+	-I $(PDK_PATH) -I $(IP_PATH) -I $(RTL_PATH) -I $(RAPCORES_PATH)/.. -I $(RAPCORES_PATH)/src -I $(RAPCORES_PATH)/testbench \
 	-o $@ $<
+else
+	iverilog -DFUNCTIONAL -DSIM -DGL -I $(BEHAVIOURAL_MODELS) \
+	-I $(PDK_PATH) -I $(IP_PATH) -I $(RTL_PATH) -I $(RAPCORES_PATH)/.. -I $(RAPCORES_PATH)/src \
+	-o $@ $<
+endif
+# MERGE: -I $(VERILOG_PATH) maybe needed for GL
 
 %.vcd: %.vvp
 	vvp $<
@@ -27,7 +37,7 @@
 	${GCC_PATH}/${GCC_PREFIX}-gcc -march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $<
 
 %.hex: %.elf
-	${GCC_PATH}/${GCC_PREFIX}-objcopy -O verilog $< $@ 
+	${GCC_PATH}/${GCC_PREFIX}-objcopy -O verilog $< $@
 	# to fix flash base address
 	sed -i 's/@10000000/@00000000/g' $@
 
diff --git a/verilog/dv/caravel/user_proj_example/io_ports/io_ports.c b/verilog/dv/caravel/user_proj_example/io_ports/io_ports.c
index f6a829d..add8845 100644
--- a/verilog/dv/caravel/user_proj_example/io_ports/io_ports.c
+++ b/verilog/dv/caravel/user_proj_example/io_ports/io_ports.c
@@ -32,12 +32,48 @@
 	reg_mprj_io_3 =  GPIO_MODE_USER_STD_OUTPUT;
 	reg_mprj_io_4 =  GPIO_MODE_USER_STD_OUTPUT;
 	reg_mprj_io_5 =  GPIO_MODE_USER_STD_OUTPUT;
-	reg_mprj_io_6 =  GPIO_MODE_USER_STD_OUTPUT;
-	reg_mprj_io_7 =  GPIO_MODE_USER_STD_OUTPUT;
+	reg_mprj_io_6 =  GPIO_MODE_USER_STD_INPUT_NOPULL;
+	reg_mprj_io_7 =  GPIO_MODE_USER_STD_INPUT_NOPULL;
+	reg_mprj_io_15 =  GPIO_MODE_USER_STD_OUTPUT;
+	reg_mprj_io_16 =  GPIO_MODE_USER_STD_OUTPUT;
+	reg_mprj_io_14 =  GPIO_MODE_USER_STD_OUTPUT;
+	reg_mprj_io_15 =  GPIO_MODE_USER_STD_OUTPUT;
+	reg_mprj_io_16 =  GPIO_MODE_USER_STD_OUTPUT;
+	reg_mprj_io_17 =  GPIO_MODE_USER_STD_OUTPUT;
+	reg_mprj_io_18 =  GPIO_MODE_USER_STD_OUTPUT;
+	reg_mprj_io_19 =  GPIO_MODE_USER_STD_OUTPUT;
+	reg_mprj_io_20 =  GPIO_MODE_USER_STD_OUTPUT;
+	reg_mprj_io_21 =  GPIO_MODE_USER_STD_OUTPUT;
+	reg_mprj_io_22 =  GPIO_MODE_USER_STD_INPUT_NOPULL;
+	reg_mprj_io_23 =  GPIO_MODE_USER_STD_OUTPUT;
+	reg_mprj_io_24 =  GPIO_MODE_USER_STD_OUTPUT;
+	reg_mprj_io_25 =  GPIO_MODE_USER_STD_INPUT_NOPULL;
+	reg_mprj_io_26 =  GPIO_MODE_USER_STD_INPUT_NOPULL;
+	reg_mprj_io_27 =  GPIO_MODE_USER_STD_OUTPUT;
+	reg_mprj_io_28 =  GPIO_MODE_USER_STD_OUTPUT;
+	reg_mprj_io_29 =  GPIO_MODE_USER_STD_INPUT_NOPULL;
+	reg_mprj_io_30 =  GPIO_MODE_USER_STD_OUTPUT;
+	reg_mprj_io_31 =  GPIO_MODE_USER_STD_OUTPUT;
+	reg_mprj_io_32 =  GPIO_MODE_USER_STD_INPUT_NOPULL;
+	reg_mprj_io_33 =  GPIO_MODE_USER_STD_INPUT_NOPULL;
+	reg_mprj_io_34 =  GPIO_MODE_USER_STD_INPUT_NOPULL;
+	reg_mprj_io_35 =  GPIO_MODE_USER_STD_INPUT_NOPULL;
+	reg_mprj_io_36 =  GPIO_MODE_USER_STD_OUTPUT;
+	reg_mprj_io_37 =  GPIO_MODE_USER_STD_OUTPUT;
 
         /* Apply configuration */
         reg_mprj_xfer = 1;
         while (reg_mprj_xfer == 1);
 
+	// Configure LA probes [31:0], [127:64] as inputs to the cpu 
+	// Configure LA probes [63:32] as outputs from the cpu
+	reg_la0_ena = 0xFFFFFFFF;    // [31:0]
+	reg_la1_ena = 0x00000000;    // [95:64]
+	reg_la2_ena = 0x00000000;    // [63:32]
+	reg_la3_ena = 0xFFFFFFFF;    // [127:96]
+
+	// Set Counter value to zero through LA probes [63:32]
+	reg_la2_data = 0x00000003;
+
 }
 
diff --git a/verilog/dv/caravel/user_proj_example/io_ports/io_ports_tb.v b/verilog/dv/caravel/user_proj_example/io_ports/io_ports_tb.v
index 63b7c93..579ad1d 100644
--- a/verilog/dv/caravel/user_proj_example/io_ports/io_ports_tb.v
+++ b/verilog/dv/caravel/user_proj_example/io_ports/io_ports_tb.v
@@ -2,6 +2,34 @@
 
 `timescale 1 ns / 1 ps
 
+`include "defines.v"
+`include "rapcore_caravel_defines.v"
+`include "macro_params.v"
+`include "constants.v"
+`include "quad_enc.v"
+`include "spi.v"
+`include "dda_timer.v"
+`include "spi_state_machine.v"
+`include "microstepper/chargepump.v"
+`include "microstepper/microstepper_control.v"
+`include "microstepper/mytimer_8.v"
+`include "microstepper/mytimer_10.v"
+`include "microstepper/microstep_counter.v"
+`include "microstepper/cosine.v"
+`include "microstepper/analog_out.v"
+`include "microstepper/microstepper_top.v"
+`include "rapcore.v"
+`include "hbridge_coil.v"
+`include "pwm_duty.v"
+
+//`define USE_POWER_PINS
+
+`ifdef PROJ_GL
+  `include "gl/rapcore.v"
+`else
+  `include "rapcores.v"
+`endif
+
 `include "caravel.v"
 `include "spiflash.v"
 
@@ -33,7 +61,7 @@
 
 		// Repeat cycles of 1000 clock edges as needed to complete testbench
 		repeat (25) begin
-			repeat (1000) @(posedge clock);
+			repeat (4000) @(posedge clock);
 			// $display("+1000 cycles");
 		end
 		$display("%c[1;31m",27);
@@ -53,7 +81,7 @@
 	    wait(mprj_io_0 == 8'h07);
             wait(mprj_io_0 == 8'h08);
 	    wait(mprj_io_0 == 8'h09);
-            wait(mprj_io_0 == 8'h0A);   
+            wait(mprj_io_0 == 8'h0A);
 	    wait(mprj_io_0 == 8'hFF);
 	    wait(mprj_io_0 == 8'h00);
 
@@ -83,7 +111,7 @@
 	end
 
 	always @(mprj_io) begin
-		#1 $display("MPRJ-IO state = %b ", mprj_io[7:0]);
+		#1 $display("MPRJ-IO state = %b ", mprj_io[37:0]);
 	end
 
 	wire flash_csb;
@@ -97,6 +125,96 @@
 	wire USER_VDD1V8 = power4;
 	wire VSS = 1'b0;
 
+
+    reg                 step;
+    reg                 dir;
+    reg                 enable_in;
+    wire        [12:0]  target_current1;
+    wire        [12:0]  target_current2;
+    wire signed  [12:0]  current1;
+    wire signed  [12:0]  current2;
+
+	wire analog_out1;
+	wire analog_out2;
+    reg             analog_cmp1;
+    reg             analog_cmp2;
+    reg     [40:0]  step_clock;
+    reg     [20:0]  cnt;
+    reg     [12:0]  current_abs1;
+    reg     [12:0]  current_abs2;
+    wire            phase_a1_l;
+    wire            phase_a2_l;
+    wire            phase_b1_l;
+    wire            phase_b2_l;
+    wire            phase_a1_h;
+    wire            phase_a2_h;
+    wire            phase_b1_h;
+    wire            phase_b2_h;
+	wire 			resetn;
+
+//	assign CHARGEPUMP		= mprj_io[15];
+	assign analog_out1		= mprj_io[27];
+	assign analog_out2		= mprj_io[28];
+	assign phase_a1_l			= mprj_io[23];
+	assign phase_a2_l			= mprj_io[19];
+	assign phase_b1_l			= mprj_io[16];
+	assign phase_b2_l			= mprj_io[20];
+	assign phase_a1_h		= mprj_io[21];
+	assign phase_a2_h		= mprj_io[18];
+	assign phase_b1_h		= mprj_io[14];
+	assign phase_b2_h		= mprj_io[17];
+//	assign BUFFER_DTR		= mprj_io[37];
+//	assign MOVE_DONE		= mprj_io[24];
+//	assign CIPO				= mprj_io[36];
+//	assign STEPOUTPUT		= mprj_io[30];
+//	assign DIROUTPUT		= mprj_io[31];
+	assign mprj_io[25]		= analog_cmp1;
+	assign mprj_io[26]		= analog_cmp2;
+//	assign mprj_io[18]		= ENC_B;
+//	assign mprj_io[19]		= ENC_A;
+//	assign mprj_io[29]		= HALT;
+//	assign mprj_io[35]		= SCK;
+//	assign mprj_io[34]		= CS;
+//	assign mprj_io[22]		= COPI;
+	assign mprj_io[32]		= step;
+	assign mprj_io[33]		= dir;
+	assign resetn = RSTB;
+
+    always @(posedge clock) begin
+        if (!resetn) begin
+            cnt <= 0;
+            analog_cmp1 <= 1;
+            analog_cmp2 <= 1;
+            step <= 1;
+            step_clock <= 40'b0;
+        end
+        else begin
+            cnt <= cnt + 1;
+            enable_in <= 1;
+            if (current1[12] == 1'b1) begin
+                current_abs1 = -current1;
+            end
+            else begin
+                current_abs1 = current1;
+            end
+            if (current2[12] == 1'b1) begin
+                current_abs2 = -current2;
+            end
+            else begin
+                current_abs2 = current2;
+            end
+            step_clock <= step_clock + 1;
+            step <= step_clock[10];
+            analog_cmp1 <= (current_abs1[11:0] >= target_current1[11:0]); // compare unsigned
+            analog_cmp2 <= (current_abs2[11:0] >= target_current2[11:0]);
+            if (cnt <= 20'h4CA9) begin
+                dir <= 1;
+            end
+            else
+                dir <= 0;
+        end
+    end
+
 	caravel uut (
 		.vddio	  (VDD3V3),
 		.vssio	  (VSS),
@@ -122,6 +240,7 @@
 		.resetb	  (RSTB)
 	);
 
+
 	spiflash #(
 		.FILENAME("io_ports.hex")
 	) spiflash (
@@ -133,5 +252,37 @@
 		.io3()			// not used
 	);
 
+    pwm_duty duty1(
+        .clk(clock),
+        .resetn(resetn),
+        .pwm(analog_out1),
+        .duty(target_current1)
+    );
+    pwm_duty duty2(
+        .clk(clock),
+        .resetn(resetn),
+        .pwm(analog_out2),
+        .duty(target_current2)
+    );
+    hbridge_coil hbridge_coil1(
+        .clk(clock),
+        .resetn(resetn),
+        .low_1(phase_a1_l),
+        .high_1(phase_a1_h),
+        .low_2(phase_a2_l),
+        .high_2(phase_a2_h),
+        .current(current1),
+        .polarity_invert_config(1'b0)
+    );
+    hbridge_coil hbridge_coil2(
+        .clk(clock),
+        .resetn(resetn),
+        .low_1(phase_b1_l),
+        .high_1(phase_b1_h),
+        .low_2(phase_b2_l),
+        .high_2(phase_b2_h),
+        .current(current2),
+        .polarity_invert_config(1'b0)
+    );
 endmodule
 `default_nettype wire
diff --git a/verilog/rtl/rapcore.v b/verilog/rtl/rapcore.v
deleted file mode 100644
index d976d7a..0000000
--- a/verilog/rtl/rapcore.v
+++ /dev/null
@@ -1,123 +0,0 @@
-`default_nettype none
-/*
- *-------------------------------------------------------------
- *
- * user_proj_example
- *
- * This is an example of a (trivially simple) user project,
- * showing how the user project can connect to the logic
- * analyzer, the wishbone bus, and the I/O pads.
- *
- * This project generates an integer count, which is output
- * on the user area GPIO pads (digital output only).  The
- * wishbone connection allows the project to be controlled
- * (start and stop) from the management SoC program.
- *
- * See the testbenches in directory "mprj_counter" for the
- * example programs that drive this user project.  The three
- * testbenches are "io_ports", "la_test1", and "la_test2".
- *
- *-------------------------------------------------------------
- */
-
-module rapcore #(
-    parameter BITS = 32
-)(
-`ifdef USE_POWER_PINS
-    inout vdda1,	// User area 1 3.3V supply
-    inout vdda2,	// User area 2 3.3V supply
-    inout vssa1,	// User area 1 analog ground
-    inout vssa2,	// User area 2 analog ground
-    inout vccd1,	// User area 1 1.8V supply
-    inout vccd2,	// User area 2 1.8v supply
-    inout vssd1,	// User area 1 digital ground
-    inout vssd2,	// User area 2 digital ground
-`endif
-
-    // Wishbone Slave ports (WB MI A)
-    input wb_clk_i,
-    input wb_rst_i,
-    input wbs_stb_i,
-    input wbs_cyc_i,
-    input wbs_we_i,
-    input [3:0] wbs_sel_i,
-    input [31:0] wbs_dat_i,
-    input [31:0] wbs_adr_i,
-    output wbs_ack_o,
-    output [31:0] wbs_dat_o,
-
-    // Logic Analyzer Signals
-    input  [127:0] la_data_in,
-    output [127:0] la_data_out,
-    input  [127:0] la_oen,
-
-    // IOs
-    input  [`MPRJ_IO_PADS-1:0] io_in,
-    output [`MPRJ_IO_PADS-1:0] io_out,
-    output [`MPRJ_IO_PADS-1:0] io_oeb
-);
-    wire clk;
-    wire rst;
-
-    wire [`MPRJ_IO_PADS-1:0] io_in;
-    wire [`MPRJ_IO_PADS-1:0] io_out;
-    wire [`MPRJ_IO_PADS-1:0] io_oeb;
-
-    wire [31:0] rdata;
-    wire [31:0] wdata;
-    wire [BITS-1:0] count;
-
-    wire valid;
-    wire [3:0] wstrb;
-    wire [31:0] la_write;
-
-    // WB MI A
-    assign valid = wbs_cyc_i && wbs_stb_i;
-    assign wstrb = wbs_sel_i & {4{wbs_we_i}};
-    assign wbs_dat_o = rdata;
-    assign wdata = wbs_dat_i;
-
-    // IO
-    //assign io_out = count;
-    //assign io_oeb = {(`MPRJ_IO_PADS-1){rst}};
-
-    // LA
-    assign la_data_out = {{(127-BITS){1'b0}}, count};
-    // Assuming LA probes [63:32] are for controlling the count register
-    assign la_write = ~la_oen[63:32] & ~{BITS{valid}};
-    // Assuming LA probes [65:64] are for controlling the count clk & reset
-    assign clk = wb_clk_i;
-    assign rst = (~la_oen[65]) ? la_data_in[65]: wb_rst_i;
-
-
-    top top (
-
-        // IO Pads
-        .CLK(clk),
-        .CHARGEPUMP(io_out[15]),
-        .analog_cmp1(io_in[25]),
-        .analog_out1(io_out[27]),
-        .analog_cmp2(io_in[26]),
-        .analog_out2(io_out[28]),
-        .PHASE_A1(io_out[23]),
-        .PHASE_A2(io_out[19]),
-        .PHASE_B1(io_out[16]),
-        .PHASE_B2(io_out[20]),
-        .PHASE_A1_H(io_out[21]),
-        .PHASE_A2_H(io_out[18]),
-        .PHASE_B1_H(io_out[14]),
-        .PHASE_B2_H(io_out[17]),
-        .ENC_B(io_in[18]),
-        .ENC_A(io_in[19]),
-        .BUFFER_DTR(io_out[12]),
-        .MOVE_DONE(io_out[24]),
-        .HALT(io_in[29]),
-        .SCK(io_in[10]),
-        .CS(io_in[9]),
-        .COPI(io_in[8]),
-        .CIPO(io_out[11])
-    );
-
-endmodule
-
-`default_nettype wire
diff --git a/verilog/rtl/rapcores.v b/verilog/rtl/rapcores.v
new file mode 100644
index 0000000..15640ba
--- /dev/null
+++ b/verilog/rtl/rapcores.v
@@ -0,0 +1,187 @@
+`default_nettype none
+/*
+ *-------------------------------------------------------------
+ *
+ * user_proj_example
+ *
+ * This is an example of a (trivially simple) user project,
+ * showing how the user project can connect to the logic
+ * analyzer, the wishbone bus, and the I/O pads.
+ *
+ * This project generates an integer count, which is output
+ * on the user area GPIO pads (digital output only).  The
+ * wishbone connection allows the project to be controlled
+ * (start and stop) from the management SoC program.
+ *
+ * See the testbenches in directory "mprj_counter" for the
+ * example programs that drive this user project.  The three
+ * testbenches are "io_ports", "la_test1", and "la_test2".
+ *
+ *-------------------------------------------------------------
+ */
+
+`default_nettype none
+
+module rapcores #(
+    parameter BITS = 32
+)(
+`ifdef USE_POWER_PINS
+    inout vdda1,	// User area 1 3.3V supply
+    inout vdda2,	// User area 2 3.3V supply
+    inout vssa1,	// User area 1 analog ground
+    inout vssa2,	// User area 2 analog ground
+    inout vccd1,	// User area 1 1.8V supply
+    inout vccd2,	// User area 2 1.8v supply
+    inout vssd1,	// User area 1 digital ground
+    inout vssd2,	// User area 2 digital ground
+`endif
+
+    // Wishbone Slave ports (WB MI A)
+    input wb_clk_i,
+    input wb_rst_i,
+    input wbs_stb_i,
+    input wbs_cyc_i,
+    input wbs_we_i,
+    input [3:0] wbs_sel_i,
+    //input [31:0] wbs_dat_i,
+    //input [31:0] wbs_adr_i,
+    output wbs_ack_o,
+    //output [31:0] wbs_dat_o,
+
+    // Logic Analyzer Signals
+    input  [127:0] la_data_in,
+    output [127:0] la_data_out,
+    input  [127:0] la_oen,
+
+    // IOs
+    input  [`MPRJ_IO_PADS-1:0] io_in,
+    output [`MPRJ_IO_PADS-1:0] io_out,
+    output [`MPRJ_IO_PADS-1:0] io_oeb
+);
+
+    wire clk;
+    wire rst;
+    wire enable;
+
+    wire [`MPRJ_IO_PADS-1:0] io_in;
+    wire [`MPRJ_IO_PADS-1:0] io_out;
+    wire [`MPRJ_IO_PADS-1:0] io_oeb;
+
+    //wire [31:0] rdata;
+    //wire [31:0] wdata;
+    wire [BITS-1:0] count;
+
+    wire valid;
+    wire [3:0] wstrb;
+    wire [31:0] la_write;
+
+    // WB MI A
+    assign valid = wbs_cyc_i && wbs_stb_i;
+    assign wstrb = wbs_sel_i & {4{wbs_we_i}};
+    //assign wbs_dat_o = rdata;
+    //assign wdata = wbs_dat_i;
+
+    // IO
+    //assign io_out = count;
+    //assign io_oeb = {(`MPRJ_IO_PADS-1){rst}};
+
+		assign count = 0;
+    // LA
+    assign la_data_out = {{(127-BITS){1'b0}}, count};
+    // Assuming LA probes [63:32] are for controlling the count register
+    assign la_write = ~la_oen[63:32] & ~{BITS{valid}};
+    // Assuming LA probes [65:64] are for controlling the count clk & reset
+    assign clk = wb_clk_i;
+    assign rst = ~la_oen[65] && la_data_in[65] && ~wb_rst_i;
+    assign enable = ~la_oen[64] && la_data_in[64];
+
+    // GPIO output enable (0 = output, 1 = input)
+    assign io_oeb[15] = 1'b0;    // CHARGEPUMP
+    assign io_oeb[25] = 1'b1;    // analog_cmp1
+    assign io_oeb[27] = 1'b0;    // analog_out1
+    assign io_oeb[26] = 1'b1;    // analog_cmp2
+    assign io_oeb[28] = 1'b0;    // analog_out2
+    assign io_oeb[23] = 1'b0;    // PHASE_A1
+    assign io_oeb[19] = 1'b0;    // PHASE_A2
+    assign io_oeb[16] = 1'b0;    // PHASE_B1
+    assign io_oeb[20] = 1'b0;    // PHASE_B2
+    assign io_oeb[21] = 1'b0;    // PHASE_A1_H
+    assign io_oeb[18] = 1'b0;    // PHASE_A2_H
+    assign io_oeb[14] = 1'b0;    // PHASE_B1_H
+    assign io_oeb[17] = 1'b0;    // PHASE_B2_H
+    assign io_oeb[12] = 1'b0;    // ENC_B
+    assign io_oeb[13] = 1'b0;    // ENC_A
+    assign io_oeb[37] = 1'b0;    // BUFFER_DTR
+    assign io_oeb[24] = 1'b0;    // MOVE_DONE
+    assign io_oeb[29] = 1'b1;    // HALT
+    assign io_oeb[35] = 1'b1;    // SCK
+    assign io_oeb[34] = 1'b1;     // CS
+    assign io_oeb[33] = 1'b1;     // COPI
+    assign io_oeb[36] = 1'b0;    // CIPO
+    assign io_oeb[30] = 1'b0;    // STEPOUTPUT
+    assign io_oeb[31] = 1'b0;    // DIROUTPUT
+    assign io_oeb[32] = 1'b1;    // STEPINPUT
+    assign io_oeb[33] = 1'b1;    // DIRINPUT
+    // unused
+    assign io_oeb[0] = 1'b0;    // JTAG I/O
+    assign io_oeb[1] = 1'b0;    // SDO
+    assign io_oeb[2] = 1'b0;    // SDI
+    assign io_oeb[3] = 1'b0;    // CSB
+    assign io_oeb[4] = 1'b0;    // SCK
+    assign io_oeb[5] = 1'b0;    // Rx
+    assign io_oeb[6] = 1'b0;    // Tx
+    assign io_oeb[7] = 1'b0;    // IRQ
+    assign io_oeb[13] = 1'b1;
+    assign io_oeb[8] = 1'b1;
+    assign io_oeb[9] = 1'b1;
+    assign io_oeb[10] = 1'b1;
+    assign io_oeb[11] = 1'b1;
+    assign io_oeb[12] = 1'b1;
+
+
+		wire resetn;
+    reg [13:0] resetn_counter = 0;
+		assign resetn = &resetn_counter && rst;
+
+		always @(posedge wb_clk_i) begin
+		  if (!resetn && !wb_rst_i && rst) resetn_counter <= resetn_counter +1;
+		end
+
+    // IO
+    assign io_out[7:0] = resetn_counter[13:6]; //count;
+
+    rapcore rapcore0 (
+
+        // IO Pads
+        .CLK(wb_clk_i),
+        .resetn_in(resetn),
+        .CHARGEPUMP(io_out[15]),
+        .analog_cmp1(io_in[25]),
+        .analog_out1(io_out[27]),
+        .analog_cmp2(io_in[26]),
+        .analog_out2(io_out[28]),
+        .PHASE_A1(io_out[23]),
+        .PHASE_A2(io_out[19]),
+        .PHASE_B1(io_out[16]),
+        .PHASE_B2(io_out[20]),
+        .PHASE_A1_H(io_out[21]),
+        .PHASE_A2_H(io_out[18]),
+        .PHASE_B1_H(io_out[14]),
+        .PHASE_B2_H(io_out[17]),
+        .ENC_B(io_in[18]),
+        .ENC_A(io_in[19]),
+        .BUFFER_DTR(io_out[37]),
+        .MOVE_DONE(io_out[24]),
+        .HALT(io_in[29]),
+        .SCK(io_in[35]),
+        .CS(io_in[34]),
+        .COPI(io_in[22]),
+        .CIPO(io_out[36]),
+        .STEPOUTPUT(io_out[30]),
+        .DIROUTPUT(io_out[31]),
+        .STEPINPUT(io_in[32]),
+        .DIRINPUT(io_in[33]),
+        .ENINPUT(enable)
+    );
+
+endmodule
diff --git a/verilog/rtl/user_proj_example.v b/verilog/rtl/user_proj_example.v
index 89d09b8..3445aa0 100644
--- a/verilog/rtl/user_proj_example.v
+++ b/verilog/rtl/user_proj_example.v
@@ -63,7 +63,7 @@
     wire [`MPRJ_IO_PADS-1:0] io_out;
     wire [`MPRJ_IO_PADS-1:0] io_oeb;
 
-    wire [31:0] rdata;
+    wire [31:0] rdata; 
     wire [31:0] wdata;
     wire [BITS-1:0] count;
 
@@ -72,7 +72,7 @@
     wire [31:0] la_write;
 
     // WB MI A
-    assign valid = wbs_cyc_i && wbs_stb_i;
+    assign valid = wbs_cyc_i && wbs_stb_i; 
     assign wstrb = wbs_sel_i & {4{wbs_we_i}};
     assign wbs_dat_o = rdata;
     assign wdata = wbs_dat_i;
@@ -83,41 +83,75 @@
 
     // LA
     assign la_data_out = {{(127-BITS){1'b0}}, count};
-    // Assuming LA probes [63:32] are for controlling the count register
+    // Assuming LA probes [63:32] are for controlling the count register  
     assign la_write = ~la_oen[63:32] & ~{BITS{valid}};
-    // Assuming LA probes [65:64] are for controlling the count clk & reset
-    assign clk = wb_clk_i;
+    // Assuming LA probes [65:64] are for controlling the count clk & reset  
+    assign clk = (~la_oen[64]) ? la_data_in[64]: wb_clk_i;
     assign rst = (~la_oen[65]) ? la_data_in[65]: wb_rst_i;
 
-
-    top top (
-
-        // IO Pads
-        .CLK(clk),
-        .CHARGEPUMP(io_out[15]),
-        .analog_cmp1(io_in[25]),
-        .analog_out1(io_out[27]),
-        .analog_cmp2(io_in[26]),
-        .analog_out2(io_out[28]),
-        .PHASE_A1(io_out[23]),
-        .PHASE_A2(io_out[19]),
-        .PHASE_B1(io_out[16]),
-        .PHASE_B2(io_out[20]),
-        .PHASE_A1_H(io_out[21]),
-        .PHASE_A2_H(io_out[18]),
-        .PHASE_B1_H(io_out[14]),
-        .PHASE_B2_H(io_out[17]),
-        .ENC_B(io_in[18]),
-        .ENC_A(io_in[19]),
-        .BUFFER_DTR(io_out[12]),
-        .MOVE_DONE(io_out[24]),
-        .HALT(io_in[29]),
-        .SCK(io_in[10]),
-        .CS(io_in[9]),
-        .COPI(io_in[8]),
-        .CIPO(io_out[11])
+    counter #(
+        .BITS(BITS)
+    ) counter(
+        .clk(clk),
+        .reset(rst),
+        .ready(wbs_ack_o),
+        .valid(valid),
+        .rdata(rdata),
+        .wdata(wbs_dat_i),
+        .wstrb(wstrb),
+        .la_write(la_write),
+        .la_input(la_data_in[63:32]),
+        .count(count)
     );
 
 endmodule
 
+module counter #(
+    parameter BITS = 32
+)(
+    input clk,
+    input reset,
+    input valid,
+    input [3:0] wstrb,
+    input [BITS-1:0] wdata,
+    input [BITS-1:0] la_write,
+    input [BITS-1:0] la_input,
+    output ready,
+    output [BITS-1:0] rdata,
+    output [BITS-1:0] count
+);
+    reg ready;
+    reg [BITS-1:0] count;
+    reg [BITS-1:0] rdata;
+
+    always @(posedge clk) begin
+        if (reset) begin
+            count <= 0;
+            ready <= 0;
+        end else begin
+            ready <= 1'b0;
+            if (~|la_write) begin
+                count <= count + 1;
+            end
+            if (valid && !ready) begin
+                ready <= 1'b1;
+                rdata <= count;
+                if (wstrb[0]) count[7:0]   <= wdata[7:0];
+                if (wstrb[1]) count[15:8]  <= wdata[15:8];
+                if (wstrb[2]) count[23:16] <= wdata[23:16];
+                if (wstrb[3]) count[31:24] <= wdata[31:24];
+            end
+        end
+    end
+
+    genvar i;
+    generate 
+        for(i=0; i<BITS; i=i+1) begin
+          always @(posedge clk) begin
+              if (la_write[i]) count[i] <= la_input[i];
+          end
+        end
+    endgenerate
+
+endmodule
 `default_nettype wire
diff --git a/verilog/rtl/user_project_wrapper.v b/verilog/rtl/user_project_wrapper.v
index fb0b56c..737db20 100644
--- a/verilog/rtl/user_project_wrapper.v
+++ b/verilog/rtl/user_project_wrapper.v
@@ -64,70 +64,48 @@
     /* User project is instantiated  here   */
     /*--------------------------------------*/
 
-    rapcore rapcore (
+    rapcores rapcores0 (
 
-        // IO Pads
-        .CLK(wb_clk_i),
-        .CHARGEPUMP(io_out[15]),
-        .analog_cmp1(io_in[25]),
-        .analog_out1(io_out[27]),
-        .analog_cmp2(io_in[26]),
-        .analog_out2(io_out[28]),
-        .PHASE_A1(io_out[23]),
-        .PHASE_A2(io_out[19]),
-        .PHASE_B1(io_out[16]),
-        .PHASE_B2(io_out[20]),
-        .PHASE_A1_H(io_out[21]),
-        .PHASE_A2_H(io_out[18]),
-        .PHASE_B1_H(io_out[14]),
-        .PHASE_B2_H(io_out[17]),
-        .ENC_B(io_in[18]),
-        .ENC_A(io_in[19]),
-        .BUFFER_DTR(io_out[12]),
-        .MOVE_DONE(io_out[24]),
-        .HALT(io_in[29]),
-        .SCK(io_in[10]),
-        .CS(io_in[9]),
-        .COPI(io_in[8]),
-        .CIPO(io_out[11]),
-        .STEPOUTPUT(io_out[30]),
-        .DIROUTPUT(io_out[31]),
-        .STEPINPUT(io_in[32]),
-        .DIRINPUT(io_in[33])
+`ifndef SIM
+    `ifdef USE_POWER_PINS
+	.vdda1(vdda1),	// User area 1 3.3V power
+	.vdda2(vdda2),	// User area 2 3.3V power
+	.vssa1(vssa1),	// User area 1 analog ground
+	.vssa2(vssa2),	// User area 2 analog ground
+	.vccd1(vccd1),	// User area 1 1.8V power
+	.vccd2(vccd2),	// User area 2 1.8V power
+	.vssd1(vssd1),	// User area 1 digital ground
+	.vssd2(vssd2),	// User area 2 digital ground
+    `endif
+`endif
+	// MGMT core clock and reset
+
+    	.wb_clk_i(wb_clk_i),
+    	.wb_rst_i(wb_rst_i),
+
+	// MGMT SoC Wishbone Slave
+
+	.wbs_cyc_i(wbs_cyc_i),
+	.wbs_stb_i(wbs_stb_i),
+	.wbs_we_i(wbs_we_i),
+	.wbs_sel_i(wbs_sel_i),
+	//.wbs_adr_i(wbs_adr_i),
+	//.wbs_dat_i(wbs_dat_i),
+	.wbs_ack_o(wbs_ack_o),
+	//.wbs_dat_o(wbs_dat_o),
+
+	// Logic Analyzer
+
+	.la_data_in(la_data_in),
+	.la_data_out(la_data_out),
+	.la_oen (la_oen),
+
+	// IO Pads
+
+	.io_in (io_in),
+    	.io_out(io_out),
+    	.io_oeb(io_oeb)
     );
 
 endmodule	// user_project_wrapper
-
-(* blackbox *)
-module rapcore (
-    input  CLK,
-      input  SCK,
-      input  CS,
-      input  COPI,
-      output CIPO,
-      output CHARGEPUMP,
-      input analog_cmp1,
-      output analog_out1,
-      input analog_cmp2,
-      output analog_out2,
-      output wire PHASE_A1,  // Phase A
-      output wire PHASE_A2,  // Phase A
-      output wire PHASE_B1,  // Phase B
-      output wire PHASE_B2,  // Phase B
-      output wire PHASE_A1_H,  // Phase A
-      output wire PHASE_A2_H,  // Phase A
-      output wire PHASE_B1_H,  // Phase B
-      output wire PHASE_B2_H,  // Phase B
-      input ENC_B,
-      input ENC_A,
-      output BUFFER_DTR,
-      output MOVE_DONE,
-      input HALT,
-      input STEPINPUT,
-      input DIRINPUT,
-      output STEPOUTPUT,
-      output DIROUTPUT
-);
-endmodule
-
 `default_nettype wire