PWM reload cmp at end of cycle and improve timings.
diff --git a/README.md b/README.md
index 188e4f0..116ba4d 100644
--- a/README.md
+++ b/README.md
@@ -10,6 +10,7 @@
 
 - `digitalcore_macro` - Digital top sea of gates containing control logic and digital peripherals.
     - `gpio0` - Wishbone 32-bit GPIO peripheral
+    - `pwm[0-3]` - Wishbone PWM peripherals with 16-bit prescaler and 16-bit counter/compare
     - `uart0` - Wishbone UART peripheral
     - `ring0` - Ring oscillator controller for collapsing ring.
     - `ring1` - Ring oscillator controller for free running ring oscillator.
diff --git a/ip/randsack/rtl/pwm_wb.v b/ip/randsack/rtl/pwm_wb.v
index 58bc4a7..fc0111d 100644
--- a/ip/randsack/rtl/pwm_wb.v
+++ b/ip/randsack/rtl/pwm_wb.v
@@ -56,6 +56,9 @@
   reg [CNT_BITS-1:0] cntmax_reg;
   reg [CNT_BITS-1:0] cmp_reg;
 
+  // Captured regs.
+  reg [CNT_BITS-1:0] cmp_captured;
+
   // Counters.
   reg [DIV_BITS-1:0] div_cnt;
   reg [CNT_BITS-1:0] cnt_cnt;
@@ -88,14 +91,17 @@
   end
 
   // DIV counter.
-  wire div_match = div_cnt == div_reg;
+  reg div_match;
   always @(posedge clk or negedge resetb) begin
     if (!resetb) begin
       div_cnt <= {DIV_BITS{1'b0}};
+      div_match <= 1'b0;
     end else begin
-      if (div_match) begin
+      if (div_cnt == div_reg) begin
+        div_match <= 1'b1;
         div_cnt <= {DIV_BITS{1'b0}};
       end else begin
+        div_match <= 1'b0;
         div_cnt <= div_cnt + 1'b1;
       end
     end
@@ -115,16 +121,23 @@
     end
   end
 
+  // Capture new cmp value at end of cycle.
+  always @(posedge clk or negedge resetb) begin
+    if (!resetb) begin
+      cmp_captured <= {CNT_BITS{1'b0}};
+    end else begin
+      if (cnt_cnt == cntmax_reg) begin
+        cmp_captured <= cmp_reg;
+      end
+    end
+  end
+
   // Compare.
   always @(posedge clk or negedge resetb) begin
     if (!resetb) begin
       pwm_out <= 1'b0;
     end else begin
-      if (cnt_cnt < cmp_reg) begin
-        pwm_out <= 1'b1;  
-      end else begin
-        pwm_out <= 1'b0;
-      end
+      pwm_out <= cnt_cnt < cmp_captured;
     end
   end
 
diff --git a/openlane/digitalcore_macro/config.tcl b/openlane/digitalcore_macro/config.tcl
index c24140c..3e0439e 100755
--- a/openlane/digitalcore_macro/config.tcl
+++ b/openlane/digitalcore_macro/config.tcl
@@ -20,9 +20,10 @@
 set ::env(VERILOG_FILES) "\
 	$::env(CARAVEL_ROOT)/verilog/rtl/defines.v \
 	$script_dir/../../ip/randsack/rtl/digitalcore_macro.v \
+	$script_dir/../../ip/randsack/rtl/pwm_wb.v \
 	$script_dir/../../ip/third_party/picorv32_wb/gpio32_wb.v \
 	$script_dir/../../ip/third_party/picorv32_wb/simpleuart_div16_wb.v \
-	$script_dir/../../ip/third_party/verilog-wishbone/rtl/wb_mux_4.v \
+	$script_dir/../../ip/third_party/verilog-wishbone/rtl/wb_mux_8.v \
 	$script_dir/../../ip/randsack/rtl/ring_control.v"
 
 set ::env(DESIGN_IS_CORE) 0
@@ -35,13 +36,24 @@
 set ::env(CLOCK_PERIOD) "10"
 
 # Various options to tweak if there are slew / hold issues.
+set ::env(PL_RESIZER_TIMING_OPTIMIZATIONS) 1
+set ::env(GLB_RESIZER_TIMING_OPTIMIZATIONS) 1
+set ::env(PL_RESIZER_SETUP_SLACK_MARGIN) 0.1
+set ::env(PL_RESIZER_HOLD_SLACK_MARGIN) 0.2
+set ::env(GLB_RESIZER_SETUP_SLACK_MARGIN) 0.1
+set ::env(GLB_RESIZER_HOLD_SLACK_MARGIN) 0.2
+set ::env(GLB_RESIZER_HOLD_MAX_BUFFER_PERCENT) 80
+set ::env(PL_RESIZER_HOLD_MAX_BUFFER_PERCENT) 80
+set ::env(GLB_RESIZER_SETUP_MAX_BUFFER_PERCENT) 80
+set ::env(PL_RESIZER_SETUP_MAX_BUFFER_PERCENT) 80
 # set ::env(PL_RESIZER_ALLOW_SETUP_VIOS) 1
+# set ::env(GLB_RESIZER_ALLOW_SETUP_VIOS) 1
 # set ::env(SYNTH_MAX_FANOUT) 4
 # set ::env(CLOCK_BUFFER_FANOUT) 12
 # set ::env(CTS_CLK_BUFFER_LIST) "sky130_fd_sc_hd__clkbuf_4 sky130_fd_sc_hd__clkbuf_8"
 
 set ::env(FP_SIZING) absolute
-set ::env(DIE_AREA) "0 0 500 500"
+set ::env(DIE_AREA) "0 0 500 1000"
 
 set ::env(FP_PIN_ORDER_CFG) $script_dir/pin_order.cfg