I want to make a counter which can start counting at posedge of a specific signal. And once it counts to 256, stop counting, set the counter to 0 and output something.
I wrote the following code, but apparently it'll cause a "multiple driver" error.
But I can't think of another way. Can someone provide an idea?
always@(posedge a_specific_signal)
begin
counter_switch <= 1;
end
always@(posedge clk)
begin
if (counter_switch == 1)
counter <= counter + 1;
if (counter == 256)
begin
counter <= 0;
counter_switch <= 0;
something <= 1;
end
end
You can't change the value of counter_switch
in two different always
statements. You need to do that within the same always
block.
I'd do something like this: (didn't test the code could contain bugs)
input clock, reset;
reg counter_switch, ready;
reg [7:0] counter;
always@(posedge clock) begin
if (reset) begin
counter_switch <= 0;
end else begin
if (a_specific_signal) begin
counter_switch <= 1;
end else if (ready) begin
counter_switch <= 0;
end
end
end
always@(posedge clock) begin
if (reset) begin
ready <= 0;
counter <= 0;
end else begin
if (counter_switch) begin
if (counter == 255) begin
counter <= 0;
ready <= 1;
end else begin
counter <= counter + 1;
end
end else begin
ready <= 0;
end
end
end
Here is your counter, for 0 to 256
count.
module counter (clk, reset, op);
input logic clk, reset;
output logic [16:0] op;
logic [16:0] current_cnt, next_cnt;
assign next_cnt = (current_cnt[16]) ? 17'd0 : (current_cnt + 17'd1);
assign op = current_cnt;
always @ (posedge clk, negedge reset)
begin
if (~reset)
current_cnt <= 17'd0;
else
current_cnt <= next_cnt;
end
endmodule
So whenever you reach to 256, then your 17th bit of current_cnt will be 1, which means that your next_cnt should be 0. In all other cases, your next count should be +1.
The "multiple driver" error arises from trying to modify a signal from different processes / always blocks. You shouldn't do this.
I'm used to working with fully synchronic systems, so I should ask you what "a_specific_signal" is like, and what the relationship to your main clock is.
Hence my approach would be: 1. synchronizing "a_specific_signal" to my current clock, 2. detecting its positive edges, 3. using this as a drive for a flag for my counter
reg a_spec_signal_reg0 = 1'b0, a_spec_signal_reg1 = 1'b0, a_spec_signal_reg2 = 1'b0;
always @(posedge clk) begin --synchronizer with 3 FFs
a_spec_signal_reg0 <= a_specific_signal;
a_spec_signal_reg1 <= a_spec_signal_reg0;
a_spec_signal_reg2 <= a_spec_signal_reg1;
end
wire a_spec_signal_posedge;
assign a_spec_signal_posedge = a_spec_signal_reg1 & ~(a_spec_signal_reg2);
reg counter_switch = 1'b0;
always @(posedge clk) begin
something <= 1'b0;
if (a_spec_signal_posedge)
counter_switch <= 1'b1;
if (counter_switch) begin
counter <= counter + 1;
if (counter == 255) begin
counter <= 0;
counter_switch <= 0;
something <= 1'b1;
end
end
end
A few notes: I assumed you wanted to count 256 events, so that means using a counter from 0 to 255 (8 bits). And also the something signal is set as 0 in its default state, so when the condition "counter == 255" arrives, it outputs a tick for just a clock cycle, which is what's usually used.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.