如何每 n 个时钟周期切换一个采样时钟?
How do I toggle a sample clock every n clock cycles?
我是 Verilog 的新手,所以我不知道该怎么做。我有一个时钟,'samp_clk',它每 10 个系统时钟周期切换一次,'clock'(或者这就是我试图做的)。这是我目前所拥有的:
//'counter' counts the number of rising edges for system clock
//'samp_clk' is the sample clock, 'clock' is system clock
always @ (posedge clock)begin
if(~reset)begin
if(counter == 10)begin
samp_clk <= 1;
counter <= 0;
end
else begin
samp_clk <= 0;
counter <= counter + 1;
end
end
end
按照我写的方式,我觉得我的 samp_clk 只会在一个时钟周期内保持断言。我怎样才能让它每十个时钟周期在 1 和 0 之间切换?
你要切换,就切换。
另请注意,要每 10 个时钟切换一次,当计数器的值为 10-1 时,您必须将计数器设置为 0。
试试这个(未测试):
//'counter' counts the number of rising edge s for system clock
//'samp_clk' is the sample clock, 'clock' is sy stem clock
always @ (posedge clock)begin
if(~reset)begin
if(counter == 9)begin
samp_clk <= ~samp_clk;
counter <= 0;
end
else begin
counter <= counter + 1;
end
end
else begin
samp_clk <= 0;
end
end
你是对的,当 counter
为 10
时,此代码将 samp_clk
设置为 1
,否则将其设置为 0
。这意味着您将拥有一个信号,该信号在 1 个时钟周期内有效,在 10 个时钟周期内保持低电平。基本逻辑是正确的(计数10个时钟周期)但是给samp_clk
的值不正确。
你想要的是 samp_clk
与上一个循环中的值相同,如果 counter
ins't 10
并翻转 samp_clk
几时。要翻转信号,您希望将信号分配给信号的反转:samp_clk <= ~samp_clk
.
完成该工作后,您可能需要重构代码,因为我认为它会在当前状态下生成锁存器。
来自您的代码:
if(counter == 10)begin
samp_clk <= 1;
counter <= 0;
end
这将产生 11 个时钟周期,因为我们从 0 开始计数到 10。
第一步,定义一个计数器,其中它重置为某个值
数(时钟周期)。比如你要检测10时钟
循环(n = 10),当counter
大于或等于9时,
它设置回 0。
always @ (posedge clk)begin
if(~reset)begin
counter <= 0;
end
else begin
if(counter >= 9)begin
counter <= 0;
end
else begin
counter <= counter + 1;
end
end
end
然后简单地,当 counter
等于 n-1 (10 - 1 = 9) 时切换 samp_clk
。
always @(posedge clk) begin
if (~reset) begin
samp_clk <= 0;
end
else begin
if (counter == 9) begin
samp_clk <= ~samp_clk;
end
end
end
注意我把两个触发器分开了,方便调试
并且足够清楚地理解它的逻辑。
这是包含测试平台的代码。
module ten_clock(input clk, reset, output reg samp_clk);
reg [7:0] counter;
//'counter' counts the number of rising edges for system clock
always @ (posedge clk)begin
if(~reset)begin
counter <= 0;
end
else begin
if(counter == 10)begin
//samp_clk <= 1;
counter <= 0;
end
else begin
//samp_clk <= 0;
counter <= counter + 1;
end
end
end
//'samp_clk' is the sample clock, 'clock' is system clock
always @(posedge clk) begin
if (~reset) begin
samp_clk <= 0;
end
else begin
if (counter == 9) begin
samp_clk <= ~samp_clk;
end
end
end
endmodule
module test;
reg clk, reset;
wire samp_clk;
ten_clock ten_clock(.*);
initial begin
clk = 0;
forever #1 clk = !clk;
end
initial begin
reset <= 1;
repeat (2) @(posedge clk);
reset <= 0;
repeat (2) @(posedge clk);
reset <= 1;
repeat (100) @(posedge clk);
$finish;
end
initial begin
$dumpfile("dump.vcd"); $dumpvars;
end
endmodule
你可以试试运行这个
code 看波形
如果此行为符合您的预期。
我是 Verilog 的新手,所以我不知道该怎么做。我有一个时钟,'samp_clk',它每 10 个系统时钟周期切换一次,'clock'(或者这就是我试图做的)。这是我目前所拥有的:
//'counter' counts the number of rising edges for system clock
//'samp_clk' is the sample clock, 'clock' is system clock
always @ (posedge clock)begin
if(~reset)begin
if(counter == 10)begin
samp_clk <= 1;
counter <= 0;
end
else begin
samp_clk <= 0;
counter <= counter + 1;
end
end
end
按照我写的方式,我觉得我的 samp_clk 只会在一个时钟周期内保持断言。我怎样才能让它每十个时钟周期在 1 和 0 之间切换?
你要切换,就切换。
另请注意,要每 10 个时钟切换一次,当计数器的值为 10-1 时,您必须将计数器设置为 0。
试试这个(未测试):
//'counter' counts the number of rising edge s for system clock
//'samp_clk' is the sample clock, 'clock' is sy stem clock
always @ (posedge clock)begin
if(~reset)begin
if(counter == 9)begin
samp_clk <= ~samp_clk;
counter <= 0;
end
else begin
counter <= counter + 1;
end
end
else begin
samp_clk <= 0;
end
end
你是对的,当 counter
为 10
时,此代码将 samp_clk
设置为 1
,否则将其设置为 0
。这意味着您将拥有一个信号,该信号在 1 个时钟周期内有效,在 10 个时钟周期内保持低电平。基本逻辑是正确的(计数10个时钟周期)但是给samp_clk
的值不正确。
你想要的是 samp_clk
与上一个循环中的值相同,如果 counter
ins't 10
并翻转 samp_clk
几时。要翻转信号,您希望将信号分配给信号的反转:samp_clk <= ~samp_clk
.
完成该工作后,您可能需要重构代码,因为我认为它会在当前状态下生成锁存器。
来自您的代码:
if(counter == 10)begin
samp_clk <= 1;
counter <= 0;
end
这将产生 11 个时钟周期,因为我们从 0 开始计数到 10。
第一步,定义一个计数器,其中它重置为某个值
数(时钟周期)。比如你要检测10时钟
循环(n = 10),当counter
大于或等于9时,
它设置回 0。
always @ (posedge clk)begin
if(~reset)begin
counter <= 0;
end
else begin
if(counter >= 9)begin
counter <= 0;
end
else begin
counter <= counter + 1;
end
end
end
然后简单地,当 counter
等于 n-1 (10 - 1 = 9) 时切换 samp_clk
。
always @(posedge clk) begin
if (~reset) begin
samp_clk <= 0;
end
else begin
if (counter == 9) begin
samp_clk <= ~samp_clk;
end
end
end
注意我把两个触发器分开了,方便调试 并且足够清楚地理解它的逻辑。
这是包含测试平台的代码。
module ten_clock(input clk, reset, output reg samp_clk);
reg [7:0] counter;
//'counter' counts the number of rising edges for system clock
always @ (posedge clk)begin
if(~reset)begin
counter <= 0;
end
else begin
if(counter == 10)begin
//samp_clk <= 1;
counter <= 0;
end
else begin
//samp_clk <= 0;
counter <= counter + 1;
end
end
end
//'samp_clk' is the sample clock, 'clock' is system clock
always @(posedge clk) begin
if (~reset) begin
samp_clk <= 0;
end
else begin
if (counter == 9) begin
samp_clk <= ~samp_clk;
end
end
end
endmodule
module test;
reg clk, reset;
wire samp_clk;
ten_clock ten_clock(.*);
initial begin
clk = 0;
forever #1 clk = !clk;
end
initial begin
reset <= 1;
repeat (2) @(posedge clk);
reset <= 0;
repeat (2) @(posedge clk);
reset <= 1;
repeat (100) @(posedge clk);
$finish;
end
initial begin
$dumpfile("dump.vcd"); $dumpvars;
end
endmodule
你可以试试运行这个 code 看波形 如果此行为符合您的预期。