📄 fracn09.pl
字号:
do { my $old_tabstop = $tabstop; $tabstop = 10; comment " Divider summary :\n"; comment "\n"; comment " Approx\tApprox\tRelative\tApprox\t\n"; comment " ff\tVirtex\tFrequency\tJitter\tDivider\n"; comment " count\tSlices\tError\t(seconds)\t(generic parameters)\n"; comment "\n"; comment " " . ($num_bits + 2) . "\ttbd" . (sprintf "\t%1.2g", ($error_achieved_pa / $fout)) . (sprintf "\t%1.2g", (1 / $fin)) . "\tuse_phase_accumulator\n"; comment " " . ($num_bits + 5) . "\ttbd" . (sprintf "\t%1.2g", ($error_achieved_pa / $fout)) . (sprintf "\t%1.2g", (0.5 / $fin)) . "\tuse_phase_accumulator improve_duty_cycle\n"; comment " " . ((ceil(log($n + 1) / log(2)) + 2) + $ff_count_recursive_controller) . "\ttbd" . (sprintf "\t%1.2g", ($error_achieved / $fout)) . (sprintf "\t%1.2g", $good_jitter) . "\tuse_recursive_controller\n"; comment " " . ((ceil(log($n + 1) / log(2)) + 3) + $ff_count_recursive_controller) . "\ttbd" . (sprintf "\t%1.2g", ($error_achieved / $fout)) . (sprintf "\t%1.2g", $good_jitter) . "\tuse_recursive_controller improve_duty_cycle\n"; comment " " . ((ceil(log($n + 1) / log(2)) + 2) + (ceil(log($a + $b) / log(2)) + 1)) . "\ttbd" . (sprintf "\t%1.2g", ($error_achieved / $fout)) . (sprintf "\t%1.2g", $good_jitter) . "\tminimum_jitter\n"; comment " " . ((ceil(log($n + 1) / log(2)) + 3) + (ceil(log($a + $b) / log(2)) + 1)) . "\ttbd" . (sprintf "\t%1.2g", ($error_achieved / $fout)) . (sprintf "\t%1.2g", $good_jitter) . "\tminimum_jitter improve_duty_cycle\n"; comment " " . ((ceil(log($n + 1) / log(2)) + 2) + (ceil(log($a + $b) / log(2)) + 1)) . "\ttbd" . (sprintf "\t%1.2g", ($error_achieved / $fout)) . (sprintf "\t%1.2g", $bad_jitter) . "\t(none)\n"; comment " " . ((ceil(log($n + 1) / log(2)) + 3) + (ceil(log($a + $b) / log(2)) + 1)) . "\ttbd" . (sprintf "\t%1.2g", ($error_achieved / $fout)) . (sprintf "\t%1.2g", $bad_jitter) . "\t(none) improve_duty_cycle\n"; comment "\n"; $tabstop = $old_tabstop;};comment " Warnings:\n";comment ((@warnings == 0) ? " none\n" : @warnings);comment "\n";comment " Do not fix bugs by hand editing this file - fix the Perl source instead!\n";comment_line;# write library use clausesvhdl "library ieee;\n";vhdl "use ieee.std_logic_1164.all;\n";vhdl "-- " if ($std_logic_unsigned or $std_logic_arith);vhdl "use ieee.numeric_std.all;\n";vhdl "use ieee.std_logic_unsigned.all;\n" if ($std_logic_unsigned);vhdl "use ieee.std_logic_arith.all;\n" if ($std_logic_arith);# no need for library use clauses in Verilog# write entity declarationvhdl "\n";vhdl "entity $entity_name is\n";vhdl "\tgeneric (\n";vhdl "\t\tuse_phase_accumulator : boolean := FALSE;\n";vhdl "\t\t\t-- TRUE uses classic NCO design.\n";vhdl "\t\t\t-- FALSE uses prescaler / controller design\n";vhdl "\t\tuse_recursive_controller : boolean := TRUE;\n";vhdl "\t\tminimum_jitter : boolean := FALSE;\n";if ($low_jitter_controller) { vhdl "\t\t\t-- TRUE may use more hardware, but has lowest jitter\n"; vhdl "\t\t\t-- (only applies when use_phase_accumulator is FALSE)\n";}else { vhdl "\t\t\t-- Do not set the minimum_jitter generic to TRUE!\n"; vhdl "\t\t\t-- This file does not contain the code to support it!\n"; vhdl "\t\t\t-- (The Perl script was run with the \"-g\" option.)\n";}vhdl "\t\timprove_duty_cycle : boolean := TRUE\n";vhdl "\t\t\t-- TRUE uses a falling edge ff to make the output duty cycle closer to 50%\n";vhdl "\t);\n";vhdl "\tport (\n";vhdl "\t\tasync_reset : in std_logic := '0';\t-- active high reset\n";vhdl "\t\tclock : in std_logic; \t-- $fin Hz input clock\n";vhdl "\t\tclock_enable : in std_logic := '1';\t-- active high clock enable\n";if ($gen_50_percent_output) { vhdl "\t\toutput_50 : out std_logic;\t-- $fout Hz output - approx 50% duty cycle\n";}else { vhdl "\t\toutput_50 : out std_logic;\t-- This signal not implemented for this divider!\n"; vhdl "\t\t \t-- It is only available for ratios > 2.\n";}vhdl "\t\toutput_pulse : out std_logic \t-- $fout Hz output - high for single clock per cycle\n";vhdl "\t);\n";vhdl "end $entity_name;\n";vhdl "\n";vhdl "architecture $architecture_name of $entity_name is\n";vhdl "\n";# write module declarationverilog "\n";verilog "module $entity_name (async_reset, clock, clock_enable, output_50, output_pulse);\n";verilog "\tinput async_reset; \t// active high reset\n";verilog "\tinput clock; \t// $fin Hz input clock\n";verilog "\tinput clock_enable;\t// active high clock enable\n";if ($gen_50_percent_output) { verilog "\toutput output_50; \t// $fout Hz output - approx 50% duty cycle\n";}else { verilog "\toutput output_50; \t// This signal not implemented for this divider!\n"; verilog "\t \t// It is only available for ratios > 2.\n";}verilog "\toutput output_pulse;\t// $fout Hz output - high for single clock per cycle\n";verilog "\n";# write list of parametersverilog "\tparameter use_phase_accumulator = 0;\n";verilog "\t\t// TRUE uses classic NCO design.\n";verilog "\t\t// FALSE uses prescaler / controller design\n";verilog "\tparameter use_recursive_controller = 1;\n";verilog "\tparameter minimum_jitter = 0;\n";if ($low_jitter_controller) { verilog "\t\t// TRUE may use more hardware, but has lowest jitter\n"; verilog "\t\t// (only applies when use_phase_accumulator is FALSE)\n";}else { verilog "\t\t// Do not set the minimum_jitter generic to TRUE!\n"; verilog "\t\t// This file does not contain the code to support it!\n"; verilog "\t\t// (The Perl script was run with the \"-g\" option.)\n";}verilog "\tparameter improve_duty_cycle = 1;\n";verilog "\t\t// TRUE uses a falling edge ff to make the output duty cycle closer to 50%\n";verilog "\n";# write list of signals and constantscomment "\t definitions for prescaler / controller design\n";vhdl "\tconstant n : positive := $n;\t-- prescaler divides by n or n + 1\n";verilog "\tparameter n = $n;\t// prescaler divides by n or n + 1\n";vhdl "\tconstant a : positive := $a;\t-- this many counts of $n\n";verilog "\tparameter a = $a;\t// this many counts of $n\n";vhdl "\tconstant b : natural := $b;\t-- this many counts of " . ($n + 1) . "\n";verilog "\tparameter b = $b;\t// this many counts of " . ($n + 1) . "\n";vhdl "\tsignal modulus_control : std_logic;\n";verilog "\twire modulus_control;\n";vhdl "\tsignal prescaler_count : integer range 0 to n;\n";verilog "\treg [" . (log2($n) - 1) . ":0] prescaler_count;\n";vhdl "\tsignal controller_count : integer range 0 to a + b - 1;\n";verilog "\treg [" . (log2($a + $b - 1) - 1) . ":0] controller_count;\n";vhdl "\tsignal prescaler_out : std_logic;\n";verilog "\treg prescaler_out;\n" if ($n > 1);verilog "\twire prescaler_out;\n" if ($n <= 1);vhdl "\tsignal prescaler_out_50 : std_logic;\n";verilog "\treg prescaler_out_50;\n";vhdl "\tsignal duty_correction : std_logic;\n";verilog "\treg duty_correction;\n";comment "\t definitions for recursive controller design\n";for (my $s = 1; $s <= $stage + 1; $s++) { vhdl "\tconstant n$s : natural := $n_array[$s];\t-- prescaler \#$s divides by n$s or n$s + 1\n"; vhdl "\tconstant m$s : positive := $m_array[$s];\t-- determines output duty cycle for prescaler \#$s\n"; verilog "\tparameter n$s = $n_array[$s];\t// prescaler \#$s divides by n$s or n$s + 1\n"; verilog "\tparameter m$s = $m_array[$s];\t// determines output duty cycle for prescaler \#$s\n";}for (my $s = 1; $s <= $stage + 1; $s++) { vhdl "\tsignal stage$s\_count : integer range 0 to n$s;\n"; verilog "\treg [" . (log2($n_array[$s]) - 1) . ":0] stage$s\_count;\n";}for (my $s = 1; $s <= $stage + 1; $s++) { vhdl "\tsignal stage$s\_out : std_logic;\n"; verilog "\treg stage$s\_out;\n";}for (my $s = 1; $s <= $stage; $s++) { vhdl "\tsignal stage$s\_carry : std_logic;\n"; verilog "\treg stage$s\_carry;\n";}vhdl "\n";verilog "\n";comment "\t definitions for phase accumulator design\n";vhdl "\tconstant num_bits : positive := $num_bits;\t-- size of phase accumulator\n";verilog "\tparameter num_bits = $num_bits;\t// size of phase accumulator\n";if (($c >= (2 ** 31)) or $std_logic_arith or $std_logic_unsigned) { # avoid overflowing integers in VHDL vhdl "\t--constant c : unsigned(num_bits - 1 downto 0) := to_unsigned($c, num_bits);\n"; vhdl "\tconstant c : " . unsigned . "(num_bits - 1 downto 0) := \""; # This should be recoded using unpack() ??? for (my $ctemp = $c, my $bit = $num_bits - 1; $bit >= 0; $bit--) { if ($ctemp >= 2 ** $bit) { $ctemp -= 2 ** $bit; vhdl "1"; } else { vhdl "0"; } } vhdl "\";\n";}else { vhdl "\tconstant c : unsigned(num_bits - 1 downto 0) := to_unsigned($c, num_bits);\n";}verilog "\tparameter c = $num_bits\'d$c;\n";vhdl "\tsignal phase : " . unsigned . "(num_bits downto 0);\t-- MSB is carry output from adder\n";verilog "\treg [$num_bits:0] phase;\t// MSB is carry output from adder\n";vhdl "\n";verilog "\n";if ($gen_50_percent_output) { vhdl "\t-- definitions for phase accumulator design with improved duty cycle\n"; vhdl "\tsignal carry : std_logic;\n"; vhdl "\tsignal d_carry : std_logic;\n"; vhdl "\tsignal late : std_logic;\n"; vhdl "\tsignal msb : std_logic;\n"; vhdl "\tsignal d_msb_1 : std_logic;\n"; vhdl "\tsignal d_msb_2_neg : std_logic;\n"; vhdl "\tsignal phase_diff : " . unsigned . "(num_bits downto 0);\n"; vhdl "\n";}# begin architecturevhdl "begin -- $architecture_name\n";vhdl "\n";# write standard phase accumulator processcomment_line;comment " Standard Phase accumulator.\n";comment " Adds c to phase each clock.\n";comment " phase(num_bits) is actually the registered carry output.\n";comment_line;if ($gen_50_percent_output) { # this process does the normal case only. # Duty cycle improvement is done in another process vhdl "gen_phase_accumulator : if use_phase_accumulator and not improve_duty_cycle generate\n";}else { # this one process handles both cases vhdl "gen_phase_accumulator : if use_phase_accumulator generate\n";}vhdl "\tphase_accumulator : process (async_reset, clock)\n";vhdl "\tbegin\n";vhdl "\t\tif (async_reset = '1') then\n";vhdl "\t\t\tphase <= (others => '0');\n";vhdl "--" if (not $gen_50_percent_output);vhdl "\t\t\toutput_50 <= '0';\n";vhdl "\t\telsif (rising_edge(clock)) then\n";vhdl "\t\t\tif (clock_enable = '1') then\n";#vhdl "\t\t\t\t-- manage counter\n";vhdl "\t\t\t\tphase <= ('0' & phase(num_bits - 1 downto 0)) + ('0' & c);\n";#vhdl "\t\t\t\t-- decode counter\n";vhdl "--" if (not $gen_50_percent_output);vhdl "\t\t\t\toutput_50 <= phase(num_bits - 1);\n";vhdl "\t\t\tend if;\n";vhdl "\t\tend if;\n";vhdl "\tend process phase_accumulator;\n";vhdl "\n";vhdl "\toutput_pulse <= '1';\t-- special hack for this ratio\n--" if ($c > ((2 ** $num_bits) - 1));vhdl "\toutput_pulse <= phase(num_bits);\n";vhdl "\n";vhdl "end generate gen_phase_accumulator;\n";vhdl "\n";verilog "/** this section not yet implemented in the Verilog version */\n\n";if ($gen_50_percent_output) { # write improved duty cycle phase accumulator process comment_line; comment " Phase accumulator with lower jitter (on output_50) and improved duty cycle.\n"; #comment " Adds c to phase each clock.\n"; #comment " phase(num_bits) is actually the registered carry output.\n"; comment_line; vhdl "gen_other_phase_accumulator : if use_phase_accumulator and improve_duty_cycle generate\n"; vhdl "\tphase_accumulator : process (async_reset, clock)\n"; vhdl "\t\tvariable new_phase : " . unsigned . "(num_bits - 1 downto 0);\n"; vhdl "\tbegin\n"; vhdl "\t\tif (async_reset = '1') then\n"; vhdl "\t\t\tphase <= (others => '0');\n"; vhdl "\t\t\toutput_pulse <= '0';\n"; vhdl "\t\t\tcarry <= '0';\n"; vhdl "\t\t\td_carry <= '0';\n"; vhdl "\t\t\tlate <= '0';\n"; vhdl "\t\t\tmsb <= '0';\n"; vhdl "\t\t\td_msb_1 <= '0';\n"; vhdl "\t\telsif (rising_edge(clock)) then\n"; vhdl "\t\t\tif (clock_enable = '1') then\n"; #vhdl "\t\t\t\t-- manage counter\n"; vhdl "\t\t\t\tnew_phase := ('0' & phase(num_bits - 2 downto 0)) + c;\n"; vhdl "\t\t\t\tphase(num_bits - 2 downto 0) <= new_phase(num_bits - 2 downto 0);\n";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -