I Q Demodulation

N

Nemesis

Hi all, I'm working on a Digital Down Converter, the first stage of this
converter is composed by two blocks wich perform the I/Q demodulation
multiplicating the input sequence with sin/cos.
Frequencies are in a particular ratio, so this demodulation is
performed multiplicating the input sequence by (1,0,-1,0)/(0,-1,0,1).

So I used a 2-counter which feeds two blocks that implement this
demodulation. These blocks are implemented like multiplexers, in the
bottom of this article I pasted one of the blocks.

I have problems with the simulation of these blocks. When the SEL input
changes from the "00" value to "11" value, the output bits doesn't
change in the same time, so I can see a certain amount of "undesidered"
transitions, is that normal? Is there something wrong in the code?

I also tried using a DEMOD variable instead of DEMOD_OUT, but nothing
changed (I got exactly the same RTL).



******************Q_Demod.vhd***************************
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity Q_Demod is
port(
CLK : in STD_LOGIC;
INPUT : in STD_LOGIC_VECTOR(13 downto 0);
SEL : in STD_LOGIC_VECTOR(1 downto 0);
DEMOD_OUT : out STD_LOGIC_VECTOR(13 downto 0)
);
end Q_DEMOD;

architecture Behavioral of Q_DEMOD is
begin
------------------------------------------
process (CLK)
begin
if rising_edge(CLK) then
case SEL is
when "00" => DEMOD_OUT <= "00000000000000"; -- 0
when "01" => DEMOD_OUT <= (not INPUT) + 1; -- -1
when "10" => DEMOD_OUT <= "00000000000000"; -- 0
when "11" => DEMOD_OUT <= INPUT; -- 1
when others => NULL;
end case;
end if;
end process;
 
H

Hans

Add INPUT to your sensitivity list,

process(CLK, INPUT)

Hans.
www.ht-lab.com


| Hi all, I'm working on a Digital Down Converter, the first stage of this
| converter is composed by two blocks wich perform the I/Q demodulation
| multiplicating the input sequence with sin/cos.
| Frequencies are in a particular ratio, so this demodulation is
| performed multiplicating the input sequence by (1,0,-1,0)/(0,-1,0,1).
|
| So I used a 2-counter which feeds two blocks that implement this
| demodulation. These blocks are implemented like multiplexers, in the
| bottom of this article I pasted one of the blocks.
|
| I have problems with the simulation of these blocks. When the SEL input
| changes from the "00" value to "11" value, the output bits doesn't
| change in the same time, so I can see a certain amount of "undesidered"
| transitions, is that normal? Is there something wrong in the code?
|
| I also tried using a DEMOD variable instead of DEMOD_OUT, but nothing
| changed (I got exactly the same RTL).
|
|
|
| ******************Q_Demod.vhd***************************
| library IEEE;
| use IEEE.STD_LOGIC_1164.ALL;
| use IEEE.STD_LOGIC_ARITH.ALL;
| use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
| entity Q_Demod is
| port(
| CLK : in STD_LOGIC;
| INPUT : in STD_LOGIC_VECTOR(13 downto 0);
| SEL : in STD_LOGIC_VECTOR(1 downto 0);
| DEMOD_OUT : out STD_LOGIC_VECTOR(13 downto 0)
| );
| end Q_DEMOD;
|
| architecture Behavioral of Q_DEMOD is
| begin
| ------------------------------------------
| process (CLK)
| begin
| if rising_edge(CLK) then
| case SEL is
| when "00" => DEMOD_OUT <= "00000000000000"; -- 0
| when "01" => DEMOD_OUT <= (not INPUT) + 1; -- -1
| when "10" => DEMOD_OUT <= "00000000000000"; -- 0
| when "11" => DEMOD_OUT <= INPUT; -- 1
| when others => NULL;
| end case;
| end if;
| end process;
| ------------------------------------------
| end Behavioral;
| ******************Q_Demod.vhd***************************
| --
| If you cannot convince them, confuse them.
|
| |\ | |HomePage : http://nem01.altervista.org
| | \|emesis |XPN (my nr): http://xpn.altervista.org
|
 
I

info_

Hans said:
Add INPUT to your sensitivity list,

process(CLK, INPUT)


NO ! This is indeed wrong. The sensitivity list WAS correct,
do NOT add anything to it !!!

Process(Clk)
or
Process (Clk,Rst) -- in case of asynchronous reset
fyi I published recently VHDL Coding style rules that can be useful.

The "problem" is probably non-existent.

| I have problems with the simulation of these blocks. When the SEL input
| changes from the "00" value to "11" value, the output bits doesn't
| change in the same time, so I can see a certain amount of "undesidered"
| transitions, is that normal? Is there something wrong in the code?

I suppose you mean "timing simulation", not RTL simulation.
And you observe a change in the output as a result of a clock (rising) edge.
And you have inputs changing at a time which is not craeting timing violations.

The notion of "at the same time" in the real (analog) world isn't a good notion.
If your outputs are not direct FF outputs that are put in the I/Os, you _will_ likely
get timing differences between all the signals, as you probably observed.

This is indeed fine if you use these signals in a _synchronous_ way (in the same
clock domain) in which case the static timing analysis will tell you if the setup
time to all the receiving FFs is met, in which case everything is fine.

If those signals are are chip outputs, and you want to minimize the timing
differences, then make sure the outputs are straight out of FFs and that these FFs
are moved to the IOs.

Bert Cuzeau
 
N

Nemesis

Mentre io pensavo ad una intro simpatica "info_" scriveva:
The "problem" is probably non-existent.

| I have problems with the simulation of these blocks. When the SEL input
| changes from the "00" value to "11" value, the output bits doesn't
| change in the same time, so I can see a certain amount of "undesidered"
| transitions, is that normal? Is there something wrong in the code?

I suppose you mean "timing simulation", not RTL simulation.

Hmm, I'm using what ISE calls "Post Place&Route Simulation".
And you observe a change in the output as a result of a clock (rising) edge.
And you have inputs changing at a time which is not craeting timing violations.

The notion of "at the same time" in the real (analog) world isn't a good notion.
If your outputs are not direct FF outputs that are put in the I/Os, you _will_ likely
get timing differences between all the signals, as you probably observed.

Yes, these signals are not direct outputs, I must send them inside other
stages.
This is indeed fine if you use these signals in a _synchronous_ way (in the same
clock domain) in which case the static timing analysis will tell you if the setup
time to all the receiving FFs is met, in which case everything is fine.

OK, now I have a more clear view of the problem.
As you say I'm going to use these signals in a _synchronous_ way.

But now I discovered another problem (maybe). I scaled the clock timings
to simulate the real clock I'll have on the board wich is 64MHz, so I
set Tup and Tdown to 7812ps (till now I performed simulations with the
default timings, i.e. Tup=Tdown=50ns). I got a bad output, it is
very delayed from the input, probably the circuit is to slow for such
a clock. In the timing report I read:

Timing Summary:
---------------
Speed Grade: -6

Minimum period: No path found
Minimum input arrival time before clock: 4.062ns
Maximum output required time after clock: 4.575ns
Maximum combinational path delay: No path found

These number seems to close to clock period, but I don't know how to
interpret them.
 
I

info_

Nemesis said:
But now I discovered another problem (maybe). I scaled the clock timings
to simulate the real clock I'll have on the board wich is 64MHz, so I
set Tup and Tdown to 7812ps (till now I performed simulations with the
default timings, i.e. Tup=Tdown=50ns). I got a bad output, it is
very delayed from the input, probably the circuit is to slow for such
a clock. In the timing report I read:

Timing Summary:
---------------
Speed Grade: -6

Minimum period: No path found
Minimum input arrival time before clock: 4.062ns
Maximum output required time after clock: 4.575ns
Maximum combinational path delay: No path found

These number seems to close to clock period, but I don't know how to
interpret them.

Please, please : do NOT rely on timing (post-layout) simulation to verify against
timing problems !
(In fact, we usually don't do timing simulations until the end of the project,
or when we have doubts about what the tool did -like for the bug I reported
recently). Timing simulation is slow and cumbersome and will not detect most
timing problems, or detect non-problems. So unless yo have a very good
reason to do post-layout sim : do synchtronous design and rely on STA (see below).

One marvelous thing has been invented (for synchronous designs) named
"Static Timing Analysis".

And the tools (including ISE indeed) do it for you !
Look at the Fmax figures, and you will get confirmation or not of you potential
problem. It's a tiny bit more tricky with _syn_chronous external inputs/outputs.

Also important : _always_ let your P&R tool know your exact Clk frequency (constraint).
Most modern P&R tools are timing driven, and you must provide them with the accurate
information about your clock frequency.

Bert Cuzeau
 
H

Hans

Oops, yes, sorry Nemesis, I was still asleep when I replied :-(

Regards,
Hans.
www.ht-lab.com


| Hans wrote:
|
| > Add INPUT to your sensitivity list,
| >
| > process(CLK, INPUT)
|
|
| NO ! This is indeed wrong. The sensitivity list WAS correct,
| do NOT add anything to it !!!
|
 
N

Nemesis

Mentre io pensavo ad una intro simpatica "Hans" scriveva:
Oops, yes, sorry Nemesis, I was still asleep when I replied :-(

No problem, I already tried _everything_! :-D
 
N

Nemesis

Mentre io pensavo ad una intro simpatica "info_" scriveva:

Please, please : do NOT rely on timing (post-layout) simulation to verify against
timing problems ! [cut]

One marvelous thing has been invented (for synchronous designs) named
"Static Timing Analysis".

With Xilinx ISE I can perform two type of Static Timing Analysis, the
former after Mapping and the latter after Place and Route (but I still
have problems reading and interpreting the results), so do you think the
former is the best.
Also important : _always_ let your P&R tool know your exact Clk frequency (constraint).
Most modern P&R tools are timing driven, and you must provide them with the accurate
information about your clock frequency.

I managed to add a Clock constraint ... but I still don't know how to
check if the entity is good for its purpose. :-/
 
J

Jim George

Nemesis said:
Hi all, I'm working on a Digital Down Converter, the first stage of this
converter is composed by two blocks wich perform the I/Q demodulation
multiplicating the input sequence with sin/cos.
Frequencies are in a particular ratio, so this demodulation is
performed multiplicating the input sequence by (1,0,-1,0)/(0,-1,0,1).

So I used a 2-counter which feeds two blocks that implement this
demodulation. These blocks are implemented like multiplexers, in the
bottom of this article I pasted one of the blocks.

I have problems with the simulation of these blocks. When the SEL input
changes from the "00" value to "11" value, the output bits doesn't
change in the same time, so I can see a certain amount of "undesidered"
transitions, is that normal? Is there something wrong in the code?

I also tried using a DEMOD variable instead of DEMOD_OUT, but nothing
changed (I got exactly the same RTL).



******************Q_Demod.vhd***************************
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity Q_Demod is
port(
CLK : in STD_LOGIC;
INPUT : in STD_LOGIC_VECTOR(13 downto 0);
SEL : in STD_LOGIC_VECTOR(1 downto 0);
DEMOD_OUT : out STD_LOGIC_VECTOR(13 downto 0)
);
end Q_DEMOD;

architecture Behavioral of Q_DEMOD is
begin
------------------------------------------
process (CLK)
begin
if rising_edge(CLK) then
case SEL is
when "00" => DEMOD_OUT <= "00000000000000"; -- 0
when "01" => DEMOD_OUT <= (not INPUT) + 1; -- -1
when "10" => DEMOD_OUT <= "00000000000000"; -- 0
when "11" => DEMOD_OUT <= INPUT; -- 1
when others => NULL;
end case;
end if;
end process;

First, you can verify that the glitches occur far away from a clock
edge, so they wont make a difference if the subsequent logic is also
sequential and clocked by the same edge. Next, to verify this, actually
put a register there and re-run your timing sim. Finally, if you think
you're pushing your clock too high for your speed grade, then try
placing the components one by one in Floorplanner so they form a neat
line. Sometimes this affects the skew.
 
N

Nemesis

Mentre io pensavo ad una intro simpatica "Jim George" scriveva:
First, you can verify that the glitches occur far away from a clock
edge, so they wont make a difference if the subsequent logic is also
sequential and clocked by the same edge. Next, to verify this, actually
put a register there and re-run your timing sim. Finally, if you think
you're pushing your clock too high for your speed grade, then try
placing the components one by one in Floorplanner so they form a neat
line. Sometimes this affects the skew.

Thanks for this hints. At least I think the circuit is working
correctly, I added the next stage (a fir filter) and the output seems
good.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top