新手求教:quartus verilog 关于timescale的问题。。
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了新手求教:quartus verilog 关于timescale的问题。。相关的知识,希望对你有一定的参考价值。
用quartus设计verilog代码的时候 ,整了半天感觉timescale和#(延迟)一点作用都没有。。
我是这么作的:我用的是Vector Waveform file 产生的波形。。是不是要先在Simulator Tool下把mode设置成Functional,再Generate Functional Simulation Netlist一下,然后无论如何调整timescale 和# 都一点效果都没有。
我也试过Simulator Tool下把mode设置成Time 但是产生的波形跟我的设计似乎没啥关系。想知道这两个选项到底是作什么用的。
本来我想用他产生一个时钟波形:代码如下
`timescale 2ns/1ns
module jiou(clk);
output reg clk;
initial
begin
clk=0;
#1 forever
#5 clk=~clk;
end
endmodule
他提示。。non-constrast循环不能超过250次。这是为什么啊。书上就是这么写的
弄的我只好用repeat产生少几个时钟,但是最后也因为timescale的关系就是一条直线。
我是自学这个东西的。大家多多帮助哈~~
`timescale 1ns/1ns
改了以后,我用modelsim跑试了一下,可以跑出波形。
另外,需要设置一个时间限制,不然会一直跑下去停不了。再添加一点东西:
initial
begin
#1000
$stop;
end
你的资料书质量不太高,仿真工具也不太行。追问
额。资料书夏文宇翻译的verilog hdl 入门,软件用的是quartus II 9.0
我这个软件按你说的改了timescale和加上时间限制还是不行
还是提示Error (10119): Verilog HDL Loop Statement error at jiou.v(8): loop with non-constant loop condition must terminate within 250 iterations 。
是不是仿真的时候都用modelsim,不用quartus 啊,初入此道,十分受挫。。。照书打都出问题
只听说过“夏宇闻”,没听说过“夏文宇”
夏宇闻的资料适合入门,但入门了就不要再用了,很多东西不实用,代码风格也是乱七八糟的。
另外,在本人就职过的几家公司里,没看到哪个工程师用quartus,PC机上都是用modelsim。可能是本人孤陋寡闻吧。
原创如何使用DE2的1602LCD --之一(quartus)(verilog)(digital logic)
1. 缘起
会了点HDL和数字逻辑基础后,操作DE2上的开关,led,7断码数码管都没啥问题,但至此好像也只能玩玩n年前教科书上都有的lab,啥数字钟,汽车尾灯,交通灯之类。浪费了DE2的资源,未免对不起DE2的价钱。板子上最明显的东东莫过于那个1602的LCD了,遂想玩玩这个东东。伟大的教育培养的惯性思维:照书本来,狗来狗去,国产的似乎就只有一本关于DE2的书(上交的一个博士写的),拜读一下,大半是DE2附带的光盘lab的中译版,。。。总之,DE2的玩法,没在这本书里找到,估计又是应付国内职评的产物。没期望过,所以没啥失望,好在web上tw的教育网页可打开,那边的学生都推荐OO无双说过的那两本,遍历卓越等,大陆没引进,所以没得卖。再看看老美的,别个用乔治亚理工的helben写的那本,down个电子版(同样国内没引进,amazon上60多刀)。遗憾没得随书的DVD,里面的source code都在DVD上,只能看个大概。看来国内的高人都没得时间写书。要玩转这个LCD,还的靠自己。一切还是老老实实的从DE2附带的DEMO开始(感谢terasic,起码提供了demo)。
2. 涅槃
手边最基本、最可靠的东东就是DE2光盘里的DEMO和datasheet了,俺喜欢从低级的玩起,所以代码就从default开始。先看datasheet,这个LCD的控制器是HD4470,说是较通用的型号,以前没玩过,不知道有多通用,简化版的datasheet有16页,主要说明这块LCD可以显示英文、数字、标点符号和日文。中文估计得自己加字库,(加到哪里,flash?啥,俺现在还比较糊,所以先不考虑显示中文。)
总结一下这块LCD:共计11条指令,指令格式用RS,RW,DB7-0共10位的方式表示。
- display_clear = 00_0000_0001
功能:DDRAM设为20H、光标回到起始位置、AC置0.
2. return_home = 00_0000_001x
功能:光标回到起始位置、AC置0、DDRAM内容不变。
3. mode_set = 00_0000_01 l/D S
功能:设定每次输入一位数据后,光标的移动方向,并且设定每次写入的一个字符是否移动。
l/D 0-左移;1-右移。
S 0-屏不动;1-屏右移1。
4. display_on = 00_0000_1 D C B
功能:控制显示的开关,光标显示/关闭,以及光标是否闪烁。
D 0-显示关;1-显示开。
C 0-无光标;1-有光标。
B 0-光标闪;1-不闪。
5. cursor or display shift = 00_0001_S/C R/L xx
功能:S/C R/L
0 0 光标左移1格,且AC-1
0 1 光标右移1格,且AC+1
1 0 显示屏上的字符全左移1格,但光标不动
1 1 显示屏上的字符全右移1格,但光标不动
6. function set = 00_001DL_NFxx
功能:设定数据总线位数,显示的行数及字型。
DL 0-4 bit 1-8 bit
N 0-1行 1-2行
F 0-5*8dots 1-5*11dots
7. set CGRAM address = 00_01_AC5-0
8. set DDRAM address = 00_1_AC6-0
9. read busy flag and address = 01_BF_AC6-0
BF 1-忙, 0-可接受外部数据或指令。
10. write data to RAM = 10_D7-0
字符码写入DDRAM,显示字符;自定义图形存入CGRAM。
11. read data from RAM = 11_D7-0
除了上述11条指令,比较难的就是时序,读、写的时序,每条指令的执行时间。对于LCD_EN,有2中有效状态,高电平和下降沿。其为高电平时读取信息;下降沿时执行指令。在将E置高电平之前,先设置好RS和RW,在E下降沿到来之前,准备好写入的命令或数据。只需在适当的地方加上延时,就可以满足要求。
DDRAM里的内容是要显示的字符的地址,DDRAM的地址是显示字符的位置。AC在显示字符串时用。
3. 代码
目的是显示如图所示的字符。
代码:
1 module LCD_top(
2 CLOCK_50, // 50 MHz
3 LCD_ON, // LCD Power ON/OFF
4 LCD_BLON, // LCD Back Light ON/OFF
5 LCD_RW, // LCD Read/Write Select, 0 = Write, 1 = Read
6 LCD_EN, // LCD Enable
7 LCD_RS, // LCD Command/Data Select, 0 = Command, 1 = Data
8 LCD_DATA // LCD Data bus 8 bits
9 );
10
11 input CLOCK_50; // 50 MHz
12 inout [7:0] LCD_DATA; // LCD Data bus 8 bits
13 output LCD_ON; // LCD Power ON/OFF
14 output LCD_BLON; // LCD Back Light ON/OFF
15 output LCD_RW; // LCD Read/Write Select, 0 = Write, 1 = Read
16 output LCD_EN; // LCD Enable
17 output LCD_RS; // LCD Command/Data Select, 0 = Command, 1 = Data
18
19 // LCD ON
20 assign LCD_ON = 1b1;
21 assign LCD_BLON = 1b1;
22
23 wire DLY_RST;
24
25 Reset_Delay r0 ( .iCLK(CLOCK_50),.oRESET(DLY_RST) );
26
27 LCD_TEST u5 ( // Host Side
28 .iCLK(CLOCK_50),
29 .iRST_N(DLY_RST),
30 // LCD Side
31 .LCD_DATA(LCD_DATA),
32 .LCD_RW(LCD_RW),
33 .LCD_EN(LCD_EN),
34 .LCD_RS(LCD_RS) );
35
36 endmodule
37
1 module LCD_TEST ( // Host Side
2 iCLK,iRST_N,
3 // LCD Side
4 LCD_DATA,LCD_RW,LCD_EN,LCD_RS );
5 // Host Side
6 input iCLK,iRST_N;
7 // LCD Side
8 output [7:0] LCD_DATA;
9 output LCD_RW,LCD_EN,LCD_RS;
10 // Internal Wires/Registers
11 reg [5:0] LUT_INDEX;
12 reg [8:0] LUT_DATA;
13 reg [5:0] mLCD_ST;
14 reg [17:0] mDLY;
15 reg mLCD_Start;
16 reg [7:0] mLCD_DATA;
17 reg mLCD_RS;
18 wire mLCD_Done;
19
20 parameter LCD_INTIAL = 0;
21 parameter LCD_LINE1 = 5;
22 parameter LCD_CH_LINE = LCD_LINE1+16;
23 parameter LCD_LINE2 = LCD_LINE1+16+1;
24 parameter LUT_SIZE = LCD_LINE1+32+1;
25
26 always@(posedge iCLK or negedge iRST_N)
27 begin
28 if(!iRST_N)
29 begin
30 LUT_INDEX <= 0;
31 mLCD_ST <= 0;
32 mDLY <= 0;
33 mLCD_Start <= 0;
34 mLCD_DATA <= 0;
35 mLCD_RS <= 0;
36 end
37 else
38 begin
39 if(LUT_INDEX<LUT_SIZE)
40 begin
41 case(mLCD_ST)
42 0: begin
43 mLCD_DATA <= LUT_DATA[7:0];
44 mLCD_RS <= LUT_DATA[8];
45 mLCD_Start <= 1;
46 mLCD_ST <= 1;
47 end
48 1: begin
49 if(mLCD_Done)
50 begin
51 mLCD_Start <= 0;
52 mLCD_ST <= 2;
53 end
54 end
55 2: begin
56 if(mDLY<18h3FFFE) // 5.2ms
57 mDLY <= mDLY+1;
58 else
59 begin
60 mDLY <= 0;
61 mLCD_ST <= 3;
62 end
63 end
64 3: begin
65 LUT_INDEX <= LUT_INDEX+1;
66 mLCD_ST <= 0;
67 end
68 endcase
69 end
70 end
71 end
72
73 always
74 begin
75 case(LUT_INDEX)
76 // Initial
77 LCD_INTIAL+0: LUT_DATA <= 9h038; //Fun set
78 LCD_INTIAL+1: LUT_DATA <= 9h00C; //dis on
79 LCD_INTIAL+2: LUT_DATA <= 9h001; //clr dis
80 LCD_INTIAL+3: LUT_DATA <= 9h006; //Ent mode
81 LCD_INTIAL+4: LUT_DATA <= 9h080; //set ddram address
82 // Line 1
83 LCD_LINE1+0: LUT_DATA <= 9h120; //
84 LCD_LINE1+1: LUT_DATA <= 9h168; // h
85 LCD_LINE1+2: LUT_DATA <= 9h174; // t
86 LCD_LINE1+3: LUT_DATA <= 9h174; // t
87 LCD_LINE1+4: LUT_DATA <= 9h170; // p
88 LCD_LINE1+5: LUT_DATA <= 9h13A; // :
89 LCD_LINE1+6: LUT_DATA <= 9h12F; // /
90 LCD_LINE1+7: LUT_DATA <= 9h12F; // /
91 LCD_LINE1+8: LUT_DATA <= 9h168; // h
92 LCD_LINE1+9: LUT_DATA <= 9h161; // a
93 LCD_LINE1+10: LUT_DATA <= 9h16C; // l
94 LCD_LINE1+11: LUT_DATA <= 9h166; // f
95 LCD_LINE1+12: LUT_DATA <= 9h16C; // l
96 LCD_LINE1+13: LUT_DATA <= 9h169; // i
97 LCD_LINE1+14: LUT_DATA <= 9h166; // f
98 LCD_LINE1+15: LUT_DATA <= 9h165; // e
99 // Change Line
100 LCD_CH_LINE: LUT_DATA <= 9h0C0;
101 // Line 2
102 LCD_LINE2+0: LUT_DATA <= 9h12E; // .
103 LCD_LINE2+1: LUT_DATA <= 9h163; // c
104 LCD_LINE2+2: LUT_DATA <= 9h16E; // n
105 LCD_LINE2+3: LUT_DATA <= 9h162; // b
106 LCD_LINE2+4: LUT_DATA <= 9h16C; // l
107 LCD_LINE2+5: LUT_DATA <= 9h16F; // o
108 LCD_LINE2+6: LUT_DATA <= 9h167; // g
109 LCD_LINE2+7: LUT_DATA <= 9h173; // s
110 LCD_LINE2+8: LUT_DATA <= 9h12E; // .
111 LCD_LINE2+9: LUT_DATA <= 9h163; // c
112 LCD_LINE2+10: LUT_DATA <= 9h16F; // o
113 LCD_LINE2+11: LUT_DATA <= 9h16D; // m
114 LCD_LINE2+12: LUT_DATA <= 9h120;
115 LCD_LINE2+13: LUT_DATA <= 9h120;
116 LCD_LINE2+14: LUT_DATA <= 9h120;
117 LCD_LINE2+15: LUT_DATA <= 9h120;
118 default: LUT_DATA <= 9h000;
119 endcase
120 end
121
122 LCD_Controller u0 ( // Host Side
123 .iDATA(mLCD_DATA),
124 .iRS(mLCD_RS),
125 .iStart(mLCD_Start),
126 .oDone(mLCD_Done),
127 .iCLK(iCLK),
128 .iRST_N(iRST_N),
129 // LCD Interface
130 .LCD_DATA(LCD_DATA),
131 .LCD_RW(LCD_RW),
132 .LCD_EN(LCD_EN),
133 .LCD_RS(LCD_RS) );
134
135 endmodule
1 module LCD_Controller ( // Host Side
2 iDATA,iRS,
3 iStart,oDone,
4 iCLK,iRST_N,
5 // LCD Interface
6 LCD_DATA,
7 LCD_RW,
8 LCD_EN,
9 LCD_RS );
10 // CLK
11 parameter CLK_Divide = 16;
12
13 // Host Side
14 input [7:0] iDATA;
15 input iRS,iStart;
16 input iCLK,iRST_N;
17 output reg oDone;
18 // LCD Interface
19 output [7:0] LCD_DATA;
20 output reg LCD_EN;
21 output LCD_RW;
22 output LCD_RS;
23 // Internal Register
24 reg [4:0] Cont;
25 reg [1:0] ST;
26 reg preStart,mStart;
27
28 /////////////////////////////////////////////
29 // Only write to LCD, bypass iRS to LCD_RS
30 assign LCD_DATA = iDATA;
31 assign LCD_RW = 1b0;
32 assign LCD_RS = iRS;
33 /////////////////////////////////////////////
34
35 always@(posedge iCLK or negedge iRST_N)
36 begin
37 if(!iRST_N)
38 begin
39 oDone <= 1b0;
40 LCD_EN <= 1b0;
41 preStart<= 1b0;
42 mStart <= 1b0;
43 Cont <= 0;
44 ST <= 0;
45 end
46 else
47 begin
48 ////// Input Start Detect ///////
49 preStart<= iStart;
50 if(preStart,iStart==2b01) // latch ?
51 begin
52 mStart <= 1b1;
53 oDone <= 1b0;
54 end
55 //////////////////////////////////
56 if(mStart) //generate LCD_EN
57 begin
58 case(ST)
59 0: ST <= 1; // Wait Setup, tAS >= 40ns
60 1: begin
61 LCD_EN <= 1b1;
62 ST <= 2;
63 end
64 2: begin
65 if(Cont<CLK_Divide)
66 Cont <= Cont+1;
67 else
68 ST <= 3;
69 end
70 3: begin
71 LCD_EN <= 1b0;
72 mStart <= 1b0;
73 oDone <= 1b1;
74 Cont <= 0;
75 ST <= 0;
76 end
77 endcase
78 end
79 end
80 end
81
82 endmodule
1 module Reset_Delay(iCLK,oRESET);
2 input iCLK;
3 output reg oRESET;
4 reg [19:0] Cont;
5
6 always@(posedge iCLK)
7 begin
8 if(Cont!=20hFFFFF) //21ms
9 begin
10 Cont <= Cont+1;
11 oRESET <= 1b0;
12 end
13 else
14 oRESET <= 1b1;
15 end
16
17 endmodule
仿真结果:
4. 小结
上面的代码也是terasic的default文件的设计思想,利用2个FSM来实现写入数据,并显示。在LCD_Controller里的FSM是写操作的过程,如下图
关键是产生有效的E。LCD_TEST里的FSM则是初始化数据,调用LCD_Controller写入数据,设置合理延时(5.2ms),循环递进显示下一条数据。难点在于这2个FSM咋联系起来,一说子函数调用,简单,关键是这里从一个FSM的某个状态进入另一个FSM的某个状态,被调用的FSM的多个状态又包含在上层的FSM的一个状态中,其间的时序,关联就靠start和done来实现,这一点也是仿真了demo,才分析出来的。可能比较麻烦,所以才没人把每步的时序分解说明。看来,读代码的“黑屋修炼”是不可太期望别个会帮助的。
ps: 在仿真时,用qII花了不少时间,用modelsim,提示内存不足。
以上是关于新手求教:quartus verilog 关于timescale的问题。。的主要内容,如果未能解决你的问题,请参考以下文章
原创如何使用DE2的1602LCD --之一(quartus)(verilog)(digital logic)
软件:Quartus II,语言:VHDL或verilog HDL?