diff --git a/library/common/up_clock_mon.v b/library/common/up_clock_mon.v index cadffc82f..c6c7364d7 100644 --- a/library/common/up_clock_mon.v +++ b/library/common/up_clock_mon.v @@ -38,76 +38,89 @@ module up_clock_mon ( // internal registers - reg [15:0] up_count = 'd0; - reg up_count_toggle = 'd0; - reg up_count_toggle_m1 = 'd0; - reg up_count_toggle_m2 = 'd0; - reg up_count_toggle_m3 = 'd0; - reg d_count_toggle_m1 = 'd0; - reg d_count_toggle_m2 = 'd0; - reg d_count_toggle_m3 = 'd0; - reg d_count_toggle = 'd0; - reg [31:0] d_count_hold = 'd0; + reg [15:0] up_count = 'd1; + reg up_count_run = 'd0; + reg up_count_running_m1 = 'd0; + reg up_count_running_m2 = 'd0; + reg up_count_running_m3 = 'd0; + reg d_count_run_m1 = 'd0; + reg d_count_run_m2 = 'd0; + reg d_count_run_m3 = 'd0; reg [32:0] d_count = 'd0; // internal signals - wire up_count_toggle_s; - wire d_count_toggle_s; + wire up_count_capture_s; + wire d_count_reset_s; // processor reference - assign up_count_toggle_s = up_count_toggle_m3 ^ up_count_toggle_m2; + // Capture on the falling edge of running + assign up_count_capture_s = up_count_running_m3 == 1'b1 && up_count_running_m2 == 1'b0; + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_count_running_m1 <= 1'b0; + up_count_running_m2 <= 1'b0; + up_count_running_m3 <= 1'b0; + end else begin + up_count_running_m1 <= d_count_run_m3; + up_count_running_m2 <= up_count_running_m1; + up_count_running_m3 <= up_count_running_m2; + end + end always @(negedge up_rstn or posedge up_clk) begin if (up_rstn == 0) begin - up_count <= 'd0; - up_count_toggle <= 'd0; - up_count_toggle_m1 <= 'd0; - up_count_toggle_m2 <= 'd0; - up_count_toggle_m3 <= 'd0; up_d_count <= 'd0; + up_count_run <= 1'b0; + end else begin + if (up_count_running_m3 == 1'b0) begin + up_count_run <= 1'b1; + end else if (up_count == 'h00) begin + up_count_run <= 1'b0; + end + + if (up_count_capture_s == 1'b1) begin + up_d_count <= d_count; + end + end + end + + always @(posedge up_clk) begin + if (up_count_run == 1'b0) begin + up_count <= 'h01; end else begin up_count <= up_count + 1'b1; - if (up_count == 16'd0) begin - up_count_toggle <= ~up_count_toggle; - end - up_count_toggle_m1 <= d_count_toggle; - up_count_toggle_m2 <= up_count_toggle_m1; - up_count_toggle_m3 <= up_count_toggle_m2; - if (up_count_toggle_s == 1'b1) begin - up_d_count <= d_count_hold; - end end end // device free running - assign d_count_toggle_s = d_count_toggle_m3 ^ d_count_toggle_m2; + // Reset on the rising edge of run + assign d_count_reset_s = d_count_run_m3 == 1'b0 && d_count_run_m2 == 1'b1; always @(posedge d_clk or posedge d_rst) begin if (d_rst == 1'b1) begin - d_count_toggle_m1 <= 'd0; - d_count_toggle_m2 <= 'd0; - d_count_toggle_m3 <= 'd0; + d_count_run_m1 <= 1'b0; + d_count_run_m2 <= 1'b0; + d_count_run_m3 <= 1'b0; end else begin - d_count_toggle_m1 <= up_count_toggle; - d_count_toggle_m2 <= d_count_toggle_m1; - d_count_toggle_m3 <= d_count_toggle_m2; + d_count_run_m1 <= up_count_run; + d_count_run_m2 <= d_count_run_m1; + d_count_run_m3 <= d_count_run_m2; end end always @(posedge d_clk) begin - if (d_count_toggle_s == 1'b1) begin - d_count_toggle <= ~d_count_toggle; - d_count_hold <= d_count[31:0]; - end - if (d_count_toggle_s == 1'b1) begin - d_count <= 33'd1; - end else if (d_count[32] == 1'b0) begin - d_count <= d_count + 1'b1; - end else begin - d_count <= {33{1'b1}}; + if (d_count_reset_s == 1'b1) begin + d_count <= 'h00; + end else if (d_count_run_m3 == 1'b1) begin + if (d_count[32] == 1'b0) begin + d_count <= d_count + 1'b1; + end else begin + d_count <= {33{1'b1}}; + end end end diff --git a/library/xilinx/common/up_clock_mon_constr.xdc b/library/xilinx/common/up_clock_mon_constr.xdc index da3881ca3..e21b70af7 100644 --- a/library/xilinx/common/up_clock_mon_constr.xdc +++ b/library/xilinx/common/up_clock_mon_constr.xdc @@ -1,7 +1,7 @@ -set_property ASYNC_REG TRUE [get_cells -hier -filter {name =~ *up_count_toggle_m*}] -set_property ASYNC_REG TRUE [get_cells -hier -filter {name =~ *d_count_toggle_m*}] +set_property ASYNC_REG true [get_cells -hier -filter {name =~ *up_count_running_m*}] +set_property ASYNC_REG true [get_cells -hier -filter {name =~ *d_count_run_m*}] -set_false_path -from [get_cells -hier -filter {name =~ *d_count_toggle_reg && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *up_count_toggle_m1_reg && IS_SEQUENTIAL}] -set_false_path -from [get_cells -hier -filter {name =~ *up_count_toggle_reg && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *d_count_toggle_m1_reg && IS_SEQUENTIAL}] -set_false_path -from [get_cells -hier -filter {name =~ *d_count_hold* && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *up_d_count* && IS_SEQUENTIAL}] +set_false_path -from [get_cells -hier -filter {name =~ *d_count_run_m3_reg && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *up_count_running_m1_reg && IS_SEQUENTIAL}] +set_false_path -from [get_cells -hier -filter {name =~ *up_count_run_reg && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *d_count_run_m1_reg && IS_SEQUENTIAL}] +set_false_path -from [get_cells -hier -filter {name =~ *d_count* && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *up_d_count* && IS_SEQUENTIAL}]