1
\$\begingroup\$

I am just getting started with verilog and I wanted to try to create a module which calculates whether a point in the Mandelbrot set diverges or not. I am planing on using the Xilinx IP for 32 bit floating point math. Bellow is the code I have so far which is far from complete.

What I want to do is when the enable wire is flipped from false to true I want to reset the state of all of my registers so the calculation can begin on the next clock cycle. I was wondering if this is a good practice or not. I was thinking the issue may be that when enable changes to true, but the always @(posedge clk && enable == 1) begin executes before the initialization is done. Is there a better way to go about this? Maybe I should have an internal enable register which is changed when the enable wire is triggered.

Also I am just wondering if the EE stack exchange is the best place for verilog questions? I have been posting on stack overflow but these questions tend to not get much attention.

module mandelbrot(
    input [31:0] x,
    input [31:0] y,
    input clk,
    input enable,

    output reg [7:0] count,
    output done);

    reg [61:0] z;
    reg [61:0] zsq;
    reg [1:0] state;
    parameter SQUARING = 0;
    parameter COMPARING = 1;
    parameter ADDING = 2;

    reg valid_sq;
    reg done_sq;
    reg in_sq;

    reg valid_add;
    reg done_add;
    reg in_add;

    reg valid_lt;
    reg done_lt;
    reg in_lt;

    always @(posedge enable) begin
        z = {x, y};
        valid_sq <= 0;
        done_sq <= 0;
        in_sq <= 0;
        valid_add <= 0;
        done_add <= 0;
        in_add <= 0;
        valid_lt <= 0;
        done_lt <= 0;
        in_lt <= 0;
    end

    always @(posedge clk && enable == 1) begin
        case(state)
            SQUARING:

            COMPARING:
                state <= ADDING;
            ADDING:
                state <= SQUARING;
        endcase
    end

endmodule
\$\endgroup\$
4
\$\begingroup\$
always @(posedge clk && enable == 1) begin

That's not the way to do it. I'm not even sure it's a valid syntax. Furthermore, you can only control a reg or integer type variable from a single always block, so having the first always block that is sensitive to enable means you couldn't control any of those signals in any other always block.

What you are looking for depends on what the logic connects to. For example if you want to do calculations while enable is high, but then don't use the values when it is low, then you can simply use the enable signal as a negative reset. If this is the case then really the signal should be called just that, "reset" not "enable".

always @ (posedge clock) begin
    if (~enable) begin
        //Reset the values ready for next time
    end else begin
        //Do stuff when enabled

    end
end

This may not be what you want. For example if you need the registers to hold their value when the enable signal is low, and then clear them just before a calculation. This can be done too, but only if you don't mind it taking one clock cycle. This approach can be accomplished using a synchronous reset and an edge detection circuit.

reg enableDelay;
always @ (posedge clock) begin
    enableDelay <= enable; //Keep track of the previous value
end

wire enableRising = enable && !enableDelay; //enableRising will be high for a single clock cycle at the rising edge of enable

always @ (posedge clock) begin
    if (enableRising) begin
         //Clear stuff on rising edge of enable
         data <= 1'b1; //Maybe we set the register 'data' to 1 or whatever
    end else if (enableDelay) begin
         //While the delayed enable signal is high, do stuff.
         data <= something;
    end
end

The code above will produce the following output:

Waveform

  1. There is a rising edge of the enable signal. Notice how the enableRising signal also goes high at the same time.
  2. The enableDelay signal goes high as it is always one clock cycle delayed from the enable signal. At the same moment, the second always block detects that the enableRising signal is high and performs the "reset" operation. This is indicated by the data signal going high.
  3. On the third clock cycle, enableRising is now low again, so the data signal is set to whatever calculation you do in the else part of that block. It will keep executing the else part each clock cycle until the enableDelay signal goes low again.

Basically the block will clear on the rising edge, and then do n calculations (where n is the number of clock cycles that the enable signal was high).


The trouble with your question is a classic X-Y problem. You are describing Y when really you should be telling us X. Y is what you think is the way to do something, X is what you actually are trying to do. Please clarify in your question.

Directly answering the title of the question: "It depends". Some signals you might want to clear - maybe a counter needs resetting to zero, or something. There may be others which don't matter - say the output of a calculation that doesn't affect the input.

Tasks that require doing a sequence of events are best organising into a state machine, such that when some trigger occurs (e.g. rising edge of a signal), your state machine starts running through each state. Once the task is complete, it then returns to an idle state waiting for another trigger. This way you don't need to reset stuff on the trigger as the state machine if designed correctly would leave all the signals it controls in a default state when it returns to idle.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks. That makes sense. Like I said I am new to verilog. And to just clarify, in your second always, it is ok to use enableDelay so long as you don't set it since that is the job of the first always right? \$\endgroup\$ – chasep255 Dec 16 '15 at 1:31
  • \$\begingroup\$ @chasep255 the enableDelay signal is configured to always be the value of enable from the previous clock cycle. It instantiates enableDelay as a D-type flip-flop which updates on every rising clock edge. \$\endgroup\$ – Tom Carpenter Dec 16 '15 at 1:52
2
\$\begingroup\$

You're describing a RESET behavior, not an ENABLE behavior.

The usual way to code a flip flop with asyncronous reset and enable inputs is

reg Q
always @(posedge clk or posedge reset) begin
if reset begin
   Q <= 0
end
else if enable begin
   Q <= <whatever Q gets>
end

You should have all your code that sets any particular register in the same always block. Your code as two always blocks, one to respond to the "enable" signal and one to respond to the clock signal. It is not clear what this will produce in synthesis or if it can be synthesized at all.

Also, you must consider that the flip-flops in the Xilinx device have certain capabilities such as asyncronous reset and enable. If you try to code some behavior that they aren't capable of (such as having a single signal that first resets them and then allows them to take new values) your code will either fail to synthesize or produce unpredictable results when implemented in the actual hardware.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Your code example is missing an end. \$\endgroup\$ – pre_randomize Dec 16 '15 at 7:50

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.