DASM
DExecHW/SimpleTimer.pm
Go to the documentation of this file.
00001 #!/usr/bin/perl -w
00002 ##
00003 # HW implementation for 'SimpleTimer'.
00004 #
00005 # A very simple timer measuring microseconds since the hardware was
00006 # initialised. FIXME Allow this to be CPU start?
00007 #
00008 # 3 words are provided (little endian):
00009 #
00010 # | Offset | Name   | Meaning |
00011 # |--------|--------|---------|
00012 # | +0     | Low    | low word (bits 0-15) |
00013 # | +1     | Middle | middle word (bits 16-31) |
00014 # | +2     | High   | high word (bits 32-47) |
00015 #
00016 # The middle and high words are latched by reading the low word.
00017 #
00018 # Writing to any register has the effect of resetting the clock to
00019 # 0.
00020 #
00021 # @file
00022 # @author Justin Fletcher
00023 #
00024 
00025 package DExecHW::SimpleTimer;
00026 
00027 use Time::HiRes qw(gettimeofday tv_interval);
00028 
00029 
00030 ##
00031 # Construct a new hardware device object.
00032 #
00033 # @param[in]  $proto   This class object, or prototype to add to
00034 # @param[in]  $object  The object to proxy for
00035 # @param[in]  $offset  The offset this object is created for
00036 #
00037 # @return Assembler object
00038 sub new
00039 {
00040     my $proto = shift;
00041     my $object = shift;
00042     my $offset = shift || 0;
00043     my $class = ref($proto) || $proto;
00044     my $self = {
00045             'initial' => [gettimeofday],
00046             0         => 0,
00047             1         => 0,
00048             2         => 0,
00049         };
00050 
00051     bless $self, $class;
00052     
00053     return $self;
00054 }
00055 
00056 
00057 ##
00058 # Return the size of of the implementation.
00059 #
00060 # @param[in] $self   Object
00061 #
00062 # @return Size of the hardware implementation in words
00063 sub window
00064 {
00065     # 3 words is 2^48 microseconds, which is 3257 days.
00066     return 3;
00067 }
00068 
00069 
00070 ##
00071 # Read value
00072 #
00073 # @param[in] $self   Object
00074 # @param[in] $offset Offset of register within window
00075 # @param[in] $exec   DExec object opon which this object is operating
00076 #
00077 # @return value of this register
00078 sub read
00079 {
00080     my ($self, $offset, $exec) = @_;
00081     
00082     if ($offset == 0)
00083     {
00084         # Latch value into registers
00085         my $diff = tv_interval($self->{'initial'});
00086         
00087         # Measure in milliseconds.
00088         $diff = $diff * 1E6;
00089         
00090         $self->{0} = $diff & 0xFFFF;
00091         $self->{1} = ($diff>>16) & 0xFFFF;
00092         $self->{2} = ($diff>>32) & 0xFFFF;
00093     }
00094     
00095     return $self->{$offset};
00096 }
00097 
00098 
00099 ##
00100 # Write value
00101 #
00102 # @param[in] $self   Object
00103 # @param[in] $offset Offset of register within window
00104 # @param[in] $exec   DExec object upon which this object is operating
00105 # @param[in] $value  Value to write
00106 #
00107 # @return ignored
00108 sub write
00109 {
00110     my ($self, $offset, $exec, $value) = @_;
00111     
00112     $self->{'initial'} = [gettimeofday];
00113 }
00114 
00115 
00116 ##
00117 # Get the symbol name for an offset
00118 #
00119 # @param[in] $self   Object
00120 # @param[in] $offset Offset of register within window
00121 #
00122 # @return symbol name to use
00123 # @retval undef for a default symbol
00124 # @retval "" for no symbol
00125 sub symbol
00126 {
00127     my ($self, $offset) = @_;
00128     
00129     return ("Low", "Middle", "High")[$offset];
00130 }
00131 
00132 
00133 # Must return 1
00134 1;