EmbDev.net

Forum: FPGA, VHDL & Verilog Place 30-574 Poor placement for routing between an IO pin and BUFG


Author: tj anderson (Guest)
Posted on:

Rate this post
0 useful
not useful
`timescale 1ns / 1ps    
    module stopwatch(
        input clock,
        input reset,
        input increment,
        input start,
        output [6:0] seg,
        output dp,
        output [3:0] an
        );
     
        reg [3:0] reg_d0, reg_d1, reg_d2, reg_d3; //registers that will hold the individual counts
        reg [22:0] ticker;
        wire click;
         
         
        //the mod 1kHz clock to generate a tick ever 0.001 second
         
        always @ (posedge (clock) or posedge (reset))
        begin
            if(reset)
            begin
                ticker <= 0;
            end
            else 
            begin
                if (start)
                begin
                    if(ticker == (100000 - 1)) //if it reaches the desired max value reset it
                        ticker <= 0;
                    else if (increment)
                        ticker <= ticker;
                    else
                        ticker <= ticker + 1;
                end 
            end
        end
        
        //increment a second everytime rising edge of down button
        reg [3:0] inc_temp;
        always @ (posedge (increment)) 
        begin
            if (reg_d3 == 9)
                inc_temp = 0;
            else
                inc_temp = reg_d3 + 1;
        end
        
        assign click = ((ticker == (100000 - 1))?1'b1:1'b0); //click to be assigned high every 0.001 second
        
        //update data start from here
        always @ (posedge (clock) or posedge (reset))
        begin
            if(reset)
            begin
                reg_d0 <= 0;
                reg_d1 <= 0;
                reg_d2 <= 0;
                reg_d3 <= 0;
            end
            
            else
            begin
                if (increment)
                    begin
                        reg_d3 <= inc_temp;
                        reg_d0 <= reg_d0;
                        reg_d1 <= reg_d1;
                        reg_d2 <= reg_d2;    
                    end
                    else if (click) //increment at every click
                    begin
                        if(reg_d0 == 9) //xxx9 - 1th milisecond
                        begin
                            reg_d0 <= 0;
                            if (reg_d1 == 9) //xx99 - 10th milisecond
                            begin
                                reg_d1 <= 0;
                                if (reg_d2 == 9) //x999 - 100th milisecond
                                begin
                                    reg_d2 <= 0;
                                    if(reg_d3 == 9) //9999 - The second digit
                                        reg_d3 <= 0;
                                    else
                                        reg_d3 <= reg_d3 + 1;
                                end
                                else
                                    reg_d2 <= reg_d2 + 1;
                            end
                                
                            else
                                reg_d1 <= reg_d1 + 1;
                        end
                        
                        else
                            reg_d0 <= reg_d0 + 1;
                    end
                    else
                    begin
                        reg_d3 <= reg_d3;
                        reg_d0 <= reg_d0;
                        reg_d1 <= reg_d1;
                        reg_d2 <= reg_d2;
                    end
            end
            
        end
        
        
    
        //Mux for display 4 7segs LEDs
        localparam N = 18; 
        reg [N-1:0]count;
        always @ (posedge clock or posedge reset)
        begin
            if (reset)
                count <= 0;
            else
                count <= count + 1;
        end
         
        reg [6:0]sseg;
        reg [3:0]an_temp;
        reg reg_dp;
        always @ (*)
            begin
                case(count[N-1:N-2])
                    2'b00 :
                    begin
                        sseg = reg_d0;
                        an_temp = 4'b1110;
                        reg_dp = 1'b1;
                    end
                    
                    2'b01:
                    begin
                        sseg = reg_d1;
                        an_temp = 4'b1101;
                        reg_dp = 1'b0;
                    end
                    
                    2'b10:
                    begin
                        sseg = reg_d2;
                        an_temp = 4'b1011;
                        reg_dp = 1'b1;
                    end
                    
                    2'b11:
                    begin
                        sseg = reg_d3;
                        an_temp = 4'b0111;
                        reg_dp = 1'b0;
                    end
                endcase
            end
        assign an = an_temp;
         
        //update the data to display to LEDs
        reg [6:0] sseg_temp;
        always @ (*)
        begin
            case(sseg)
                4'd0 : sseg_temp = 7'b1000000;
                4'd1 : sseg_temp = 7'b1111001;
                4'd2 : sseg_temp = 7'b0100100;
                4'd3 : sseg_temp = 7'b0110000;
                4'd4 : sseg_temp = 7'b0011001;
                4'd5 : sseg_temp = 7'b0010010;
                4'd6 : sseg_temp = 7'b0000010;
                4'd7 : sseg_temp = 7'b1111000;
                4'd8 : sseg_temp = 7'b0000000;
                4'd9 : sseg_temp = 7'b0010000;
                default : sseg_temp = 7'b0111111; //dash
            endcase
        end
        assign seg = sseg_temp;
        assign dp = reg_dp;
    endmodule

I'm trying to design a stop watch, but i'm stuck at the increment thing. 
The intend is when I press `increment`(a button) the `reg_d3` will 
increment by one and hold it state until the button is release. I'm able 
to make the clock stop when the button is pressed, but I can't update 
the `reg_d3`. I always receive `[Place 30-574] Poor placement for 
routing between an IO pin and BUFG`. I don't know why, I use increment 
in the clkdivider just find. Please help me. Thanks

: Edited by Moderator
Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
The problem is this here:
> when I press `increment`(a button)
>  always @ (posedge (increment))

This is VERY BAD design practise due to a bunch of reasons:
1. every mechanical switch bounces, so you will get
   some undefined clock pulses every keypress

2. you add an asynchronous clock domain to your design

3. every asynchronous signal (e.g. switch, sensor...)
   must be synchronized to your systems clock

4. you use a non dedicated pin for a clock signal

BTW: number 4 is the tiniest problem in your design, although it is the 
reason for you error message...

My major hints for your designs are:
A. use only one clock throughout the whole design
B. every external signal must be synchronized to that clock with 2 
flipflops

tj anderson wrote:
> I'm trying to design a stop watch
So, not just copy a code from a place even your teacher knows very 
well 
(http://simplefpga.blogspot.de/2012/07/to-code-stop...), 
but at least try to understand, what happens there. And then find the 
right place to dig a hole for your buttons (after adding a sync stage 
and an edge detection to them)...

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.