专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
FPGA
举例说明VHDL中关于变量和信号的赋值、if语句的描述方法
2020-02-17 19:44
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
FPGA
5025
15
15
本帖最后由 mhanchen 于 2013-7-30 17:37 编辑
所用例子实现功能很简单,2 bits的计数器循环计数,计到2后清零。在这里强烈推荐第一种写法,原因如下:在一个process(或者always)中不要描述并列语句,在控制信号增多或者计数器位数增加的情况下也会出现错误,而且综合后电路与各并列语句的描述顺序有很大关系,电路规模大时会影响综合器的工作效率,第二种和第四种写法就是典型的C风格,不符合HDL的代码风格而且容易出错(见最后两个例子)。第三种写法其实也不会出错,但是习惯的写法都是尽量用signal,这样会准确地综合出触发器。下面每个综合后的电路效果大家可以仿真一下或者按时钟节拍去分析各个触发器的输出。
我用的综合工具是Synplify 2012.03,映射芯片是S6 LX9。
PS:以下例程对应到
Verilog HDL
将信号和变量赋值分别改为非阻塞和阻塞赋值可得到相同的综合结果。
一、
……
process(clk, rst)
begin
if(rst = '1') then
cnt <= (others => '0');
elsif(clk'enent and clk = '1') then
if(cnt = "10") then
cnt <= (others => '0');
else
cnt <= cnt + '1';
end if;
end if;
end process;
……
二、
……
process(clk,rst)
begin
if(rst = '1') then
cnt <= (others => '0');
elsif(clk'enent and clk = '1') then
cnt <= cnt + '1';
if(cnt = "10") then
cnt <= (others => '0');
end if;
end if;
end process;
……
三、
……
process(clk, rst)
variable cnt_reg :std_logic_vector(1 downto 0);
begin
if(rst = '1') then
cnt_reg := (others => '0');
elsif(clk'enent and clk = '1') then
if(cnt_reg = "10")then
cnt_reg := (others => '0');
else
cnt_reg := cnt_reg + '1';
end if;
end if;
dout <= cnt_reg;
end process;
……
以上三种写法的综合后电路如下图,此时计数器可以正确计数到
"10"
并回零:
四、
…
process(clk, rst)
variable cnt_reg :std_logic_vector(1 downto 0);
begin
if(rst = '1') then
cnt_reg := (others => '0');
elsif(clk'event and clk = '1') then
cnt_reg := cnt_reg + '1';
if(cnt_reg = "10") then
cnt_reg := (others => '0');
end if;
end if;
dout <= cnt_reg;
end process;
…
第四种写法综合后电路图如下,此时计数器只能计数到
"01"
,即计数值与代码中不符:
若将第二种写法中计数器加
1
的操作语句放到
if
条件判断之后,即:
…
process(clk, rst)
begin
if(rst = '1') then
cnt <= (others => '0');
elsif(clk'event and clk = '1') then
if(cnt = "10") then
cnt <= (others => '0');
end if;
cnt <= cnt + '1';
end if;
end process;
…
综合后电路图如下,此时计数器可以从
0
计到
3
,
if
语句的控制不起作用:
若将第四种写法中计数器加
1
的操作语句放到
if
条件判断之后,即:
…
process(clk, rst)
variable cnt_reg :std_logic_vector(1 downto 0);
begin
if(rst = '1') then
cnt_reg := (others => '0');
elsif(clk'event and clk = '1') then
if(cnt_reg = "10") then
cnt_reg := (others => '0');
end if;
cnt_reg := cnt_reg + '1';
end if;
dout <= cnt_reg;
end process;
…
综合后电路图如下,此时计数器可以计到
"10"
,但之后无法回零,而是从
"01"
开始:
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
15条回答
chenzhi658
2020-02-20 00:01
GoldSunMonkey 发表于 2013-7-30 23:49
感谢你的分享
猴哥,这里的第二种方法,与第一种建立的逻辑应该是一样的吗?有什么不好的地方吗?我对于有些信号的优先等级,经常使用第二种方法。
加载中...
查看其它15个回答
一周热门
更多
>
相关问题
如何用FPGA驱动LCD屏?
5 个回答
请教一下各位专家如何用FPGA做eDP接口?
6 个回答
FPGA CH7301c DVI(显示器数字接口)没有数字输出
7 个回答
100颗FPGA的板子,开开眼界
6 个回答
求教自制最小系统版
10 个回答
相关文章
嵌入式领域,FPGA的串口通信接口设计,VHDL编程,altera平台
0个评论
Xilinx的FPGA开发工具——ISE开发流程
0个评论
基于FPGA的详细设计流程
0个评论
干货分享,FPGA硬件系统的设计技巧
0个评论
一种通过FPGA对AD9558时钟管理芯片进行配置的方法
0个评论
×
关闭
采纳回答
向帮助了您的知道网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
FPGA
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
×
付费偷看金额在0.1-10元之间
确定
×
关闭
您已邀请
0
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
猴哥,这里的第二种方法,与第一种建立的逻辑应该是一样的吗?有什么不好的地方吗?我对于有些信号的优先等级,经常使用第二种方法。
一周热门 更多>