Electronic – How to have an edged triggered reset signal in a sequential verilog circuit

verilog

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?

Best Answer

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