1
\$\begingroup\$

I'm coding for a stopwatch which displays 10ths of a second on the rightmost two displays and seconds on the left two displays. The synthesis completes properly but after I make the UCF file and try to implement the design the following two warnings occur.

WARNING:CLK Net: check

WARNING:CLK Net: carry

I tried ignoring the warnings and went to generate the programming file but this warning came up and nothing happened on the FPGA kit and all the displays had 8 on them.

WARNING:PhysDesignRules:372 - Gated clock. Clock net check is sourced by a combinatorial pin. This is not good design practice. Use the CE pin to control the loading of data into the flip-flop.

I have no idea what any of these warnings even mean and I tried searching for them online but I found nothing from which I could understand my problem. I figured that there is something wrong with the check and carry variables but I'm having no luck fixing the problem as it seems all fine to me logic wise. And also I'm having a hard time being trying to figure out how to start and pause the stopwatch. Here's my code:

module stopwatch(clk,rst,a,b,c,d,e,f,g,dot,an);

input clk,rst;
output a,b,c,d,e,f,g,dot;
output [3:0] an;

reg [22:0] count_time;
reg [3:0] first,second,third,fourth;
reg check;
reg carry;

//counting 1 second and producing a tick at every 1 second

always @ (posedge clk or posedge rst)
begin
    if(rst)
      begin
      count_time <=0;
      check<=0;
      end
    else
      begin
      count_time<=count_time+1;
        if(&count_time==1)
         check<=1;
        else
         check<=0;
      end
end

//counting on last two SSDs

always @ (posedge check or posedge rst)
begin
    if (rst)
      begin
      third<=0;
      fourth<=0;
      end
    else if(fourth==9)
      begin
        if(third==1)
         begin
         third<=0;
         fourth<=0;
         carry<=1;
         end
        else
         begin
         third<=third+1;
         fourth<=0;
         carry<=0;
         end
      end
    else
      fourth<=fourth+1;
end

//counting one First two SSDs

always @ (posedge carry or posedge rst)
begin
   if (rst)
     begin
     first<=0;
     second<=0;
     end
   else if(second==9)
     begin
       if(first==9)
         begin
         first<=0;
         second<=0;
         end
       else
         begin
         first<=first+1;
         second<=0;
         end
     end
   else
     second<=second+1;
end

//multiplexing of 4 SSDs using the 'an' bits

parameter X = 18; //we will use the top 2 bits (since 4 SSDs) for multiplexing and the lower X-2 bits for frequency control
reg [X-1:0] counter;

always @ (posedge clk or posedge rst) //counter to produce multiplexing
begin
 if(rst)
   counter<=0;
 else
   counter<=counter+1;
end 

reg [3:0] an_temp;
reg [6:0] out;

always @ *
begin
case(counter[X-1:X-2])

   2'b00:
    begin
     out = fourth;
     an_temp = 4'b1110;
    end

   2'b01:
    begin
     out = third;
     an_temp = 4'b1101;
    end

   2'b10:
    begin
     out = second; //dont care
     an_temp = 4'b1011;
    end

   2'b11:
    begin
     out = first; //dont care
     an_temp = 4'b0111;
    end

endcase
end

assign an = an_temp;

//sending digits to SSDs for each muliplexing interval

reg [6:0] temp;
always @ *
begin
case(out)
   4'd0 : temp = 7'b0000001; 
   4'd1 : temp = 7'b1001111; 
    4'd2 : temp = 7'b0010010; 
   4'd3 : temp = 7'b0000110; 
   4'd4 : temp = 7'b1001100; 
   4'd5 : temp = 7'b0100100; 
   4'd6 : temp = 7'b0100000; 
   4'd7 : temp = 7'b0001111; 
   4'd8 : temp = 7'b0000000; 
   4'd9 : temp = 7'b0000100; 
   default : temp = 7'b1001000; // H
  endcase
end 

assign {a,b,c,d,e,f,g} = temp;
assign dot = 1'b1; //dots are off

endmodule
\$\endgroup\$
  • 1
    \$\begingroup\$ You use some combinatorial signals as clocks (check a RTL scheme generated by your tool). You should not do that. \$\endgroup\$ – Qiu Dec 9 '14 at 19:49
  • \$\begingroup\$ Where is the clk signal to the stopwatch module sourced from? \$\endgroup\$ – duskwuff Dec 9 '14 at 20:00
  • \$\begingroup\$ You may find this answer relevant; some background on FPGA global clock signals: electronics.stackexchange.com/questions/140232/… \$\endgroup\$ – MarkU Dec 10 '14 at 1:45
  • \$\begingroup\$ @duskwuff I've assigned it to pin B8 .. and it is CCLK instead of JTAG if thats what you're asking \$\endgroup\$ – Hameem Dec 10 '14 at 3:27
0
\$\begingroup\$

Firstly I'm assuming the signal clk is a nice clean clock signal driven from outside the FPGA, maybe by crystal oscillator, LVDS clock source or similar, preferably on a dedicated clock pin?

Your code creates a roll-over counter stored in count_time that overflows to zero after 22-bits, where cycle with all-1's sets signal check high for one cycle. So far all fine.

always @ (posedge clk or posedge rst) begin
    if (rst) begin
      count_time <=0;
      check <=0;
    end else begin
      count_time <= count_time+1;
      check      <= &count_time;
    end
end

The problem is how you use the signal check. You have added it to the sensitivity list of the process //counting on last two SSDs. Since this signal is the output from a flip flop, rather than a nice clean external clock signal, the tools are warning you. This arrangement (logic from one stage feeding the CLOCK of a subsequent register) is called a "gated clock". It is popular in ASIC design but not good synchronous design practice for targeting FPGAs.

The way to solve this is to re-write your code so that all processes are sensitive only to the clk and rst signals. The signal check will be promoted to become the CLOCK ENABLE input for all the logic within the process, I'll do one to get you started:

//counting on last two SSDs

always @ (posedge clk or posedge rst) begin
    if (rst) begin
      third <= 0;
      fourth <= 0;
    end else if (check) begin
        if (fourth==9) begin
           fourth<=0;
           if (third==1) begin
              third <= 0;
              carry <= 1;
           end else begin
              third <= third + 1;
              carry <= 0;
           end
        end else begin
          fourth <= fourth+1;
        end
    end
end

This probably isn't why the design doesn't work, but it should clear up those warnings and put you on the right path. It would be advisable to get this running in a simulator like Icarus Verilog to see if the design has any fundamental problems.

You also should:

  • register the output of a,b,c,d,e,f,g,dot and anodes an so they reveal to the outside world on a common clock edge, rather than after arbitary logic/routing delays. The reg will be absorved into the pin I/O pads so don't worry about 'extra' logic usage, you'll have it anyway

  • Depending on what the source (clk) clock rate is, you might want to massively reduce the base frequency of the multiplexed outputs (using enables again) - it won't work effectively if the active time for each display is just hundreds of nanoseconds before switching. To get flicker free visual aliasing aim for a redraw of about 25-50Hz on each digit, so with four displays you want to switch the output at 200-500hz. I would add many more bits to counter and use the upper bits to drive the multiplexer.

\$\endgroup\$
  • \$\begingroup\$ Thanks a lot, that was a great answer. Solved my problem and also that multiplexing frequency change you suggested also solves a small problem I have been having. But the only thing I don't understand is that if this logic of driving the next input with a signal from a previous output is not used in FPGAs, then how do we implement frequency dividers using flip flips? I mean I have done it so I don't understand how that worked and this wont. \$\endgroup\$ – Hameem Dec 13 '14 at 2:15
  • \$\begingroup\$ These design recommendations are more crucial as you push the chips towards their highest operating (clock) rates. There is a specific low skew but global routing network for clocks, and another for routing data signals over short/medium/long distances point-to-point. Crossing between the two networks adds extra routing delay over to the injection points. Working at 250-400Mhz this is the difference between passing timing and missing it by a mile. As a beginner if you skip simulation and timing checks and still get a working circuit congrats, as professionals we cant leave timing to chance! \$\endgroup\$ – shuckc Dec 13 '14 at 14:25
  • \$\begingroup\$ Indeed it's very common to need a slow clock from a fast one (or visa-versa) or to adjust the phase or duty relationship from one clock to another. For this reason FPGAs include one (or more) digital clock management blocks than do all this (and more). There physical position is near the injection points of the H-tree clock network. If you have these blocks, there's just no need to use inferior flip-flop derived clock networks. Often the timing constraints for derived clocks will be auto generated. \$\endgroup\$ – shuckc Dec 13 '14 at 16:31
  • \$\begingroup\$ It would seem to me that using gated clocks, in cases where one can guarantee that a downstream register's active clock edge won't occur anywhere near the upstream one, should be a safe and effective means of saving current (even if a clock edge doesn't cause any registers to actually change state, distributing the clock everywhere must surely increase the current wasted in parasitic capacitance). Is the reason such techniques don't seem to be used much a consequence of poor development-tool support or what? \$\endgroup\$ – supercat Dec 13 '14 at 19:39
  • \$\begingroup\$ Sure, to save power you can drive the enable pin of the DCM core - see e.g. ena on the Altera altclkctrl block This way you power down the clock output completely. With a flip-flop gated clock, the output would still have to hit an injection point on the clock network, which would presumably still have the drivers powered up. \$\endgroup\$ – shuckc Dec 14 '14 at 10:08

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.