题解 | #使用握手信号实现跨时钟域数据传输#
使用握手信号实现跨时钟域数据传输
https://www.nowcoder.com/practice/2bf1b28a4e634d1ba447d3495134baac
//题设中考虑clk_a与clk_b频率不同但相差不大
`timescale 1ns/1ns
module data_driver(
input clk_a,
input rst_n,
input data_ack,
output reg [3:0]data,
output reg data_req
);
//
reg data_ack_r1 ;
reg data_ack_r2 ;
reg [2 :0] bit_cnt ;
reg [2 :0] wait_cnt ;
//data_ack_cross
always @(posedge clk_a or negedge rst_n)
begin
if(!rst_n)
begin
data_ack_r1 <= 1'b0 ;
data_ack_r2 <= 1'b0 ;
end
else
begin
data_ack_r1 <= data_ack ;
data_ack_r2 <= data_ack_r1 ;
end
end
//data
always @(posedge clk_a or negedge rst_n)
begin
if(!rst_n)
data <= 3'd0 ;
else if(data == 4'd7)
data <= 4'd0 ;
else if(data_ack_r2)
data <= data + 1'b1 ;
end
//data_req
always @(posedge clk_a or negedge rst_n)
begin
if(!rst_n)
data_req <= 1'b0 ;
else if(wait_cnt == 3'd4)
data_req <= 1'b1 ;
else if(data_ack_r2)
data_req <= 1'b0 ;
end
//wait_cnt
always @(posedge clk_a or negedge rst_n)
begin
if(!rst_n)
wait_cnt <= 3'd0 ;
else if(data_req)
wait_cnt <= 3'd0 ;
else if(!data_req)
wait_cnt <= wait_cnt + 1'b1 ;
end
endmodule
/* -------------------------------- receiver -------------------------------- */
module data_receiver(
input clk_b,
input rst_n,
input data_req,
input wire [3:0]data,
output reg data_ack
);
//
reg data_req_r1 ;
reg data_req_r2 ;
reg [3 :0] data_r ;
//data_req_cross
always @(posedge clk_b or negedge rst_n)
begin
if(!rst_n)
begin
data_req_r1 <= 1'b0 ;
data_req_r2 <= 1'b0 ;
end
else
begin
data_req_r1 <= data_req ;
data_req_r2 <= data_req_r1 ;
end
end
//data_r
always @(posedge clk_b or negedge rst_n )
begin
if(!rst_n)
data_r <= 4'd0 ;
else if(data_req_r1)
data_r <= data ;
end
//data_ack
always @(posedge clk_b or negedge rst_n )
begin
if(!rst_n)
data_ack <= 1'b0 ;
else if(data_req_r1)
data_ack <= 1'b1 ;
else
data_ack <= 1'b0 ;
end
endmodule

正浩创新EcoFlow公司福利 646人发布