实施后如何调试?我的代码在仿真中能很好地工作,显示出硬件中的异常行为 [英] How to debug after implementation? My code that works perfectly in simulation shows strange behaviour in hardware

查看:77
本文介绍了实施后如何调试?我的代码在仿真中能很好地工作,显示出硬件中的异常行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的反应测试仪代码可以完美运行,并且可以在仿真中正常运行.但是,当我将其移至FPGA器件时,只要按一下启动按钮,它就会停顿,而且由于在仿真中可以正常工作,所以我无法弄清楚出了什么问题.

概念是,当按下复位键时,在屏幕上显示Hi,当按下start时,从LFSR中选择一个随机值并计数到最大值,从而使其成为随机延迟.当达到此寄存器的最大计数时,打开LED,启动计时器并等待按下stop按钮.

这是在仿真中工作的代码的屏幕截图:

在这里0000是正常的,因为注意行情自动收录器开始递增,并且当其达到所需值时,它会递增计时器,使其变为0001,因此,如果我向前滚动足够,它将显示正确的操作.

这是注释的代码,我添加了(* KEEP = "TRUE" *)reg [1:0] sel;,因为在优化过程中,已删除sel信号,因为它已声明但从未被调用,但显然我需要它.

  reg [12:0] random, random_next, random_done; //**13 bit for simulation purposes

reg [4:0] count_r, count_next_r; //to keep track of the shifts. 5 bit register to count up to 30


wire feedback = random[12] ^ random[3] ^ random[2] ^ random[0]; //**for simulation

always @ (posedge clock or posedge reset)
begin
    if (reset)
    begin
        random <= 13'hF; //**An LFSR cannot have an all 0 state, thus reset to FF
        count_r <= 0;
    end

    else
    begin
        random <= random_next;
        count_r <= count_next_r;
    end
end

always @ (*)
begin
    random_next = random; //default state stays the same
    count_next_r = count_r;

        random_next = {random[11:0], feedback}; //**shift left the xor'd every posedge clock
        count_next_r = count_r + 1;

    if (count_r == 13) //**for implementation its 30, simulation its 13
    begin
        count_next_r = 0;
        random_done = random; //assign the random number to output after 13 shifts
    end

end
//random number block ends

reg outled;

reg [3:0] reg_d0, reg_d1, reg_d2, reg_d3; //registers that will hold the individual counts
(* KEEP = "TRUE" *)reg [1:0] sel;
localparam [1:0]
                        idle = 2'b00,
                        starting = 2'b01,
                        time_it = 2'b10,
                        done = 2'b11;

reg [1:0] state_reg, state_next;
reg [12:0] count_reg, count_next; //**change for simulation, 30 bits for implementation, 13 bits for simulation

always @ (posedge clock or posedge reset)
begin
    if(reset)
        begin 
            state_reg <= idle;
            count_reg <= 0;
        end
    else
        begin
            state_reg <= state_next;
            count_reg <= count_next;
        end
end

reg go_start;
always @ (*)
begin
    state_next = state_reg; //default state stays the same
    count_next = count_reg;

    case(state_reg)
        idle:
            begin
                //DISPLAY HI HERE
                sel = 2'b00;
                if(start)
                begin
                    count_next = random_done; //get the random number from LFSR module
                    state_next = starting;
                end
            end
        starting:
            begin
                if(count_next == 8191) // **750M equals a delay of 15 seconds.
                begin                           //and starting from 'rand' ensures a random delay
                    outled = 1'b1; //turn on the led 
                    state_next = time_it; //go to next state
                end

                else
                    count_next = count_reg + 1; 
            end     
        time_it:
            begin
                    sel = 2'b01; //start the timer
                    state_next = done;                  
            end

        done:
            begin
                if(stop)
                    begin
                        sel = 2'b10; //stop the timer
                        outled = 1'b0;
                    end
            end

        endcase

    case(sel)
        2'b00: //hi
        begin
            go_start = 0; //make sure timer module is off
            regd0 = 4'd12; 
            regd1 = 4'd11;
            regd2 = 4'd10;
            regd3 = 4'd12;
        end

        2'b01: //timer
        begin

            go_start = 1'b1; //enable start signal to start timer
            regd0 = reg_d0;
            regd1 = reg_d1;
            regd2 = reg_d2;
            regd3 = reg_d3;
        end

        2'b10: //stop timer
        begin
            go_start = 1'b0;
        end

        default:
        begin
            regd0 = 4'bx;
            regd1 = 4'bx;
            regd2 = 4'bx;
            regd3 = 4'bx;
        end
    endcase         
end


//the stopwatch block


reg [15:0] ticker; //**16 bits needed to count up to 50K bits, 10 bit for simulation
wire click;

//the mod 50K clock to generate a tick ever 0.001 second

always @ (posedge clock or posedge reset)
begin
    if(reset)

        ticker <= 0;

    else if(ticker == 50000) //**if it reaches the desired max value of 50K reset it, 500 for simulation
        ticker <= 0;
    else if(go_start) //only start if the input is set high
        ticker <= ticker + 1;
end

assign click = ((ticker == 50000)?1'b1:1'b0); //**click to be assigned high every 0.001 second

always @ (posedge clock or posedge reset)
begin
    if (reset)
        begin
            reg_d0 <= 0;
            reg_d1 <= 0;
            reg_d2 <= 0;
            reg_d3 <= 0;
        end

    else if (click) //increment at every click
        begin
            if(reg_d0 == 9) //xxx9 - the 0.001 second digit
            begin  //if_1
                reg_d0 <= 0;

                if (reg_d1 == 9) //xx99 
                begin  // if_2
                    reg_d1 <= 0;
                    if (reg_d2 == 5) //x599 - the two digit seconds digits
                    begin //if_3
                        reg_d2 <= 0;
                        if(reg_d3 == 9) //9599 - The minute digit
                            reg_d3 <= 0;
                        else
                            reg_d3 <= reg_d3 + 1;
                    end
                    else //else_3
                        reg_d2 <= reg_d2 + 1;
                end

                else //else_2
                    reg_d1 <= reg_d1 + 1;
            end 

            else //else_1
                reg_d0 <= reg_d0 + 1;
        end
end

这是将采用regd0-regd3值的显示电路.

    localparam N = 18; //18 for implementation, 8 for simulation

reg [N-1:0]count;

always @ (posedge clock or posedge reset)
    begin
        if (reset)
            count <= 0;
        else
            count <= count + 1;
    end

reg [3:0]sseg;
reg [3:0]an_temp;
reg reg_dp;
always @ (*)
    begin
        case(count[N-1:N-2]) //MSB and MSB-1 for multiplexing

            2'b00 : 
                begin
                    sseg = first;
                    an_temp = 4'b1110;
                    reg_dp = 1'b1;
                end

            2'b01:
                begin
                    sseg = second;
                    an_temp = 4'b1101;
                    reg_dp = 1'b0;
                end

            2'b10:
                begin
                    sseg = third;
                    an_temp = 4'b1011;
                    reg_dp = 1'b1;
                end

            2'b11:
                begin
                    sseg = fourth;
                    an_temp = 4'b0111;
                    reg_dp = 1'b0;
                end
        endcase
    end
assign an_m = an_temp;

reg [6:0] sseg_temp;    
always @ (*)
    begin
        case(sseg)
            4'd0 : sseg_temp = 7'b1000000; //display 0
            4'd1 : sseg_temp = 7'b1111001; //display 1
            4'd2 : sseg_temp = 7'b0100100;// display 2
            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;
            4'd10 : sseg_temp = 7'b0001001; //to display H
            4'd11 : sseg_temp = 7'b1001111; //to display I
            default : sseg_temp = 7'b0111111; //dash
        endcase
    end
assign {g_m, f_m, e_m, d_m, c_m, b_m, a_m} = sseg_temp; 
assign dp_m = reg_dp;

endmodule

在重置时将其移至我的FPGA器件上时,将按原样显示"Hi",但是当我按start时,显示屏仅显示0000并停留在该位置. led不会同时打开,这意味着按下start按钮之后永远都不会初始化时间.我已经尝试了好几天了,似乎无法弄清楚为什么会这样.当某些东西在仿真中工作但在硬件中无法正常工作时,该怎么办?

使用固定的闩锁更新代码:

    //Block for LFSR random number generator        
reg [12:0] random, random_next, random_done; //**13 bit for simulation purposes
//reg [29:0] random, random_next, random_done; //30 bit register to keep track upto 15 seconds
reg [4:0] count_r, count_next_r; //to keep track of the shifts. 5 bit register to count up to 30

//wire feedback = random[29] ^ random[5] ^ random[3] ^ random[0]; 
wire feedback = random[12] ^ random[3] ^ random[2] ^ random[0]; //**for simulation

always @ (posedge clock or posedge reset)
begin
    if (reset)
    begin
        random <= 13'hF; //**An LFSR cannot have an all 0 state, thus reset to FF
        count_r <= 0;
    end

    else
    begin
        random <= random_next;
        count_r <= count_next_r;
    end
end

always @ (*)
begin
    random_next = random; //default state stays the same
    count_next_r = count_r;

        random_next = {random[11:0], feedback}; //**shift left the xor'd every posedge clock
        //count_next_r = count_r + 1;

    if (count_r == 13) //**for implementation its 30, simulation its 13
    begin
        count_next_r = 0;
        random_done = random; //assign the random number to output after 13 shifts
    end
    else
    begin
        count_next_r = count_r + 1;
        random_done = 13'b0;
    end

end
//random number block ends

reg outled;

reg [3:0] reg_d0, reg_d1, reg_d2, reg_d3; //registers that will hold the individual counts
/*(* KEEP = "TRUE" *)*/reg [1:0] sel, sel_next;
localparam [1:0]
                        idle = 2'b00,
                        starting = 2'b01,
                        time_it = 2'b10,
                        done = 2'b11;

reg [1:0] state_reg, state_next;
reg [12:0] count_reg, count_next; //**change for simulation, 30 bits for implementation, 13 bits for simulation

always @ (posedge clock or posedge reset)
begin
    if(reset)
        begin 
            state_reg <= idle;
            count_reg <= 0;
            sel <=0;
        end
    else
        begin
            state_reg <= state_next;
            count_reg <= count_next;
            sel <= sel_next;
        end
end

reg go_start;
always @ (*)
begin
    state_next = state_reg; //default state stays the same
    count_next = count_reg;
    sel_next = sel;
    case(state_reg)
        idle:
            begin
                //DISPLAY HI HERE
                //sel_next = 2'b00;
                if(start)
                begin
                    count_next = random_done; //get the random number from LFSR module
                    state_next = starting;
                end
            end
        starting:
            begin
                if(count_next == 8191) // **750M equals a delay of 15 seconds.
                begin                           //and starting from 'rand' ensures a random delay
                    outled = 1'b1; //turn on the led 
                    state_next = time_it; //go to next state
                end

                else
                begin
                    count_next = count_reg + 1; 
                    outled = 1'b0;
                end
            end     
        time_it:
            begin
                    sel_next = 2'b01; //start the timer
                    state_next = done;                  
            end

        done:
            begin
                if(stop)
                    begin
                        sel_next = 2'b10; //stop the timer
                        outled = 1'b0;
                    end
            end

        endcase

    case(sel_next)
        2'b00: //hi
        begin
            go_start = 0; //make sure timer module is off
            regd0 = 4'd12; 
            regd1 = 4'd11;
            regd2 = 4'd10;
            regd3 = 4'd12;
        end

        2'b01: //timer
        begin

            go_start = 1'b1; //enable start signal to start timer
            regd0 = reg_d0;
            regd1 = reg_d1;
            regd2 = reg_d2;
            regd3 = reg_d3;
        end

        2'b10: //stop timer
        begin
            go_start = 1'b0;
            regd0 = reg_d0;
            regd1 = reg_d1;
            regd2 = reg_d2;
            regd3 = reg_d3;
        end

        2'b11:
        begin
            regd0 = 4'd12;
            regd1 = 4'd12;
            regd2 = 4'd12;
            regd3 = 4'd12;
            go_start = 1'b0;
        end

        default:
        begin
            regd0 = 4'd12;
            regd1 = 4'd12;
            regd2 = 4'd12;
            regd3 = 4'd12;
            go_start = 1'b0;
        end
    endcase         
end


//the stopwatch block


reg [15:0] ticker; //**16 bits needed to count up to 50K bits, 10 bit for simulation
wire click;

//the mod 50K clock to generate a tick ever 0.001 second

always @ (posedge clock or posedge reset)
begin
    if(reset)

        ticker <= 0;

    else if(ticker == 50000) //**if it reaches the desired max value of 50K reset it, 500 for simulation
        ticker <= 0;
    else if(go_start) //only start if the input is set high
        ticker <= ticker + 1;
end

assign click = ((ticker == 50000)?1'b1:1'b0); //**click to be assigned high every 0.001 second

always @ (posedge clock or posedge reset)
begin
    if (reset)
        begin
            reg_d0 <= 0;
            reg_d1 <= 0;
            reg_d2 <= 0;
            reg_d3 <= 0;
        end

    else if (click) //increment at every click
        begin
            if(reg_d0 == 9) //xxx9 - the 0.001 second digit
            begin  //if_1
                reg_d0 <= 0;

                if (reg_d1 == 9) //xx99 
                begin  // if_2
                    reg_d1 <= 0;
                    if (reg_d2 == 5) //x599 - the two digit seconds digits
                    begin //if_3
                        reg_d2 <= 0;
                        if(reg_d3 == 9) //9599 - The minute digit
                            reg_d3 <= 0;
                        else
                            reg_d3 <= reg_d3 + 1;
                    end
                    else //else_3
                        reg_d2 <= reg_d2 + 1;
                end

                else //else_2
                    reg_d1 <= reg_d1 + 1;
            end 

            else //else_1
                reg_d0 <= reg_d0 + 1;
        end
end
assign led = outled;
endmodule 

解决方案

您是否擦洗了综合日志中的警告或错误之类的内容?我要做的第一件事是弄清楚该sel信号是怎么回事.如果综合认为未使用它,则说明它有很大问题,您不必用任何特殊的KEEP指令覆盖它.

有一件事,我注意到您已经推断出sel上的闩锁,因为您没有在每个状态下都分配它.推断锁存器对于仿真没有问题,但是您的FPGA可能不喜欢它.

可能想读:为什么推断出的闩锁不好?

您还有很多其他推断出的闩锁:outledregd0-3random_donego_start,也许还有其他.在尝试调试FPGA上的任何内容之前,您应该先清理所有这些内容.

My code for a reaction tester works perfectly and as it should in simulation. But when I move it to my FPGA device it just stalls as soon as I press the start button and I cannot figure out what goes wrong as it is working perfectly in simulation.

The concept is, when reset is pressed display Hi on the screen, when start is pressed, pick a random value from LFSR and count up to max value, thus making it a random delay. When max count for this reg is reached turn on the led, start the timer and wait for the stop button to be pressed.

Here is a screenshot of the code working in simulation:

Here 0000 is normal as notice that ticker starts incrementing and when it reaches its desired value it increments the timer making it 0001, so if I scroll forward enough it shows proper operation.

Here is the commented code, I added the (* KEEP = "TRUE" *)reg [1:0] sel; because during optimization the sel signal was removed as it was declared but never called, but obviously I needed it as it is.

  reg [12:0] random, random_next, random_done; //**13 bit for simulation purposes

reg [4:0] count_r, count_next_r; //to keep track of the shifts. 5 bit register to count up to 30


wire feedback = random[12] ^ random[3] ^ random[2] ^ random[0]; //**for simulation

always @ (posedge clock or posedge reset)
begin
    if (reset)
    begin
        random <= 13'hF; //**An LFSR cannot have an all 0 state, thus reset to FF
        count_r <= 0;
    end

    else
    begin
        random <= random_next;
        count_r <= count_next_r;
    end
end

always @ (*)
begin
    random_next = random; //default state stays the same
    count_next_r = count_r;

        random_next = {random[11:0], feedback}; //**shift left the xor'd every posedge clock
        count_next_r = count_r + 1;

    if (count_r == 13) //**for implementation its 30, simulation its 13
    begin
        count_next_r = 0;
        random_done = random; //assign the random number to output after 13 shifts
    end

end
//random number block ends

reg outled;

reg [3:0] reg_d0, reg_d1, reg_d2, reg_d3; //registers that will hold the individual counts
(* KEEP = "TRUE" *)reg [1:0] sel;
localparam [1:0]
                        idle = 2'b00,
                        starting = 2'b01,
                        time_it = 2'b10,
                        done = 2'b11;

reg [1:0] state_reg, state_next;
reg [12:0] count_reg, count_next; //**change for simulation, 30 bits for implementation, 13 bits for simulation

always @ (posedge clock or posedge reset)
begin
    if(reset)
        begin 
            state_reg <= idle;
            count_reg <= 0;
        end
    else
        begin
            state_reg <= state_next;
            count_reg <= count_next;
        end
end

reg go_start;
always @ (*)
begin
    state_next = state_reg; //default state stays the same
    count_next = count_reg;

    case(state_reg)
        idle:
            begin
                //DISPLAY HI HERE
                sel = 2'b00;
                if(start)
                begin
                    count_next = random_done; //get the random number from LFSR module
                    state_next = starting;
                end
            end
        starting:
            begin
                if(count_next == 8191) // **750M equals a delay of 15 seconds.
                begin                           //and starting from 'rand' ensures a random delay
                    outled = 1'b1; //turn on the led 
                    state_next = time_it; //go to next state
                end

                else
                    count_next = count_reg + 1; 
            end     
        time_it:
            begin
                    sel = 2'b01; //start the timer
                    state_next = done;                  
            end

        done:
            begin
                if(stop)
                    begin
                        sel = 2'b10; //stop the timer
                        outled = 1'b0;
                    end
            end

        endcase

    case(sel)
        2'b00: //hi
        begin
            go_start = 0; //make sure timer module is off
            regd0 = 4'd12; 
            regd1 = 4'd11;
            regd2 = 4'd10;
            regd3 = 4'd12;
        end

        2'b01: //timer
        begin

            go_start = 1'b1; //enable start signal to start timer
            regd0 = reg_d0;
            regd1 = reg_d1;
            regd2 = reg_d2;
            regd3 = reg_d3;
        end

        2'b10: //stop timer
        begin
            go_start = 1'b0;
        end

        default:
        begin
            regd0 = 4'bx;
            regd1 = 4'bx;
            regd2 = 4'bx;
            regd3 = 4'bx;
        end
    endcase         
end


//the stopwatch block


reg [15:0] ticker; //**16 bits needed to count up to 50K bits, 10 bit for simulation
wire click;

//the mod 50K clock to generate a tick ever 0.001 second

always @ (posedge clock or posedge reset)
begin
    if(reset)

        ticker <= 0;

    else if(ticker == 50000) //**if it reaches the desired max value of 50K reset it, 500 for simulation
        ticker <= 0;
    else if(go_start) //only start if the input is set high
        ticker <= ticker + 1;
end

assign click = ((ticker == 50000)?1'b1:1'b0); //**click to be assigned high every 0.001 second

always @ (posedge clock or posedge reset)
begin
    if (reset)
        begin
            reg_d0 <= 0;
            reg_d1 <= 0;
            reg_d2 <= 0;
            reg_d3 <= 0;
        end

    else if (click) //increment at every click
        begin
            if(reg_d0 == 9) //xxx9 - the 0.001 second digit
            begin  //if_1
                reg_d0 <= 0;

                if (reg_d1 == 9) //xx99 
                begin  // if_2
                    reg_d1 <= 0;
                    if (reg_d2 == 5) //x599 - the two digit seconds digits
                    begin //if_3
                        reg_d2 <= 0;
                        if(reg_d3 == 9) //9599 - The minute digit
                            reg_d3 <= 0;
                        else
                            reg_d3 <= reg_d3 + 1;
                    end
                    else //else_3
                        reg_d2 <= reg_d2 + 1;
                end

                else //else_2
                    reg_d1 <= reg_d1 + 1;
            end 

            else //else_1
                reg_d0 <= reg_d0 + 1;
        end
end

And here is the display circuit that will take the regd0-regd3 values.

    localparam N = 18; //18 for implementation, 8 for simulation

reg [N-1:0]count;

always @ (posedge clock or posedge reset)
    begin
        if (reset)
            count <= 0;
        else
            count <= count + 1;
    end

reg [3:0]sseg;
reg [3:0]an_temp;
reg reg_dp;
always @ (*)
    begin
        case(count[N-1:N-2]) //MSB and MSB-1 for multiplexing

            2'b00 : 
                begin
                    sseg = first;
                    an_temp = 4'b1110;
                    reg_dp = 1'b1;
                end

            2'b01:
                begin
                    sseg = second;
                    an_temp = 4'b1101;
                    reg_dp = 1'b0;
                end

            2'b10:
                begin
                    sseg = third;
                    an_temp = 4'b1011;
                    reg_dp = 1'b1;
                end

            2'b11:
                begin
                    sseg = fourth;
                    an_temp = 4'b0111;
                    reg_dp = 1'b0;
                end
        endcase
    end
assign an_m = an_temp;

reg [6:0] sseg_temp;    
always @ (*)
    begin
        case(sseg)
            4'd0 : sseg_temp = 7'b1000000; //display 0
            4'd1 : sseg_temp = 7'b1111001; //display 1
            4'd2 : sseg_temp = 7'b0100100;// display 2
            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;
            4'd10 : sseg_temp = 7'b0001001; //to display H
            4'd11 : sseg_temp = 7'b1001111; //to display I
            default : sseg_temp = 7'b0111111; //dash
        endcase
    end
assign {g_m, f_m, e_m, d_m, c_m, b_m, a_m} = sseg_temp; 
assign dp_m = reg_dp;

endmodule

When I move it on to my FPGA device at reset "Hi" is displayed as it should but when I press start the display just shows 0000 and stays at that. The led wont turn on either so that means the times was never initialized after the start button was pressed. I have been trying to sort this out for days now and cant seem to figure out why this is happening. What does one do when something works in simulation but does not work as its supposed to in hardware?

Update code with the latches fixed:

    //Block for LFSR random number generator        
reg [12:0] random, random_next, random_done; //**13 bit for simulation purposes
//reg [29:0] random, random_next, random_done; //30 bit register to keep track upto 15 seconds
reg [4:0] count_r, count_next_r; //to keep track of the shifts. 5 bit register to count up to 30

//wire feedback = random[29] ^ random[5] ^ random[3] ^ random[0]; 
wire feedback = random[12] ^ random[3] ^ random[2] ^ random[0]; //**for simulation

always @ (posedge clock or posedge reset)
begin
    if (reset)
    begin
        random <= 13'hF; //**An LFSR cannot have an all 0 state, thus reset to FF
        count_r <= 0;
    end

    else
    begin
        random <= random_next;
        count_r <= count_next_r;
    end
end

always @ (*)
begin
    random_next = random; //default state stays the same
    count_next_r = count_r;

        random_next = {random[11:0], feedback}; //**shift left the xor'd every posedge clock
        //count_next_r = count_r + 1;

    if (count_r == 13) //**for implementation its 30, simulation its 13
    begin
        count_next_r = 0;
        random_done = random; //assign the random number to output after 13 shifts
    end
    else
    begin
        count_next_r = count_r + 1;
        random_done = 13'b0;
    end

end
//random number block ends

reg outled;

reg [3:0] reg_d0, reg_d1, reg_d2, reg_d3; //registers that will hold the individual counts
/*(* KEEP = "TRUE" *)*/reg [1:0] sel, sel_next;
localparam [1:0]
                        idle = 2'b00,
                        starting = 2'b01,
                        time_it = 2'b10,
                        done = 2'b11;

reg [1:0] state_reg, state_next;
reg [12:0] count_reg, count_next; //**change for simulation, 30 bits for implementation, 13 bits for simulation

always @ (posedge clock or posedge reset)
begin
    if(reset)
        begin 
            state_reg <= idle;
            count_reg <= 0;
            sel <=0;
        end
    else
        begin
            state_reg <= state_next;
            count_reg <= count_next;
            sel <= sel_next;
        end
end

reg go_start;
always @ (*)
begin
    state_next = state_reg; //default state stays the same
    count_next = count_reg;
    sel_next = sel;
    case(state_reg)
        idle:
            begin
                //DISPLAY HI HERE
                //sel_next = 2'b00;
                if(start)
                begin
                    count_next = random_done; //get the random number from LFSR module
                    state_next = starting;
                end
            end
        starting:
            begin
                if(count_next == 8191) // **750M equals a delay of 15 seconds.
                begin                           //and starting from 'rand' ensures a random delay
                    outled = 1'b1; //turn on the led 
                    state_next = time_it; //go to next state
                end

                else
                begin
                    count_next = count_reg + 1; 
                    outled = 1'b0;
                end
            end     
        time_it:
            begin
                    sel_next = 2'b01; //start the timer
                    state_next = done;                  
            end

        done:
            begin
                if(stop)
                    begin
                        sel_next = 2'b10; //stop the timer
                        outled = 1'b0;
                    end
            end

        endcase

    case(sel_next)
        2'b00: //hi
        begin
            go_start = 0; //make sure timer module is off
            regd0 = 4'd12; 
            regd1 = 4'd11;
            regd2 = 4'd10;
            regd3 = 4'd12;
        end

        2'b01: //timer
        begin

            go_start = 1'b1; //enable start signal to start timer
            regd0 = reg_d0;
            regd1 = reg_d1;
            regd2 = reg_d2;
            regd3 = reg_d3;
        end

        2'b10: //stop timer
        begin
            go_start = 1'b0;
            regd0 = reg_d0;
            regd1 = reg_d1;
            regd2 = reg_d2;
            regd3 = reg_d3;
        end

        2'b11:
        begin
            regd0 = 4'd12;
            regd1 = 4'd12;
            regd2 = 4'd12;
            regd3 = 4'd12;
            go_start = 1'b0;
        end

        default:
        begin
            regd0 = 4'd12;
            regd1 = 4'd12;
            regd2 = 4'd12;
            regd3 = 4'd12;
            go_start = 1'b0;
        end
    endcase         
end


//the stopwatch block


reg [15:0] ticker; //**16 bits needed to count up to 50K bits, 10 bit for simulation
wire click;

//the mod 50K clock to generate a tick ever 0.001 second

always @ (posedge clock or posedge reset)
begin
    if(reset)

        ticker <= 0;

    else if(ticker == 50000) //**if it reaches the desired max value of 50K reset it, 500 for simulation
        ticker <= 0;
    else if(go_start) //only start if the input is set high
        ticker <= ticker + 1;
end

assign click = ((ticker == 50000)?1'b1:1'b0); //**click to be assigned high every 0.001 second

always @ (posedge clock or posedge reset)
begin
    if (reset)
        begin
            reg_d0 <= 0;
            reg_d1 <= 0;
            reg_d2 <= 0;
            reg_d3 <= 0;
        end

    else if (click) //increment at every click
        begin
            if(reg_d0 == 9) //xxx9 - the 0.001 second digit
            begin  //if_1
                reg_d0 <= 0;

                if (reg_d1 == 9) //xx99 
                begin  // if_2
                    reg_d1 <= 0;
                    if (reg_d2 == 5) //x599 - the two digit seconds digits
                    begin //if_3
                        reg_d2 <= 0;
                        if(reg_d3 == 9) //9599 - The minute digit
                            reg_d3 <= 0;
                        else
                            reg_d3 <= reg_d3 + 1;
                    end
                    else //else_3
                        reg_d2 <= reg_d2 + 1;
                end

                else //else_2
                    reg_d1 <= reg_d1 + 1;
            end 

            else //else_1
                reg_d0 <= reg_d0 + 1;
        end
end
assign led = outled;
endmodule 

解决方案

Have you scrubbed your synthesis logs for anything like warnings or errors? The first thing I would do would figure out what's going on with that sel signal. If synthesis thinks it is not used then something is very wrong with it, you shouldn't have to override it with any special KEEP directive.

For one thing I notice that you have inferred a latch on sel as you don't assign it in every state. Inferring latches is no problem for simulation, but your FPGA may not like it.

May want to read: Why are Inferred Latches Bad?

You have quite a few other inferred latches as well: outled, regd0-3, random_done, go_start, and maybe others. You should try to clean these all up before trying to debug anything on the FPGA.

这篇关于实施后如何调试?我的代码在仿真中能很好地工作,显示出硬件中的异常行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆