⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fracn09.pl

📁 Clock generation perl to vhdl oijoij
💻 PL
📖 第 1 页 / 共 5 页
字号:
$i_array[$stage + 1] = 0;# work out how many ff are used.$ff_count_recursive_controller = 0;for (my $s = 1; $s <= $stage + 1; $s++) {    $ff_count_recursive_controller++;   # for stageN_output retime    $ff_count_recursive_controller++;   # for stageN_carry retime    $ff_count_recursive_controller += (ceil(log($n_array[$s] + 1) / log(2))); # counter}$ff_count_recursive_controller--;   # no carry from last stage!############### Design the phase accumulator ###################################print "designing phase accumulator\n" if ($verbose);use vars qw($num_bits $c $ratio_pa $fout_achieved_pa $error_achieved_pa); # more global variables$num_bits = 0;while (1){    $num_bits++;    $c =   floor(0.5 + ((2 ** $num_bits) / $desired_ratio));    next if ($c == 0);    $ratio_pa = (2 ** $num_bits) / $c;    last if (($ratio_pa <= $max_ratio) and ($ratio_pa >= $min_ratio));  # ok    #last if ($c > (2 ** 30));   # avoid overflowing integers in VHDL    last if (($num_bits > 56) and $convergence_check);   # exceeding Perl floating point accuracy!}$fout_achieved_pa = $fin / $ratio_pa;           # Hz$error_achieved_pa = $fout_achieved_pa - $fout; # Hzif (abs($error_achieved_pa / $fout) > $tolerance) {    warning("Warning: Phase accumulator design did not meet frequency tolerance target.");}############### Check for Fout > 1/2 Fin ######################################## If the output frequency is > 1/2 the input frequency, the 50% duty# cycle output doesn't make sense, so we need to detect this special case.# We also disable for >= 1/2, to get around code generation problem in# phase accumulator jitter improver.use vars qw($gen_50_percent_output); # more global variables#$gen_50_percent_output = ($fin/$fout >= 2);#$gen_50_percent_output = (($c <= (2 ** ($num_bits - 1))) and ($n > 1));$gen_50_percent_output = (($c < (2 ** ($num_bits - 1))) and ($n > 1));  # ver 07if (not $gen_50_percent_output) {    warning("Warning: Fin/Fout ratio < 2.",            "  The 50% duty cycle output \"output_50\" has not been implemented.");}#$gen_50_percent_output = 1;    # use this to test test bench.############### generate some VHDL and Verilog ################################## open vhdl fileprint "opening $vhdl_name\n" if ($verbose);rename $vhdl_name, "$vhdl_name.bak";open (VHDL, ">$vhdl_name") or die "Can't open VHDL file $vhdl_name: $!";# open verilog fileprint "opening $verilog_name\n" if ($verbose);rename $verilog_name, "$verilog_name.bak";open (VERILOG, ">$verilog_name") or die "Can't open Verilog file $verilog_name: $!";# subs for optionally expanding tabs to spaces before writing to files# (the "expand" sub uses the value of the global variable "tabstop")sub vhdl {    foreach my $line (@_) {        print VHDL ($tabstop > 0) ? expand($line) : $line;    }}sub verilog {    foreach my $line (@_) {        print VERILOG ($tabstop > 0) ? expand($line) : $line;    }}# write a comment to both filessub comment{    foreach my $line (@_) {        if ( $line =~ m/^(\t+)(.*)$/s ) {            # indented comment, maintain leading tabs            vhdl    $1 . "--" . $2;            verilog $1 . "//" . $2;        }        else {            # comment at left margin            vhdl    "--" . $line;            verilog "//" . $line;        }    }}# write a solid "separator" line to both filessub comment_line{    vhdl    "-" x 80 . "\n";    verilog "/" x 80 . "\n";}# returns "unsigned" or "std_logic_vector" depending on whether we# are using IEEE.numeric_std or Synopsys std_logic_unsigned library.sub unsigned {    return ($std_logic_unsigned ? "std_logic_vector" : "unsigned");}# Work out whether a word is plural (returns "" or "s", depending on whether# the numeric argument is equal to 1)sub plural {    return ($_[0] == 1 ? "" : "s");}# function that returns the number of bits needed to hold integer range 0 to argsub log2{    use integer;    my $result = 0;    my $count = $_[0];    while ($count > 0) {        $result = $result + 1;        $count = $count / 2;    }    no integer;    return $result;}print "writing to $vhdl_name and $verilog_name\n" if ($verbose);# write file headercomment_line;vhdl    "-- File         : $vhdl_name (machine generated)\n";vhdl    "-- Contains     : entity $entity_name (architecture $architecture_name)\n";verilog "// File         : $verilog_name (machine generated)\n";verilog "// Contains     : module $entity_name\n";comment " Author       : $0  (version $version)\n";comment " Command Line : $0 @argv_orginal\n";comment " Date         : " . (scalar localtime) . "\n";comment " Complain to  : fractional_divider\@hotmail.com\n";comment "\n";vhdl    "-- This machine generated VHDL file contains a fixed ratio frequency divider.\n";verilog "// This machine generated Verilog file contains a fixed ratio frequency divider.\n";comment " Different styles of dividers can be selected by generics or parameters.\n";comment "\n";comment "  use_phase_accumulator = TRUE   selects a \"classic\" phase accumulator\n";comment "                                 frequency divider\n";comment "\n";comment "  use_phase_accumulator = FALSE  selects a frequency divider made up of\n";comment "                                 a dual modulus prescaler and a controller\n";comment "                                 In this case, the generics \"minimum_jitter\"\n";comment "                                 and \"use_recursive_controller\"\n";comment "                                 control size / jitter tradeoffs in\n";comment "                                 the controller.\n";comment "\n";comment " The phase accumulator style divider has a regular structure (in the sense\n";comment " that it doesn't change much if the ratio is changed - which is good for\n";comment " floorplanning) and it is quite easy to understand.\n";comment " The output frequency is a rational multiple of the input frequency in\n";comment " the form:\n";comment "\n";comment "       c\n";comment " --------------- * Fin\n";comment " (2 ** num_bits)\n";comment "\n";comment " where c and num_bits are integers.\n";comment " The hardware consists of a constant adder, so it will be simple to\n";comment " make it work at high speed.\n";comment " The output jitter will generally be equal to or just less than one\n";comment " cycle of the input clock.\n";comment " Here is a block diagram:\n";comment " \n";comment " 'clock'-----------------------+\n";comment "                               |\n";comment "             +-------+    +----------+\n";comment " Constant--->|       |    |          |\n";comment " 'c'         | Adder |--->| Register |-+-->'phase'\n";comment "          +->|       |    |          | |\n";comment "          |  +-------+    +----------+ |\n";comment "          |                            |\n";comment "          +----------------------------+\n";comment "\n";comment " The MSB of the 'phase' signal has approximately a 50% duty cycle, and\n";comment " is retimed (in another ff not shown) and used as the 'output_50' output.\n";comment " The carry output of the adder will be high once every output cycle,\n";comment " and is registered (in another ff not shown) and used as the\n";comment " 'output_pulse' output.\n";comment "\n";comment "\n";comment " The dual modulus prescaler divider is somewhat harder to understand, but\n";comment " it may result in less hardware, and it may enable the exact ratio to\n";comment " be produced.\n";comment " In this case, the output frequency is a rational multiple of the input\n";comment " frequency in the form:\n";comment "\n";comment "       (a + b)\n";comment " ----------------------- * Fin\n";comment " (a * n) + (b * (n + 1))\n";comment "\n";comment " where a, b, and n are integers.\n";comment " The dual modulus prescaler divides the input clock by n or (n+1).\n";comment " The controller causes the prescaler to divide by n for a cycles of the\n";comment " output, and divide by (n+1) for b cycles of the output.\n";comment " Depending on how these a and b cycles are mixed up, the output\n";comment " jitter will vary.\n";comment " There are a number of ways to make the controller.\n";comment " If the generic use_recursive_controller is TRUE, the controller consists\n";comment " of a state machine that produces the best interleaving of the a and b cycles,\n";comment " which gives about the same jitter as the phase accumulator.\n";comment " If use_recursive_controller is FALSE, the controller consists of a counter\n";comment " and a lookup table to interleave the a and b cycles.\n";comment " There are more tradeoffs: if the generic minimum_jitter is FALSE, the lookup\n";comment " table bunches all the a cycles together, and all the b cycles together.\n";comment " This results in simple hardware, but may produce lots of jitter.\n";comment " If the generic minimum_jitter is TRUE, the lookup table produces the best\n";comment " interleaving of the a and b cycles, but it may result in an excessively\n";comment " large case statement.\n";comment " (It will usually be possible to come up with a much better\n";comment " controller design by hand, but the details vary so much with\n";comment " the choice of frequencies that it is hard to generalise this\n";comment " into a simple script.)\n";if (not $low_jitter_controller) {    comment " Note: the minimum_jitter controller has not been implemented in this file,\n";    comment " so don't set the generic minimum_jitter to TRUE.\n";}comment " Here is a block diagram:\n";comment "\n";comment "             +--------------+\n";comment "             | Dual modulus | 'prescaler_out'\n";comment " 'clock'---->|  Prescaler   |------+--------->\n";comment "             | /n or /(n+1) |      |\n";comment "             +--------------+      |\n";comment "                    ^              |\n";comment "                    |       +------------+\n";comment "                    |       |            |\n";comment "                    +-------| Controller |\n";comment "          'modulus_control' |            |\n";comment "                            +------------+\n";comment "\n";comment "\n";comment " For a given set of input to output frequency ratio and tolerance,\n";comment " the only way to work out which type of divider is better is\n";comment " to try them!  Generally, the phase accumulator is better for\n";comment " loose tolerances (> 10ppm), and the dual modulus prescaler is\n";comment " better if the ratio must be exact, but this depends on the ratio.\n";comment "\n";comment " Frequency Parameters:\n";comment " Input Frequency: $fin Hz.\n";comment " Desired Output Frequency: $fout Hz.\n";comment " Requested Relative Frequency Error Bounds (+/-) : $tolerance (" . ($tolerance * 1e6) . " ppm)\n";comment "\n";comment " Frequency Results (use_phase_accumulator = FALSE) :\n";comment "  Achieved Output Frequency: $fout_achieved Hz.\n";comment "  Achieved Relative Frequency Error: " . ($error_achieved / $fout) . " (" . (($error_achieved / $fout) * 1e6) . " ppm)\n";comment "  Achieved Frequency Error: $error_achieved Hz.\n";comment "\n";comment " Frequency Results (use_phase_accumulator = TRUE) :\n";comment "  Achieved Output Frequency: $fout_achieved_pa Hz.\n";comment "  Achieved Relative Frequency Error: " . ($error_achieved_pa / $fout) . " (" . (($error_achieved_pa / $fout) * 1e6) . " ppm)\n";comment "  Achieved Frequency Error: $error_achieved_pa Hz.\n";comment "\n";comment " Output Jitter Parameters (use_phase_accumulator = FALSE) :\n";comment "  The fundamental frequency is " . ($fin / ($a * $n + $b * ($n + 1))) . " Hz.\n";comment "  The amplitude is $bad_jitter seconds p-p (minimum_jitter = FALSE).\n";comment "  The amplitude is $good_jitter seconds p-p (minimum_jitter = TRUE).\n";comment "\n";comment " Output Jitter Parameters (use_phase_accumulator = TRUE) :\n";comment "  The fundamental frequency is " . ($fin / (2 ** $num_bits)) . " Hz.\n";comment "  The amplitude is " . (1 / $fin) . " seconds p-p (approx).\n";comment "\n";comment " Design Parameters (use_phase_accumulator = FALSE) :\n";comment "  Approx " .           ((ceil(log($n + 1) / log(2)) + 2) + (ceil(log($a + $b) / log(2)) + 1)) .           " flip flops (" .           (ceil(log($n + 1) / log(2))) . " in prescaler, " .           (ceil(log($a + $b) / log(2)) + 1) . " in controller and 2 retimes).\n";comment "  The recursive controller uses approx $ff_count_recursive_controller flip flop" . (plural $ff_count_recursive_controller) . ".\n";comment "  The Dual-Modulus Prescaler uses ratios /$n,/" . ($n + 1) . "\n";comment "  The Output consists of $a cycle" . (plural $a) . " of $n input clock" . (plural $n) . ",\n";comment "  and $b cycle" . (plural $b) . " of " . ($n + 1) . " input clocks.\n";comment "  There " . (($a + $b) == 1 ? "is" : "are") . " " . ($a + $b) . " output clock" . (plural ($a + $b)) . " for every " . ($a * $n + $b * ($n + 1)) . " input clock" . (plural ($a * $n + $b * ($n + 1))) . ".\n";comment "\n";comment " Design Parameters (use_phase_accumulator = TRUE) :\n";comment "  Approx " . ($num_bits + 2) . " flip flops ($num_bits in accumulator and 2 retimes)\n";comment "  There " . ($c == 1 ? "is" : "are") . " " . ($c) . " output clock" . (plural $c) . " for every " . (2**$num_bits) . " input clocks.\n";comment "\n";# write summary of all dividers generated

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -