题目描述
在data_en为高期间,data_in将保持不变,data_en为高至少保持3个B时钟周期。表明,当data_en为高时,可将数据进行同步。
本题中data_in端数据变化频率很低,相邻两个数据间的变化,至少间隔10个B时钟周期。
电路的接口如下图所示。端口说明如下表所示。
解题:
这一题总体思路是将A时钟域输入信号,同步到B时钟域,并随B时钟上升沿到来而输出。这里的思路是在A时钟设立一个有效信号data_en,当data_en满三个周期有效时,data_out读取data_in的值,实现一个跨时钟域的输出。
详解如下:
module mux(
input clk_a ,
input clk_b ,
input arstn ,
input brstn ,
input [3:0] data_in ,
input data_en ,
output reg [3:0] dataout
);
integer i; //定义一个参数来打拍
always @(posedge clk_b or negedge brstn) begin
if(!arstn) dataout <= 0;
else if(i>=4) dataout <= data_in;
else dataout <= dataout; //当data_en为低电平时,dataout保持不变,而不是置零(一开始写错了)
end
always @(posedge clk_a or negedge arstn)begin
if(!brstn) i<=0;
else if(data_en) i <= i+1; //三个a周期后,i=4,需要满3个周期才行;
else i <= 0; //低电平 i置零,等待重新计数
end
endmodule
这里的思路是声明一个参数i来打拍,在看别人的答案里,看到一种方法比较有意思值得学习一下:
...
else if(data_en)
data_a <= {data_a[11:0],data_in}; //打拍,利用移位寄存器
...
dataout <= data_a[15:12];
//输出最高4位,即打拍三次后才可以输出,而当en为低电平时,不移位
//要输入新的值也需要移位三次才可以,很好的符合题目条件
...
结束啦