FPGA跨时钟域握手信号的结构
FPGA跨时钟数据传输,是我们经常遇到的问题的,下面给出一种跨时钟握手操作的电路结构。先上图

先对与其他人的结构,这个结构最大的特点是使用 req 从低到高或者高到低的变化 来表示DIN数据有效并开始传输。并且同过判断 req与ack信号是否相等就可以判断传输是否完成。当req !=ack时表示正在传输,不可以发起新的传输操作。当req=ack时表示传输完成,可以开始新的传输过程。
并且这样的结构在req传输发生亚稳态时也可以有效的传输信号,可以适应任意时钟域之间的数据传输。仿真图如下

代码:
module handshack2 #( parameter DATA_SIZE = 8, parameter SREG_LENG = 3 ) ( input rsta, input clka, input reqa,//变化沿表示数据有效 input [DATA_SIZE-1:0] dina, output acka, input rstb, input clkb, output reg rdyb, output reg [DATA_SIZE-1:0] doutb ); reg req_ra; reg [DATA_SIZE-1:0] din_ra; reg[SREG_LENG-1:0] ack_ra; reg[SREG_LENG-1:0] req_rb; //clka always@(posedge clka)begin if(rsta)begin req_ra <= 0; end else begin req_ra <= reqa; end din_ra <= dina; end always@(posedge clka) if(rsta)begin ack_ra <= 0; end else begin ack_ra <= {ack_ra[SREG_LENG-2:0], req_rb[SREG_LENG-1]}; end assign acka = ack_ra[SREG_LENG-1]; //clkb always@(posedge clkb) if(rstb)begin req_rb <= 0; end else begin req_rb <= {req_rb[1:0], req_ra}; end always@(posedge clkb)begin if(req_rb[SREG_LENG-1]^req_rb[SREG_LENG-2])begin doutb <= din_ra; end rdyb <= req_rb[SREG_LENG-1]^req_rb[SREG_LENG-2]; end endmodule
测试脚本:
module tst_handshack2; // Inputs reg rsta; reg clka; reg reqa; reg [7:0] dina; reg rstb; reg clkb; // Outputs wire acka; wire rdyb; wire [7:0] doutb; // Instantiate the Unit Under Test (UUT) handshack2 uut ( .rsta(rsta), .clka(clka), .reqa(reqa), .dina(dina), .acka(acka), .rstb(rstb), .clkb(clkb), .rdyb(rdyb), .doutb(doutb) ); initial begin clka = 0; #5 forever #5 clka = ~clka; end initial begin rsta <= 0; dina <= 0; reqa <= 0; #100; dina <= 10; reqa <= !reqa; #10; wait( acka == reqa) #10; dina <= 100; reqa <= !reqa; end initial begin #2.7; clkb = 0; #3 forever #3 clkb = ~clkb; end initial begin rstb <= 0; #90; end endmodule
浙公网安备 33010602011771号