library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
entity counter is
port(CLK, CLR : in std_logic;
output : inout std_logic_vector(3 downto 0));
end counter;
architecture archi of counter is
signal tmp: std_logic_vector(3 downto 0);
begin
process (CLK, CLR)
variable i: integer:=0;
begin
if (CLR='1') then
tmp <= "0000";
elsif (clk = '1') then
for i in 0 to 6 loop
tmp <= tmp + 1;
end loop;
end if;
计数到7我已经在0到10中完成了i。它没有显示任何错误但它从0000到1111计数
end process;
output <= tmp;
end architecture;
你可以建议怎么做......对不起英语错误的语法
答案 0 :(得分:3)
由于您的counter
port
中包含clk
,我们可以假设您希望计数器与时钟同步计数。
您正在关闭两个时钟边沿
elsif (clk = '1') then
应该是
elsif clk'event and clk = '1' then
或
elsif rising_edge(clk) then
这些示例使用clk的上升沿。根据IEEE-1076.6 IEEE VHDL寄存器标准,您无法合成使用两个时钟边沿的内容 转移水平(RTL)合成。它不是一种公认的计时方法。
假设您希望计数器从0变为9并翻转此
for i in 0 to 6 loop
tmp <= tmp + 1;
end loop;
应该像
if tmp = "1001" then # binary 9
tmp <= (others => '0'); # equivalent to "0000"
else
tmp <= tmp + 1;
end if;
这模拟了一个同步负载,优先于外部“状态”识别器驱动的增量。通过异步清零,它将模拟74163 4位计数器,外部4输入门识别“1001”并产生加载“0000”的同步并行负载信号。
如图所示,循环过程将导致单个增量,并在"1111"
处产生计数器翻转,就像您描述的那样。您可以删除for ... loop
和end loop;
语句,但行为相同。每个驱动程序的信号只有一个计划未来更新,并且一个进程只为其分配的每个信号都有一个驱动程序。所有循环迭代都发生在同一clk
事件中。 tmp
在下一个模拟周期(循环完成后)之前不会更新,并且它的赋值在所有循环迭代中都是相同的,表达式tmp + 1
。最后一个循环迭代赋值将是实际发生的赋值,它指定的值将是相同的。
当counter
处于状态驱动状态时(状态≃tmp
),不需要使用循环语句。 <{1}}代表的附加状态不需要。
答案 1 :(得分:0)
entity mod10 is
Port ( d : out std_logic_vector(3 downto 0);
clr: in std_logic;
clk : in std_logic);
end mod10;
architecture Behavioral of mod10 is
begin
process(clk)
variable temp:std_logic_vector(3 downto 0);
begin
if(clr='1') then temp:="0000";
elsif(rising_edge(clk)) then
temp:=temp+1;
if(temp="1010") then temp:="0000";
end if;
end if;
d<=temp;
end process;
end Behavioral;