Hi All,I created a simple VHDL D flip flop but saw strange results on the logic analyzer. The code is as follows:
df:process(reset,clk) begin if(reset='1') then Q<=0; else if(clk'event AND clk='1') then if(A AND B) then Q<=D; else Q<=Q; end if; end if; end if; end process;Where reset,clk, A, Q, D, and B are standard logic vectors. When I view what is happening on the logic analyzer, I see that Q always follows the value of D, regardless of the value of A and B. I'm new to VHDL but what from what I understand Q should never be updated with D unless A and B are true on a clock edge. I also got a compiler warning in Quartus 12.1 about not having D in my sensitivity list. Is there something wrong with this code? Thanks, DigitalEE
There could be a great many things wrong with it ... but you haven't posted a sufficient amount of code.For example the statement Q <= 0 is not valid for std_logic, it should be Q <= '0', but then again, perhaps you have included a conversion library ... Post a complete example, rather than a code snippet. Here's how I would normally write this piece of code;
-- Start with only this library (you can get fancy later) library ieee; use ieee.std_logic_1164.all; .... process(clk, reset) begin if (reset = '1') then q <= '0'; elsif rising_edge(clk) then if ((a = '1') and (b = '1')) then q <= d; end if; end if; end process;Note the use of elsif, and also note that I've assumed a and b are std_logic, so to turn them into boolean I've compared them with a std_logic '1'. I do this out of habit, the syntax you have used might be allowed with VHDL-2008. Play with this example and see what you are allowed to do and what you cannot. Cheers, Dave
Thanks for the quick reply Dave. I do have conversion libraries, and in the original code I initialize the output to a signal, not to a constant. I just put that constant in as an example of what I was doing. Sorry for not posting the whole code, this snippet is part of a huge module that I'm upgrading.I think the problem is that in my code I only check if (A AND B ), not ((A='1') AND (B='1')). I have a lot experience in verilog which allows you to do that with no problem. I have to remind myself of the strict type checking in VHDL. Also elsif is interesting, didn't know there was a difference. That could also be a problem that I'm facing. Finally, I could probably lose the Q<=Q; part of my process. I will try the code you gave me and compare it to what I have and see how I can fix mine. Thanks for your help.
--- Quote Start --- I do have conversion libraries --- Quote End --- Which ones? For math, you should use numeric_std and math_real, not the older std_logic_arith libraries. --- Quote Start --- Sorry for not posting the whole code, this snippet is part of a huge module that I'm upgrading. --- Quote End --- That's ok, but when paring down code, synthesize it before posting it, as then the compiler performs the first level of syntax checks. --- Quote Start --- I have to remind myself of the strict type checking in VHDL. --- Quote End --- I think its a good thing. There is much less ambiguity when reading code other people have written. --- Quote Start --- Also elsif is interesting, didn't know there was a difference. That could also be a problem that I'm facing. --- Quote End --- There's also another factor. The tool. The style of code that I wrote infers a register ... perhaps the style you wrote does not. The way to answer that question is to look at the synthesized output. In Quartus there is an RTL netlist viewer which draws a schematic of your circuit. Use it to look at how Quartus interprets your code vs my code ... perhaps its identical. (Tools->Netlist Viewers->RTL Viewer). Use both Modelsim and Quartus while learning about FPGAs and HDLs. Feedback is good 🙂 Cheers, Dave