Author Topic: What is causing this non-deterministic result in my FPGA?!  (Read 2433 times)

0 Members and 1 Guest are viewing this topic.

Offline MattHollandsTopic starter

  • Frequent Contributor
  • **
  • Posts: 313
  • Country: gb
    • Matt's Projects
What is causing this non-deterministic result in my FPGA?!
« on: October 30, 2016, 01:31:36 am »
Hi,

As part of a larger project, the aim of my Verilog is, when a button is pressed, load a 72-bit value into a register and then shift that data onto a wire one bit at a time and have a flag that goes high for one clock cycle when there is new data available on this line.

Here is my code:
Code: [Select]
module Main(
    input wire CLK100MHZ,
    output wire [15:0] LED,
    input wire [15:0] SW,
    input wire BTNC,
    output wire CA, CB, CC, CD, CE, CF, CG, DP,
    output wire [7:0] AN);

    reg [71:0] DATA; //the data we are shifting
    reg NEW_DATA; //flag indicating new data available on DATA[71]
   
    reg [31:0] data7; //output to the seven segment display for debugging
    reg [11:0] new_counter;
   
    seven_seg_decoder seven_seg(.clk(CLK100MHZ), //seven segment display driver module
                            .number(data7),
                            .CA(CA),
                            .CB(CB),
                            .CC(CC),
                            .CD(CD),
                            .CE(CE),
                            .CF(CF),
                            .CG(CG),
                            .DP(DP),
                            .AN(AN));

reg last_BTNC;
    reg [31:0] counter;

    assign LED[1] = (DATA == 72'h000000000000000000);
   
    always @(posedge CLK100MHZ) begin
//mux data to seven segment display for debugging
        case(SW[3:1])
            0: data7 <= DATA[31:0];
            1: data7 <= DATA[63:32];
            2: data7 <= {24'h000000, DATA[71:64]};
            3: data7 <= {20'h00000, new_counter};
            4: data7 <= counter;
            default: data7 <= {32'd0};
        endcase
   
        if(counter < 36863) begin //keep counting until we have bit-shifted 72 times
            counter <= counter + 1;
        end
       
//on button press, load data and reset counter
        if(BTNC == 1 && last_BTNC != BTNC && DATA == 72'h000000000000000000) begin
            DATA <= 72'hAABBCCDDEEFFAABBCC;
            counter <= 0;
        end
   
//every 256 clock cycles turn on NEW_DATA for one clock indicating that DATA[71] has changed
        if(counter[8:0] == 9'h100) begin
            NEW_DATA <= 1;
        end else begin
            NEW_DATA <= 0;
        end
   
//every 256 clock cycles, shift bit shift DATA
        if(counter[8:0] == 9'h100) begin
            DATA[71:0] <= {DATA[70:0] , 1'b0};
        end
       
//count the number of times NEW_DATA is asserted
        if(NEW_DATA == 1) begin
            new_counter <= new_counter + 1;
        end
       
        last_BTNC <= BTNC;
    end
   
endmodule

 

CA, CB, CC, CD, CE, CF, CG, DP, AN are outputs for a 32-bit seven segment display. SW[15:0] are latching switch inputs. LED[15:0] are LED outputs. BTNC is a tactile switch.

What should happen is, when BTNC is pressed, DATA becomes 0xAABBCCDDEEFFAABBCC and counter gets set to zero. The counter then counts up and every 256 clock cycles DATA is shifted to the left by one bit and the lowest bit becomes a zero until DATA is entirely zeros.

In reality, this happens most of the time. But If I keep pressing the button, eventually  DATA gets stuck at a non-zero value e.g. 0x4.

I can't find any way to explain this. Please help!!
Read about my stuff at: projects.matthollands.com
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 26755
  • Country: nl
    • NCT Developments
Re: What is causing this non-deterministic result in my FPGA?!
« Reply #1 on: October 30, 2016, 01:39:02 am »
It seems you didn't debounce AND synchronise the button signal to the internal clock.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 
The following users thanked this post: MattHollands

Offline MattHollandsTopic starter

  • Frequent Contributor
  • **
  • Posts: 313
  • Country: gb
    • Matt's Projects
Re: What is causing this non-deterministic result in my FPGA?!
« Reply #2 on: October 30, 2016, 01:49:05 am »
Wow. I implemented the button_conditioner module from https://embeddedmicro.com/tutorials/mojo/metastability-and-debouncing

With some preliminary testing it seems fixed - have to say, I didn't realise that not synchronising could cause such unexpected behaviour.

Thanks!
Read about my stuff at: projects.matthollands.com
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 26755
  • Country: nl
    • NCT Developments
Re: What is causing this non-deterministic result in my FPGA?!
« Reply #3 on: October 30, 2016, 01:55:55 am »
Read more about synchronous logic and clock domain crossing. Basically all external signals are in a different clock domain so you have to synchronise them first with the internal clock. Inside an FPGA each bit of a counter has it's own logic and the delays between the inputs, other bits will be different for each bit. The FPGA synthesiser software will take the maximum frequency into account and make sure/check all signals originating from a flipflop driven by the same clock will arrive at the input of a flipflop before the next edge of the clock. With an unsynchronised external signal (fed into each logic block feeding the flipflops of the counter) the timing relation isn't there so you'll basically get a random result.
« Last Edit: October 30, 2016, 01:57:29 am by nctnico »
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf