As part of an assignment, I must create these blocks that tie in to a larger top level module. (there are more blocks not pictured). I have everything working fine, except this UP/DOWN counter because I can't really work out how this can possibly be implemented without a CLK.
The EN_UP
and EN_DOWN
signals are simple pulses that should increment or decrement an internal 16-bit value, which gets split into nibbles and put on the output. I feel as if this should be fairly simple, but I can't work this out.
I've tried multiple approaches.
1) - Inside a single process
count : PROCESS (RESET, EN_UP, EN_DOWN)
BEGIN
if(RESET = '1') then
countSignal <= x"0000";
elsif(rising_edge(EN_UP) and EN_DOWN = '0') then
countSignal <= countSignal + 1;
elsif(rising_edge(EN_DOWN) and EN_UP = '0') then
countSignal <= countSignal - 1;
end if;
END PROCESS;
This ultimately compiles with no errors or warnings, however the compiler ends up creating the wrong circuit, tying the EN_UP
to the CLK
of the flip-flip, and the EN_DOWN
to the CE (clock enable)
. While yes, that is part of the equation, it doesn't mirror that for the opposite case.
2) - Separate processes
countUP : PROCESS (RESET, EN_UP)
BEGIN
if(RESET = '1') then
countSignal <= x"0000";
elsif(rising_edge(EN_UP) and EN_DOWN = '0') then
countSignal <= countSignal + 1;
end if;
END PROCESS;
countDOWN : PROCESS (RESET, EN_DOWN)
BEGIN
if(RESET = '1') then
countSignal <= x"0000";
elsif(rising_edge(EN_DOWN) and EN_UP = '0') then
countSignal <= countSignal - 1;
end if;
END PROCESS;
This results in: Signal countSignal[15] in unit UD_COUNTER is connected to following multiple drivers:
3) Multiple processes with Hi-Z states
I tried some attempt with Hi-Z which also failed.
Answer
You're right in thinking that you will have to use something for a clock for the counter. Otherwise there is nothing to tell it when to count. Either the clock is missing from the diagram, or you will have to edge-trigger on the enables, in which case the circuit you think it should have synthesized to is impossible, as you can't drive the same register with two different clocks. You might try something like:
en_either <= en_up or en_down;
process (en_either, rst)
begin
if rst = '1' then
count <= (others => '0');
elsif rising_edge(en_either) then
if en_up = '1' then
count <= count + 1;
else
count <= count - 1;
end if;
end if;
end process;
There may be better ways, but if you really can't have a clock, I suppose that will work. If the enables overlap in any way, of course, this may not work as intended.
As the error message indicates, your two-process version will not work because you're driving the same signal from two different processes. There may be ways to work around this, but it would be much more trouble than the 1-process version.
As David points out in the comments, this will not work properly unless your enables are bounce-free. The source of the enables isn't clear from your post.
No comments:
Post a Comment