0
\$\begingroup\$

I want to rise a flag once I enter procedural block#1, and I want to reset it to zero in another procedural block. Of course I get an error saying the flag is driven by too many drivers. How can I overcome this problem?

Block 1, sensitive to sw (FPGA board switches):

always @ (sw)
flag =1;
begin 
case (sw)   
8'bxxxxxx01: x2= 13'd1249;
8'bxxxxxx10: x2= 13'd2499;
8'bxxxxxx11: x2= 13'd3749;

endcase

end

Block 2, sensitive to CLK:

always @ (posedge CLK)

        begin

        if (counter2 == x2)
        begin
        counter2 <=0;
        flag=0;
        end

        else
        counter2 <= counter2 +1;

        end

Assuming all initialization are taken care of.

\$\endgroup\$
1

3 Answers 3

1
\$\begingroup\$

Obviously, you need to pass a signal from one process to the other (either direction) so that all updates to flag can occur in one process.

But what would be wrong with sampling the switches inside the clocked process? Is the clock so slow that it would miss changes on the switch inputs? I would write something like this:

reg [7:0] sw_prev;

always @ (posedge CLK)
begin

  /* Note that flag will be overridden if counter overflows on the
   * same clock cycle that the switches change. To avoid that, put
   * these two statements inside the 'else' clause below.
   */
  sw_prev <= sw;
  if (sw != sw_prev) flag <= 1;

  case (sw)   
  8'bxxxxxx01: x2 <= 13'd1249;
  8'bxxxxxx10: x2 <= 13'd2499;
  8'bxxxxxx11: x2 <= 13'd3749;
  endcase

  if (counter2 == x2) begin
    counter2 <= 0;
    flag <= 0;
  end else begin
    counter2 <= counter2 + 1;
  end
end

Always keep in mind that Verilog is a hardware description language, not a sequential programming language. What hardware do you imagine could be used to implement flag as you've written it? When dealing with asynchronous parts of your design, you need to think at a very low level, and then write code that more or less explicitly spells out that logic.

\$\endgroup\$
5
  • \$\begingroup\$ The clock is not slow, I need to rise the flag once sw is altered (block1)and reset it once counting is done (block2), and this is why I need the two blocks but I am unable to let them communicate. Thanks for the advice will keep that in mind. \$\endgroup\$
    – HaneenSu
    Oct 11, 2015 at 11:37
  • \$\begingroup\$ What do you mean, "I am unable to let them communicate"? Why not? \$\endgroup\$
    – Dave Tweed
    Oct 11, 2015 at 11:50
  • \$\begingroup\$ Sorry I meant I can't control the "same flag" using the two always blocks due to the reasons mentioned in the answers I got. HDL is new to me and I am trying to orient my previous programming experience. \$\endgroup\$
    – HaneenSu
    Oct 11, 2015 at 11:57
  • \$\begingroup\$ ♦ I think the I was messing up the whole code because I was missing the simple concept behind this line of code: sw_prev <= sw; So basically here we are capturing the value of the switches at the positive edge and comparing it with the continuously changing input (sw) right? \$\endgroup\$
    – HaneenSu
    Oct 12, 2015 at 4:57
  • \$\begingroup\$ Yes. Since the whole thing is inside a clocked process, those two statements constitute a discrete-time edge detector, rather than the continuous-time edge detection implied by always @(sw) ... -- which is not synthesizable anyway. \$\endgroup\$
    – Dave Tweed
    Oct 12, 2015 at 11:32
1
\$\begingroup\$
always @ (sw) ...

This is combinational logic, which means if you set flag=1 in here, it will always be 1. It is essentially no different from doing assign flag = 1;.

Why? because sw will always be, doesn't matter what it is, it will always be something, so always @ (sw) will always be done - it is not a clocked process.


Registers and wires should be driven from only one source, never more than one (i.e. you can't drive a signal from two always blocks).

Now what you could do is the following:

reg [7:0] sw_delay;
wire sw_edge;

always @ (posedge CLK) begin
   sw_delay <= sw;
end

assign sw_edge = |(sw_delay ^ sw); //If any edge on any switch is detected

always @ (posedge CLK) begin
    if (sw_edge) begin
        //Do something in the clock cycle when an edge is detected
    end else begin
        //Otherwise do something else
    end
end

Rather than just asking a question of how do I make Y work to do X, you should also give information on what X is and they we can help advise if Y is really the way to go.

\$\endgroup\$
0
\$\begingroup\$

You are asking the software to solve an ambiguous problem, right now flag is trying to act as some kind of shared bus (most likely, depends on the synthesis toolchain)

I am not sure what type flag is, but it seems you want it to act as a global variable. In that case, it needs memory assigned to it, and you might be better off defining it as a flip-flop (synchronous) or RS latch (asynchronous "flip-flop") explicitly. Depending on the exact logic you want, the two operations may also be able to be split up as inputs to a "logic gate"/ logical operator. Please rethink the logic carefully, then choose the most appropriate solution.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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