I am working on a counter that counts the number of bits high in an input bit-stream of variable width. The code is as follows:
module counter(i_clk, i_arst, i_data, o_done, o_cnt);
// ---------------------------------------- SIGNALS ---------------------------------------- //
// Parameters
parameter OUT_WIDTH; // Width of the output in bits
parameter IN_WIDTH; // Number of bits in an input bit stream
// Input
input wire i_clk; // Clock
input wire i_arst; // Active high asynchronous reset
input wire i_data; // Input data
// Outputs
output reg o_done; // Output done bit
output reg[OUT_WIDTH-1:0] o_cnt; // WIDTH-bit output counter
// Internal signals
integer index; // Bit index for the input
reg[OUT_WIDTH-1:0] r_cnt_tmp; // Temporary counter for assignment
// ---------------------------------------- LOGIC ---------------------------------------- //
// Combinational logic
always @(*) begin
o_cnt = r_cnt_tmp;
end
// Sequential logic
always @(posedge i_clk or posedge i_arst) begin
// Reset the counter
if(i_arst) begin
r_cnt_tmp <= {OUT_WIDTH{1'b0}};
o_done <= 1'b0;
index <= 0;
end
else begin
// When a new bit stream arrives
if(index == 0) begin
r_cnt_tmp <= {OUT_WIDTH{1'b0}}; // Reset the output data
o_done <= 1'b0; // Data is now invalid because it is a new bit stream
// It only happens after a reset or a valid data output
end
// If bit is set
if(i_data == 1'b1) begin
r_cnt_tmp <= r_cnt_tmp + 1; // Count up
end
index <= index + 1; // Increment the index
if(index == IN_WIDTH) begin // The input has been completely looped over
o_done <= 1'b1; // Data is now valid for the output
index <= 0; // Reset the index
end
end
end
endmodule
Once I am done with the current bit-stream, I set the o_done signal to inform that the output data is valid and I reset the variable index to start with a new bit-stream. Then at the next clock rising edge, I reset the o_done signal and the counter value andstart counting again.
The problem I have is that my counter does not always reset. Since the signal takes its value only at the end of the block, if the first bit of the bit-stream is high, then it is not reset.
I would like to reset and start counting again in the same clock cycle because I do not want more latency and I have continuous bit-streams arriving on the input.
Is there a solution to avoid this issue ?
Thanks for your help.
both assignments. All assignments are in the same block. This one:o_cnt = r_cnt_tmp;is redundant. If I understand what you want you 1/ need a extra copy of your bit counter to output. 2/ You need a to take into account that a bit may arrive whilst you want to restart the count. That needs a more complex if statement to cope with the extra condition of a bit arriving or not.