2
\$\begingroup\$

I am wondering how it is possible to build a sequential verilog circuit with a reset trigger. The problem I am having is that I need an always block specifically for when the reset is triggered. I have created this example of a counter to demonstrate what I mean:

`timescale 1ns / 1ps
module Counter(input CLK, reset, output reg[2:0] val);
 always@(posedge CLK)
 val = val+1;
 always@(negedge reset)
 val = 0;
endmodule

The bug I get when synthesizing this is

"ERROR:Xst:528 - Multi-source in Unit <Counter> on signal <Mcount_val_cy<0>>; this signal is connected to multiple drivers.
Drivers are: 
 Output signal of FD instance <val_0>
 Signal <val<0>> in Unit <Counter> is assigned to GND" 

This is because val is updated in 2 always statements.

How can I work around this and have a sequential circuit with a reset trigger?

Dave Tweed
184k17 gold badges248 silver badges431 bronze badges
asked Apr 18, 2018 at 0:42
\$\endgroup\$
2
  • \$\begingroup\$ Keep in mind that Verilog is a hardware description language. What kind of hardware do you imagine could do what you're trying to do here? \$\endgroup\$ Commented Apr 18, 2018 at 1:06
  • 1
    \$\begingroup\$ I doubt whether edge triggering clock and edge triggered reset together be implemented correctly in FPGAs \$\endgroup\$ Commented Apr 18, 2018 at 3:06

2 Answers 2

2
\$\begingroup\$

One way to do this is to combine the always blocks, like this:

module Counter(input CLK, reset, output reg[2:0] val);
 always@(posedge CLK or negedge reset) begin
 if (!reset) begin
 val <= 0;
 end else begin
 val <= val+1;
 end
 end
endmodule

This will reset the counter whenever reset is low.

However, this may or may not be the functionality you're looking for. Generally, asynchronous resets in FPGAs are not a super great idea. An alternative is to use an edge detector, like this:

module Counter(input CLK, reset, output reg[2:0] val);
 reg reset_reg = 0;
 reg last_reset_reg = 0;
 always@(posedge CLK) begin
 reset_reg <= reset;
 last_reset <= reset_reg;
 if (!reset_reg && last_reset_reg) begin
 val <= 0;
 end else begin
 val <= val+1;
 end
 end
endmodule
answered Apr 18, 2018 at 0:52
\$\endgroup\$
2
  • \$\begingroup\$ That would work if I wanted the val to be 0 whenever reset is low, but I want it to set val = 0 only on the negative edge of reset. This means that even if reset is at 0 it can keep counting. \$\endgroup\$ Commented Apr 18, 2018 at 0:59
  • \$\begingroup\$ This absolutely has to be asynchronous? \$\endgroup\$ Commented Apr 18, 2018 at 1:05
2
\$\begingroup\$

The most straightforward way to do this would be to synchronize the reset signal into the counter's clock domain and then do the edge detection on it. Here's an actual snippet from a project I'm currently working on. I'm using a fixed local clock to measure the period of an incoming data signal.

 /* This logic is in the "fast local clock" domain.
 * The local clock is assumed to be faster than the RF signal itself, by
 * a factor of at least two. We resynchronize bit_pulse to the FLC domain
 * and count the number of cycles between the rising edges of those pulses.
 *
 * The bit_period is stable by the time the logic in the rf_in domain
 * looks at it based on a delayed version of the original bit_pulse.
 */
 always @(posedge clock) begin
 flc_pulse_a <= bit_pulse;
 flc_pulse_b <= flc_pulse_a;
 flc_pulse_c <= flc_pulse_b;
 if (sim_reset || (flc_pulse_b && !flc_pulse_c)) begin
 bit_period <= bit_count;
 bit_count <= 0;
 end else begin
 bit_count <= bit_count + 1;
 end
 end

Note that it IS possible to do what you want with a complex asynchronous state machine, but FPGAs do not generally have the resources to implement such things efficiently, and the tools are not set up to support such designs.

Plus, you need to think about boundary cases: If the two events (posedge clock and negedge reset_l) are truly asynchronous, that means they can occur arbitrarily close together. What behavior do you expect when that happens?

answered Apr 18, 2018 at 1:21
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.