玩转VHDL006-写编译器能懂的语句

2020-02-02 11:48发布

我们在写程序的时候,有没有考虑过编译器其实并不足够智能?那么程序语句能给编译器指明最简捷的道路尤为重要。下面以Quartus II v13.1为平台,举两个小例子说明。1:设计一个32位计数器,在计数器为全1时输出一个脉冲,输出不用组合逻辑实现。那么,这么个简单的功能,可以用4中写法列举如下:clock                   : instd_logic;q                          :out std_logic;signal cn            :std_vector(0 to 31);Process(clock) begin         if rising_edge(clock)then                   cn <= cn+ 1;         1       q <= STDZ(signed(cn)=-2);         2       q <= STDZ(signed(cn)=3-5);         3       q <= STDZ(signed(cn)+5 = 3);         4       q <= STDZ(cn = 2**cn'length-2);         end if;End process;最后综合的结果是,前两种消耗资源相同,速率也较高,第3种资源消耗大速率也低,第4种没有实现我们想要的功能,完全被综合掉了。当信号cn的比特长度小于32时,第4种写法与前2种是完全相同的,2**32超出了VHDL所能表示的整数范围被解释为0,用定义为std_vector型的cn与一个负数比较则永远不相等,所以被综合掉了。第3种写法不同于其他写法的原因是综合器(或者说编译器,就那么回事)并没有智能到会在等式两边移项的程度,况且在有些时候移项也是不合理的,在此,我们称之为移项问题。但综合器知道合并常数,即第1和第2写法完全相同。本例中只涉及一个变量cn,如果有两个或多个变量,那么移项问题依然存在。1告诉我们,注意不同类型数据的取值范围,移项问题完全由程序员自己决定。2:有一个8位计数器cnt,在不同数值下输出一个3位状态q,功能描述如下q                : outstd_vector(0 to 2);signal cnt : std_vector(0 to7);Process(clock) begin         if rising_edge(clock)then                   cnt <=cnt+1;                   if cnt = 0then                            q<= "000";                   elsif cnt =1 then                            q<= "001";                   elsif  cnt <= 8 then                            q<= "010";                   elsif cnt =10 then                            q<= "011";                   elsif cnt =20 then                            q<= "100";                   elsif cnt>= 23 and cnt <= 32 then                            q<= "101";                   else                            q<= "110";                   end if;         end if;End process;在功能保持不变的情况下,也可以写成:Process(clock) begin         if rising_edge(clock)then                   cnt <=cnt+1;                   caseSTDV_INT(cnt) is                   when 0                        => q <="000";                   when 1                        => q <="001";                   when 2 to 8              =>q <= "010";                   when 10                     => q <="011";                   when 20                     => q <="100";                   when 23   to 32         =>q <= "101";                   when others              => q <= "110";                   end case;          end if;End process;或者写成with STDV_INT(cnt) select iq<=     "000"        when 0,         "001"        when 1,         "010"        when 2 to 8,         "011"        when 10,         "100"        when 20,         "101"        when 23 to 32,         "110"        when others;Process(clock) begin         if rising_edge(clock)then                   cnt <=cnt+1;                   q <= iq;         end if;End process;综合后,后两种写法结果相同,但与第一种写法不同。例2告诉我们,代码的表述方式能用开关选择的逻辑就不用优先编码的逻辑。一句话:编译器很听话,但不会懂你。
0条回答

一周热门 更多>