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

In verilog, how to double the high signal and keep the low signal same

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 用于计算 high 有多少个周期,并将其用于 sub one 以实现加倍。然后 count_down 用于计算低信号的周期。但我意识到当有效高时 valid_reg 会高。

谁能告诉我如何使输出信号中的低信号 运行 具有相同的周期?任何想法也很棒。

你没有提到输入信号是否是周期性的。鉴于您的输出会随着时间的推移而延长,如果输入不是周期性的,那么您将需要无限的存储空间来跟踪输入信号的样子。如果它是周期性的,或者准周期性的,你可以像下面那样做。
跟踪一个块中的高计数和低计数,并使用计数的当前寄存值在另一个块中生成输出信号。让输出的第一个边缘与输入的边缘对齐有点棘手,需要一个多路复用器,根据它是否是第一次通过循环来选择。

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