Sometimes, the fpga have synchronous memory bloc with 2 clocks, one for each port.
nicO > I get the idea. This forces the data from domain 1 to sit still on > the data_hold register for at least 2 clock1 periods before it's gated > into > out_data on clock2. That doesn't guarantee with perfect certainty that it > will settle in time, but with any modern register the odds in favor are > extreme. > I think I did something like this in VHDL about 4 years ago. The > memories are pretty hazy now, but I think I might have used clocked data > registers, more gates, and fewer flip-flops. (There are still the > handshake > signals to add.) > Seems like there should be a textbook solution to this. My second > book on Verilog arrived yesterday, which concentrates on how to apply it > rather than its syntax. I haven't been into it yet; I'm still reading up > on > the language itself. > I guess the main problem this solves in OGP is that the dotclock > can't synchronize to the host bus handshake, short of adding a complicated > kind of phase-locked loop. Theoretically doable, I suppose, but > cross-domain data buffering looks a lot easier to implement. > > > > On Tue, Jun 07, 2005 at 04:29:56PM -0400, Timothy Miller wrote: >> The biggest problem with getting data between clock domains is >> metastability. Metastability can occur where you try to latch a >> signal at time when that signal is in transition. What we need is a >> reliable means to ensure that one register's Q's are going to meet the >> setup and hold time for another register's D's. To do this, we store >> data (the payload) in a register in one clock domain and make sure we >> hold it there unchanged long enough to ensure that we can reliably >> store it into a register in the other domain. To ensure that payload >> data is held long enough, we handshake between the two clock domains >> by, essentially, passing a token back and forth, and when >> metastability affects the token, the worst case is a slight additional >> delay in passing the payload. >> >> >> Here's a circuit diagram: >> >> http://opengraphics.gitk.com/sync.gif >> >> >> And here's the source code: >> >> >> >> module sync( >> in_clock, >> in_data, >> >> out_reset, >> out_clock, >> out_data); >> >> parameter HIGHBIT = 7; >> >> input out_reset; >> input in_clock, out_clock; >> input [HIGHBIT:0] in_data; >> output [HIGHBIT:0] out_data; >> >> reg flag_1, flag_2, flag_3, flag_4, flag_5; >> reg [HIGHBIT:0] data_hold, out_data; >> >> always @(negedge in_clock) flag_1 <= !flag_5; >> >> always @(posedge in_clock) begin >> if (!flag_2) data_hold <= in_data; >> flag_2 <= flag_1; >> end >> >> always @(negedge out_clock) begin >> if (out_reset) begin >> flag_4 <= 0; >> end else begin >> flag_4 <= flag_3; >> end >> end >> >> always @(posedge out_clock) begin >> if (out_reset) begin >> flag_3 <= 0; >> flag_5 <= 1; >> out_data <= 0; >> end else begin >> flag_3 <= flag_2; >> flag_5 <= flag_4; >> if (flag_4 & !flag_5) out_data <= data_hold; >> end >> end >> >> endmodule >> >> >> >> >> >> Note that the placement of the inverter is somewhat arbitrary. Since >> inverters are usually free, we can do this. If the inverter were a >> separate component, it would be better to put it between registers of >> the same clock domain. >> >> _______________________________________________ >> Open-graphics mailing list >> [email protected] >> http://lists.duskglow.com/mailman/listinfo/open-graphics >> List service provided by Duskglow Consulting, LLC (www.duskglow.com) > _______________________________________________ > Open-graphics mailing list > [email protected] > http://lists.duskglow.com/mailman/listinfo/open-graphics > List service provided by Duskglow Consulting, LLC (www.duskglow.com) > _______________________________________________ Open-graphics mailing list [email protected] http://lists.duskglow.com/mailman/listinfo/open-graphics List service provided by Duskglow Consulting, LLC (www.duskglow.com)
