對於FPGA的verilog語言,,,規定一個變量不能在多個always中被賦值.但是可以在多個alway塊中做判斷--結合狀態機思想
module state(key,led,clk); input key;//輸入按鍵 input clk;//輸入時鍾48M output reg led;//輸出led reg state=0;//記錄按鈕狀態 reg[27:0] cnt=0;//計數器 always@(*) begin if(key == 0)//按下了 state = 1; //狀態置一 else if(cnt==48000000)//到了計數值 state = 0;//狀態復位 end always@(posedge clk) begin if(state == 1)//如果狀態置一 cnt<=cnt+1'b1;//開始計數 else cnt<=0;//松開或沒有按下,清零 end always@(posedge clk) begin if(state == 1)//如果狀態置一 led <=1;//燈亮 else led <=0; end endmodule
按下按鍵燈就會亮,如果一直按着燈就會一直亮(
if(key == 0)//按下了 state = 1; //狀態置一 else if(cnt==48000000)//到了計數值 state = 0;//狀態復位
),可以改變一下代碼,變成按下松開燈亮一秒后滅,就是加一個松手檢測,或者做別的修改...
一開始請教的群里的大神給的代碼--狀態機思想
module relay(input clk,//輸入時鍾 input rst,//輸入復位 input a, //輸入信號 output reg b//輸出 ); reg[3:0] current_state=0,next_state=0;//現在的狀態,下一個狀態 reg[27:0] state_cnt=0;//狀態計數 localparam sIdle_state=0;//空閑 localparam sInput_high=1;//輸入高 localparam sInput_low=2;//輸入低 localparam sOutput_pluse=3;//輸出 always@(posedge clk or negedge rst) begin if(~rst) current_state <= sIdle_state;//復位空閑 else current_state <= next_state;//把下一個狀態給它 end always@(*) begin case(current_state) sIdle_state://空閑態 begin if(a==1)//輸入為高 next_state <= sInput_high;//賦為輸入高 else next_state <= current_state;//賦為空閑 end sInput_high://輸入高 begin if(a==0) next_state = sInput_low;//賦為輸入低 else next_state = current_state;//賦為空 end sInput_low://輸入低 begin next_state = sOutput_pluse;//賦為端口輸出模式 end sOutput_pluse: begin if(state_cnt == 48000000) next_state = sIdle_state; else next_state = current_state;//現在的狀態 end default: next_state = sIdle_state; endcase end always@(posedge clk or negedge rst) begin if(~rst) begin b<=0; end else begin case(next_state) sIdle_state://如果是空閑狀態 begin end sOutput_pluse://如果是輸出狀態 b<=1;//輸出高 default: b<=0; endcase end end always@(posedge clk or negedge rst) begin if(~rst) state_cnt <= 0; else if(next_state != current_state)//如果上一個狀態和現在的不一樣 state_cnt<=0; else state_cnt<=state_cnt+1'b1; end endmodule