MFMv2.0.10
Movable Feast Machine Simulator 2.0.10
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
P0Atom.h
Go to the documentation of this file.
1 /* -*- mode:C++ -*-
2  P0Atom.h Simplest of the MFM Atoms
3  Copyright (C) 2014 The Regents of the University of New Mexico. All rights reserved.
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this library; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
18  USA
19 */
20 
27 #ifndef P0ATOM_H
28 #define P0ATOM_H
29 
30 #include <stdio.h>
31 #include "itype.h"
32 #include "Point.h"
33 #include "BitField.h"
34 #include "Atom.h"
35 #include "Element.h"
36 #include "CoreConfig.h"
37 #include "ParamConfig.h"
38 
39 #define P0ATOM_HEADER_LENGTH_SIZE 2
40 #define P0ATOM_TYPE_WIDTH_INCREMENT 12
41 #define P0ATOM_STATE_SIZE 48
42 
43 namespace MFM
44 {
45 
46  template <class PC>
47  class P0Atom : public Atom< CoreConfig< P0Atom<PC>, PC> >
48  {
49  public:
50  enum
51  {
52  ATOM_CATEGORY = 0,
53  ATOM_FIRST_STATE_BIT = 0
54  };
55  private:
56 
57  typedef CoreConfig< P0Atom<PC>, PC> CC;
58  typedef typename CC::PARAM_CONFIG P;
59  enum { BPA = P::BITS_PER_ATOM };
60 
61  enum
62  {
63  BITS = 64,
64  // For now we insist on exact match. Possibly longer could be
65  // supported relatively easily.
66  CONFIGURED_BITS_PER_ATOM_IS_INCOMPATIBLE_WITH_P0ATOM = 1/((PC::BITS_PER_ATOM==BITS)?1:0)
67  };
68 
69  enum
70  {
71  TYPE0_LENGTH = 0*P0ATOM_TYPE_WIDTH_INCREMENT,
72  TYPE1_LENGTH = 1*P0ATOM_TYPE_WIDTH_INCREMENT,
73  TYPE2_LENGTH = 2*P0ATOM_TYPE_WIDTH_INCREMENT,
74  TYPE3_LENGTH = 28
75  };
76  // Type info at end of atom so state bits start at a compile-time known bit position (0)
77  typedef BitField<BitVector<BITS>,VD::U32,P0ATOM_HEADER_LENGTH_SIZE,BITS - P0ATOM_HEADER_LENGTH_SIZE> AFTypeLengthCode;
78 
79  // These BitFields represent just the extended type information, exclusive of the length code
80  typedef BitField<BitVector<BITS>,VD::U32,TYPE0_LENGTH, AFTypeLengthCode::START - TYPE0_LENGTH> AFTypeLength0;
81  typedef BitField<BitVector<BITS>,VD::U32,TYPE1_LENGTH, AFTypeLengthCode::START - TYPE1_LENGTH> AFTypeLength1;
82  typedef BitField<BitVector<BITS>,VD::U32,TYPE2_LENGTH, AFTypeLengthCode::START - TYPE2_LENGTH> AFTypeLength2;
83  typedef BitField<BitVector<BITS>,VD::U32,TYPE3_LENGTH, AFTypeLengthCode::START - TYPE3_LENGTH> AFTypeLength3;
84 
85  // These BitFields represent the entire type information, including the length code
86  typedef BitField<BitVector<BITS>,VD::U32,TYPE0_LENGTH + P0ATOM_HEADER_LENGTH_SIZE, AFTypeLength0::START> AFType0;
87  typedef BitField<BitVector<BITS>,VD::U32,TYPE1_LENGTH + P0ATOM_HEADER_LENGTH_SIZE, AFTypeLength1::START> AFType1;
88  typedef BitField<BitVector<BITS>,VD::U32,TYPE2_LENGTH + P0ATOM_HEADER_LENGTH_SIZE, AFTypeLength2::START> AFType2;
89  typedef BitField<BitVector<BITS>,VD::U32,TYPE3_LENGTH + P0ATOM_HEADER_LENGTH_SIZE, AFTypeLength3::START> AFType3;
90 
91  protected:
92 
93  /* We really don't want to allow the public to change the type of a
94  P0Atom, since the type doesn't mean much without the atomic
95  header as well */
96 
97  void SetType(u32 lengthCode, u32 type)
98  {
99  AFTypeLengthCode::Write(this->m_bits,lengthCode);
100  switch (lengthCode)
101  {
102  case 0: AFTypeLength0::Write(this->m_bits,type); break;
103  case 1: AFTypeLength1::Write(this->m_bits,type); break;
104  case 2: AFTypeLength2::Write(this->m_bits,type); break;
105  case 3: AFTypeLength3::Write(this->m_bits,type); break;
106  default:
107  FAIL(ILLEGAL_ARGUMENT);
108  }
109  }
110 
111  u32 GetLengthCodeForType(u32 type)
112  {
113  if ((1 << TYPE0_LENGTH) > type) return 0;
114  if ((1 << TYPE1_LENGTH) > type) return 1;
115  if ((1 << TYPE2_LENGTH) > type) return 2;
116  if ((1 << TYPE3_LENGTH) > type) return 3;
117  FAIL(ILLEGAL_ARGUMENT);
118  }
119 
123  u32 EndStateBit() const
124  {
126  }
127 
128  static u32 EndStateBit(u32 lengthCode)
129  {
130  switch(lengthCode)
131  {
132  case 0:
133  return AFTypeLength0::START;
134  case 1:
135  return AFTypeLength1::START;
136  case 2:
137  return AFTypeLength2::START;
138  case 3:
139  return AFTypeLength3::START;
140  default:
141  FAIL(ILLEGAL_ARGUMENT);
142  }
143  }
144 
145  public:
146 
147  bool IsSaneImpl() const
148  {
149  // P0Atom has no error detection abilities
150  return true;
151  }
152 
153  bool HasBeenRepairedImpl()
154  {
155  // If somebody thinks it's bad, we can't fix it.
156  return false;
157  }
158 
159  u32 GetTypeImpl() const
160  {
161  u32 lengthCode = AFTypeLengthCode::Read(this->m_bits);
162  switch (lengthCode) {
163  case 0: return AFTypeLength0::Read(this->m_bits);
164  case 1: return AFTypeLength1::Read(this->m_bits);
165  case 2: return AFTypeLength2::Read(this->m_bits);
166  case 3: return AFTypeLength3::Read(this->m_bits);
167  default:
168  FAIL(UNREACHABLE_CODE);
169  }
170  }
171 
176  u32 GetStateField(u32 stateIndex, u32 stateWidth) const
177  {
178  const u32 lastState = EndStateBit();
179  const u32 firstState = ATOM_FIRST_STATE_BIT + stateIndex;
180 
181  if (firstState + stateWidth >= lastState)
182  FAIL(ILLEGAL_ARGUMENT);
183 
184  return this->m_bits.Read(firstState, stateWidth);
185  }
186 
192  void SetStateField(u32 stateIndex, u32 stateWidth, u32 value)
193  {
194  const u32 lastState = EndStateBit();
195  const u32 firstState = ATOM_FIRST_STATE_BIT + stateIndex;
196 
197  if (firstState + stateWidth >= lastState)
198  FAIL(ILLEGAL_ARGUMENT);
199 
200  return this->m_bits.Write(firstState, stateWidth, value);
201  }
202 
203  void WriteStateBitsImpl(ByteSink& ostream) const
204  {
205  u32 endStateBit = EndStateBit();
206 
207  for(u32 i = ATOM_FIRST_STATE_BIT; i < endStateBit; i++)
208  {
209  ostream.Printf("%d", this->m_bits.ReadBit(i) ? 1 : 0);
210  }
211  }
212 
213  void ReadStateBitsImpl(const char* stateStr)
214  {
215  u32 endStateBit = EndStateBit();
216 
217  for(u32 i = ATOM_FIRST_STATE_BIT; i < endStateBit; i++)
218  {
219  this->m_bits.WriteBit(i, stateStr[i] == '0' ? 0 : 1);
220  }
221  }
222 
223  void ReadStateBitsImpl(const BitVector<BITS> & bv)
224  {
225  u32 endStateBit = EndStateBit();
226 
227  for(u32 i = ATOM_FIRST_STATE_BIT; i < endStateBit; i++)
228  {
229  this->m_bits.WriteBit(i, bv.ReadBit(i));
230  }
231  }
232 
233  static u32 GetMaxStateSize(u32 lengthCode) {
234  return EndStateBit(lengthCode);
235  }
236 
237  P0Atom(u32 type = 0, u32 longc = 0, u32 shortc = 0, u32 statec = 0)
238  {
239  InitAtom(type,longc,shortc,statec);
240  }
241 
242  void InitAtom(u32 type, u32 longc, u32 shortc, u32 statec)
243  {
244  if (longc != 0)
245  FAIL(ILLEGAL_ARGUMENT);
246  if (shortc != 0)
247  FAIL(ILLEGAL_ARGUMENT);
248 
249  u32 lengthCode =
250  GetLengthCodeForType(type);
251  u32 maxState =
252  GetMaxStateSize(lengthCode);
253 
254  if (statec > maxState)
255  FAIL(ILLEGAL_ARGUMENT);
256 
257  SetType(lengthCode, type);
258 
259  }
260 
261  void PrintBits(ByteSink & ostream) const
262  { this->m_bits.Print(ostream); }
263 
264  void PrintImpl(ByteSink & ostream) const
265  {
266  u32 lengthCode = AFTypeLengthCode::Read();
267  u32 type = this->GetType();
268  ostream.Printf("P0[%x/",type);
269  u32 length = GetMaxStateSize(lengthCode);
270  for (int i = 0; i < length; i += 4) {
271  u32 nyb = this->m_bits.Read(ATOM_FIRST_STATE_BIT+i,4);
272  ostream.Printf("%x",nyb);
273  }
274  ostream.Printf("]");
275  }
276 
277  P0Atom& operator=(const P0Atom & rhs);
278  };
279 } /* namespace MFM */
280 
281 #include "P0Atom.tcc"
282 
283 #endif /*P0ATOM_H*/
static void Write(BV &bv, u32 val)
Definition: BitField.h:84
u32 EndStateBit() const
Definition: P0Atom.h:123
P PARAM_CONFIG
Definition: CoreConfig.h:51
void Write(const u32 startIdx, const u32 length, const u32 value)
Definition: BitVector.tcc:99
u32 GetType() const
Definition: Atom.h:178
static u32 Read(const BV &bv)
Definition: BitField.h:73
u32 Read(const u32 startIdx, const u32 length) const
Definition: BitVector.tcc:129
Definition: Atom.h:71
void WriteBit(u32 idx, bool bit)
Definition: BitVector.tcc:41
Definition: P0Atom.h:47
Definition: CoreConfig.h:40
void Print(ByteSink &ostream) const
Definition: BitVector.tcc:202
Definition: Atom.h:45
Definition: ByteSink.h:47
bool ReadBit(u32 idx)
Definition: BitVector.tcc:65
void SetStateField(u32 stateIndex, u32 stateWidth, u32 value)
Definition: P0Atom.h:192
BitVector< BPA > m_bits
Definition: Atom.h:99
u32 GetStateField(u32 stateIndex, u32 stateWidth) const
Definition: P0Atom.h:176