我们可以利用带有使能端的D触发器来实现时钟使能的功能。
在上图中clk1x是CLK的四分频后产生的时钟,clk1x_en是与clk1x同频的时钟使能信号,用clk1x_en作为DFF的使能端,D端的数据只有在clk1x_en有效地时候才能打入D触发器,从而在不引入新时钟的前提,完成了下图电路一致的逻辑功能。
在某系统中,前级数据输入位宽为8,而后级的数据输出位宽32,我们需要将8bit的数据转换成32bit的数据,因此后级处理的时钟频率为前级的1/4,若不使用时钟时能,则就要将前级时钟进行4分频来作为后级处理的时钟,这种设计方法会引入新的时钟域,为了避免这种情况,我们采用了时钟时能的方法来减少设计的复杂度。
module
gray
(
input clk,
input rst_n,
input [ 7 : 0 ] data_in,
output reg [ 31 : 0 ] data_out,
output reg clk1x_en
);
reg [ 1 : 0 ] cnt;
reg [ 31 : 0 ] shift_reg;
always @ ( posedge clk, negedge rst_n)
begin
if ( ! rst_n)
cnt <= 2 ' b0;
else
cnt <= cnt + 1 ' b1;
end
always @ ( posedge clk, negedge rst_n)
begin
if ( ! rst_n)
clk1x_en <= 1 ' b0;
else if (cnt == 2 ' b01)
clk1x_en <= 1 ' b1;
else
clk1x_en <= 1 ' b0;
end
always @ ( posedge clk, negedge rst_n)
begin
if ( ! rst_n)
shift_reg <= 32 ' b0;
else
shift_reg <= {shift_reg[ 23 : 0 ],data_in};
end
always @ ( posedge clk, negedge rst_n)
begin
if ( ! rst_n)
data_out <= 32 ' b0;
else if (clk1x_en == 1 ' b1)//仅在clk1x_en为1时才将shift_reg的值赋给data_out
data_out <= shift_reg;
end
endmodule
(
input clk,
input rst_n,
input [ 7 : 0 ] data_in,
output reg [ 31 : 0 ] data_out,
output reg clk1x_en
);
reg [ 1 : 0 ] cnt;
reg [ 31 : 0 ] shift_reg;
always @ ( posedge clk, negedge rst_n)
begin
if ( ! rst_n)
cnt <= 2 ' b0;
else
cnt <= cnt + 1 ' b1;
end
always @ ( posedge clk, negedge rst_n)
begin
if ( ! rst_n)
clk1x_en <= 1 ' b0;
else if (cnt == 2 ' b01)
clk1x_en <= 1 ' b1;
else
clk1x_en <= 1 ' b0;
end
always @ ( posedge clk, negedge rst_n)
begin
if ( ! rst_n)
shift_reg <= 32 ' b0;
else
shift_reg <= {shift_reg[ 23 : 0 ],data_in};
end
always @ ( posedge clk, negedge rst_n)
begin
if ( ! rst_n)
data_out <= 32 ' b0;
else if (clk1x_en == 1 ' b1)//仅在clk1x_en为1时才将shift_reg的值赋给data_out
data_out <= shift_reg;
end
endmodule