1
\$\begingroup\$

so I've been trying to solve some questions in the book Free Range VHDL. The question I have problems with is:

Provide a VHDL behavioral model of the D flip-flop. The S and R inputs are an active low asynchronous preset and clear. If both the S and R inputs are asserted simultaneously, the output of the flip-flop will toggle.

My code is:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;


entity sds is
    Port ( d,clk,s,r :in std_logic;
           f: out STD_LOGIC);
end sds;

architecture Behavioral of sds is
signal sr: std_logic_vector(1 downto 0);
signal outs : std_logic;
begin

sr <= s & r; --concatenating set and reset

process(clk,sr)

begin
case sr is
when "00" => outs <= not outs; --should toggle when both set and reset are 0
when "01" => outs <= '1'; --output should be 1 when set is 0
when "10" => outs <= '0'; --output should be zero when set is 1 and reset is 0
when "11" => if rising_edge(clk) then outs <= d; --classic d flip flop
end if;
when others => outs <= '0';


end case;
end process;
f <= outs;
end Behavioral;

The code works fine on my FPGA except for the toggling part. I cannot make the output toggle when both set and reset are 0. It always produces 1. Where is my mistake in the code? Thank you all.

\$\endgroup\$
  • 1
    \$\begingroup\$ In the "00" case you need to make the flopping code run on the clock edge: IF rising_edge(clk) THEN... \$\endgroup\$ – td127 Aug 29 at 19:00
  • \$\begingroup\$ @td127 it only made the output light dimmer lol :/ \$\endgroup\$ – dubistweltmeister Aug 30 at 8:53
  • 1
    \$\begingroup\$ Forget the case statement, just use IF (r) THEN.... ELSIF (s) THEN... ELSIF rising_edge(CLK) THEN... \$\endgroup\$ – td127 Aug 30 at 17:32
  • 1
    \$\begingroup\$ What makes you think it doesn't work? It does work. The only odd thing, which maybe you didn't intend, is that when rs = 00 the output toggles on every edge of clk (both rising and falling). That's because clk is in the sensitivity list which means your process will run (and only run) upon a change in state of clk, or s, or r. So every edge of clk results in a toggle if sr=00. \$\endgroup\$ – td127 Aug 31 at 0:29
  • 1
    \$\begingroup\$ Mind you, when I say it "works" I mean that the output does what you specified. But it certainly doesn't cleanly map to a single D flip-flop if that was your intention. That's because a normal flip flop doesn't behave as you've specified when sr=00 (i.e. toggle) and it certainly doesn't do anything on a falling clk edge. These are behavior quirks the compiler will have to jump through hoops to implement, but it will if asked. I've simulated your code and it does exactly what you specified. \$\endgroup\$ – td127 Aug 31 at 2:44
0
\$\begingroup\$

Read the Synthesis Style Guide for your FPGA.

Synthesis may use the closest type of FF available on the FPGA and there may be none that implement that precise functionality.

Also, look at the synthesised circuit, identify the FF that was used, and read its description (paying attention to what it does with S and R both asserted).

Not all valid VHDL is synthesisable, and the synthesis guide is there to tell you what can or can't be implemented.

A good useful guide is to follow the supported patterns for synchronous processes, as described in the synthesis style guide. These will work : deviating from them may sometimes work, but will not always be well supported by the tools.

And of course, a different synthesis tool or a different FPGA may deliver different results.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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