在verilog中,如何将高信号加倍并保持低信号不变
In verilog, how to double the high signal and keep the low signal 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
我写了这样的代码:
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