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