举例说明VHDL中关于变量和信号的赋值、if语句的描述方法

2020-02-17 19:44发布

本帖最后由 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"并回零: 1.jpg 四、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",即计数值与代码中不符: 4.jpg

若将第二种写法中计数器加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计到3if语句的控制不起作用: 2-.jpg

若将第四种写法中计数器加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"开始: 4-.jpg
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。