blob: 159d73531558d8dfd9f7faa2a083b6644d8a365e [file] [log] [blame]
module ibex_counter (
clk_i,
rst_ni,
counter_inc_i,
counterh_we_i,
counter_we_i,
counter_val_i,
counter_val_o,
counter_val_upd_o
);
parameter signed [31:0] CounterWidth = 32;
parameter [0:0] ProvideValUpd = 0;
input wire clk_i;
input wire rst_ni;
input wire counter_inc_i;
input wire counterh_we_i;
input wire counter_we_i;
input wire [31:0] counter_val_i;
output wire [63:0] counter_val_o;
output wire [63:0] counter_val_upd_o;
wire [63:0] counter;
wire [CounterWidth - 1:0] counter_upd;
reg [63:0] counter_load;
reg we;
reg [CounterWidth - 1:0] counter_d;
assign counter_upd = counter[CounterWidth - 1:0] + {{CounterWidth - 1 {1'b0}}, 1'b1};
always @(*) begin
we = counter_we_i | counterh_we_i;
counter_load[63:32] = counter[63:32];
counter_load[31:0] = counter_val_i;
if (counterh_we_i) begin
counter_load[63:32] = counter_val_i;
counter_load[31:0] = counter[31:0];
end
if (we)
counter_d = counter_load[CounterWidth - 1:0];
else if (counter_inc_i)
counter_d = counter_upd[CounterWidth - 1:0];
else
counter_d = counter[CounterWidth - 1:0];
end
reg [CounterWidth - 1:0] counter_q;
always @(posedge clk_i or negedge rst_ni)
if (!rst_ni)
counter_q <= 1'sb0;
else
counter_q <= counter_d;
generate
if (CounterWidth < 64) begin : g_counter_narrow
wire [63:CounterWidth] unused_counter_load;
assign counter[CounterWidth - 1:0] = counter_q;
assign counter[63:CounterWidth] = 1'sb0;
if (ProvideValUpd) begin : g_counter_val_upd_o
assign counter_val_upd_o[CounterWidth - 1:0] = counter_upd;
end
else begin : g_no_counter_val_upd_o
assign counter_val_upd_o[CounterWidth - 1:0] = 1'sb0;
end
assign counter_val_upd_o[63:CounterWidth] = 1'sb0;
assign unused_counter_load = counter_load[63:CounterWidth];
end
else begin : g_counter_full
assign counter = counter_q;
if (ProvideValUpd) begin : g_counter_val_upd_o
assign counter_val_upd_o = counter_upd;
end
else begin : g_no_counter_val_upd_o
assign counter_val_upd_o = 1'sb0;
end
end
endgenerate
assign counter_val_o = counter;
endmodule