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

📄 argand.tcl

📁 qam的vhdl程序
💻 TCL
📖 第 1 页 / 共 2 页
字号:
# argand.tcl
#
# Argand diagram (=constellation plot) for two vectors or numbers.
# It will be linked to the wave display in ModelSim.

# created, Jonathan Bromley  24 Apr 2002
#
# revised, Jonathan Bromley  24 Jun 2002
# * improved comments for release on Doulos website
# * replaced all [string equal] tests with ![string compare]
#   so it works OK with ModelSim pre-5.6 (Tcl 8.0)
# * replaced [string is double $x] tests with [catch {incr x 0}]
#   so it works OK with ModelSim pre-5.6 (Tcl 8.0)
# * moved "No data" message to top left corner of display to
#   simplify display maintenance
# * removed some old code from experimental versions



# ############################ SYNOPSIS ###############################
#                                                                     #
# This file contains just two procs, argand and privArgand_proc.      #
# It should be used in conjunction with the file modelsim.tcl         #
# which provides the code needed to hook this functionality into      #
# ModelSim's wave window.                                             #
#                                                                     #
#                                                                     #
#                ########### argand ###########                       #
#                                                                     #
# is used to set up a new constellation-plot window.  It will         #
# typically be called from a menu item.  It creates the window,       #
# sets up all necessary data structures, and returns the newly        #
# created window's pathname.                                          #
#                                                                     #
#                                                                     #
#           ########### privArgand_proc ###########                   #
#                                                                     #
# provides one centralised entry point for all other functionality.   #
# It is typically called from event handlers, to manage dynamic       #
# updating and repainting of the plot display.                        #
#                                                                     #
# #####################################################################



# ######################################################################
#                                                                      #
#                                 argand                               #
#                                                                      #
# ######################################################################
#
# Accept any arguments.  The first (and only!) argument is expected
# to be the name of the wave window in which we are created.  If no
# argument, default to .wave
# Any arguments after the first are silently ignored.
#
proc argand {{win .wave} args} {

  # Globals in ModelSim that we need to look at:
  #
  global PathSeparator
  global vsimPriv

  # We concentrate all our private data in one global array, to
  # avoid creating lots of different variable names that might
  # clash with existing variables:
  #
  global privArgand

  # Append .tree to the window name so that we locate the signal list.
  #
  append win .tree

  # Check that the required list window really exists, fail if not.
  #
  if {![winfo exists $win]} {
    error "argand: source window $win doesn't exist"
  }
  if {[string compare WaveTree [winfo class $win]]} {
    error "argand: source window $win isn't a WaveTree"
  }

  # We hope the user has selected the two signals they want us to plot.

  # Find which signals are selected:
  #
  set selList [$win curselection]

  # check that there are exactly two:
  #
  if {[llength $selList] != 2} {
    error "argand: must select 2 signals to plot"
  }

  # Go through the (two!) signals checking they are appropriate
  # and remembering their vital statistics
  #
  foreach sig $selList {

    # check that they are both in decimal radix
    # (and thus are fairly likely to be numbers!!!)
    #
    if {[string compare [$win itemcget $sig -radix] decimal]} {
      error "argand: selected signals must have decimal radix"
    }

    # remember their full names, for display purposes later
    #
    lappend sigList [$win get4 $sig]

  }

  # Now we know the signal names, extract their tails (the
  # HDL declared name of the signal) for annotating the display
  #
  foreach sig $sigList {
    lappend tailList [lindex [split $sig $PathSeparator] end]
  }

  # Find an index number (small integer) to identify this plot
  # uniquely.  These indices simply increment as new plots are
  # created;  there is no need to recycle index numbers from
  # plots that have been destroyed.
  #
  # The next unused index number is saved in our private global
  # array as privArgand(nextIndex).  If this is the first time
  # the procedure has been run, that variable doesn't exist so
  # it needs to be created with a suitable default value.

  # Is this the first plot we have created?
  #
  if {![info exists privArgand(nextIndex)]} {
    set privArgand(nextIndex) 0
  }

  # Capture the index number we will use to identify this plot,
  # and increment nextIndex ready for the next one.
  #
  set index $privArgand(nextIndex)
  incr privArgand(nextIndex)

  # From now on, all data we create will be stored in elements
  # of the privArgand() array, with subscripts beginning with
  # the index integer followed by a comma.

  # Save away the signal names and source window.  We don't
  # need to save the name tails;  they are used only to create
  # some text on the plot canvas.
  #
  set privArgand($index,fullNames) $sigList
  set privArgand($index,tree) $win


  # Create toplevel window, remember its name
  #
  set n [toplevel .argand$index]
  set privArgand($index,toplevel) $n

  # Create names for the enclosing frame (required for correct
  # colouring of sunken relief on canvas) and the canvas itself
  set privArgand($index,hull) $n.f
  set privArgand($index,plot) $n.f.c

  # Create the frame and canvas widgets
  #
  frame $n.f -borderwidth 2 -relief sunken -background white
  canvas $n.f.c -background black -borderwidth 0 \
                -highlightthickness 0 -width 200 -height 200
  pack $n.f -padx 0 -pady 0 -ipadx 0 -ipady 0 -fill both -expand 1
  pack $n.f.c -padx 0 -pady 0 -ipadx 0 -ipady 0 -fill both -expand 1

  # Create axes with labels
  #
  $n.f.c create line 0 100 200 100 \
                     -width 2 -fill darkgray -arrow last -tags axisX
  $n.f.c create line 100 200 100 0 \
                     -width 2 -fill darkgray -arrow last -tags axisY
  $n.f.c create text 195 95 -anchor se -text [lindex $tailList 0] \
                     -tag labelX -fill white -font bold
  $n.f.c create text 105 5 -anchor nw -text [lindex $tailList 1] \
                     -tag labelY -fill white -font bold

  # Create "no data" error message
  #
  $n.f.c create text 5 2 -anchor nw -text "No data!" \
                     -tag noData -fill red -font bold

  # Create polar plot:

  # radius vector
  #
  $n.f.c create line 100 100 100 100 -width 1 -fill green -tags vector

  # white cross at the end of it
  #
  $n.f.c create line 95 100 105 100 -width 3 -fill white -tags pointH
  $n.f.c create line 100 95 100 105 -width 3 -fill white -tags pointV

  # Set up variables describing the current location of the point.
  # This information is needed when moving the point to a new position.
  # Note the "uplevel #0" command to run privArgand_proc, since it is
  # usually run as an event handler and therefore expects to run in
  # the global context.
  #
  uplevel #0 privArgand_proc getValues $index

  # Label the toplevel window
  #
  wm title $n "X=[lindex $tailList 0] Y=[lindex $tailList 1]"

  # Set up for a repaint on size change
  #
  bind $n.f.c <Configure> [list privArgand_proc repaint $index]

  # Hook it to wave window cursor changes by tracing changes
  # in ModelSim variable "vsimPriv(acttime)".  Remember details
  # of the trace handler so that it's possible to cancel it later.
  #
  set privArgand($index,trace) \
    [list privArgand_proc trace $index]
  trace variable vsimPriv(acttime) w $privArgand($index,trace)

  # Arrange cleanup on window destruction
  #
  wm protocol $n WM_DELETE_WINDOW [list privArgand_proc destroy $index]

  # Fix the display for the first time
  #
  uplevel #0 privArgand_proc repaint $index

  # Return the name of the toplevel window, in the same way that most
  # Tk widget creation commands do.
  #
  return $n
}



# ######################################################################
#                                                                      #
#                           privArgand_proc                            #
#                                                                      #
# ######################################################################
#
# All the real work is done by one or more options of procedure
# privArgand_proc.  By building just one "proc" with lots of options,
# we reduce the number of proc names that have to be added to the
# already crowded name space, and reduce the risk of clashing with
# a proc name that already exists.

# privArgand_proc has two compulsory arguments, option and index.
#
# * option:
#   a string name specifying which function we want the proc
#   to perform on this run.  Valid names are:
#   * getValues
#     updates our internal copies of the plot's x,y signals
#     at the currently selected moment of simulation time,
#     by reading values from the appropriate wave window
#   * replot
#     re-create the display to account for changed x,y values

⌨️ 快捷键说明

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