2017-04-11 31 views
0

我想寫一個滾動移位/環形計數器,需要兩個開關作爲verilog中的時鐘。兩個時鐘環形計數器與Verilog

我的代碼如下:

module roll(CLK1, CLK2, LEDS); 
input CLK1; 
input CLK2; 
output [3:0] LEDS; 
reg [3:0] LEDS; 


initial 
begin 
LEDS = 4'b0001; 
end 


[email protected](posedge CLK1 or posedge CLK2) 
begin 
if(CLK1) 
begin 

     LEDS[3]<=LEDS[2]; 
     LEDS[2]<=LEDS[1]; 
     LEDS[1]<=LEDS[0]; 
     LEDS[0]<=LEDS[3]; 
end 

// Roll Right 
if(CLK2) 
begin 
     LEDS[3]<=LEDS[0]; 
     LEDS[2]<=LEDS[3]; 
     LEDS[1]<=LEDS[2]; 
     LEDS[0]<=LEDS[1]; 

end 
end 
endmodule 

我試圖用兩個always塊,但後來想通了,我不能這樣做。當我在always聲明中使用posedge CLK2時,我的FPGA上的LED全部保持亮起。

+0

Ofcouse,因爲你有多個驅動程序。您需要爲此分配使用多路複用器。 – Roman

+0

這個問題更多的是關於數字邏輯能做些什麼而不是關於Verilog的語法或語義,所以它可能屬於[Electrical Engineering Stackexchange](http://electronics.stackexchange.com)而不是這裏。 –

回答

4

記住Verilog不是一種編程語言,它是一種硬件描述語言。

當編寫綜合代碼時,只有編寫可以用實際門實例化的代碼才能成功。因此,如果對兩個信號之一的響應具有RESET或PRESET操作的效果,則不能合成寫入對兩個不同信號的邊沿敏感的always塊。

你的代碼在邏輯上也不會做你想要的東西。考慮到當CLK1已經很高時(如果CLK2有上升沿的話),你的代碼會發生什麼情況。你的燈會向左滾動,然後立即滾動右邊的增益,導致沒有變化。

更常見的方法是讓一個時鐘的運行速度比預期的UP和DOWN輸入變化更快,然後用它來驅動邏輯。例如,

module roller(input clk, input rst, input UP, input DOWN, output reg LEDS[3:0]); 

reg UP1, DOWN1; 

always @(posedge clk or posedge rst) 
if (rst) begin 
    LEDS[3:0] <= 4'b0001; 
end 
else 
begin 
    UP1 <= UP; 
    DOWN1 <= DOWN; 
    if (UP & ~UP1) begin 
     LEDS[3:0] <= {LEDS[2:0], LEDS[3]}; 
    end 
    else if (DOWN & ~DOWN1) begin 
     LEDS[3:0] <= {LEDS[0], LEDS[3:1]}; 
    end 
end 
endmodule; 

請注意,這給予UP的優先權。如果UP和DOWN兩者均被置位,則模式將向上滾動而不是向下滾動。如果你想要一個不同的行爲,你必須修改代碼來實現它。