UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Visitor davidbear
Visitor
7,696 Views
Registered: ‎06-20-2009

problems with synchronization

Jump to solution

Dear all,

 

   I have done some reading, so I am sure that my problem is a metastability problem, my problem is I don't know what it is.  On a XC9572XL, I use a button to switch between a second pulse and a faster pulse in order to run through the timed seconds and "set" my watch.  The problem is that when I release the button, sometimes the displayed time becomes "random."  If someone could take a look at the code below and suggest how to bring my code out of metastability, I certainly would appreciate it.

 

DavidBear

 

 

module twodigit(clk, reset, button, display, control, clk_out); input clk; input reset; input button; output [6:0] display; reg [6:0] display; output [1:0] control; output clk_out; reg clk_out; wire [13:0] top_number = ~14'b1111011_1111011; // 99 parameter start_number_ones = ~7'b0110000; parameter start_number_tens = ~7'b1111110; reg cntl; reg [6:0] ones; reg [6:0] tens; wire [6:0] temp1; wire [6:0] temp10; initial begin ones <= start_number_ones; tens <= start_number_tens; clk_out = 1'b0; cntl = 1'b0; end easyclock ms1(clk, clocks, quick, second); assign control[0] = cntl == 0?1'b0:1'bz; assign control[1] = cntl == 0?1'bz:1'b0; assign temp1 = ones; assign temp10 = tens; always @(posedge clocks) begin cntl <= cntl + 1; if(~cntl) display <= temp1; else display <= temp10; end reg [1:0] button_db; reg [2:0] pulse; always @(posedge clocks) begin button_db = {button_db[0],button}; end wire button_push = button & button_db[0] & button_db[1]; always @(posedge clk) begin if(button_push) pulse <= {pulse[1],pulse[0],quick}; else pulse <= {pulse[1],pulse[0],second}; end wire downbeat; assign downbeat = pulse[0] & pulse[1] & !pulse[2]; always @(negedge downbeat or posedge reset) begin if(reset) begin ones <= start_number_ones; tens <= start_number_tens; clk_out <= 1; end else if({tens,ones} == top_number) begin ones <= start_number_ones; tens <= start_number_tens; clk_out <= 0; end else case(ones) ~7'b1111110: begin // 0 ones <= ~7'b0110000; end ~7'b0110000: ones <= ~7'b1101101; // 1 ~7'b1101101: ones <= ~7'b1111001; // 2 ~7'b1111001: ones <= ~7'b0110011; // 3 ~7'b0110011: ones <= ~7'b1011011; // 4 ~7'b1011011: ones <= ~7'b1011111; // 5 ~7'b1011111: ones <= ~7'b1110000; // 6 ~7'b1110000: ones <= ~7'b1111111; // 7 ~7'b1111111: ones <= ~7'b1111011; // 8 ~7'b1111011: // 9 begin ones <= ~7'b1111110; case(tens) ~7'b1111110: begin // 0 tens <= ~7'b0110000; clk_out <= 1; end ~7'b0110000: tens <= ~7'b1101101; // 1 ~7'b1101101: tens <= ~7'b1111001; // 2 ~7'b1111001: tens <= ~7'b0110011; // 3 ~7'b0110011: tens <= ~7'b1011011; // 4 ~7'b1011011: tens <= ~7'b1011111; // 5 ~7'b1011111: tens <= ~7'b1110000; // 6 ~7'b1110000: tens <= ~7'b1111111; // 7 ~7'b1111111: tens <= ~7'b1111011; // 8 ~7'b1111011: tens <= ~7'b1111110; // 9 endcase end endcase end endmodule module easyclock(clk, out, out2, thousandX); input clk; output out; reg out; output out2; output thousandX; reg thousandX; reg [13:0] count; always @ (posedge clk) begin count = count + 1; if(count == 14'd15000) begin count = 0; out = ~out; end end reg [8:0] count2; always @(negedge out) begin count2 = count2 + 1; if(count2 == 9'd500) begin count2 = 0; thousandX = ~ thousandX; end end assign out2 = count2[6]; endmodule

 

 

 

0 Kudos
1 Solution

Accepted Solutions
Visitor davidbear
Visitor
9,773 Views
Registered: ‎06-20-2009

Re: problems with synchronization

Jump to solution

Eilert,

 

    I should have done more to define the problem, clk is defined by a 30 * 10^6 Hz oscillator.  "easyclock" takes that clk signal and counts  15 * 10^3 times and flips the register out (known as "counts" in the main "twodigit" module) to give a 1 KHz signal. This signal is further counted 500 times and flips the register thousandX to give a  1 Hz signal (known as "second" in the "twodigit" module) additionally an ~8Hz signal is generated from count2, known as "quick" in the "twodigit" module.  Now, I use the signal clocks to (multiplex) alternate between two seven-segment digits known as ones and tens, which feed the seven-segment "output" and two control lines that activate two seven-segment displays.  So, when control[0] is low, the segments corresponding to ones are present in "display", and the seven-segment display corresponding to the ones digit is lit; 1/1000th of a second later, control[1] goes low and the segments corresponding to tens are present in "display", and the seven-segment display corresponding to the ones digit is lit.  So, each of the two digits are lit with the correct number with a frequency of 500 Hz and a 50% duty cycle (the eye sees this as a half-intensity digit.  This works.

 

I was trying to use this code to debounce my button and multiplex my two signals "second" and "quick."

 

always @(posedge clocks) begin
button_db = {button_db[0],button};
end

wire button_push = button & button_db[0] & button_db[1];

 

always @(posedge clk) begin
if(button_push) pulse <= {pulse[1],pulse[0],quick};
else pulse <= {pulse[1],pulse[0],second};
end

wire downbeat;

assign downbeat = pulse[0] & pulse[1] & !pulse[2];
 

 It turns out that I have now solved my problem by using a non-blocking assignment and slowing down my sampling of the multiplexer, so the code now looks like this:

 

reg button_db;
reg pulse;

always @(posedge clocks) begin
button_db <= button;
end

wire button_push = button & button_db;

always @(posedge clocks) begin
if(button_push) pulse <= quick;
else pulse <= second;
end

wire downbeat;

assign downbeat = pulse;

always @(negedge downbeat or posedge reset) begin
....

 

 

 With this code, my second watch appears to behave normally, and I can reliably "set" the watch with the button.  If you see additional problems with my code or have futher comment, it will be appreciated.  In particular, If anyone can find additional registers that can be removed (other than using a slower clock), I would love to fit a minutes and seconds onto this 72 register device (currently 54 of 72 used).

 

DavidBear

 

0 Kudos
5 Replies
Advisor eilert
Advisor
7,684 Views
Registered: ‎08-14-2007

Re: problems with synchronization

Jump to solution

Hi David,

do I see it right, that you are going to set your watch at a speed of 500 Increments per second? 

(clk = 7,5 MHz, quick = 500 Hz, second = 1 Hz)

 

And you really can follow that to set your watch on a desired value?

Even 5 Hz would be hard to use.

 

Also, you did nothing to debounce your switch. After release it wil toggle a while between quick and second.

 

No metastability involved as far as I can see. 

 

Have a nice synthesis

  Eilert

Visitor davidbear
Visitor
9,774 Views
Registered: ‎06-20-2009

Re: problems with synchronization

Jump to solution

Eilert,

 

    I should have done more to define the problem, clk is defined by a 30 * 10^6 Hz oscillator.  "easyclock" takes that clk signal and counts  15 * 10^3 times and flips the register out (known as "counts" in the main "twodigit" module) to give a 1 KHz signal. This signal is further counted 500 times and flips the register thousandX to give a  1 Hz signal (known as "second" in the "twodigit" module) additionally an ~8Hz signal is generated from count2, known as "quick" in the "twodigit" module.  Now, I use the signal clocks to (multiplex) alternate between two seven-segment digits known as ones and tens, which feed the seven-segment "output" and two control lines that activate two seven-segment displays.  So, when control[0] is low, the segments corresponding to ones are present in "display", and the seven-segment display corresponding to the ones digit is lit; 1/1000th of a second later, control[1] goes low and the segments corresponding to tens are present in "display", and the seven-segment display corresponding to the ones digit is lit.  So, each of the two digits are lit with the correct number with a frequency of 500 Hz and a 50% duty cycle (the eye sees this as a half-intensity digit.  This works.

 

I was trying to use this code to debounce my button and multiplex my two signals "second" and "quick."

 

always @(posedge clocks) begin
button_db = {button_db[0],button};
end

wire button_push = button & button_db[0] & button_db[1];

 

always @(posedge clk) begin
if(button_push) pulse <= {pulse[1],pulse[0],quick};
else pulse <= {pulse[1],pulse[0],second};
end

wire downbeat;

assign downbeat = pulse[0] & pulse[1] & !pulse[2];
 

 It turns out that I have now solved my problem by using a non-blocking assignment and slowing down my sampling of the multiplexer, so the code now looks like this:

 

reg button_db;
reg pulse;

always @(posedge clocks) begin
button_db <= button;
end

wire button_push = button & button_db;

always @(posedge clocks) begin
if(button_push) pulse <= quick;
else pulse <= second;
end

wire downbeat;

assign downbeat = pulse;

always @(negedge downbeat or posedge reset) begin
....

 

 

 With this code, my second watch appears to behave normally, and I can reliably "set" the watch with the button.  If you see additional problems with my code or have futher comment, it will be appreciated.  In particular, If anyone can find additional registers that can be removed (other than using a slower clock), I would love to fit a minutes and seconds onto this 72 register device (currently 54 of 72 used).

 

DavidBear

 

0 Kudos
Advisor eilert
Advisor
7,654 Views
Registered: ‎08-14-2007

Re: problems with synchronization

Jump to solution

Hi David,

Thx for clarifying the frequencies. I missed that you inverted the output signals which added an additional division by 2.

 

The only weakness I can see in your debouncing is that you are doing it with the original clock, (30 MHz) which is way too fast for that purpose.

The bouncing of switches/keys is somwhere between some microseconds to a few milliseconds (it differs from switch to swich).

So the sampling frequency for the debouncer has to be in a similar range. I think your 1Khz signal will work reliable in your application.

 (Or are you already using such a frequency with the "clocks" signal?)

 

Have a nice synthesis

  Eilert

 

Highlighted
Observer satish.84ts
Observer
5,621 Views
Registered: ‎10-21-2012

problems with synchronization

Jump to solution

Hi.......

 I have a signal coming from one block which is operating at 44Mhz,this is going to another block which is operating at 50Mhz.So I have to take output signal from the first block(44Mhz) to input for the next block(50Mhz),how to synchronize these two block as that signal can't loose any values.. ............

       " Without using FIFO,is there any another technique available two synchronize the signal in between these two blocks(44Mhz,50Mhz).......Please help me........Thanks...........

Tags (1)
0 Kudos
Historian
Historian
5,611 Views
Registered: ‎02-25-2008

Re: problems with synchronization

Jump to solution
I think you want to not lose any values, not loose them.
----------------------------Yes, I do this for a living.
0 Kudos