FPGA按一下按鍵,對應端口輸出單個脈沖


對於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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM