在verilog中,如何将高信号加倍并保持低信号相同

时间:2016-06-17 12:06:01

标签: verilog

the picture indicates what I want the output signal is: the high signal double and the low signal keep same.

我编写的代码如下:

integer x=0, count_valid=1, count_down=0;
reg valid_1, valid_reg;
always@(posedge clk)
begin
  if(tag==1) begin
   if(valid) begin
    count_valid <= count_valid +1;
    x<=x+1;
    valid_reg <= 1;
    end
    else begin
     x<=0;
     count_down <= count_down+1;
     if(count_valid>0) begin
     valid_reg <= 1;
     count_valid <= count_valid -1;
    end
    else if(count_down>0) begin
     valid_reg <= 0;
     count_down <= count_down-1;
     end
   end
  end
  else begin
  valid_reg <= valid;
  if (valid) x<=x+1;
  else x<=0;
  end
  valid_1 <= valid_reg;
end

valid是图片中的原始信号,valid_reg是修改后的信号。 count_valid用于计算高的循环次数,并将其用于次级以实现加倍。然后count_down用于计算低信号的周期。但我意识到当有效高时valid_reg会很高。

有谁能让我知道如何让低信号在输出信号中运行相同的周期?任何想法都很棒。

1 个答案:

答案 0 :(得分:0)

您没有提及输入信号是否是周期性的。鉴于您的输出随着时间推移而延伸,如果输入不是周期性的,那么您将需要无限存储来跟踪输入信号的样子。如果是周期性的或准周期性的,您可以执行以下操作 跟踪一个块中的高计数和低计数,并使用当前注册的计数值在另一个块中生成输出信号。使输出的第一个边缘与输入对齐是一种棘手的问题,需要一个多路复用器,根据它是否是第一次通过循环而选择。

integer count, count_q, countdown, countdown_q, outcount;
logic valid_q, valid_reg, out_q;
logic new;
always @(posedge clk or negedge reset_n)
  begin
  if(~reset_n)
    begin
    if(~reset_n)
      begin
      new <= 1;
      valid_q <= 0;
      count_q <= 0;
      countdown_q <= 0;
      end
    else
      begin
      valid_q <= valid;
      if(valid & ~valid_q)//rising edge
        begin
        count <= 1;
        countdown_q <= countdown;
        end
      else if(~valid & valid_q)//falling edge
        begin
        new <= 0;
        count_q <= count;
        countdown <= 1;
        end
      else if(valid)
        count <= count+1;
      else 
        countdown <= countdown+1;
      end
    end
  end
always @(posedge clk or negedge reset_n)
  begin
  if(~reset)
    begin
    outcount <= 0;
    out_q <= 0;
    end
  else
    begin
    if(new & valid & ~valid_q)
      begin
      out_q <= 1;
      outcount <= 2;//valid_reg is already high here
      end
    else
      if(out_q && (outcount == (count_q<<1)))
        begin
        out_q <= 0;
        outcount <= 1;
        end
      else if(~out_q && (outcount == (countdown_q)))
        begin
        out_q <= 1;
        outcount <= 1;
        end
      else
        outcount <= outcount + 1;
    end
  end
assign valid_reg = new? valid : out_q;//this gets your initial rising edge lined up