Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16623 Discussions

Simulation Results Always Show Don't Care?

Altera_Forum
Honored Contributor II
1,314 Views

Hello All, 

 

I am very new at digital design and am learning on an Altera DE2-70 using VHDL. I have the following code snippet which always shows "Don't Care (XXX)" for the simulation results (clkOut). Can anyone help? The code basically takes clkIn and generates a clkOut whose period is given by the number of input clkIn clocks. I have also attached a Quartus II project archive if anyone cares to run the simulation. 

 

Thanks. 

 

-- Frequency Divider (must be multiple of 2) -- Author : Hitesh Patel, October 2008 -- blog.nirosoftware.com -- LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; ENTITY FrequencyDivider IS GENERIC (NumBits : INTEGER := 26); PORT( clkIn : IN STD_LOGIC; divisor : IN STD_LOGIC_VECTOR(NumBits-1 DOWNTO 0); -- 26 bits, must be multiple of 2 clkOut : BUFFER STD_LOGIC := '1'); END FrequencyDivider; ARCHITECTURE FrequencyDivider OF FrequencyDivider IS BEGIN PROCESS(clkIn) VARIABLE count : STD_LOGIC_VECTOR(NumBits-2 DOWNTO 0); BEGIN IF(clkIn'EVENT AND (clkIn = '1')) THEN count := count + 1; END IF; IF(count = divisor(NumBits-2 DOWNTO 1)) THEN clkOut <= NOT clkOut; count := (OTHERS => '0'); END IF; END PROCESS; END FrequencyDivider;
0 Kudos
5 Replies
Altera_Forum
Honored Contributor II
518 Views

I suggest don't use buffer ports. Instead use an internal signal in order to have internal access

0 Kudos
Altera_Forum
Honored Contributor II
518 Views

It basically don't work to have part of the clock divider logic outside the clock edge sensitive condition. This way, no Flipflop for clkOut can be inferred. 

 

There may be also a problem in comparing signals of different bitwidth. 

 

A power of two divider ratio can be simply achieved by allowing an overflow of the counter (don't need any compare or reset to 0) and using the MSB as output signal (if a 50% duty cycle is intended).
0 Kudos
Altera_Forum
Honored Contributor II
518 Views

'X' in std_logic doesn't mean don't care - it means "Forcing Unknown" - i.e. the simulator is trying to drive a '1' or '0' onto the signal but it can't determine which. This can be for several reasons such as putting 'U' into an arithmetic function; but very commonly it can be because you have two drivers for one signal - e.g. two processes which both try and drive the same signal. In logic terms this is like wiring up the outputs of two gates or registers together - the wire will be driven to some value as one or other of the gates is likely to be stronger than the other, but whether the high driving gate is stronger than the low driving one is unpredictable: so in simulation you end up with 'X'. 

 

Parrado is on the ball with the advice of "buffer" direction. I would avoid this as in VHDL pre-2002 buffer ports could only be connected to other buffer ports - i.e. once you start with it you have to propagate the "buffer" all the way up. Use an internal signal (say clkOut_int) and then somewhere in your code apply this to the output: clkOut <= clkOut_int; 

 

Make this the only assignment to the output! 

 

I would have a look at your synthesis output as the synthesis tool may be getting confused. You need to be very strict and if you want a register then put everything inside the clk'event bit: 

process(clk) begin -- don't put anything here if clk'event and clk = '1' then -- put your code here end if; -- don't put anything here end process; 

 

Read the Altera's coding style document: 

 

http://www.altera.com/literature/hb/qts/qts_qii51007.pdf?gsa_pos=1&wt.oss_r=1&wt.oss=coding%20style 

 

There are some slight variations if you want asynchronous resets and/or clock enables, but you need to be very strict with your code to get registers right. You may find with your code as it is that you are inferring a register and a separate latch or combinatorial function which are being wired up together to give your 'X' output - a guess but either way your code will give you problems as it is. 

 

Good luck
0 Kudos
Altera_Forum
Honored Contributor II
518 Views

First off thank you to parrado, FvM and batfink for your time and advice. Indeed I have a lot to learn even simple designs can trip you over! Anway, attached are 3 images from the RTL viewer (basically the synthesis results). The first image is that of my original faulty design. The second image is one for the following changed working code. Basically, all I changed was to bring all code into the clk'EVENT conditional (clkOut still declared as BUFFER). Finally, the last image is one that includes the above change plus declaring clkOut as OUT, ie using an internal signal to drive clkOut---those aspects of the code appear as comments in the snippet below. Both the final designs simulate well and notice that removing BUFFER added an additional output flip-flop but everything else is the same. 

 

Thank you to all. 

---- 

Hitesh Patel @ http://blog.nirosoftware.com (http://blog.nirosoftware.com/) (where I am documenting these learning experiences) 

 

 

-- Frequency Divider (must be multiple of 2) -- Author : Hitesh Patel, October 2008 -- blog.nirosoftware.com -- LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; ENTITY FrequencyDivider IS GENERIC (NumBits : INTEGER := 26); PORT( clkIn : IN STD_LOGIC; divisor : IN STD_LOGIC_VECTOR(NumBits-1 DOWNTO 0); -- 26 bits, must be multiple of 2 clkOut : BUFFER STD_LOGIC); END FrequencyDivider; ARCHITECTURE FrequencyDivider OF FrequencyDivider IS BEGIN PROCESS(clkIn) VARIABLE count : STD_LOGIC_VECTOR(NumBits-2 DOWNTO 0); --VARIABLE clkOut_t : STD_LOGIC; BEGIN IF(clkIn'EVENT AND (clkIn = '1')) THEN count := count + 1; IF(count = divisor(NumBits-2 DOWNTO 1)) THEN --clkOut_t := NOT clkOut_t; --clkOut <= clkOut_t; clkOut <= NOT clkOut; count := (OTHERS => '0'); END IF; END IF; END PROCESS; END FrequencyDivider;
0 Kudos
Altera_Forum
Honored Contributor II
518 Views

You results are as I would expect them. The additional flip-flop is generated, when you assign the internal signal to the output under the clock sensitive condition. Usually the assignment of outputs would be done in concurrent code (outside the process) without inferring an additional flip-flop. 

 

You also showed, that the doubts, that have been worded regarding the usage of a buffer port are apparently unfounded. That's also according to my experience, although I think, that using an internal signal (and assigning it delayless in concurrent code to the outut port) is a better style.
0 Kudos
Reply