对于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