Corrected the counter/timer and made an enhancement to respond to a
disable/enable sequence as a counter reset. Generated testbenches
for both counter/timers.
diff --git a/verilog/rtl/counter_timer.v b/verilog/rtl/counter_timer.v
index ccd1431..9e25281 100755
--- a/verilog/rtl/counter_timer.v
+++ b/verilog/rtl/counter_timer.v
@@ -1,7 +1,7 @@
/* Simple 32-bit counter-timer for Caravel. */
module counter_timer_wb # (
- parameter BASE_ADR = 32'h2200_0000,
+ parameter BASE_ADR = 32'h2400_0000,
parameter CONFIG = 8'h00,
parameter VALUE = 8'h04,
parameter DATA = 8'h08
@@ -85,6 +85,7 @@
reg 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
@@ -96,10 +97,12 @@
always @(posedge clkin or negedge resetn) begin
if (resetn == 1'b0) begin
enable <= 1'b0;
+ lastenable <= 1'b0;
oneshot <= 1'b0;
updown <= 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];
@@ -117,10 +120,10 @@
if (resetn == 1'b0) begin
value_reset <= 32'd0;
end else begin
- if (reg_val_we[3]) value_reset <= reg_val_di[31:24];
- if (reg_val_we[2]) value_reset <= reg_val_di[23:16];
- if (reg_val_we[1]) value_reset <= reg_val_di[15:8];
- if (reg_val_we[0]) value_reset <= reg_val_di[7:0];
+ 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
@@ -140,7 +143,9 @@
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 (value_cur == value_reset) 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
@@ -150,7 +155,9 @@
irq_out <= 1'b0;
end
end else begin
- if (value_cur == 32'd0) 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
diff --git a/verilog/rtl/housekeeping_spi.v b/verilog/rtl/housekeeping_spi.v
index c6a4860..8ae1b81 100644
--- a/verilog/rtl/housekeeping_spi.v
+++ b/verilog/rtl/housekeeping_spi.v
@@ -118,15 +118,16 @@
wire pass_thru_user_delay;
wire loc_sdo;
- // Pass-through mode handling
+ // Pass-through mode handling. Signals may only be applied when the
+ // core processor is in reset.
- assign pass_thru_mgmt_csb = ~pass_thru_mgmt_delay;
- assign pass_thru_mgmt_sck = pass_thru_mgmt ? SCK : 1'b0;
- assign pass_thru_mgmt_sdi = pass_thru_mgmt ? SDI : 1'b0;
+ assign pass_thru_mgmt_csb = reset ? ~pass_thru_mgmt_delay : 1'bz;
+ assign pass_thru_mgmt_sck = reset ? (pass_thru_mgmt ? SCK : 1'b0) : 1'bz;
+ assign pass_thru_mgmt_sdi = reset ? (pass_thru_mgmt ? SDI : 1'b0) : 1'bz;
- assign pass_thru_user_csb = ~pass_thru_user_delay;
- assign pass_thru_user_sck = pass_thru_user ? SCK : 1'b0;
- assign pass_thru_user_sdi = pass_thru_user ? SDI : 1'b0;
+ assign pass_thru_user_csb = reset ? ~pass_thru_user_delay : 1'bz;
+ assign pass_thru_user_sck = reset ? (pass_thru_user ? SCK : 1'b0) : 1'bz;
+ assign pass_thru_user_sdi = reset ? (pass_thru_user ? SDI : 1'b0) : 1'bz;
assign SDO = pass_thru_mgmt ? pass_thru_mgmt_sdo :
pass_thru_user ? pass_thru_user_sdo : loc_sdo;
diff --git a/verilog/rtl/mgmt_soc.v b/verilog/rtl/mgmt_soc.v
index f6cf0f6..e5375ff 100644
--- a/verilog/rtl/mgmt_soc.v
+++ b/verilog/rtl/mgmt_soc.v
@@ -153,14 +153,14 @@
parameter FLASH_BASE_ADR = 32'h 1000_0000;
parameter UART_BASE_ADR = 32'h 2000_0000;
parameter GPIO_BASE_ADR = 32'h 2100_0000;
- parameter COUNTER_TIMER0_BASE_ADR = 32'h 2110_0000;
- parameter COUNTER_TIMER1_BASE_ADR = 32'h 2120_0000;
- parameter SPI_MASTER_BASE_ADR = 32'h 2130_0000;
- parameter LA_BASE_ADR = 32'h 2200_0000;
- parameter MPRJ_CTRL_ADR = 32'h 2300_0000;
- parameter MPRJ_BASE_ADR = 32'h 3000_0000; // WB MI A
- parameter SYS_BASE_ADR = 32'h 2F00_0000;
+ parameter COUNTER_TIMER0_BASE_ADR = 32'h 2200_0000;
+ parameter COUNTER_TIMER1_BASE_ADR = 32'h 2300_0000;
+ parameter SPI_MASTER_BASE_ADR = 32'h 2400_0000;
+ parameter LA_BASE_ADR = 32'h 2500_0000;
+ parameter MPRJ_CTRL_ADR = 32'h 2600_0000;
parameter FLASH_CTRL_CFG = 32'h 2D00_0000;
+ parameter SYS_BASE_ADR = 32'h 2F00_0000;
+ parameter MPRJ_BASE_ADR = 32'h 3000_0000; // WB MI A
parameter XBAR_BASE_ADR = 32'h 8000_0000;
// UART