- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
hi everyone
i try to make a project to count people entering or going out from a hall using VHDL and altera board DE0 i made two clocks one for counting up (clku) it come from a trigger outside board and one for counting down (clkd) also come from a trigger outside board . but when doing this Error 10820 appear that says "can't infer register for count because its behavior depends on the edges of multiple distinct clocks" the Full Code is here ENTITY mod_ten_ud ISPORT( clku,clkd, enable :IN BIT ; q :OUT INTEGER RANGE 0 TO 9);END mod_ten_ud; ARCHITECTURE a OF mod_ten_ud ISBEGIN PROCESS (clku ,clkd) VARIABLE count :INTEGER RANGE 0 TO 9; BEGIN IFenable = '1' THEN IF( clku = '1' AND clku'EVENT ) THEN count := count + 1; ELSIF( clkd = '1' AND clkd'EVENT ) THEN count := count - 1; END IF; END IF; q <= count; END PROCESS; END a; please help me because it is my final study project and thanks a lotコピーされたリンク
4 返答(返信)
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
First: Please use the CODE-Tags for Code. (obvious, isn't it?)
ENTITY mod_ten_ud ISPORT(
clku,clkd, enable :IN BIT ;
q :OUT INTEGER RANGE 0 TO 9);END mod_ten_ud;
ARCHITECTURE a OF mod_ten_ud
ISBEGIN
PROCESS (clku ,clkd)
VARIABLE count :INTEGER RANGE 0 TO 9;
BEGIN
IFenable = '1'
THEN
IF( clku = '1' AND clku'EVENT )
THEN count := count + 1;
ELSIF( clkd = '1' AND clkd'EVENT )
THEN count := count - 1;
END IF;
END IF;
q <= count;
END PROCESS;
END a;
Second: You can't use two clock edges in one process. And it is rather bad style to declare a simple signal as clock and count on the clock edges. Better is: You create one very fast clock to sample your two input signals. Like this:
if (rising_edge(fast_clk)) then
prev_sig1 <= sig1;
prev_sig2 <= sig2;
if ((prev_sig1 = '0') and (sig1 = '1')) then
{count up}
end if;
if ((prev_sig2 = '0') and (sig2 = '1')) then
{count down}
end if;
end if;
This will also give you something like an edge-detect on your signals. But without the meaning that these are clocks.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
As the signals are asynchronous (external to the board) they need to pass each a double FF synchronizer before entering the edge detection. Otherwise you should expect a certain amount of counting errors (missed or double counted events).
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
I've had a little play and this is how I would do an up down counter:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity people_count is
generic
(
COUNTER_WIDTH: integer := 8
);
port (
in_clk : in std_logic;
in_reset : in std_logic;
in_incCount : in std_logic;
in_decCount : in std_logic;
out_count : out std_logic_vector(COUNTER_WIDTH-1 downto 0)
);
end entity people_count;
architecture arch_people_count of people_count is
signal count: unsigned(COUNTER_WIDTH-1 downto 0);
signal count_up: std_logic;
signal count_down: std_logic;
begin
count_up <= '1' when in_incCount ='1' and in_decCount = '0' else '0';
count_down <= '1' when in_incCount ='0' and in_decCount = '1' else '0';
process(in_clk, in_reset)
begin
if in_reset = '1' then
count <= (others => '0');
elsif rising_edge(in_clk) then
if (count_up = '1') then
count <= count + 1;
elsif (count_down = '1') then
count <= count - 1;
end if;
end if;
end process;
out_count <= std_logic_vector(count);
end architecture arch_people_count;
but you would need to synchronize the inputs, debounce the switch and put an edge detector on the input! have fun :) geobyjmh http://geobyjmhembeddedengineer.blogspot.co.uk/
