本帖最后由 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"开始:
|