0

这是代码首先...

always@(posedge clk)
begin
if(cstate==idle)    rclk<=1;
else rclk<=0;
end

always@(negedge clk)
rclk<=0;

我想要实现的是:每次在时钟信号的上升沿,如果信号 cstate 等于 idle(4'b0000),则 rclk 变为 1,否则变为 0,同时,每次下降clk 的边缘会将 rclk 设置为零。此代码不可合成,因为编译器给出错误“rclk 信号由多个驱动程序驱动”。

如何通过其他技术实现相同的功能?

4

1 回答 1

1

看起来你想要一个时钟门单元。基于 1 个周期宽的使能信号生成与输入时钟具有相同高电平时间的时钟脉冲。

这样做的一种天真的方法可能是:

assign rclk = (cstate==idle) ? clk : 1'b0 ;

可以很容易地合成assign rclk = (cstate==idle) & clk ;
cstate == idle会出现故障,这就是为什么它通常会被触发器使用,允许答案在使用之前稳定下来。

使用时钟门单元可以防止您在 (rclk) 时钟线上产生毛刺。为此,在 rtl 中实例化您的库时钟门单元是很常见的。在 RTL 中,它可能类似于:

reg result;
always @(posedge clk or negedge rst_n) begin
  if (~rst_n) begin
    result <= 1'b0;
  end
  else begin
    result <= (cstate == idle);
  end
end

assign rclk = (result) ? clk : 1'b0 ;

这意味着每个时钟周期的结果都是稳定的,不允许来自比较器的毛刺。

扩展答案

我在下面再次用波形包含了我的示例,我用一个简单的计数器替换了你的状态比较,该计数器溢出以重置自身。不是比较匹配到 2'b10;这意味着时钟出现在以下计数(2'b11)上。如果时钟出现在您的比较匹配的完全相同的时间,那么您的时钟上没有故障抑制,并且可能会产生不可靠的硬件。

reg [1:0] counter = 0;

always @(posedge clk) 
  counter <= counter+1;

reg  result;
wire result_a = (counter == 2'b10 );

always @(posedge clk or negedge rst_n) begin
  if (~rst_n) begin
    result <= 1'b0;
  end
  else begin
    result <= result_a;
  end
end

assign rclk = (result) ? clk : 1'b0 ;

时钟门的示例波形

于 2013-03-31T17:13:04.870 回答