打印

这个VHLD用法是技巧还是坏习惯?

[复制链接]
2974|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
丁弋宇|  楼主 | 2010-7-29 21:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
ge, ni, se, edge, ce
本帖最后由 丁弋宇 于 2010-7-29 21:50 编辑

process (clk)
  variable   cnt : integer range 0 to 7;
begin
  if (rising_edge(clk)) then
   if reset = '1' then
    cnt := 0;
   else
    cnt := cnt + 1;
    led <= '1';
    if cnt = 0 then
     led <= '0';
    end if;   
   end if;
  end if;
end process;
解释下,也就是LED在if外面赋缺省值,如果if内部重新赋值以新值为算
当然,一般做法LED<='1'都是放else里面做到互斥了。
这里我举的是个简单化的特例供大家研究

相关帖子

沙发
ar_dong| | 2010-7-30 14:10 | 只看该作者
很经典啊,这种程序经常见啊

使用特权

评论回复
板凳
wu283326736| | 2010-7-30 16:35 | 只看该作者
我个人认为,做FPGA编程时使用阻塞赋值是很容易出错的,我写的时候使用verilog都用的是非阻塞赋值。
你上面的程序只要稍微对led=1和=0位置换了就会出错。
可能和你讨论的内容不太相同,但你写大工程的时候你会注意到这点的。

使用特权

评论回复
地板
丁弋宇|  楼主 | 2010-7-30 16:52 | 只看该作者
我倒不觉得是类似verilog的阻塞问题,而是这里这么写如果有几个if并行情况下,都各自根据不同条件对led赋值,不是一种好风格,一旦程序员埋了个bug,很难找到

使用特权

评论回复
5
wu283326736| | 2010-7-31 09:15 | 只看该作者
楼上的,我也说的是不好的风格,所以建议非阻塞赋值。可以减少错误,这样写太............

使用特权

评论回复
6
drentsi| | 2010-7-31 11:07 | 只看该作者
这个程序只有一个问题,就是在
  if reset = '1' then
    cnt := 0;
这里没有加上复位状态  led <= '1';
简单的逻辑里面,这样的做法让人觉得很奇怪,但是多数复杂的逻辑状态下,这却是省资源和提高速度的做法,作以下假设:正常的逻辑过程如下
if a='1' and b='1' then
  if c='1'  and d='1' then
  led <= '1';
  aaaa<="0000";
else
   led <= '0';
  aaaa<=aaaa;
end if;
else
aaaa<="1111";
  led <= '0';
end if;
这相当于两个逻辑过程扯到了一起,对aaaa和led进行条件幅值,对这样一个问题有很多种不同的做法,我可以举出以下句法:
led<=a and b and c and d;一句话搞定,简洁明了,当a,b,c,d为单比特时好办,如果为向量,就麻烦了。
当条件变得复杂时,不能用上面的逻辑表达式,好,换一种
led <= '0';
if a='1' and b='1' and c='1' and d='1' then
led <= '1';
end if;
这句话同样没有else led <= '0';,把led <= '0';放到上面去了,好,再来理解这句话
默认情况下led <= '0';当满足条件时再赋值1,编译器最终会编译成FDS port map(C=>clk,D=>'0',S=>SSS,...),SSS就是上面的条件最后综合出来的一个信号。
当你对寄存器进行操作时,FPGA的FF隐含了几种逻辑,这种逻辑是不需要你用代码描述出来的。
理解这些逻辑很重要,可以写出简洁,可靠的代码。
if a='0' or b='0' then
aaaa<="1111";
elsif c='1'  and d='1' then
aaaa<="0000";
end if;不需要else了,else是隐性的,这几行逻辑实现的就是FDRSE,隐性的else就是CE='0'的情况,寄存器的值保持不变。
条件赋值,可以综合成前面根据条件来实现MUX,最后加上一级FD锁存,也可以把诸多条件直接加到FDRSE上,省去大量的逻辑。FDRSE是FPGA的一个精髓
  FDRSE_inst : FDRSE
   generic map (
      INIT => '0') -- Initial value of register ('0' or '1')  
   port map (
      Q => Q,      -- Data output
      C => C,      -- Clock input
      CE => CE,    -- Clock enable input
      D => D,      -- Data input
      R => R,      -- Synchronous reset input
      S => S       -- Synchronous set input
   );
这实现的是什么功能呢,
if C'event and C='1' then
if R='1' then
Q<='0';
elsif S='1' then
Q<='1';
elsif CE='1' then
Q<=D;
else
Q<=Q;
end if;
end  if;
这个一个原生的FF是不是保护了强大的条件赋值功能,而这是不需要你额外花逻辑去实现的。
在你设计逻辑的时候,只要不违反语法,只要不违反设计细想,只要便于阅读,都是可以的。
楼主那个问题,我的做法是这样的
process (clk)
  variable   cnt :  std_logic_vector(0 to 2);
begin
  if clk'event and clk='1' then
   if reset = '1' then
    cnt := (others=>'0');
   led<='1';
   else
    cnt := cnt + 1;
   led<=cnt(0) or cnt(1) or cnt(2) ;
    end if;
  end if;
end process;
假设cnt非常大,则变成
process (clk)
  variable   cnt :  std_logic_vector(0 to 31);
begin
  if clk'event and clk='1' then
   if reset = '1' then
    cnt := (others=>'0');
    led<='1';
   else
    cnt := cnt + 1;
    led<='1';
    if cnt=0 then
    led<='0';
    end if;
    end if;
  end if;
end process;
led赋0值只有一种情况,cnt=0的时候,其它情况都赋1值
    led<='1';
    if cnt=0 then
    led<='0';
    end if;

    if cnt=0 then
    led<='0';
   else
   led<='1';
    end if;
意义和编译之后的结果是一模一样的,不会存在任何问题,你对VHDL的基本原则理解了就会认同我的观点。尽信书不如无书。
还有一个问题,各位发现了没有,我定义了一个std_logic_vector(0 to 31);是不是非常不顺眼?
向量为什么要这样定义,不规范啊,这个规范的基本原则是什么?是某本书上说的吗,有道理吗?
我有我的道理,我们的powerpc,microblaze都是big endian的,这样描述对于字节的寻址会减少非常多的不必要的麻烦。
另外,网络通信,SPI,I2C通信采用这种方式会减少BYTE之间的交换,避免引起混淆。
当然书上讲的都是std_logic_vector(31 downto 0);这些都是都不是死的,以简洁实用为主,各自好好理解吧。

使用特权

评论回复
7
drentsi| | 2010-7-31 11:29 | 只看该作者
在FPGA设计中,以简单的电路解决复杂的问题,以简洁的语句描述复杂的电路是我们追求的目标。
有些时候,我们的工程代码行数超过了20万行,想到于200个1000行的VHDL问题,减少不必要的代码行数对于代码的维护非常重要,同时对于代码的编写也减少了工作量,像上面所讲的,减少一个else就减少一行,把向量的定义转换一种方式就少敲几个字母,有的时候一个部件的代码量太多,甚至将几个process合并。对应着精简得不能再精简的20万行代码,最终却是编译到1万个silices里面去,而同样一个项目,第一版的是10万行代码却要3万个silices。思想的改进带来的是资源的减少,但是对应的代码却在增加,奇怪吧。

使用特权

评论回复
8
wenunit| | 2010-9-10 10:50 | 只看该作者
学习,思考。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:发丘印,摸金符,搬山卸岭寻龙诀; 人点烛,鬼吹灯,勘舆倒斗觅星峰; 水银斑,养明器,龙楼宝殿去无数; 窨沉棺,青铜椁,八字不硬莫近前。

317

主题

1957

帖子

4

粉丝