欲看图文版pdf,请电邮14518918@qq.com。
我是上世纪九十年代的成电毕业生,计算机语言这门课学的是Pascal,它是一种强类型结构化编程语言,竟然和毕业后向王师兄学到的硬件描述语言VHDL比较类似,都是if (...) then和begin ... end这样比较严谨但啰嗦的风格。这导致我在后来的职业生涯中,编程风格就比较保守,难以精进。同样是硬件描述语言的verilog,看着就有点像我后来工作做跟康师兄学到的C语言,简洁如if {...}这样的了。
为了消除新人Ellen对陌生技术的畏难情绪,证明清代学者彭端淑写的《为学一首示子侄》中的一句话:"为之,则难者亦易矣",我用了一个上午,一起实操了一下,用豆包给的三个verilog模块文件,在Quartus Prime Lite 18中编译并烧录到CPLD EPM570T100C5。
注意,只有Quartus的前身,即MaxPlus II软件,有一体式图形化仿真模块。我就先用原理图的方式画出来的一个电路并快速获得了功能仿真结果,不超过10分钟。这里有一个CLK时钟输入管脚,被三级二分频之后,输出CLK/8方波到DIV_OUT管脚,同时也反相再输出到OUT管脚。
为了体现verilog模块化编程的风格,我请豆包提供了Maxplus II能认的基于Verilog-1995标准的三个模块代码。然后在Maxplus II中做了图形化仿真。
这是二分频的div2.v
c
// 二分频器:输入 CLK,输出 OUT = CLK/2,占空比 50%
module div2 (CLK, OUT);
input CLK; // 输入时钟
output OUT; // 二分频输出
reg OUT; // 时序逻辑,输出必须用 reg 保存状态
always @(posedge CLK) begin
OUT <= ~OUT; // 每个上升沿翻转一次,就是除以 2
end
endmodule
这是反相器的mynot.v
c
module mynot(IN, OUT);
input IN;
output OUT;
assign OUT = ~IN;
endmodule
这是调用三个div2.v实例和一个mynot.v实例的top.v:
c
// 顶层:分频器与反相器各自独立引出管脚,外部短接完成级联
// 引脚规划:
// CLK ------ 输入时钟 (引脚1)
// DIV_OUT ------ 分频器输出 (引脚2)
// OUT ------ 反相器输出 (引脚3)
module top (CLK, DIV_OUT, OUT);
input CLK; // 分频器时钟输入
output DIV_OUT; // 分频器输出
output OUT; // 反相器输出
wire DIV_OUT1, DIV_OUT2;
// 例化二分频:CLK 接输入引脚,OUT 直接引到输出引脚
div2 u_div2 (
.CLK (CLK),
.OUT (DIV_OUT1)
);
// 四分分频
div2 u_div2a (
.CLK (DIV_OUT1),
.OUT (DIV_OUT2)
);
// 八分频
div2 u_div2b (
.CLK (DIV_OUT2),
.OUT (DIV_OUT)
);
// 例化反相器:IN 来自输入引脚,OUT 引到输出引脚
mynot u_not (
.IN (DIV_OUT),
.OUT (OUT)
);
endmodule
注意,虽然verilog的out管脚,可以在内部被回读,所以八分频输出到DIV_OUT,然后DIV_OUT还可以作为反相器的输入:
c
// 八分频
div2 u_div2b (
.CLK (DIV_OUT2),
.OUT (DIV_OUT)
);
// 例化反相器
mynot u_not (
.IN (DIV_OUT),
.OUT (OUT)
);
一个输出信号能从管脚被回读来做输入信号?VHDL-1995表示不能接收,因为VHDL的output管脚从来就不能被回读,除非这个管脚是inout管脚并妥善区分何时高阻做输入何时推挽做输出。VHDL必须额外定义一个中间single,用single来承接需要输出的信号,最后用single对output管脚赋值,这里的single才能在内部被回读利用。
比较麻烦的是,MaxPlus II只认ANSI编码的中文,到了Quartus这个默认UTF-8编码的环境,中文会乱码。必须用记事本打开.v文件,另存为UTF-8编码,才能用Quartus正常显示中文。但此刻回到MaxPlus II,就又乱码了。只见新人笑,不闻旧人哭,这就是升级的代价。Quartus Prime Lite18是免费版,只需要注册一个intel账号,就能从收购了Altera的Intel官网下载:https://www.intel.com/content/www/us/en/software-kit/665990/intel-quartus-prime-lite-edition-design-software-version-18-1-for-windows.html。
下面是实操过程,运行Quartus。
1,新建一个项目
菜单File--New Quartus Prime Project,出现项目配置向导页面,在这一页,需要选中三个.v文件所在的工程目录比如D:/CPLD_Test,需要填写工程名,必须和顶层设计文件名保持一致,那就是top了。
然后选默认的空项目:
然后给项目添加源文件,点"Add All"可以把当前工程目录(不包含子目录)下所有源文件(包括.gdf原理图,.v硬件描述文本等)都列出来,再选中无关的文件点"Remove"从项目树中删掉。
然后选择目标CPLD的产品系列,封装、管脚数、速度等级,完了再下面的Available Device栏,选中目标CPLD型号,比如EPM570T100C5。
然后是配置第三方综合、仿真、分析工具,我们这些粗人用不了那么高级细腻的第三方软件,直接next。
最后是Summary,点Finish
这样,一个新的工程就搭建好了,在左侧目录树可见一个top顶层模块下挂了4个模块,其中有三个模块都是源自同一个div2.v,第四个模块源自mynot.v。
2,语法检查
点击图标栏中的"Start Analysis & Elaboration",一个带勾三角形,由于只检查语法和层次结构,生成端口列表(Node List),但不布局布线(Fitter)、不生成.pof固件,所以会节省时间得多。
3,管脚分配
菜单Assignments--Pin Planner,弹出管脚分配窗,在双击Location栏,在下拉菜单中选择端口管脚序号。
注意,CPLD一般都有几个专门的GCLK 全局时钟引脚,内部走全局时钟网络(全局网络是芯片预制的专用金属布线树,不走普通可编程互联矩阵,delay均衡,skew很小),可以给芯片内所有功能块提供时钟;也可以用作全局复位、全局输出使能等高扇出控制信号。
4,生成可烧录固件
点击图标栏中的"Start Compilation",一个不带勾三角形,可见左下角有几行进度条在疯狂逼近100%,就比较耗时。
注意,若综合时出现时序警告,可通过修改Timing Constraints或降低输入时钟频率来解决问题。
Quartus编译会同时输出*.sof和*.pof两个可烧录固件。.pof文件,这是烧录到CPLD的FLASH存储器的,掉电还在。.sof文件,这是烧录到CPLD的RAM存储器的,一掉电就没了。好在Programmer默认是调用.pof文件烧录到FLASH的。
5,时序仿真
由于Quartus Lite18 不再自带波形编辑器,需要用到第三方软件ModelSim Altera,就比较麻烦还很慢。这部分可参考我以往些的文档《Quartus 18.1精简版的下载安装暨ModelSIM联合仿真》。
6,固件烧录
点击图标栏中的Programmer",一排彩色杜邦线插入板子,会弹出烧录窗口。
在烧录窗口,首先点击"Hardware Setup"按键,确保已选中下载头是USB-Blaster;然后勾选下面三个选项,最后按"Start"开始烧录,当Progress进行到100%就success了。
然后就能在示波器上看到输入到PIN12的200MHz时钟,被8分频成25MHz方波,还有25MHz方波取反输出信号。但是AI提醒我,EPM570T100C5的实际硬件达不到 200MHz 输入时钟,虽然时序分析的Flow Summary说Fmax=456MHz,但这只是综合理论值,不是实际芯片能力。不过,我真的在示波器上看到比较方正的25MHz方波,也许是大力出奇迹?
附:工程目录压缩包,展开后双击磁盘文件top.qpf,即可呼出quartus软件并打开该工程。
附《为学一首示子侄》 清·彭端淑
天下事有难易乎?为之,则难者亦易矣;不为,则易者亦难矣。人之为学有难易乎?学之,则难者亦易矣;不学,则易者亦难矣。
吾资之昏,不逮人也;吾材之庸,不逮人也;旦旦而学之,久而不怠焉,迄乎成,而亦不知其昏与庸也。吾资之聪,倍人也;吾材之敏,倍人也;屏弃而不用,其与昏与庸无以异也。圣人之道,卒于鲁也传之。然则昏庸聪敏之用,岂有常哉?
蜀之鄙有二僧:其一贫,其一富。贫者语于富者曰:"吾欲之南海,何如?"富者曰:"子何恃而往?"曰:"吾一瓶一钵足矣。"富者曰:"吾数年来欲买舟而下,犹未能也。子何恃而往!"越明年,贫者自南海还,以告富者,富者有惭色。
西蜀之去南海,不知几千里也,僧富者不能至而贫者至焉。人之立志,顾不如蜀鄙之僧哉?
是故聪与敏,可恃而不可恃也;自恃其聪与敏而不学者,自败者也。昏与庸,可限而不可限也;不自限其昏与庸而力学不倦者,自力者也。
注:文中最后一句"不自限其昏与庸而力学不倦者,自力者也",意思是:不因为自己天资愚钝、才能平庸就自我设限,而是勤奋学习、毫不懈怠的人,是真正靠自己努力获得成功的人。