What is causing this non-deterministic result in my FPGA?! - Page 1
Forum section: electronics / general

author: MattHollands
author_rank: Frequent Contributor
timestamp: October 30, 2016, 01:31:36 am
content: 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: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 shiftingreg NEW_DATA; //flag indicating new data available on DATAreg [31:0] data7; //output to the seven segment display for debuggingreg [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 = (DATA == 72'h000000000000000000);always @(posedge CLK100MHZ) begin//mux data to seven segment display for debuggingcase(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};endcaseif(counter < 36863) begin //keep counting until we have bit-shifted 72 timescounter <= counter + 1;end//on button press, load data and reset counterif(BTNC == 1 && last_BTNC != BTNC && DATA == 72'h000000000000000000) beginDATA <= 72'hAABBCCDDEEFFAABBCC;counter <= 0;end//every 256 clock cycles turn on NEW_DATA for one clock indicating that DATA has changedif(counter[8:0] == 9'h100) beginNEW_DATA <= 1;end else beginNEW_DATA <= 0;end//every 256 clock cycles, shift bit shift DATAif(counter[8:0] == 9'h100) beginDATA[71:0] <= {DATA[70:0] , 1'b0};end//count the number of times NEW_DATA is assertedif(NEW_DATA == 1) beginnew_counter <= new_counter + 1;endlast_BTNC <= BTNC;endendmoduleCA, 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!!

author: nctnico
author_rank: Super Contributor
timestamp: October 30, 2016, 01:39:02 am
content: It seems you didn't debounce AND synchronise the button signal to the internal clock.

author: MattHollands
author_rank: Frequent Contributor
timestamp: October 30, 2016, 01:49:05 am
content: Wow. I implemented the button_conditioner module fromhttps://embeddedmicro.com/tutorials/mojo/metastability-and-debouncingWith some preliminary testing it seems fixed - have to say, I didn't realise that not synchronising could cause such unexpected behaviour.Thanks!

author: nctnico
author_rank: Super Contributor
timestamp: October 30, 2016, 01:55:55 am
content: 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.