Altera Home Page
文档资料 许可
在线购买 下载

  主页   |   产品   |   支持   |   最终市场   |   技术中心   |   教育与活动   |   公司介绍   |   在线购买  
  mySupport   |   器件   |   软件   |   IP   |   设计范例   |   参考设计  

 产品
      MAX/MAX II
      Stratix/Stratix GX
      Nios II
  
 功能
      算法
      存储器
      总线及I/O
      逻辑
      接口与外设
      DSP
      通信
      PLL & Clocking
  
 设计输入方法
      Quartus II软件工程
      Tcl
      VHDL
      Verilog HDL
      C Code 范例
      DSP Builder
      TimeQuest
   片内调试
  
 仿真工具
      Mentor Graphics ModelSim
      Cadence NCsim
      Synopsys VCS
  
 旧范例
      图形编辑器
      AHDL
  

Quartus II Tcl Example: Automatic Version Number

It is useful to have a version number or time stamp embedded in your FPGA design. A version number or time stamp eliminates any confusion about which version of your design is currently programmed in the FPGA. For such a number to be useful, it must be updated automatically in the design compilation flow. Also, the number must be stored in the design hardware, such as in memory or a bank of registers.

This Tcl example describes different ways to generate a version number or time stamp, as well as different ways to store it in a design. Then, it shows a script framework you can use to create a Tcl script that generates and stores the version number automatically, every time you compile a design. Finally, it shows an example of a complete script.

Get a Number

The following list shows how you can generate a version number:

Store the Number

In addition to getting the number, you must write it in a design file. The following are examples of how to store the number:

Script Framework

You can combine methods for getting and saving a number to suit your design flow. From the examples above, choose a method to get a number and a method to store the number. Copy the appropriate procedures to a Tcl file and add commands to call the procedures. The following script framework shows how your script should be written. Finally, add an assignment (described below) to your Quartus® II Settings File (.qsf ) to allow the script to run automatically.

# Insert procedure to get a number here

# Insert procedure to store the number here

# This line accommodates script automation, described later
foreach { flow project revision } $quartus(args) { break }

# Call procedure to get a number here
# Do any number format conversion necessary
# Call procedure to store the number here

Script Automation

Add the following line to your project's QSF to allow the script to run automatically before every compilation. Replace <script name > with the name of your Tcl file.

set_global_assignment -name PRE_FLOW_SCRIPT_FILE quartus_sh:<script name>

Refer to Automatic Script Execution for more information about the assignment and other ways to automatically run scripts.

Example

The following script example uses procedures from the following two examples:

# Gets SVN revision number for the specified file
proc get_subversion_revision { file_name } {

    global done

    # The maximum number of seconds to wait for the svn info
    # command to complete
    set timeout_seconds 30

    # The svn info command with filename that is run
    set cmd "svn info ${file_name}"

    # Attempt to get the version information.
    # If the command can't be run, return an error.
    # Otherwise set up a file event to process the command output.
    if { [catch {open "|$cmd"} input] } {
        return -code error $input
    } else {

        fileevent $input readable [list get_revision_info $input ]

        # Set up a timeout so that the process can't hang if the
        # repository is down.
        set timeout [after [ expr { $timeout_seconds * 1000 } ] \
            [list set done -1] ]

        # Don't continue until the revision number is found,
        # or the operation times out. Cancel the timeout anyway.
        vwait done
        after cancel $timeout
    }
}

# Helper procedure for the above procedure
proc get_revision_info { inp  } {

    global done revision_number

    if { [eof $inp] } {
        catch {close $inp}
        set done 1
    } elseif { $done } {
        gets $inp line
    } else {
        gets $inp line
        # Use a regular expression to match the line with the
        # revision number.
        if { [regexp {^Revision:\s+(\d+)\s*$} $line match revision_number] } {
            set done 1
        }
    }
}

# Creates a register bank in a verilog file with the specified hex value
proc generate_verilog { hex_value } {

    set num_digits [string length $hex_value]
    set bit_width [expr { 4 * $num_digits } ]
    set high_index [expr { $bit_width - 1 } ]
    set reset_value [string repeat "0" $num_digits]

    if { [catch {
        set fh [open "version_reg.v" w ]
        puts $fh "module version_reg (clock, reset, data_out);"
        puts $fh "    input clock;"
        puts $fh "    input reset;"
        puts $fh "    output \[$high_index:0\] data_out;"
        puts $fh "    reg \[$high_index:0\] data_out;"
        puts $fh "    always @ (posedge clock or negedge reset) begin"
        puts $fh "        if (!reset)"
        puts $fh "            data_out <= ${bit_width}'h${reset_value};"
        puts $fh "        else"
        puts $fh "            data_out <= ${bit_width}'h${hex_value};"
        puts $fh "    end"
        puts $fh "endmodule"
        close $fh
    } res ] } {
        return -code error $res
    } else {
        return 1
    }
}

# This line accommodates script automation
foreach { flow project revision } $quartus(args) { break }

set file_name ${project}.qpf
set done 0
set revision_number ""

# Call procedure to get file revision number and handle any errors
if { [catch { get_subversion_revision $file_name } msg] } {
    post_message -type critical_warning "Couldn't run command to get\
        revision number. $msg"
} else {

    if { -1 == $done } {
        post_message -type critical_warning "Timeout getting revision number."
    } elseif { [string equal "" $revision_number] } {
        post_message -type critical_warning \
            "Couldn't find revision number in output of svn info $file_name."
    } else {

        # Call procedure to store the number
        if { [catch { generate_verilog $revision_number } res] } {
            post_message -type critical_warning \
               "Couldn't generate Verilog file. $res"
        } else {
            post_message "Successfully updated version number to\
                version 0x${revision_number}"
        }
    }
}

If you name the script update_version.tcl, you must add the following line to your QSF:

set_global_assignment -name PRE_FLOW_SCRIPT_FILE quartus_sh:update_version.tcl

Design Examples Disclaimer

These design examples may only be used within Altera Corporation devices and remain the property of Altera. They are being provided on an “as-is” basis and as an accommodation; therefore, all warranties, representations, or guarantees of any kind (whether express, implied, or statutory) including, without limitation, warranties of merchantability, non-infringement, or fitness for a particular purpose, are specifically disclaimed. Altera expressly does not recommend, suggest, or require that these examples be used in combination with any other product not provided by Altera.

  请填写反馈意见