挺久没有更新,今天更新一篇小文章。最近正在整理一个sdram控制器的教程(vhdl),现在更新的小文章是想为后续的sdram教程以及其它比较大的教程做铺垫。本文主要讲关于vhdl编码风格(verilog也可以用同样的思想),这篇文章的核心思想就是:设计中的所有状态都应该被明确声明在寄存器中。
这句话什么意思先不谈,直接上两段代码,第一段如下:
library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use work.ff.all; -- 一些常用的元件包,这里面是可以自己写的
-- 这篇文章主要就调用了基本的d触发器,里面还有什么可以先忽略
entity bad_counter is generic( n: integer := 4 ); port( clk, rst: in std_logic;
output: buffer std_logic_vector(n-1 downto 0) );end bad_counter;
architecture impl of bad_counter issignal nxt: std_logic_vector(n-1 downto 0);begin process(clk) begin
if rising_edge(clk) then
if rst then
output 《= (others =》 ‘0’);
else
output 《= output + 1;
end if;
end if; end process;end impl;
一个4位计数器,能实现设计的功能,但其中output 《= output + 1存在一点问题,这种写法非常c语言化,这也是很多人习惯的写法。为什么说这种写法不好,因为它混淆了当前状态和下一状态。先不多解释,看下一段代码如下:
library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use work.ff.all; -- 一些常用的元件包,这里面是可以自己写的
-- 这篇文章主要就调用了基本的d触发器,里面还有什么可以先忽略
entity good_counter is generic( n: integer := 4 ); port( clk, rst: in std_logic;
output: buffer std_logic_vector(n-1 downto 0) );end good_counter;
architecture impl of good_counter is signal nxt: std_logic_vector(n-1 downto 0);begin nxt 《= (others=》‘0’) when rst else output+1;
count: vdff generic map(n) port map(clk, nxt, output);end impl;
这段代码同样的是4位计数器,为什么用这两段代码做比较,非常典型,第一段代码的思想就是c语言的思想来写的,很多人可能没有注意自己在写“数字电路”,也没有特别关注写出来的代码综合出来是什么样子。第二段代码明确表明nxt是下一状态,并且nxt是通过当前状态output得到的,这很重要,与此同时还调用了一个d触发器元件,这个d触发器为什么用,之前在异步fifo(二)中有谈到:在实现所有的状态变量都应该被明确的声明位d触发器,不要让编译器去推断应该用什么触发器。
讲到这里,可能还是不懂这两份代码有什么具体的差别,我做了一个实验,把两份代码都综合了一遍,使用了两个不同的版本,quartus20.3和quartus13.1(不同版本的软件,无论是效率还是开发便捷程度还是有一定差别的)
先看quartus13.1综合出的两份原理图
这幅原理图是第一份代码综合出来了,大概看一下没什么问题,代码也是这样写的。
再看第二份代码综合出来的原理图
区别来了,很明显,第一份代码因为用output <= output + 1的原因,左右两端使用了相同的信号,混淆当前状态和下一状态,下一状态被隐藏起来。但第二份代码综合出来的很明显,nxt是下一状态,并且nxt是通过当前状态output得到的。当然还要个比较好的地方,第二份代码直接调用d触发器元件(在package里面写了),告诉编译器状态变量要声明为d触发器,而不是让编译器自己判断(尽管它可以)。
再看quartus20.3综合出来的原理图
这个原理图是第一份代码bad_counter 综合出来的,很显然现在的eda真行,可以把不那么优秀的代码综合出优秀代码才能综合出的原理图了。当然这是很简单代码的情况下。
这个原理图是第二份代码good_counter综合出来的,除了下一状态的命名和位数区间不一样外,其它的两个代码综合出来的没有区别!
小结:从上面的四幅原理图看,尽管随着eda的发展让不那么优秀的代码综合出和优秀代码一样的原理图,但良好编码风格的代码仍然非常必要,即使是13.1和20.3巨大版本差异的情况下,良好编码风格的代码综合出来的原理图也是一样的。但在代码风格不好的情况下,13.1和20.3却有比较大的差距。人作为设计的主体,不能完全依靠eda的优化,编译器也不是万能的,有些其它地方未必会优化的那么好,在大型复杂项目中不太好的编码风格可能编译器也未必能够给出比较好的优化,好的编码风格可以让我们更好的理解一些底层的设计,也能知道代码会如何综合。更重要的是需要知道自己数字设计师!用数字的思想去设计fpga。这些只是自己的意见,大家可以做一个参考,有不对的地方也欢迎批评指正。
新能源汽车交流充电的关键——车载充电机
技术干货|AK协议
霍尔传感器IC在卷发器中的应用
“元上苏河”战略合作伙伴签约,亮风台再参与上海元宇宙重大应用场景
ADI公司推ADL5201/ADL5202/ADL5240/
关于VHDL编码风格
2.4G无线收发射频芯片内置MCU集成8位RISC内核CI2451
Git 常用命令大全
手机指纹传感器已经“烂大街”?各大厂商的竞争非常激烈
云计算领域在2020年是怎样的展望
电动调节阀在什么的工作情况下需要防爆
虹科新闻 | 虹科与RACOM正式建立合作伙伴关系
彩色电视机的伴音电路TDA1013B
如何优化PAR38 LED聚光灯并且提高工作效率
启英泰伦第三代语音AI芯片半年出货量突破1000万颗,创历史新高!
高性能GPU是算力的基石,市场规模超过百亿元
变频器和电机之间的距离多少合适?
科陆电子上半年增收不增利 投资收益成业绩风向标
瑞萨电子面向无刷直流电机应用推出全新可编程智能栅极驱动器
什么是机器学习?它的重要性体现在哪