感谢EEPW网友群里Q友们的帮助。
特别感谢EEPW-jlhgold,j03128,xieyuanfu,haitao2000s等朋友给我的帮助,还要感谢听说野鬼要给我加分,最后CCAV就不感谢了。
硬件平台:FPGA DIY—EEPW活动板
Quartus 9.0环境编译
实验目的:实现流水灯led0~led7
首先查看一下代码
代码一
module led(clk,reset,led);
input clk; //50MHz
input reset; //复位信号,低电平有效
output [7: 0] led; //8个LED灯
reg[7:0] led;
reg[7: 0] led_r;
reg[25:0] counter;
initial
begin
counter= {26{1'b0}};
led_r = {8{1'b1}};
end
always @(posedge clk or negedge reset)
if(!reset)
led_r={8{1'b1}}; //初始化led_r为全1
else
begin
counter=counter+1;
if(counter==26'b10111110101111000010000000) //50M
begin
led_r <= ((led_r<<1)+1); //红色部分
counter=0;
if(led_r=={8{1'b1}})
begin
led_r <= 8'b11111110; //绿色部分
end
led <= led_r;
end
end
endmodule
以上代码一能正常实现流水灯功能。
当然在实验中有很多弯路
问题一: 将上述代码的红色部分改成成两条语句
led_r <=led_r<<1;
led_r<=led_r+1;
改写之后,编译烧写发现实现并不是想象中的流水灯。
问题所在:经过QQ群里好心人的解答,应该是<=这个非阻塞型语句的问题,在always里非阻塞性语句是并行执行的,所以所谓的流水灯逻辑就凌乱了。当然把两条语句的<=都改成=,然后将绿色的<=也改成=(问题二),编译后即可实现流水灯功能。
问题二:将上述的绿色的<=改成= 就会出现编译错误。
问题所在:在顺序块里只能对同一种变量只能使用一种赋值语句(要么全为阻塞,要么全为非阻塞)。即将上述代码中的红色与绿色的赋值符号相同即可。
OK 所有问题解决,总结一下:在顺序块赋值时,不能随便使用阻塞与非阻塞赋值。
代码二:
另一种方法实现流水灯功能
module led(clk,reset,led);
input clk; //50MHz
input reset; //复位信号,低电平有效
output [7: 0] led; //8个LED灯
reg[7:0] led;
reg[7: 0] led_r;
reg[25:0] counter;
initial
begin
counter= {26{1'b0}};
led_r = {8{1'b1}};
end
always @(posedge clk or negedge reset)
if(!reset)
led_r<={8{1'b1}};
else
begin
counter<=counter+1;
if(counter==26'b10111110101111000010000000) //50M
begin
led_r <= ~(~led_r <<1);
counter<=0;
if(led_r=={8{1'b1}})
begin
led_r<=8'b11111110;
end
led <= led_r;
end
end
endmodule
提问者:E丶mpty (EEPW注册名eepwempty) 回答者:EEPW-jlhgold(EEPW注册名jlhgold),xieyuanfu,haitao2000s