||
从2016年6月25日开始进行FPGA的学习,目前进行了几个简单的实验和仿真,在使用过程中由于对语法的不熟悉,导致在某些问题上浪费了大量的时间。现在通过写博客的方式记录我的学习历程,并且将学习过程中所遇到的问题进行总结,以便自己提升。
一、 关于近期的几个简单的实验。
首先进行了基本的LED的实验,实现了简单的LED的闪烁、流水等、跑马灯的实验,确保了基本的工具的使用和相关的语法的具体实现。代码很简单,只是用来练手,激发自己的学习兴趣。
其中比较繁杂一点的代码就是跑马灯的实现,通过拨码开关实现3种花色的控制。具体的代码如下:
1 module SwCtrWater(
2 clk ,
3 rstn,
4 LED ,
5 SW
6 );
7
8 input clk ;
9 input rstn ;
10 input SW ;
11
12 output [7:0] LED ;
13
14 wire [2:0] SW ;
15
16 reg [24:0] count ;
17 reg [7:0] LED ;
18 //wire
[2:0] sw_pre;
19 reg flag;//用于指示一个循环的结束
20 /*reg
[3:0] ConstantA = 4'b1111;
21 reg [3:0] ConstantB
= 4'b1111;*/
22
23 //assign
sw_pre = SW ; //开关控制流水等的样式
24
25 always@(posedge clk or negedge rstn)
26 if(!rstn)
27 LED <= 8'b11111111;
28 else
29 begin
30 case(SW)
31 3'b000://实现从左到右依次亮起来
32 begin
33 if(LED == 8'b00000000)
34 LED <= 8'b11111111;
35 else if(count == 25'd24999999)
36 LED <= LED << 1;
37 else
38 LED <= LED;
39 end
40 3'b001://实现从右到左依次亮起来
41 begin
42 if(LED == 8'b00000000)
43 LED <= 8'b11111111;
44 else if(count == 25'd24999999)
45 LED <= LED >> 1;
46 else
47 LED <= LED;
48 end
49 3'b010:
50 begin
51 if(count == 25'd24999999 && flag == 1'd0)
52 begin
53 LED <= {LED[7:4]>>1,LED[3:0]<<1};
54 if(LED == 8'b00000000)
55 flag <= flag + 1'b1;
56 end
57 else if(count == 25'd24999999 && flag ==1'd1)
58 begin
59 LED<={(LED[7:4]<<1)+1'b1,(LED[3:0]>>1)+4'b1000};
60 if(LED == 8'b11111111)
61 flag <= 1'd0;
62 end
63 else
64 LED <= LED ;
65 end
66 default:LED <= LED;
67 endcase
68 end
69 //产生0.5s的定时时间
70 always@(posedge clk or negedge rstn)
71 if(!rstn)
72 count <= 25'd0;
73 else
74 begin
75 if(count == 25'd24999999)
76 count <= 25'd0;
77 else
78 count <= count + 1'b1;
79 end
80 endmodule
二、
在进行第一次仿真的时候遇到了如下的几个问题。
(1)、我使用的是xilinx和modelsim的联合仿真。在我编写完成testbench之后,发现不能进行仿真,通过排查代码也没有发现任何问题。网上搜索答案也没有找到靠谱的,所以研究了几天,最后通过咨询高手终于得以解决。
首先将我的第一次的代码附上:
1 module sparkleLight(
2 input
clk,
3 input
rstn,
4 output
[7:0]
LED_T 这种写法默认为wire类型的
5
);
6
7
8
reg [7:0]
LED_T; //输出定义为寄存器类型的 此处重复定义
9
10
always
11
begin
12 LED_T <= 8'b10101010;
13
end
14
15 endmodule
我的testbech的代码如下:
1
module sparkleLight_test;
2
3
// Inputs,对于测试平台而言,模块输入由于是可以更改的,所以需要定义为reg
4
reg clk;
5
reg rstn;
6
7
// Outputs,对于测试平台而言,模块的输出由于只是用来观看输出结果或者进行比较使用,所以输出定义为wire型
8
wire [7:0] LED1=0;
9
10
parameter PERIOD = 20;//定义时钟周期为20ns
11
//
Instantiate the Unit Under Test (UUT)
12
sparkleLight uut (
13 .clk(clk),
14 .rstn(rstn),
15 .LED_T(LED1)
16
);
17
18
initial begin
19 // greate clk;
20 clk = 0;
21 forever
22 begin
23 #(PERIOD/2) clk = ~clk;
24 $display("LED's value is %b",LED1);
25
end
26
end
27
28
//create rstn
signle
29
initial begin
30
31 reset_task(100);
32 #5000;
33 $stop;
34
end
35
36
task reset_task;
37 input [15:0] reset_time;//task的输入参数
38 begin
39 rstn = 0;
40 #reset_time;
41 rstn = 1;
42 end
43
endtask
44
经过仿真,发现出现了如下错误:
经过几天的摸索和咨询高手,终于发现了问题所在。原来是我源代码中端口声明写的有问题,导致了端口重复定义。
1 module sparkleLight(
2 input
clk,
3 input
rstn,
4 output [7:0]
LED_T //这种写法默认为wire类型的
5
);
6
7
8
reg [7:0]
LED_T; //输出定义为寄存器类型的 此处重复定义
所以只要进行简单的修改即可。
1
module sparkleLight(
2
clk,
3
rstn,
4
LED
5
);
6
7
input clk;
8
input rstn;
9
output [7:0] LED;
10
reg [7:0] LED_T; //输出定义为寄存器类型的
问题得到完美解决。
遗留问题:
在仿真的时候,虽然可以正常的完成仿真项目,但是在xinlinx的编辑框中出现了如下的warning,一直没有得到解决。
WARNING: unable to
resolve env var in modelsim.ini file entry: $::env(MODEL_TECH)/../modelsim.ini
WARNING: unable to
resolve env var in modelsim.ini file entry: $::env(MODEL_TECH)/libsm.sl
WARNING: unable to
resolve env var in modelsim.ini file entry: $::env(MODEL_TECH)/libhm.sl
希望各位网友可以讨论下。这个问题后续慢慢解决。
注:目前看到的一种解法是说modelsim和xinlinx的安装顺利不同导致的。不过还没有进行尝试。