初学者流水灯程序,请大侠们帮看一下哪里的问题!
module led(rst,clk,dout);input rst,clk;//输入:复位,50M时钟
output dout;//四位数据输出,连led灯
reg dout;
reg c_state,n_state;
parameter idle=3'b000;
parameter st1=3'b001;
parameter st2=3'b011;
parameter st3=3'b010;
parameter st4=3'b110;
reg divide_count;//分频计数值
reg divide_clk;//分频信号线
reg cnt;//计数寄存器
/*
always @(posedge clk or negedge rst)
begin
if(!rst)
begin
divide_count <=26'b0;
divide_clk <=1'b0;
end
else if(divide_count == 50000000)
begin
divide_count <=26'b0;
divide_clk <=~divide_clk;
end
else
divide_count <=divide_count+1'b1;
end
*/
always @(posedge clk or negedge rst)
begin
if(!rst)
begin
c_state<=idle;
end
else
begin
c_state<=n_state;
end
end
always @(posedge clk or negedge rst)
begin
if(!rst)
begin
cnt<=0;
dout<=4'b1111;
n_state<=idle;
end
else
begin
case(c_state)
idle:
begin
dout<=4'b1110;
n_state<=st1;
end
st1:
begin
dout<=dout ^ 4'b0001;
cnt<=cnt+1'b1;
if(cnt<3)
begin
n_state<=st1;
end
else
begin
cnt<=1'b0;
dout<=4'b1101;
n_state<=st2;
end
end
st2:
begin
dout<=dout ^ 4'b0010;
cnt<=cnt+1'b1;
if(cnt<3)
begin
n_state<=st2;
end
else
begin
cnt<=1'b0;
dout<=4'b1011;
n_state<=st3;
end
end
st3:
begin
dout<=dout ^ 4'b0100;
cnt<=cnt+1'b1;
if(cnt<3)
begin
n_state<=st3;
end
else
begin
cnt<=1'b0;
dout<=4'b0111;
n_state<=st4;
end
end
st4:
begin
dout<=dout ^ 4'b1000;
cnt<=cnt+1'b1;
if(cnt<3)
begin
n_state<=st4;
end
else
begin
cnt<=1'b0;
dout<=4'b1110;
n_state<=st1;
end
end
default:
begin
end
endcase
end
end
endmodule
这个程序是要实现每一个led灯轮流闪两下,但是出来的结果却是有时候好几个灯同时闪,总之时序是乱的。想了好久了,都没搞出来,望大虾们指点迷津!先谢了 我帮你看一下 只是一个流水灯,你这个写的太烦了吧。。 主要是想学一下状态机,但是看到第一个led灯一直在闪,而且仿真波形上看也是一直有电平跳变 有一段时间没用Verilog了,花了蛮久才找到问题,c_state的使用使得状态机延时一个周期了,直接用n_state就行了,前面的c_state那段直接去掉,后面的c_state改为n_state就可以了。 我觉得也是,你这样用那么多状态机去控制一个流水灯,没必要吧 我觉得你这个有很多问题:1,你没有用到分频,实际上电下载之后很难看清,50Mhz的频率啊!2,你程序中用到^ 看来你是想表达每次和上次 有关联吧,建议直接赋值,简单明了。3,程序好像没有你想像的那么复杂,就如之前的评论,状态机写的有些混乱。 你可以先让一个LED 亮,看到你想看到的结果。再顺序点亮,闪烁。再变化着方式 循环! 小弟愚见! 嗯, 楼上见解深入,我估计这些问题都挺值得考虑的 神马叫状态机 分频,把速度降到人眼能识别的程度。另外,楼上几位说的也是非常正确的。学习了。
确实感觉楼主弄得有点麻烦了。
页:
[1]
2