1
\$\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?

\$\endgroup\$
  • \$\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\$ – Dave Tweed Apr 18 '18 at 1:06
  • 1
    \$\begingroup\$ I doubt whether edge triggering clock and edge triggered reset together be implemented correctly in FPGAs \$\endgroup\$ – Meenie Leis Apr 18 '18 at 3:06
1
\$\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
\$\endgroup\$
  • \$\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\$ – Tyler H Apr 18 '18 at 0:59
  • \$\begingroup\$ This absolutely has to be asynchronous? \$\endgroup\$ – alex.forencich Apr 18 '18 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?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.