| module ibex_counter ( |
| clk_i, |
| rst_ni, |
| counter_inc_i, |
| counterh_we_i, |
| counter_we_i, |
| counter_val_i, |
| counter_val_o |
| ); |
| parameter signed [31:0] CounterWidth = 32; |
| 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; |
| wire [63:0] counter; |
| reg [CounterWidth - 1:0] counter_upd; |
| reg [63:0] counter_load; |
| reg we; |
| reg [CounterWidth - 1:0] counter_d; |
| 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 |
| counter_upd = counter[CounterWidth - 1:0] + {{CounterWidth - 1 {1'b0}}, 1'b1}; |
| 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 <= {CounterWidth {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] = {(63 >= CounterWidth ? 64 - CounterWidth : CounterWidth - 62) {1'sb0}}; |
| assign unused_counter_load = counter_load[63:CounterWidth]; |
| end |
| else begin : g_counter_full |
| assign counter = counter_q; |
| end |
| endgenerate |
| assign counter_val_o = counter; |
| endmodule |