DASM
|
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;