题解 | #脉冲同步器(快到慢)#
脉冲同步器(快到慢)
https://www.nowcoder.com/practice/9f7c92635b5f49579e8e38fd8c8450d7
1 脉冲展宽法:
`timescale 100ps/100ps module pulse_detect( input clka , input clkb , input rst_n , input sig_a , output sig_b ); reg data_in_reg; reg [2:0] data_slow; always @ (posedge clka, negedge rst_n) begin if(!rst_n) begin data_in_reg <= 1'b0; end else begin data_in_reg <= sig_a ? (~data_in_reg) : data_in_reg; end end always @ (posedge clkb, negedge rst_n) begin if(!rst_n) begin data_slow <= 3'b0; end else begin data_slow <= {data_slow[1:0], data_in_reg}; end end assign sig_b = data_slow[2] ^ data_slow[1]; endmodule
2 单比特握手
`timescale 1ns/1ns module pulse_detect( input clk_fast , input clk_slow , input rst_n , input data_in , output dataout ); reg fast_req, slow_ack; reg [2:0] slow_req; reg [2:0] fast_ack; //fast时钟域 //将slow时钟域的应答信号打三拍,送到fast时钟域 always @(posedge clk_fast, negedge rst_n) begin if(!rst_n) begin fast_ack <= 3'b0; end else begin fast_ack <= {fast_ack[1:0], slow_ack}; end end //生成请求信号fast_req always @(posedge clk_fast, negedge rst_n) begin if(!rst_n) begin fast_req <= 1'b0; end else if (data_in) begin fast_req <= 1'b1; end else begin fast_req <= (fast_ack[1] & (~fast_ack[2])) ? 1'b0 : fast_req; end end //slow时钟域 //将fast时钟域的请求信号打三拍,送到slow时钟域 always @(posedge clk_slow, negedge rst_n) begin if(!rst_n) begin slow_req <= 3'b0; end else begin slow_req <= {slow_req[1:0], fast_req}; end end //生成应答信号slow_ack always @(posedge clk_slow, negedge rst_n) begin if(!rst_n) begin slow_ack <= 1'b0; end else if (slow_req[1] & (~slow_req[2])) begin slow_ack <= 1'b1; end else begin slow_ack <= (slow_req[2] & (~slow_req[1])) ? 1'b0 : slow_ack; end end assign dataout = (~slow_req[2]) & (slow_req[1]); // endmodule