Bitstream Interpretation Library (BIL)  0.1
V5FrameAddress.cpp
Go to the documentation of this file.
1 
8 
9 using namespace bil;
10 
11 const unsigned BLOCK_BITSHIFT = 21;
12 const boost::uint32_t BLOCK_BITMASK = 0x7;
13 const unsigned LOWERHALF_BITSHIFT = 20;
14 const boost::uint32_t LOWERHALF_BITMASK = 0x1;
15 const unsigned ROW_BITSHIFT = 15;
16 const boost::uint32_t ROW_BITMASK = 0x1f;
17 const unsigned COLUMN_BITSHIFT = 7;
18 const boost::uint32_t COLUMN_BITMASK = 0xff;
19 const boost::uint32_t FRAME_BITMASK = 0x7f;
20 
21 
23  m_addressLayout(0),
24  m_block(0),
25  m_lowerHalf(false),
26  m_rowIndex(0),
27  m_columnIndex(0),
28  m_frameIndex(0)
29 {
30  // set to start address
31  first();
32 }
33 
34 
36  m_addressLayout(layout),
37  m_block(0),
38  m_lowerHalf(false),
39  m_rowIndex(0),
40  m_columnIndex(0),
41  m_frameIndex(0)
42 {
43  // set to start address
44  first();
45 }
46 
47 
49 {
50  m_addressLayout = layout;
51 }
52 
53 
55 {
56  return m_addressLayout;
57 }
58 
59 
61 {
62  if (BLOCK_MAX < block) throw Exception();
63  m_block = block;
64 }
65 
66 
68 {
69  return m_block;
70 }
71 
72 
73 void V5FrameAddress::lowerHalf(bool lower)
74 {
75  m_lowerHalf = lower;
76 }
77 
78 
80 {
81  return m_lowerHalf;
82 }
83 
84 
85 void V5FrameAddress::rowIndex(unsigned char ri)
86 {
87  if (ROWINDEX_MAX < ri) throw Exception();
88  m_rowIndex = ri;
89 }
90 
91 
92 unsigned char V5FrameAddress::rowIndex() const
93 {
94  return m_rowIndex;
95 }
96 
97 
98 void V5FrameAddress::columnIndex(unsigned char ci)
99 {
100  if (COLUMNINDEX_MAX < ci) throw Exception();
101  m_columnIndex = ci;
102 }
103 
104 
105 unsigned char V5FrameAddress::columnIndex() const
106 {
107  return m_columnIndex;
108 }
109 
110 
111 void V5FrameAddress::frameIndex(unsigned char fi)
112 {
113  if (FRAMEINDEX_MAX < fi) throw Exception();
114  m_frameIndex = fi;
115 }
116 
117 
118 unsigned char V5FrameAddress::frameIndex() const
119 {
120  return m_frameIndex;
121 }
122 
123 
125 {
127  m_lowerHalf = false;
128  m_rowIndex = 0;
129  m_columnIndex = 0;
130  m_frameIndex = 0;
131 }
132 
133 
135 {
136  // last address can only be determined if specific address layout is present
137  if (0 == m_addressLayout) throw Exception();
138 
139  // set last address
140  m_block = V5CfgBlock::BRAM_NONCFGDATA;
141  m_lowerHalf = true;
142  m_rowIndex = static_cast<unsigned char>(m_addressLayout->rowCount(false) - 1);
143  m_columnIndex = static_cast<unsigned char>(m_addressLayout->columnCount(V5CfgBlock::BRAM_NONCFGDATA) - 1);
144  V5CfgColumn::column_t ct = m_addressLayout->columnType(V5CfgBlock::BRAM_NONCFGDATA, m_columnIndex);
145  m_frameIndex = static_cast<unsigned char>(m_addressLayout->frameCount(V5CfgBlock::BRAM_NONCFGDATA, ct) - 1);
146 }
147 
148 
150 {
151  // increment only a valid address
152  if (!isValid()) throw Exception();
153 
154  // increment frame index
155  ++m_frameIndex;
156  // return if no frame index overflow occurred
157  V5CfgColumn::column_t ct = m_addressLayout->columnType(m_block, m_columnIndex);
158  if (m_addressLayout->frameCount(m_block, ct) > m_frameIndex) return true;
159 
160  // reset frame index to zero and increment column index
161  m_frameIndex = 0;
162  ++m_columnIndex;
163  // return if no column index overflow occurred
164  if (m_addressLayout->columnCount(m_block) > m_columnIndex) return true;
165 
166  // reset column index to zero and increment row index
167  m_columnIndex = 0;
168  ++m_rowIndex;
169  // return if no row index overflow occurred
170  if (m_addressLayout->rowCount(m_lowerHalf) > m_rowIndex) return true;
171 
172  // reset row index to zero and increment upper/lower flag
173  m_rowIndex = 0;
174  m_lowerHalf = !m_lowerHalf;
175  // return if no upper/lower flag overflow occurred
176  if (m_lowerHalf) return true;
177 
178  // increment block
179  ++m_block;
180  // If block has no columns, this can only happen for BRAM_CONTENT and
181  // BRAM_NONCFGDATA block on a device with no BRAMs. So increment block a
182  // second time, in order to go to the next block.
183  if (0 == m_addressLayout->columnCount(m_block)) ++m_block;
184  // return if no block overflow occurred
185  if (V5CfgBlock::BRAM_NONCFGDATA >= m_block) return true;
186 
187  // reached end of address space
188  return false;
189 }
190 
191 
193 {
194  // address can only be valid under a specific address layout
195  if (0 == m_addressLayout) return false;
196 
197  // test if rowIndex count is valid
198  if (m_addressLayout->rowCount(m_lowerHalf) <= m_rowIndex) return false;
199  // test if columnIndex count and block type is valid
200  if (m_addressLayout->columnCount(m_block) <= m_columnIndex) return false;
201  // test if frameIndex count is valid
202  V5CfgColumn::column_t ct = m_addressLayout->columnType(m_block, m_columnIndex);
203  if (m_addressLayout->frameCount(m_block, ct) <= m_frameIndex) return false;
204 
205  // valid!
206  return true;
207 }
208 
209 
211 {
212  // type can only be determined if specific address layout is present
213  if (0 == m_addressLayout) throw Exception();
214 
215  // test if rowIndex count is valid
216  if (m_addressLayout->rowCount(m_lowerHalf) <= m_rowIndex) throw Exception();
217  // test if columnIndex count and block type is valid
218  if (m_addressLayout->columnCount(m_block) <= m_columnIndex) throw Exception();
219  // test if frameIndex count is valid
220  V5CfgColumn::column_t ct = m_addressLayout->columnType(m_block, m_columnIndex);
221  if (m_addressLayout->frameCount(m_block, ct) <= m_frameIndex) throw Exception();
222 
223  // return resource type
224  return ct;
225 }
226 
227 
228 void V5FrameAddress::rawAddress(boost::uint32_t ra)
229 {
230  // decode raw address
231  m_block = (ra >> BLOCK_BITSHIFT) & BLOCK_BITMASK;
232  m_lowerHalf = ((ra >> LOWERHALF_BITSHIFT) & LOWERHALF_BITMASK) == 1;
233  m_rowIndex = (ra >> ROW_BITSHIFT) & ROW_BITMASK;
234  m_columnIndex = (ra >> COLUMN_BITSHIFT) & COLUMN_BITMASK;
235  m_frameIndex = ra & FRAME_BITMASK;
236 }
237 
238 
239 boost::uint32_t V5FrameAddress::rawAddress() const
240 {
241  // encode raw address from address parts
242  return (m_block << BLOCK_BITSHIFT) |
243  ((m_lowerHalf ? 1 : 0) << LOWERHALF_BITSHIFT) |
244  (m_rowIndex << ROW_BITSHIFT) |
245  (m_columnIndex << COLUMN_BITSHIFT) |
246  m_frameIndex;
247 }