08.08.2013, 05:07 PM
Ich stell mir das so vor..... Klirrmessung: Ein Generator speist feinsten Sinus ins Messobjekt.
Parallel zum Eingang befindet sich der CPLD-Graukasten und triggert den Sinus. Im Graukasten dann VHDL zur Bildung einer digitalen PLL in allen geraden und ungeraden Frequenzvervielfachungen. Einer von den Ausgängen steuert dann den einen Analogschalter, dessen NF-Eingang mit dem Messobjektausgang verbunden wird. Welchen Klirr man gerade analysiert, kann auf der Frontplatte ausgewählt werden.
Also so in etwa (nur geklaut):
-- Digital PLL based on the 74LS297 architecture
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_misc.all;
use IEEE.std_logic_unsigned.all;
entity PLL1 is
port (
clk: in STD_LOGIC; -- clock for k and id counter
f_in: in STD_LOGIC; -- input signal
f_out: inout STD_LOGIC -- output signal
);
end PLL1;
architecture PLL1_arch of PLL1 is
-- enter PLL parameters here
constant Kbit: integer:=8; -- bitwidth of the K_counter
constant N_mod: integer:=9; -- modul of N_counter
constant f_in_mod: integer:=8; -- modul of reference prescaler
constant f_out_mod: integer:=8; -- modul of DCO_postscaler
-- do not change source code below here ((uunless you know what you are doing ;-)
signal dn_up: std_logic; -- selects up or down counter of k_counter
signal ca: std_logic; -- carry out of k_counter
signal bo: std_logic; -- borrow out of k_counter
signal N_cont: integer range 0 to N_mod-1; -- N counter
signal f_in_scale: integer range 0 to f_in_mod-1; -- reference prescaler
signal f_out_scale: integer range 0 to f_out_mod-1; -- DCO postscaler
signal f_in_s, f_out_s: std_logic; -- prescaler outputs
signal k_up: std_logic_vector (Kbit-1 downto 0); -- up counter in k_counter
signal k_dn: std_logic_vector (Kbit-1 downto 0); -- down counter in k_counter
signal c1,c2,c3,c4: std_logic; -- shift register of carry
signal b1,b2,b3,b4: std_logic; -- shift register of borrow
signal id_out: std_logic; -- output of id_counter
begin
-- K_counter
k_cnt: process (clk)
begin
if clk='0' and clk'event then
if dn_up='1' then
k_dn<=k_dn+1;
else
k_up<=k_up+1;
end if;
end if;
end process;
ca<=k_up(kbit-1);
bo<=k_dn(kbit-1);
-- ID_counter
id_cnt: process (clk)
begin
if clk='1' and clk'event then -- positive edge controlled
c1<=ca;
c2<=c1;
c3<=c2;
c4<= ( (not c1) and c2 and id_out ) or ( (not c2) and c3 and id_out );
-- in the schematic of the 74LS297 the c4 uses the invertet output
-- for some strange reason we can not invert c4 here, this will eliminate 2 FFs
b1<=bo;
b2<=b1;
b3<=b2;
b4<= ( (not b1) and b2 and (not id_out) ) or ( (not b2) and b3 and (not id_out) );
-- here is a JK-FF, maybe we need a better construction in the future
-- we use the inverted signals of c4 and b4
if c4='1' and b4='1' then
id_out<=id_out;
elsif c4='0' and b4='1' then
id_out<='1';
elsif c4='1' and b4='0' then
id_out<='0';
elsif c4='0' and b4='0' then
id_out<= not id_out;
end if;
-- end of JK-FF
end if;
end process;
-- The original schematics of the 74LS297 produces a gated clock,
-- which may result in timing problems
-- We better use id_out as an clock enable for the N counter
-- ID-out is the inverted clock enable; clk is the inverted clk
-- simple XOR phase detector
-- dn_up<=f_in_s xor f_out_s; -- iff you want to use the EXOR PD, just uncomment this
-- but think about the EXOR limitations!!!!
-- edge controlled phase detector
ECPD: block is
signal pd1,pd2,rpd: std_logic;
begin
rpd<=pd2;
dn_up<=pd1;
process (rpd, f_out_s) -- a leading negative edge of
begin -- f_out sets the phase detector
if rpd='1' then
pd1<='0';
elsif f_out_s='0' and f_out_s'event then
pd1<='1';
end if;
end process;
process (rpd, f_in_s) -- a negative edge of f_in resets
begin
if rpd='1' then -- the phase detector
pd2<='0';
elsif f_in_s='0' and f_in_s'event then
pd2<='1';
end if;
end process;
end block;
-- prescalers
process (f_in)
begin
if f_in='1' and f_in'event then
if f_in_scale=f_in_mod-1 then
f_in_scale<=0; f_in_s<='0';
elsif f_in_scale>=(f_in_mod/2-1) then
f_in_scale<=f_in_scale+1; f_in_s<='1';
else
f_in_scale<=f_in_scale+1; f_in_s<='0';
end if;
end if;
end process;
process (f_out)
begin
if f_out='1' and f_out'event then
if f_out_scale=f_out_mod-1 then
f_out_scale<=0; f_out_s<='0';
elsif f_out_scale>=(f_out_mod/2-1) then
f_out_scale<=f_out_scale+1; f_out_s<='1';
else
f_out_scale<=f_out_scale+1; f_out_s<='0';
end if;
end if;
end process;
-- Divide by N counter
-- this implementation differs a lot fromm the logic in the 74LS297
-- which uses a gated clock (ID output), tthat is deadly for very high clock rates
-- (up to 180MHz in Spartan 2)
-- here we use clock enable on the N counntter
process (clk, id_out)
begin
if clk='0' and clk'event then
if id_out='0' then
if N_cont=N_mod-1 then
N_cont<=0; f_out<='0';
elsif N_cont>=(N_mod/2-1) then
N_cont<=N_cont+1; f_out<='1';
else
N_cont<=N_cont+1; f_out<='0';
end if;
end if;
end if;
end process;
end PLL1_arch;
Parallel zum Eingang befindet sich der CPLD-Graukasten und triggert den Sinus. Im Graukasten dann VHDL zur Bildung einer digitalen PLL in allen geraden und ungeraden Frequenzvervielfachungen. Einer von den Ausgängen steuert dann den einen Analogschalter, dessen NF-Eingang mit dem Messobjektausgang verbunden wird. Welchen Klirr man gerade analysiert, kann auf der Frontplatte ausgewählt werden.
Also so in etwa (nur geklaut):
-- Digital PLL based on the 74LS297 architecture
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_misc.all;
use IEEE.std_logic_unsigned.all;
entity PLL1 is
port (
clk: in STD_LOGIC; -- clock for k and id counter
f_in: in STD_LOGIC; -- input signal
f_out: inout STD_LOGIC -- output signal
);
end PLL1;
architecture PLL1_arch of PLL1 is
-- enter PLL parameters here
constant Kbit: integer:=8; -- bitwidth of the K_counter
constant N_mod: integer:=9; -- modul of N_counter
constant f_in_mod: integer:=8; -- modul of reference prescaler
constant f_out_mod: integer:=8; -- modul of DCO_postscaler
-- do not change source code below here ((uunless you know what you are doing ;-)
signal dn_up: std_logic; -- selects up or down counter of k_counter
signal ca: std_logic; -- carry out of k_counter
signal bo: std_logic; -- borrow out of k_counter
signal N_cont: integer range 0 to N_mod-1; -- N counter
signal f_in_scale: integer range 0 to f_in_mod-1; -- reference prescaler
signal f_out_scale: integer range 0 to f_out_mod-1; -- DCO postscaler
signal f_in_s, f_out_s: std_logic; -- prescaler outputs
signal k_up: std_logic_vector (Kbit-1 downto 0); -- up counter in k_counter
signal k_dn: std_logic_vector (Kbit-1 downto 0); -- down counter in k_counter
signal c1,c2,c3,c4: std_logic; -- shift register of carry
signal b1,b2,b3,b4: std_logic; -- shift register of borrow
signal id_out: std_logic; -- output of id_counter
begin
-- K_counter
k_cnt: process (clk)
begin
if clk='0' and clk'event then
if dn_up='1' then
k_dn<=k_dn+1;
else
k_up<=k_up+1;
end if;
end if;
end process;
ca<=k_up(kbit-1);
bo<=k_dn(kbit-1);
-- ID_counter
id_cnt: process (clk)
begin
if clk='1' and clk'event then -- positive edge controlled
c1<=ca;
c2<=c1;
c3<=c2;
c4<= ( (not c1) and c2 and id_out ) or ( (not c2) and c3 and id_out );
-- in the schematic of the 74LS297 the c4 uses the invertet output
-- for some strange reason we can not invert c4 here, this will eliminate 2 FFs
b1<=bo;
b2<=b1;
b3<=b2;
b4<= ( (not b1) and b2 and (not id_out) ) or ( (not b2) and b3 and (not id_out) );
-- here is a JK-FF, maybe we need a better construction in the future
-- we use the inverted signals of c4 and b4
if c4='1' and b4='1' then
id_out<=id_out;
elsif c4='0' and b4='1' then
id_out<='1';
elsif c4='1' and b4='0' then
id_out<='0';
elsif c4='0' and b4='0' then
id_out<= not id_out;
end if;
-- end of JK-FF
end if;
end process;
-- The original schematics of the 74LS297 produces a gated clock,
-- which may result in timing problems
-- We better use id_out as an clock enable for the N counter
-- ID-out is the inverted clock enable; clk is the inverted clk
-- simple XOR phase detector
-- dn_up<=f_in_s xor f_out_s; -- iff you want to use the EXOR PD, just uncomment this
-- but think about the EXOR limitations!!!!
-- edge controlled phase detector
ECPD: block is
signal pd1,pd2,rpd: std_logic;
begin
rpd<=pd2;
dn_up<=pd1;
process (rpd, f_out_s) -- a leading negative edge of
begin -- f_out sets the phase detector
if rpd='1' then
pd1<='0';
elsif f_out_s='0' and f_out_s'event then
pd1<='1';
end if;
end process;
process (rpd, f_in_s) -- a negative edge of f_in resets
begin
if rpd='1' then -- the phase detector
pd2<='0';
elsif f_in_s='0' and f_in_s'event then
pd2<='1';
end if;
end process;
end block;
-- prescalers
process (f_in)
begin
if f_in='1' and f_in'event then
if f_in_scale=f_in_mod-1 then
f_in_scale<=0; f_in_s<='0';
elsif f_in_scale>=(f_in_mod/2-1) then
f_in_scale<=f_in_scale+1; f_in_s<='1';
else
f_in_scale<=f_in_scale+1; f_in_s<='0';
end if;
end if;
end process;
process (f_out)
begin
if f_out='1' and f_out'event then
if f_out_scale=f_out_mod-1 then
f_out_scale<=0; f_out_s<='0';
elsif f_out_scale>=(f_out_mod/2-1) then
f_out_scale<=f_out_scale+1; f_out_s<='1';
else
f_out_scale<=f_out_scale+1; f_out_s<='0';
end if;
end if;
end process;
-- Divide by N counter
-- this implementation differs a lot fromm the logic in the 74LS297
-- which uses a gated clock (ID output), tthat is deadly for very high clock rates
-- (up to 180MHz in Spartan 2)
-- here we use clock enable on the N counntter
process (clk, id_out)
begin
if clk='0' and clk'event then
if id_out='0' then
if N_cont=N_mod-1 then
N_cont<=0; f_out<='0';
elsif N_cont>=(N_mod/2-1) then
N_cont<=N_cont+1; f_out<='1';
else
N_cont<=N_cont+1; f_out<='0';
end if;
end if;
end if;
end process;
end PLL1_arch;