我的always裡面有兩個posedge訊號,CLK_LF(頻率較低)和CLK(頻率較高)
若是CLK_LF的正緣,則irq=1,若是CLK的正緣,則irq=0。程式碼如下
always @( posedge CLK or posedge CLK_LF ) begin
if (CLK_LF) begin
irq<=1;
end
else begin
irq<=0;
end
end
但這樣實際上會有一個問題,當此時是CLK正緣來的時候會先執行if (CLK_LF)判斷是否為真,但這個情況下好像是看CLK_LF是否為邏輯1,而不是判斷CLK_LF是否為正緣,請問要如何寫出if (CLK_LF正緣)的verilog?
根據取樣定理, 如果CLK頻率是CLK_LF頻率的两倍或以上,便可以對CLK_LF進行取樣。
因此,在always區塊裏面,不論觸發是來自CLK或者CLK_LF,都可以對CLK_LF進行取樣(只要符合[取樣定理]便可以)。
當下次always被觸發的時候,便可用之前CLK_LF的取樣,比對觸發時CLK_LF的狀態,判斷觸發是否來自CLK_LF正緣。
[備註]當CLK正緣和CLK_LF正緣同時出現時,IRQ會被設定為1。
[Module]
module block(input clk_lf, input clk, output irq);
reg irq = 0;
reg clk_lf_r = 0; // 記錄clk_lf狀態
always @ (posedge clk or posedge clk_lf) begin
if( clk_lf & ~clk_lf_r ) begin // clk_lf正緣
irq <= 1;
end
else begin // clk正緣
irq <= 0;
end
clk_lf_r <= clk_lf; // 對clk_lf取樣
end
endmodule
[TestBench]
module main;
reg clk, clk_lf;
wire irq;
block blk1(clk_lf, clk, irq);
integer x;
initial begin
$monitor("t=%03d clk=%1d clk_lf=%1d, irq=%1d \n", $time, clk, clk_lf, irq );
for( x = 0; x < 5; x = x + 1 ) begin
clk_lf <= 0;
#30
clk_lf <= 1;
#25
clk_lf <= 0;
end
$finish;
end
initial begin
forever begin
clk <= 0;
#10
clk <= 1;
#10
clk <= 0;
end
end
endmodule