0
\$\begingroup\$

I have a CPLD XC9536XL-10VQG44C. On this CPLD I have one input "INPUT_4", one clock at 4MHz "clock" and 2 outputs "OUTPUT4_1" and "OUTPUT4_2", I also have 1 LED to drive that takes the same value than the input.

What I want to do is:

  • When INPUT_4 goes high, turn OUTPUT4_1 high and OUTPUT4_2 low for 50ms then put them both back to low.
  • When INPUT_4 goes low, turn OUTPUT4_1 as low and OUTPUT4_2 high for 50ms then put them both back to low.

So what I wanted to do was look for the input, and as soon as there is a change on it, do the corresponding change on the output and starting counting the 100ms. When the 50ms is finished, put them back low.

I appreciate that it is probably easier to do with a microcontroller but I cannot change the hardware.

For that I wrote that vhdl:

entity test_vhdl is
Port ( Input_4 : in  STD_LOGIC;
       Output4_1 : out  STD_LOGIC;
       Output4_2 : out  STD_LOGIC;
       LED_4 : out  STD_LOGIC;
       Clock : in  STD_LOGIC); --4MHz
end test_vhdl;
architecture Behavioral of test_vhdl is
constant overflow : natural := 200000; --50ms pulse with a 4MHz frequency
signal COUNTER_4   : natural range 0 to overflow;
begin
    LED_4<=Input_4;
output4: process(Input_4, Clock) is
    begin
        if rising_edge(Input_4)then
            Output4_1 <= '1';
            Output4_2 <= '0';
            COUNTER_4 <= 1;
        elsif falling_edge(Input_4) then
            Output4_1 <= '0';
            Output4_2 <= '1';
            COUNTER_4 <= 1;
        end if;
        else
        if rising_edge(Clock) then
            if COUNTER_4 /= 0 then
                COUNTER_4 <= COUNTER_4 + 1;
                if COUNTER_4 = overflow-1 then
                    Output4_1 <= '0';
                    Output4_2 <= '0';
                    COUNTER_4 <= 0;
                end if;
            end if;
        end if;
        end if;
    end process output4;

end Behavioral;

I simulated it and it works fine. But when I try to synthesize it I get the error:

Signal Output4_1 cannot be synthesized, bad synchronous description. The description style you are using to describe a synchronous element (register, memory, etc.) is not supported in the current software release.

Maybe it comes from the fact that I check the rising edge of two different signals in the same process. I am still in the learning curve of VHDL, how can I resolve this problem or is there a better way of doing what I need to?

\$\endgroup\$
8
  • \$\begingroup\$ Why did you comment away the else? As written it looks like your code will still respond to clock edges while the reset signal is asserted. Real flip flops don't work that way, so it can't be synthesized. \$\endgroup\$
    – The Photon
    Apr 25, 2019 at 14:39
  • 2
    \$\begingroup\$ Also real flip flops don't respond to both edges of reset, so that's another problem. \$\endgroup\$
    – The Photon
    Apr 25, 2019 at 14:40
  • \$\begingroup\$ In addition to @ThePhoton: The error message should be interpreted like "There exists no hardware in our CPLD which behaves the way you have described in your code" \$\endgroup\$
    – Oldfart
    Apr 25, 2019 at 15:52
  • \$\begingroup\$ @ThePhoton : the else statement was actually not commented at first, it was just a try after I got that error first. I have uncommented it after I will edit the post but it is doing the same thing. \$\endgroup\$
    – damien
    Apr 25, 2019 at 15:54
  • 1
    \$\begingroup\$ As for how to solve it, I'd suggest you think in terms of state machines rather than setting and resetting raw flip-flops. \$\endgroup\$
    – The Photon
    Apr 25, 2019 at 16:10

1 Answer 1

0
\$\begingroup\$

I am not going to write the whole code but this may help.

Below is a code snippet which detects rising and falling edges. But it is fully synchronous. Beware that the code assumes input4 is synchronous to Clock.

logic input4_one_cycle_delayed std_logic;
logic input4_rising            std_logic;
logic input4_falling           std_logic;

edges: process(Clock)    
begin
    if rising_edge(Clock) then
       input4_one_cycle_delayed <= input4;
    end if;
end

input4_rising  <=  input4 and not input4_one_cycle_delayed;
input4_falling <=  not input4 and input4_one_cycle_delayed;

I normally write Verilog so there may be some VHDL syntax errors in there. However the principle should be clear.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.