|
本人硬件工程师职位,1年工作经验,由于工作上面需要,所以决定自学FPGA,以前对51单片机了解的比较多,现在写Verilog代码就会有C语言的风格,本人也是知道两者差别较大,但是目前作为新手不好找出出错的原因,翻阅资料也没弄明白昨天的代码出错在哪里了,也许有谁稍微指点一下我就突然明白了,先谢谢阅读此贴的顾客了。
借来了一个黑金的开发板,在上面试着烧了一个例程的源码,简单测试之后认为开发板还能正常工作,如是就按照自己的理解,重新按照自己的想法写了一个功能相同的流水灯程序,经过反复修改编译,最后终于不报错了,但是有很多警告,先不管那么多了,烧进板子居然只亮了一个灯。经过反复调试修改代码,最后还是只亮一个灯。可是我觉得源代码没什么错啊,望各位指点。
附上源码:
- //定义模块,模块名:led_water,3个端口类型:时钟,复位,输出口
- module led_water(CLK, RSTn, LED_Out);
- input CLK; //输入端口,时钟
- input RSTn; //输入端口,复位
- output [3:0] LED_Out; //输出端口,4个LED接口
-
- /*******************************/
-
- //wire LED0_Out; //LED0输出端口用导线连接到外部引脚
-
- parameter T4S = 32'd200_000_000;//延时4秒钟的值,这里相当于C语言的define
- parameter T3S = 32'd150_000_000;//
- parameter T2S = 32'd100_000_000;//
- parameter T1S = 32'd50_000_000;//
-
- reg[31:0]Timer_Counter;//定义变量,类型为32位
- reg[3:0] LED_Out_Temp;
-
- always @ ( posedge CLK or negedge RSTn )
- if( !RSTn )
- LED_Out_Temp<= 4'b0000;
- else if( Timer_Counter < T1S )
- LED_Out_Temp = 4'b1000;
- else if( Timer_Counter >= T1S && Timer_Counter < T2S )
- LED_Out_Temp = 4'b0100;
- else if( Timer_Counter >= T2S && Timer_Counter < T3S )
- LED_Out_Temp = 4'b0010;
- else
- LED_Out_Temp = 4'b0001;
- always @ ( posedge CLK or negedge RSTn )
- Timer_Counter = Timer_Counter + 1'b1;
- assign LED_Out =LED_Out_Temp;
-
- endmodule
复制代码
又经过一下午的时间摸索,终于搞定了,程序编译没有错误,但有4个警告,烧到板子里面现象正确。期间遇到了很多的问题,经过例程、参考教程、百度、尝试等手段将一个个的问题慢慢解决,终于把现象搞出来了,对于新手来说是莫大的安慰啊。
源代码:- //定义模块,模块名:led_water,3个端口类型:时钟,复位,输出口
- module led_water(CLK, RSTn, LED_Out);
- input CLK; //输入端口,时钟
- input RSTn; //输入端口,复位
- output [3:0] LED_Out; //输出端口,4个LED接口
- //在C语言里面#define作为替换使用,在Verilog里面parameter作为替换使用
- parameter T4S = 32'd200_000_000;//
- parameter T3S = 32'd150_000_000;//
- parameter T2S = 32'd100_000_000;//
- parameter T1S = 32'd50_000_000;//
- //LED端口作为硬件输出接口,不能设定为wire类型,而用reg类型,但是硬件输入接口需要用wire类型
- reg [3:0]LED_Out;
- //内部数据寄存器要用reg类型定义,即:register寄存器
- reg[31:0]Timer_Counter;
- reg[3:0] LED_Out_Temp;
- //在C语言里面“{”作为函数内容开始“}”作为函数内容结束,但是Verilog里面以“begin”开始“end结束”
- //always相当于C语言里面的“while()”
- always @ ( posedge CLK or negedge RSTn ) //在时钟的上升沿或者复位脚的下降沿触发
- if( !RSTn ) //如果复位按键按下就清零
- begin
- LED_Out_Temp = 4'b0000;
- Timer_Counter = 1'b0;
- end
- else if( Timer_Counter < T1S )
- begin
- LED_Out_Temp = 4'b0001;
- Timer_Counter = Timer_Counter + 1'b1;
- end
- else if( Timer_Counter >= T1S && Timer_Counter < T2S )
- begin
- LED_Out_Temp = 4'b0010;
- Timer_Counter = Timer_Counter + 1'b1;
- end
- else if( Timer_Counter >= T2S && Timer_Counter < T3S )
- begin
- LED_Out_Temp = 4'b0100;
- Timer_Counter = Timer_Counter + 1'b1;
- end
- else if( Timer_Counter >= T3S && Timer_Counter < T4S )
- begin
- LED_Out_Temp = 4'b1000;
- Timer_Counter = Timer_Counter + 1'b1;
- end
- else if( Timer_Counter >= T4S)
- begin
- Timer_Counter = 1'b0;
- end
- always @ ( posedge CLK or negedge RSTn )
- begin
- LED_Out = LED_Out_Temp; //作为数据输出不能用assign赋值
- end
- endmodule
复制代码 一开始发现之前发的代码数据没有清空,改了Bug之后报错;后来又发现并行操作不同于单片机的顺序操作,多个地方赋值就报错;还有外部数据输入用wire类型定义,输出则直接赋值。
欢迎各位顾客吐槽 |
|