VHDL疑问,请教高人了.
时间:10-02
整理:3721RD
点击:
以下两个程序第一个无法执行.请指明原因.
两个程序都是用50兆HZ驱动8个LED指示灯轮流转动,唯一不同的地方是IF语句的使用,第一个程序用两个IF语句顺序执行,第二个用的是两个IF语句嵌套..
第一个:
ENTITY splic_clk IS
PORT(clk:IN STD_LOGIC; --输入clk
splitcclk:OUT STD_LOGIC_VECTOR(0 to 7) --输出8个驱动信号
);
END ENTITY splic_clk;
ARCHITECTURE sp_clk OF splic_clk IS
SIGNAL temp_clk:STD_LOGIC_VECTOR(0 to 7):="11111110";
BEGIN
splitcclk<=temp_clk;
PROCESS(clk) --clk驱动进程
VARIABLE counter:INTEGER :=0;
BEGIN
IF clk'event and clk='1'THEN --50兆HZ clk被分频为1HZ
counter:=counter+1; --记数器计算50兆clk上升沿个数
END IF;
IF counter=50000000 THEN --如果记数到50兆时,指示灯显示一个并且轮流到下一个.
temp_clk<=temp_clk(7)& temp_clk(0 to 6);
counter:=0; --记数器归0,准备从新记数.
END IF;
END PROCESS;
END ARCHITECTURE sp_clk;
第二个:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY splic_clk IS
PORT(clk:IN STD_LOGIC;
splitcclk:OUT STD_LOGIC_VECTOR(0 to 7)
);
END ENTITY splic_clk;
ARCHITECTURE sp_clk OF splic_clk IS
SIGNAL temp_clk:STD_LOGIC_VECTOR(0 to 7):="11111110";
BEGIN
splitcclk<=temp_clk;
PROCESS(clk)
VARIABLE counter:INTEGER :=0;
BEGIN
IF clk'event and clk='1'THEN
counter:=counter+1;
IF counter=50000000 THEN
temp_clk<=temp_clk(7)& temp_clk(0 to 6);
counter:=0;
END IF;
END IF;
END PROCESS;
END ARCHITECTURE sp_clk;
两个程序都是用50兆HZ驱动8个LED指示灯轮流转动,唯一不同的地方是IF语句的使用,第一个程序用两个IF语句顺序执行,第二个用的是两个IF语句嵌套..
第一个:
ENTITY splic_clk IS
PORT(clk:IN STD_LOGIC; --输入clk
splitcclk:OUT STD_LOGIC_VECTOR(0 to 7) --输出8个驱动信号
);
END ENTITY splic_clk;
ARCHITECTURE sp_clk OF splic_clk IS
SIGNAL temp_clk:STD_LOGIC_VECTOR(0 to 7):="11111110";
BEGIN
splitcclk<=temp_clk;
PROCESS(clk) --clk驱动进程
VARIABLE counter:INTEGER :=0;
BEGIN
IF clk'event and clk='1'THEN --50兆HZ clk被分频为1HZ
counter:=counter+1; --记数器计算50兆clk上升沿个数
END IF;
IF counter=50000000 THEN --如果记数到50兆时,指示灯显示一个并且轮流到下一个.
temp_clk<=temp_clk(7)& temp_clk(0 to 6);
counter:=0; --记数器归0,准备从新记数.
END IF;
END PROCESS;
END ARCHITECTURE sp_clk;
第二个:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY splic_clk IS
PORT(clk:IN STD_LOGIC;
splitcclk:OUT STD_LOGIC_VECTOR(0 to 7)
);
END ENTITY splic_clk;
ARCHITECTURE sp_clk OF splic_clk IS
SIGNAL temp_clk:STD_LOGIC_VECTOR(0 to 7):="11111110";
BEGIN
splitcclk<=temp_clk;
PROCESS(clk)
VARIABLE counter:INTEGER :=0;
BEGIN
IF clk'event and clk='1'THEN
counter:=counter+1;
IF counter=50000000 THEN
temp_clk<=temp_clk(7)& temp_clk(0 to 6);
counter:=0;
END IF;
END IF;
END PROCESS;
END ARCHITECTURE sp_clk;
第一种情况是并行执行的,只有到了counter==50000时第二个进程才执行。
而第二种情况是顺序执行的,并且你用的是两个if语句,而不是if elseif语句导致第二个if语句在判断完counter是不是等于50000后都继续执行counter:=0;,导致程序是不能按照预期执行的。
第二个语句的第二个if更改为elseif可以解决。
IF counter=50000000 THEN
begin
temp_clk<=temp_clk(7)& temp_clk(0 to 6);
counter:=0;
end if;
两个代码区别就是对counter=5000000的判断的地方。第一个是在时钟外进行判断的。第二个是在时钟内进行判断的。虽然你用变量声明的信号,但是,对于第一个程序来说,由于对counter=5000000的判断在时钟外,因此,在某个clk上升沿到来后counter达到5000000后,紧接着就开始对counter=5000000这个条件就成立了,然后就执行条件成立后的操作(移位和清零)。而第二个程序,由于counter在clk内,虽然是变量声明的信号,但是,当counter达到5000000后,不会马上在if counter=5000000这个条件判断下执行条件成立内的操作(移位和清零),而是要等待下一个时钟到来后才可以。
这个地方,虽然counter是变量,但是,其变化依然和用信号声明的一样。
我想你一定对变量在代码执行过程中值立即生效这个地方模糊了。