Made a number of modifications to the counter-timer to correctly pipeline
the 64-bit counter, including synchronizing the enables.  There are still
two issues, one of which causes the testbench to fail, which have not been
solved.
diff --git a/verilog/rtl/counter_timer.v b/verilog/rtl/counter_timer.v
deleted file mode 100755
index f569182..0000000
--- a/verilog/rtl/counter_timer.v
+++ /dev/null
@@ -1,192 +0,0 @@
-/* Simple 32-bit counter-timer for Caravel. */
-
-module counter_timer_wb # (
-    parameter BASE_ADR = 32'h2400_0000,
-    parameter CONFIG = 8'h00,
-    parameter VALUE  = 8'h04,
-    parameter DATA   = 8'h08
-) (
-    input wb_clk_i,
-    input wb_rst_i,
-    input strobe_in,
-    input [31:0] wb_adr_i,
-    input [31:0] wb_dat_i,
-    input [3:0] wb_sel_i,
-    input wb_we_i,
-    input wb_cyc_i,
-    input wb_stb_i,
-
-    output wb_ack_o,
-    output [31:0] wb_dat_o,
-    output strobe_out,
-    output irq
-);
-    wire [31:0] counter_timer_reg_cfg_do;
-    wire [31:0] counter_timer_reg_val_do;
-    wire [31:0] counter_timer_reg_dat_do;
-
-    wire resetn = ~wb_rst_i;
-    wire valid = wb_stb_i && wb_cyc_i;
-    wire counter_timer_reg_cfg_sel = valid && (wb_adr_i == (BASE_ADR | CONFIG));
-    wire counter_timer_reg_val_sel = valid && (wb_adr_i == (BASE_ADR | VALUE));
-    wire counter_timer_reg_dat_sel = valid && (wb_adr_i == (BASE_ADR | DATA));
-
-    wire reg_cfg_we = (counter_timer_reg_cfg_sel) ?
-		(wb_sel_i[0] & {wb_we_i}): 1'b0;
-    wire [3:0] reg_val_we = (counter_timer_reg_val_sel) ?
-		(wb_sel_i & {4{wb_we_i}}): 4'b0000;
-    wire [3:0] reg_dat_we = (counter_timer_reg_dat_sel) ?
-		(wb_sel_i & {4{wb_we_i}}): 4'b0000;
-
-    wire [31:0] mem_wdata = wb_dat_i;
-    wire reg_dat_re = counter_timer_reg_dat_sel && !wb_sel_i && ~wb_we_i;
-
-    assign wb_dat_o = (counter_timer_reg_cfg_sel) ? counter_timer_reg_cfg_do :
-		      (counter_timer_reg_val_sel) ? counter_timer_reg_val_do :
-		      counter_timer_reg_dat_do;
-    assign wb_ack_o = counter_timer_reg_cfg_sel || counter_timer_reg_val_sel ||
-			counter_timer_reg_dat_sel;
-    
-    counter_timer counter_timer_inst (
-        .resetn(resetn),
-        .clkin(wb_clk_i),
-	.strobe_in(strobe_in),
-        .reg_val_we(reg_val_we),
-        .reg_val_di(mem_wdata),
-        .reg_val_do(counter_timer_reg_val_do),
-        .reg_cfg_we(reg_cfg_we),
-        .reg_cfg_di(mem_wdata),
-        .reg_cfg_do(counter_timer_reg_cfg_do),
-        .reg_dat_we(reg_dat_we),
-        .reg_dat_di(mem_wdata),
-        .reg_dat_do(counter_timer_reg_dat_do),
-	.strobe_out(strobe_out),
-	.irq_out(irq)
-   );
-
-endmodule
-
-module counter_timer (
-    input resetn,
-    input clkin,
-    input strobe_in,
-
-    input  [3:0]  reg_val_we,
-    input  [31:0] reg_val_di,
-    output [31:0] reg_val_do,
-
-    input 	  reg_cfg_we,
-    input  [31:0] reg_cfg_di,
-    output [31:0] reg_cfg_do,
-
-    input  [3:0]  reg_dat_we,
-    input  [31:0] reg_dat_di,
-    output [31:0] reg_dat_do,
-    output	  strobe_out,
-    output	  irq_out
-);
-
-reg [31:0] value_cur;
-reg [31:0] value_reset;
-reg	   strobe_out;
-wire	   irq_out;
-
-reg enable;	// Enable (start) the counter/timer
-reg lastenable;	// Previous state of enable (catch rising/falling edge)
-reg oneshot;	// Set oneshot (1) mode or continuous (0) mode
-reg updown;	// Count up (1) or down (0)
-reg irq_ena;	// Enable interrupt on timeout
-reg chain;	// Chain to a secondary timer
-
-// Configuration register
-
-assign reg_cfg_do = {27'd0, irq_ena, chain, updown, oneshot, enable};
-
-always @(posedge clkin or negedge resetn) begin
-    if (resetn == 1'b0) begin
-	enable <= 1'b0;
-	lastenable <= 1'b0;
-	oneshot <= 1'b0;
-	updown <= 1'b0;
-	chain <= 1'b0;
-	irq_ena <= 1'b0;
-    end else begin
-	lastenable <= enable;
-	if (reg_cfg_we) begin
-	    enable <= reg_cfg_di[0];
-	    oneshot <= reg_cfg_di[1];
-	    updown <= reg_cfg_di[2];
-	    chain <= reg_cfg_di[3];
-	    irq_ena <= reg_cfg_di[4];
-	end
-    end
-end
-
-// Counter/timer reset value register
-
-assign reg_val_do = value_reset;
-
-always @(posedge clkin or negedge resetn) begin
-    if (resetn == 1'b0) begin
-	value_reset <= 32'd0;
-    end else begin
-	if (reg_val_we[3]) value_reset[31:24] <= reg_val_di[31:24];
-	if (reg_val_we[2]) value_reset[23:16] <= reg_val_di[23:16];
-	if (reg_val_we[1]) value_reset[15:8] <= reg_val_di[15:8];
-	if (reg_val_we[0]) value_reset[7:0] <= reg_val_di[7:0];
-    end
-end
-
-assign reg_dat_do = value_cur;
-
-// Counter/timer current value register and timer implementation
-
-assign irq_out = (irq_ena) ? strobe_out : 1'b0;
-
-always @(posedge clkin or negedge resetn) begin
-    if (resetn == 1'b0) begin
-	value_cur <= 32'd0;	
-	strobe_out <= 1'b0;
-    end else begin
-	if (reg_dat_we != 4'b0000) begin
-	    if (reg_dat_we[3] == 1'b1) value_cur[31:24] <= reg_dat_di[31:24];
-	    if (reg_dat_we[2] == 1'b1) value_cur[23:16] <= reg_dat_di[23:16];
-	    if (reg_dat_we[1] == 1'b1) value_cur[15:8] <= reg_dat_di[15:8];
-	    if (reg_dat_we[0] == 1'b1) value_cur[7:0] <= reg_dat_di[7:0];
-	end else if (enable == 1'b1) begin
-	    if (updown == 1'b1) begin
-		if (lastenable == 1'b0) begin
-		    value_cur <= 32'd0;
-		end else if (value_cur == value_reset) begin
-		    if (oneshot != 1'b1) begin
-			value_cur <= 32'd0;
-		    end
-		    strobe_out <= 1'b1;
-		end else begin
-		    if ((chain == 1'b0) || ((chain == 1'b1) && (strobe_in == 1'b1))) begin
-			value_cur <= value_cur + 1;	// count up
-		    	strobe_out <= 1'b0;
-		    end
-		end
-	    end else begin
-		if (lastenable == 1'b0) begin
-		    value_cur <= value_reset;
-		end else if (value_cur == 32'd0) begin
-		    if (oneshot != 1'b1) begin
-			value_cur <= value_reset;
-		    end
-		    strobe_out <= 1'b1;
-		end else begin
-		    if ((chain == 1'b0) || ((chain == 1'b1) && (strobe_in == 1'b1))) begin
-		    	value_cur <= value_cur - 1;	// count down
-		    	strobe_out <= 1'b0;
-		    end
-		end
-	    end
-	end else begin
-	    strobe_out <= 1'b0;
-	end
-    end
-end
-
-endmodule
diff --git a/verilog/rtl/counter_timer_high.v b/verilog/rtl/counter_timer_high.v
new file mode 100755
index 0000000..76db8b9
--- /dev/null
+++ b/verilog/rtl/counter_timer_high.v
@@ -0,0 +1,277 @@
+/* Simple 32-bit counter-timer for Caravel. */
+
+/* Counter acts as high 32 bits of a 64-bit counter
+ * when chained with the other counter
+ */
+
+module counter_timer_high_wb # (
+    parameter BASE_ADR = 32'h2400_0000,
+    parameter CONFIG = 8'h00,
+    parameter VALUE  = 8'h04,
+    parameter DATA   = 8'h08
+) (
+    input wb_clk_i,
+    input wb_rst_i,
+    input [31:0] wb_adr_i,
+    input [31:0] wb_dat_i,
+    input [3:0] wb_sel_i,
+    input wb_we_i,
+    input wb_cyc_i,
+    input wb_stb_i,
+
+    output wb_ack_o,
+    output [31:0] wb_dat_o,
+    input enable_in,
+    input stop_in,
+    input strobe,
+    input is_offset,
+    output stop_out,
+    output enable_out,
+    output irq
+);
+    wire [31:0] counter_timer_reg_cfg_do;
+    wire [31:0] counter_timer_reg_val_do;
+    wire [31:0] counter_timer_reg_dat_do;
+
+    wire resetn = ~wb_rst_i;
+    wire valid = wb_stb_i && wb_cyc_i;
+    wire counter_timer_reg_cfg_sel = valid && (wb_adr_i == (BASE_ADR | CONFIG));
+    wire counter_timer_reg_val_sel = valid && (wb_adr_i == (BASE_ADR | VALUE));
+    wire counter_timer_reg_dat_sel = valid && (wb_adr_i == (BASE_ADR | DATA));
+
+    wire reg_cfg_we = (counter_timer_reg_cfg_sel) ?
+		(wb_sel_i[0] & {wb_we_i}): 1'b0;
+    wire [3:0] reg_val_we = (counter_timer_reg_val_sel) ?
+		(wb_sel_i & {4{wb_we_i}}): 4'b0000;
+    wire [3:0] reg_dat_we = (counter_timer_reg_dat_sel) ?
+		(wb_sel_i & {4{wb_we_i}}): 4'b0000;
+
+    wire [31:0] mem_wdata = wb_dat_i;
+    wire reg_dat_re = counter_timer_reg_dat_sel && !wb_sel_i && ~wb_we_i;
+
+    assign wb_dat_o = (counter_timer_reg_cfg_sel) ? counter_timer_reg_cfg_do :
+		      (counter_timer_reg_val_sel) ? counter_timer_reg_val_do :
+		      counter_timer_reg_dat_do;
+    assign wb_ack_o = counter_timer_reg_cfg_sel || counter_timer_reg_val_sel ||
+			counter_timer_reg_dat_sel;
+    
+    counter_timer_high counter_timer_high_inst (
+        .resetn(resetn),
+        .clkin(wb_clk_i),
+        .reg_val_we(reg_val_we),
+        .reg_val_di(mem_wdata),
+        .reg_val_do(counter_timer_reg_val_do),
+        .reg_cfg_we(reg_cfg_we),
+        .reg_cfg_di(mem_wdata),
+        .reg_cfg_do(counter_timer_reg_cfg_do),
+        .reg_dat_we(reg_dat_we),
+        .reg_dat_di(mem_wdata),
+        .reg_dat_do(counter_timer_reg_dat_do),
+	.enable_in(enable_in),
+	.stop_in(stop_in),
+	.is_offset(is_offset),
+	.stop_out(stop_out),
+	.strobe(strobe),
+	.enable_out(enable_out),
+	.irq_out(irq)
+   );
+
+endmodule
+
+module counter_timer_high (
+    input resetn,
+    input clkin,
+
+    input  [3:0]  reg_val_we,
+    input  [31:0] reg_val_di,
+    output [31:0] reg_val_do,
+
+    input 	  reg_cfg_we,
+    input  [31:0] reg_cfg_di,
+    output [31:0] reg_cfg_do,
+
+    input  [3:0]  reg_dat_we,
+    input  [31:0] reg_dat_di,
+    output [31:0] reg_dat_do,
+    input	  stop_in,
+    input	  enable_in,
+    input	  is_offset,
+    input	  strobe,
+    output	  stop_out,
+    output	  enable_out,
+    output	  irq_out
+);
+
+reg [31:0] value_cur;
+reg [31:0] value_reset;
+reg	   irq_out;
+wire	   enable_in;		// Enable from chained counter
+wire	   strobe;		// Count strobe from low word counter
+wire	   enable_out;		// Enable to chained counter (sync)
+reg	   stop_out;		// Stop signal to low word counter
+
+wire [31:0] value_cur_plus;	// Next value, on up-count
+wire [31:0] value_cur_minus;	// Next value, on down-count
+wire [31:0] value_check_plus;	// Value to check for stop condition during up count
+wire	    loc_enable;		// Local enable
+
+reg enable;	// Enable (start) the counter/timer
+reg lastenable;	// Previous state of enable (catch rising/falling edge)
+reg oneshot;	// Set oneshot (1) mode or continuous (0) mode
+reg updown;	// Count up (1) or down (0)
+reg irq_ena;	// Enable interrupt on timeout
+reg chain;	// Chain to a secondary timer
+
+// Configuration register
+
+assign reg_cfg_do = {27'd0, irq_ena, chain, updown, oneshot, enable};
+
+always @(posedge clkin or negedge resetn) begin
+    if (resetn == 1'b0) begin
+	enable <= 1'b0;
+	oneshot <= 1'b0;
+	updown <= 1'b0;
+	chain <= 1'b0;
+	irq_ena <= 1'b0;
+    end else begin
+	if (reg_cfg_we) begin
+	    enable <= reg_cfg_di[0];
+	    oneshot <= reg_cfg_di[1];
+	    updown <= reg_cfg_di[2];
+	    chain <= reg_cfg_di[3];
+	    irq_ena <= reg_cfg_di[4];
+	end
+    end
+end
+
+// Counter/timer reset value register
+
+assign reg_val_do = value_reset;
+
+always @(posedge clkin or negedge resetn) begin
+    if (resetn == 1'b0) begin
+	value_reset <= 32'd0;
+    end else begin
+	if (reg_val_we[3]) value_reset[31:24] <= reg_val_di[31:24];
+	if (reg_val_we[2]) value_reset[23:16] <= reg_val_di[23:16];
+	if (reg_val_we[1]) value_reset[15:8] <= reg_val_di[15:8];
+	if (reg_val_we[0]) value_reset[7:0] <= reg_val_di[7:0];
+    end
+end
+
+assign reg_dat_do = value_cur;
+
+// Counter/timer current value register and timer implementation
+
+assign value_cur_plus = value_cur + 1;
+assign value_cur_minus = value_cur - 1;
+
+assign value_check_plus = (is_offset) ? value_cur_plus : value_cur;
+
+assign enable_out = enable;
+assign loc_enable = (chain == 1'b1) ? (enable && enable_in) : enable;
+
+// When acting as the high 32 bit word of a 64-bit chained counter:
+//
+// It counts when the low 32-bit counter strobes (strobe == 1).
+// It sets "stop_out" and stops on the stop condition.
+
+always @(posedge clkin or negedge resetn) begin
+    if (resetn == 1'b0) begin
+	value_cur <= 32'd0;	
+	stop_out <= 1'b0;
+	irq_out <= 1'b0;
+	lastenable <= 1'b0;
+    end else begin
+	lastenable <= loc_enable;
+
+	if (reg_dat_we != 4'b0000) begin
+	    if (reg_dat_we[3] == 1'b1) value_cur[31:24] <= reg_dat_di[31:24];
+	    if (reg_dat_we[2] == 1'b1) value_cur[23:16] <= reg_dat_di[23:16];
+	    if (reg_dat_we[1] == 1'b1) value_cur[15:8] <= reg_dat_di[15:8];
+	    if (reg_dat_we[0] == 1'b1) value_cur[7:0] <= reg_dat_di[7:0];
+
+	end else if (loc_enable == 1'b1) begin
+	    /* IRQ signals one cycle after stop, if IRQ is enabled */
+	    irq_out <= (irq_ena) ? stop_out : 1'b0;
+
+	    if (updown == 1'b1) begin
+		if (lastenable == 1'b0) begin
+		    value_cur <= 32'd0;
+		    stop_out <= 1'b0;
+		end else if (chain) begin
+		    // Chained counter behavior
+		    if (value_check_plus == value_reset) begin
+		    	stop_out <= 1'b1;
+		    end
+		    if (stop_in == 1'b1) begin	// lower word counter stopped
+			if (oneshot != 1'b1) begin
+			    value_cur <= 32'd0;	// reset count
+			    stop_out <= 1'b0;	// no longer stopped
+			end else if (strobe == 1'b1) begin
+			    value_cur <= value_cur_plus;
+			end
+		    end else if (strobe == 1'b1) begin
+			value_cur <= value_cur_plus;
+		    end
+		end else begin
+		    // Standalone counter behavior
+		    if (value_cur == value_reset) begin
+		    	if (oneshot != 1'b1) begin
+			    value_cur <= 32'd0;
+		    	    stop_out <= 1'b0;
+		    	end else begin
+		    	    stop_out <= 1'b1;
+			end
+		    end else begin
+		    	if (value_cur_plus == 32'd0) begin
+			    stop_out <= 1'b1;
+			end else begin
+			    stop_out <= 1'b0;
+			end
+		    	value_cur <= value_cur_plus;	// count up
+		    end
+		end
+	    end else begin
+		if (lastenable == 1'b0) begin
+		    value_cur <= value_reset;
+		    stop_out <= 1'b0;
+		end else if (chain) begin
+		    // Chained counter behavior
+		    if (value_cur == 32'd0) begin
+			stop_out <= 1'b1;
+		    end
+		    if (stop_in == 1'b1) begin	// lower word counter stopped
+			if (oneshot != 1'b1) begin
+			    value_cur <= value_reset;	// reset count
+			    stop_out <= 1'b0;		// no longer stopped
+			end
+		    end else if (strobe == 1'b1) begin
+		    	value_cur <= value_cur_minus;	// count down
+		    end
+		end else begin
+		    // Standalone counter behavior
+		    if (value_cur == 32'd0) begin
+		    	if (oneshot != 1'b1) begin
+			    value_cur <= value_reset;
+			    stop_out <= 1'b0;
+			end else begin
+			    stop_out <= 1'b1;
+			end
+		    end else begin
+		    	if (value_cur_minus == 32'd0) begin
+			    stop_out <= 1'b1;
+			end else begin
+			    stop_out <= 1'b0;
+			end
+		    	value_cur <= value_cur_minus;	// count down
+		    end
+		end
+	    end
+	end else begin
+	    stop_out <= 1'b0;
+	end
+    end
+end
+
+endmodule
diff --git a/verilog/rtl/counter_timer_low.v b/verilog/rtl/counter_timer_low.v
new file mode 100755
index 0000000..66989d2
--- /dev/null
+++ b/verilog/rtl/counter_timer_low.v
@@ -0,0 +1,309 @@
+/* Simple 32-bit counter-timer for Caravel. */
+
+/* Counter acts as low 32 bits of a 64-bit counter
+ * when chained with the other counter.
+ */
+
+module counter_timer_low_wb # (
+    parameter BASE_ADR = 32'h2400_0000,
+    parameter CONFIG = 8'h00,
+    parameter VALUE  = 8'h04,
+    parameter DATA   = 8'h08
+) (
+    input wb_clk_i,
+    input wb_rst_i,
+    input [31:0] wb_adr_i,
+    input [31:0] wb_dat_i,
+    input [3:0] wb_sel_i,
+    input wb_we_i,
+    input wb_cyc_i,
+    input wb_stb_i,
+
+    output wb_ack_o,
+    output [31:0] wb_dat_o,
+
+    input stop_in,
+    input enable_in,
+    output strobe,
+    output is_offset,
+    output stop_out,
+    output enable_out,
+    output irq
+);
+    wire [31:0] counter_timer_reg_cfg_do;
+    wire [31:0] counter_timer_reg_val_do;
+    wire [31:0] counter_timer_reg_dat_do;
+
+    wire resetn = ~wb_rst_i;
+    wire valid = wb_stb_i && wb_cyc_i;
+    wire counter_timer_reg_cfg_sel = valid && (wb_adr_i == (BASE_ADR | CONFIG));
+    wire counter_timer_reg_val_sel = valid && (wb_adr_i == (BASE_ADR | VALUE));
+    wire counter_timer_reg_dat_sel = valid && (wb_adr_i == (BASE_ADR | DATA));
+
+    wire reg_cfg_we = (counter_timer_reg_cfg_sel) ?
+		(wb_sel_i[0] & {wb_we_i}): 1'b0;
+    wire [3:0] reg_val_we = (counter_timer_reg_val_sel) ?
+		(wb_sel_i & {4{wb_we_i}}): 4'b0000;
+    wire [3:0] reg_dat_we = (counter_timer_reg_dat_sel) ?
+		(wb_sel_i & {4{wb_we_i}}): 4'b0000;
+
+    wire [31:0] mem_wdata = wb_dat_i;
+    wire reg_dat_re = counter_timer_reg_dat_sel && !wb_sel_i && ~wb_we_i;
+
+    assign wb_dat_o = (counter_timer_reg_cfg_sel) ? counter_timer_reg_cfg_do :
+		      (counter_timer_reg_val_sel) ? counter_timer_reg_val_do :
+		      counter_timer_reg_dat_do;
+    assign wb_ack_o = counter_timer_reg_cfg_sel || counter_timer_reg_val_sel ||
+			counter_timer_reg_dat_sel;
+    
+    counter_timer_low counter_timer_low_inst (
+        .resetn(resetn),
+        .clkin(wb_clk_i),
+        .reg_val_we(reg_val_we),
+        .reg_val_di(mem_wdata),
+        .reg_val_do(counter_timer_reg_val_do),
+        .reg_cfg_we(reg_cfg_we),
+        .reg_cfg_di(mem_wdata),
+        .reg_cfg_do(counter_timer_reg_cfg_do),
+        .reg_dat_we(reg_dat_we),
+        .reg_dat_di(mem_wdata),
+        .reg_dat_do(counter_timer_reg_dat_do),
+	.stop_in(stop_in),
+	.strobe(strobe),
+	.is_offset(is_offset),
+	.enable_in(enable_in),
+	.stop_out(stop_out),
+	.enable_out(enable_out),
+	.irq_out(irq)
+   );
+
+endmodule
+
+module counter_timer_low (
+    input resetn,
+    input clkin,
+
+    input  [3:0]  reg_val_we,
+    input  [31:0] reg_val_di,
+    output [31:0] reg_val_do,
+
+    input 	  reg_cfg_we,
+    input  [31:0] reg_cfg_di,
+    output [31:0] reg_cfg_do,
+
+    input  [3:0]  reg_dat_we,
+    input  [31:0] reg_dat_di,
+    output [31:0] reg_dat_do,
+
+    input	  stop_in,
+    input	  enable_in,
+    output	  strobe,
+    output	  enable_out,
+    output	  stop_out,
+    output	  is_offset,
+    output	  irq_out
+);
+
+reg [31:0] value_cur;
+reg [31:0] value_reset;
+reg	   irq_out;
+wire	   stop_in;		// High 32 bits counter has stopped
+reg	   strobe;		// Strobe to high 32 bits counter; occurs
+				// one cycle before actual timeout and
+				// irq signal.
+reg	   stop_out;		// Stop condition flag
+
+wire [31:0] value_cur_plus;	// Next value, on up-count
+wire [31:0] value_cur_minus;	// Next value, on down-count
+wire	    is_offset;
+
+reg enable;	// Enable (start) the counter/timer
+reg lastenable;	// Previous state of enable (catch rising/falling edge)
+reg oneshot;	// Set oneshot (1) mode or continuous (0) mode
+reg updown;	// Count up (1) or down (0)
+reg irq_ena;	// Enable interrupt on timeout
+reg chain;	// Chain to a secondary timer
+
+// Configuration register
+
+assign reg_cfg_do = {27'd0, irq_ena, chain, updown, oneshot, enable};
+
+always @(posedge clkin or negedge resetn) begin
+    if (resetn == 1'b0) begin
+	enable <= 1'b0;
+	oneshot <= 1'b0;
+	updown <= 1'b0;
+	chain <= 1'b0;
+	irq_ena <= 1'b0;
+    end else begin
+	if (reg_cfg_we) begin
+	    enable <= reg_cfg_di[0];
+	    oneshot <= reg_cfg_di[1];
+	    updown <= reg_cfg_di[2];
+	    chain <= reg_cfg_di[3];
+	    irq_ena <= reg_cfg_di[4];
+	end
+    end
+end
+
+// Counter/timer reset value register
+
+assign reg_val_do = value_reset;
+
+always @(posedge clkin or negedge resetn) begin
+    if (resetn == 1'b0) begin
+	value_reset <= 32'd0;
+    end else begin
+	if (reg_val_we[3]) value_reset[31:24] <= reg_val_di[31:24];
+	if (reg_val_we[2]) value_reset[23:16] <= reg_val_di[23:16];
+	if (reg_val_we[1]) value_reset[15:8] <= reg_val_di[15:8];
+	if (reg_val_we[0]) value_reset[7:0] <= reg_val_di[7:0];
+    end
+end
+
+assign reg_dat_do = value_cur;
+
+// Counter/timer current value register and timer implementation
+
+assign value_cur_plus = value_cur + 1;
+assign value_cur_minus = value_cur - 1;
+
+assign loc_enable = enable_in && enable;
+assign loc_enable = (chain == 1'b1) ? (enable && enable_in) : enable;
+assign enable_out = enable;
+
+// If counting up and the stop condition on the low 32 bits is zero,
+// then signal to the high word counter that the stop condition of the
+// high word must be adjusted by one, since it will roll over at the same
+// time and must be signaled early.
+
+assign is_offset = ((updown == 1'b1) && (value_reset == 0));
+
+// When acting as low 32-bit word of a 64-bit chained counter:
+// It sets the output strobe on the stop condition, one cycle early.
+// It stops on the stop condition if "stop_in" is high.
+
+always @(posedge clkin or negedge resetn) begin
+    if (resetn == 1'b0) begin
+	value_cur <= 32'd0;	
+	strobe <= 1'b0;
+	stop_out <= 1'b0;
+	irq_out <= 1'b0;
+	lastenable <= 1'b0;
+    end else begin
+	lastenable <= loc_enable;
+
+	if (reg_dat_we != 4'b0000) begin
+	    if (reg_dat_we[3] == 1'b1) value_cur[31:24] <= reg_dat_di[31:24];
+	    if (reg_dat_we[2] == 1'b1) value_cur[23:16] <= reg_dat_di[23:16];
+	    if (reg_dat_we[1] == 1'b1) value_cur[15:8] <= reg_dat_di[15:8];
+	    if (reg_dat_we[0] == 1'b1) value_cur[7:0] <= reg_dat_di[7:0];
+
+	end else if (loc_enable == 1'b1) begin
+	    /* IRQ signals one cycle after stop_out, if IRQ is enabled */
+	    irq_out <= (irq_ena) ? stop_out : 1'b0;
+
+	    if (updown == 1'b1) begin
+		if (lastenable == 1'b0) begin
+		    value_cur <= 32'd0;
+		    strobe <= 1'b0;
+		    stop_out <= 1'b0;
+		end else if (chain == 1'b1) begin
+		    // Rollover strobe (2 clock cycles advanced)
+		    if (value_cur == -1) begin
+			strobe <= 1'b1;
+		    end else begin
+			strobe <= 1'b0;
+		    end
+
+		    // Chained counter behavior
+		    if ((stop_in == 1'b1) && (value_cur == value_reset)) begin
+		    	if (oneshot != 1'b1) begin
+			    value_cur <= 32'd0;
+		    	    stop_out <= 1'b0;
+		    	end else begin
+		    	    stop_out <= 1'b1;
+			end
+		    end else begin
+		        if ((stop_in == 1'b1) && (value_cur_plus == value_reset)) begin
+		    	    stop_out <= 1'b1;
+			end else begin
+		    	    stop_out <= 1'b0;
+			end
+		    	value_cur <= value_cur_plus;	// count up
+		    end
+		end else begin
+
+		    // Single 32-bit counter behavior
+		    if (value_cur == value_reset) begin
+		    	if (oneshot != 1'b1) begin
+			    value_cur <= 32'd0;
+		    	    stop_out <= 1'b0;
+		    	end else begin
+		    	    stop_out <= 1'b1;
+			end
+		    end else begin
+		        if (value_cur_plus == value_reset) begin
+		    	    stop_out <= 1'b1;
+			end else begin
+		    	    stop_out <= 1'b0;
+			end
+		    	value_cur <= value_cur_plus;	// count up
+		    end
+		end
+	    end else begin
+		if (lastenable == 1'b0) begin
+		    value_cur <= value_reset;
+		    stop_out <= 1'b0;
+		    strobe <= 1'b0;
+		end else if (chain == 1'b1) begin
+		    // Rollover strobe (2 clock cycles advanced)
+		    if (value_cur == 2) begin
+			strobe <= 1'b1;
+		    end else begin
+			strobe <= 1'b0;
+		    end
+
+		    // Chained counter behavior
+		    if ((stop_in == 1'b1) && (value_cur == 32'd0)) begin
+		    	if (oneshot != 1'b1) begin
+			    value_cur <= value_reset;
+			    stop_out <= 1'b0;
+			end else begin
+			    stop_out <= 1'b1;
+			end
+		    end else begin
+		    	if ((stop_in == 1'b1) && (value_cur_minus == 32'd0)) begin
+			    stop_out <= 1'b1;
+			end else begin
+		    	    stop_out <= 1'b0;
+			end
+		    	value_cur <= value_cur_minus;	// count down
+		    end
+		end else begin
+
+		    // Single 32-bit counter behavior
+		    if (value_cur == 32'd0) begin
+		    	if (oneshot != 1'b1) begin
+			    value_cur <= value_reset;
+			    stop_out <= 1'b0;
+			end else begin
+			    stop_out <= 1'b1;
+			end
+		    end else begin
+		    	if (value_cur_minus == 32'd0) begin
+			    stop_out <= 1'b1;
+			end else begin
+		    	    stop_out <= 1'b0;
+			end
+		    	value_cur <= value_cur_minus;	// count down
+		    end
+		end
+	    end
+	end else begin
+	    strobe <= 1'b0;
+	end
+    end
+end
+
+endmodule
diff --git a/verilog/rtl/mgmt_soc.v b/verilog/rtl/mgmt_soc.v
index 3a8825e..67a2c17 100644
--- a/verilog/rtl/mgmt_soc.v
+++ b/verilog/rtl/mgmt_soc.v
@@ -33,7 +33,8 @@
 `include "spimemio.v"
 `include "simpleuart.v"
 `include "simple_spi_master.v"
-`include "counter_timer.v"
+`include "counter_timer_high.v"
+`include "counter_timer_low.v"
 `include "wb_intercon.v"
 `include "mem_wb.v"
 `include "gpio_wb.v"
@@ -481,14 +482,16 @@
 	.irq(irq_spi_master)
     );
 
-    wire strobe_counter_timer0, strobe_counter_timer1;
+    wire counter_timer_strobe, counter_timer_offset;
+    wire counter_timer0_enable, counter_timer1_enable;
+    wire counter_timer0_stop, counter_timer1_stop;
 
     // Wishbone Counter-timer 0
     wire counter_timer0_stb_i;
     wire counter_timer0_ack_o;
     wire [31:0] counter_timer0_dat_o;
 
-    counter_timer_wb #(
+    counter_timer_low_wb #(
         .BASE_ADR(COUNTER_TIMER0_BASE_ADR),
         .CONFIG(COUNTER_TIMER0_CONFIG),
         .VALUE(COUNTER_TIMER0_VALUE),
@@ -497,7 +500,6 @@
         // Wishbone Interface
         .wb_clk_i(wb_clk_i),
         .wb_rst_i(wb_rst_i),
-	.strobe_in(strobe_counter_timer1),
 
         .wb_adr_i(cpu_adr_o),      
         .wb_dat_i(cpu_dat_o),
@@ -508,7 +510,13 @@
         .wb_stb_i(counter_timer0_stb_i),
         .wb_ack_o(counter_timer0_ack_o),
         .wb_dat_o(counter_timer0_dat_o),
-	.strobe_out(strobe_counter_timer0),
+
+	.enable_in(counter_timer1_enable),
+	.stop_in(counter_timer1_stop),
+	.strobe(counter_timer_strobe),
+	.is_offset(counter_timer_offset),
+	.enable_out(counter_timer0_enable),
+	.stop_out(counter_timer0_stop),
 	.irq(irq_counter_timer0)
     );
 
@@ -517,7 +525,7 @@
     wire counter_timer1_ack_o;
     wire [31:0] counter_timer1_dat_o;
 
-    counter_timer_wb #(
+    counter_timer_high_wb #(
         .BASE_ADR(COUNTER_TIMER1_BASE_ADR),
         .CONFIG(COUNTER_TIMER1_CONFIG),
         .VALUE(COUNTER_TIMER1_VALUE),
@@ -526,7 +534,6 @@
         // Wishbone Interface
         .wb_clk_i(wb_clk_i),
         .wb_rst_i(wb_rst_i),
-	.strobe_in(strobe_counter_timer0),
 
         .wb_adr_i(cpu_adr_o),      
         .wb_dat_i(cpu_dat_o),
@@ -537,7 +544,13 @@
         .wb_stb_i(counter_timer1_stb_i),
         .wb_ack_o(counter_timer1_ack_o),
         .wb_dat_o(counter_timer1_dat_o),
-	.strobe_out(strobe_counter_timer1),
+
+	.enable_in(counter_timer0_enable),
+	.strobe(counter_timer_strobe),
+	.stop_in(counter_timer0_stop),
+	.is_offset(counter_timer_offset),
+	.enable_out(counter_timer1_enable),
+	.stop_out(counter_timer1_stop),
 	.irq(irq_counter_timer1)
     );