byteman  1.3 (Build #225)
Bitstream relocation and manipulation tool
inlineMerge.h
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright 2022 Kristiyan Manev (University of Manchester)
3  *
4  * Licensed under the Apache License, Version 2.0(the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *****************************************************************************/
16 
17 inline void ensureRowCompatibility(Coord2D src, int offsetRow, int sizeCol, Coord2D dst){
18  int srcRA = (src.row + offsetRow) / CLB_PER_CLOCK_REGION;
19  int dstRA = (dst.row + offsetRow) / CLB_PER_CLOCK_REGION;
20  for(int c = 0 ; c < sizeCol ; c++){
21  if(resourceString[srcRA][src.col + c] != resourceString[dstRA][dst.col + c]){//if any two letters are different
22  if(LUT_numberOfFramesForResourceLetter[(uint8_t)resourceString[srcRA][src.col + c]] != LUT_numberOfFramesForResourceLetter[(uint8_t)resourceString[dstRA][dst.col + c]]){
23  //also the number of frames is different?!
24  throw std::runtime_error(std::string("Please check your merge coordinates. Tried to merge incompatible resources (from \"").append(LUT_typeOfFrameForResourceLetter[(uint8_t)resourceString[srcRA][src.col + c]]).append("\" to \"").append(LUT_typeOfFrameForResourceLetter[(uint8_t)resourceString[dstRA][dst.col + c]]).append("\")."));
25  } else {
26  //okay, different col, but same width. Throw warning?
27  warn("Relocating from frame type " + std::string(LUT_typeOfFrameForResourceLetter[(uint8_t)resourceString[srcRA][src.col + c]]) + " to frame type " + std::string(LUT_typeOfFrameForResourceLetter[(uint8_t)resourceString[dstRA][dst.col + c]]) + ".");
28  }
29  }
30  }
31 }
32 
34  for(int r = 0 ; r < src.size.row ; ){ //this loop will iterate south border and all (srcRow:srcRow + sizeRow) at CLBs 0 and 59
35  ensureRowCompatibility(src.position, r, src.size.col, dst);
36  if( ((src.position.row + r) % CLB_PER_CLOCK_REGION) == (CLB_PER_CLOCK_REGION-1) ) { // isLastCLBinRow
37  r++;
38  } else if( ((src.position.row + r) % CLB_PER_CLOCK_REGION) == 0 ) { // isFirstCLBinRow
39  r += (CLB_PER_CLOCK_REGION - 2);
40  } else { // get to the next {isLastCLBinRow}
41  r += (CLB_PER_CLOCK_REGION - 1 - ((src.position.row + r) % CLB_PER_CLOCK_REGION));
42  }
43  }
44  ensureRowCompatibility(src.position, src.size.row-1, src.size.col, dst); //iterate north border as well
45 }
46 
47 /**************************************************************************/
51 inline void fastMerge(XilinxConfigurationAccessPort* srcBitstream, Rect2D src, Coord2D dst){
52  log("fastMerge function called");
53  int srcRA = src.position.row / CLB_PER_CLOCK_REGION;
54  int sizeR = src.size.row / CLB_PER_CLOCK_REGION;
55  int dstRA = dst.row / CLB_PER_CLOCK_REGION;
56 
57  for(int r = 0 ; r < sizeR ; r++){
58  for(int c = 0 ; c < src.size.col ; c++){//relocate dst[dstRA + r][dst.col + c] <= src[srcRA + r][src.position.col + c]
59  for(int m = 0 ; m < LUT_numberOfFramesForResourceLetter[(uint8_t)resourceString[dstRA + r][dst.col + c]] ; m++){
60  if(selectedOptions.clb && selectedOptions.clk){
61  memcpy(&bitstreamCLB[dstRA + r][dst.col + c][m*WORDS_PER_FRAME] , &srcBitstream->bitstreamCLB[srcRA + r][src.position.col + c][m*WORDS_PER_FRAME], WORDS_PER_FRAME*4);
62  } else {
63  if(selectedOptions.clb){
64  memcpy(&bitstreamCLB[dstRA + r][dst.col + c][m*WORDS_PER_FRAME] , &srcBitstream->bitstreamCLB[srcRA + r][src.position.col + c][m*WORDS_PER_FRAME], WORDS_BEFORE_CLK*4);
65  memcpy(&bitstreamCLB[dstRA + r][dst.col + c][m*WORDS_PER_FRAME + WORDS_BEFORE_CLK + WORDS_AT_CLK] , &srcBitstream->bitstreamCLB[srcRA + r][src.position.col + c][m*WORDS_PER_FRAME + WORDS_BEFORE_CLK + WORDS_AT_CLK], WORDS_AFTER_CLK*4);
66  }
67  if(selectedOptions.clk){
68  for(int w = WORDS_BEFORE_CLK ; w < (WORDS_BEFORE_CLK + WORDS_AT_CLK) ; w++)
69  bitstreamCLB[dstRA + r][dst.col + c][m*WORDS_PER_FRAME + w] = srcBitstream->bitstreamCLB[srcRA + r][src.position.col + c][m*WORDS_PER_FRAME + w];
70  }
71  }
72  }
73  }
74  }
75  if(selectedOptions.bram){
76  for(int r = 0 ; r < sizeR ; r++){
77  int bramCols = numberOfBRAMsBeforeCol[r][src.position.col + src.size.col] - numberOfBRAMsBeforeCol[r][src.position.col];
78  int srcCol = numberOfBRAMsBeforeCol[r][src.position.col];
79  int dstCol = numberOfBRAMsBeforeCol[r][dst.col];
80  memcpy(&bitstreamBRAM[dstRA + r][dstCol][0] , &srcBitstream->bitstreamBRAM[srcRA + r][srcCol][0], bramCols * FRAMES_PER_BRAM_CONTENT_COLUMN * WORDS_PER_FRAME * 4);
81  }
82  }
83  bitstreamHasValidData = true;
84 }
85 
86 inline void flexiMerge(XilinxConfigurationAccessPort* srcBitstream, Endianness endianConversionNeeded, Rect2D src, Coord2D dst){
87  log("flexiMerge function called");
88  ensureInitializedBitstreamArrays();//initialize bitstream arrays before modifications
89  srcBitstream->ensureInitializedBitstreamArrays();//initialize bitstream arrays before modifications
90  int srcRA = src.position.row / CLB_PER_CLOCK_REGION;
91  int sizeR = src.size.row / CLB_PER_CLOCK_REGION;
92  int dstRA = dst.row / CLB_PER_CLOCK_REGION;
93 
94  for(int r = 0 ; r < sizeR ; r++){
95  for(int c = 0 ; c < src.size.col ; c++){//relocate dst[dstRA + r][dst.col + c] <= src[srcRA + r][src.position.col + c]
96  for(int m = 0 ; m < LUT_numberOfFramesForResourceLetter[(uint8_t)resourceString[dstRA + r][dst.col + c]] ; m++){
97  for(int w = 0 ; w < WORDS_PER_FRAME ; w++){
98  if(WORDS_BEFORE_CLK <= w && (WORDS_BEFORE_CLK + WORDS_AT_CLK) > w){
99  if(!selectedOptions.clk)
100  continue;
101  } else {
102  if(!selectedOptions.clb)
103  continue;
104  }
105  switch(selectedOptions.op){
106  case MergeOP::SET:
107  bitstreamCLB[dstRA + r][dst.col + c][m*WORDS_PER_FRAME + w] = Endian::NativeToAnyEndianness32(srcBitstream->bitstreamCLB[srcRA + r][src.position.col + c][m*WORDS_PER_FRAME + w], endianConversionNeeded);
108  break;
109  case MergeOP::XOR:
110  bitstreamCLB[dstRA + r][dst.col + c][m*WORDS_PER_FRAME + w] ^= Endian::NativeToAnyEndianness32(srcBitstream->bitstreamCLB[srcRA + r][src.position.col + c][m*WORDS_PER_FRAME + w], endianConversionNeeded);
111  break;
112  case MergeOP::OR:
113  bitstreamCLB[dstRA + r][dst.col + c][m*WORDS_PER_FRAME + w] |= Endian::NativeToAnyEndianness32(srcBitstream->bitstreamCLB[srcRA + r][src.position.col + c][m*WORDS_PER_FRAME + w], endianConversionNeeded);
114  break;
115  case MergeOP::AND:
116  bitstreamCLB[dstRA + r][dst.col + c][m*WORDS_PER_FRAME + w] &= Endian::NativeToAnyEndianness32(srcBitstream->bitstreamCLB[srcRA + r][src.position.col + c][m*WORDS_PER_FRAME + w], endianConversionNeeded);
117  break;
118  }
119  }
120  }
121  }
122  }
123  if(selectedOptions.bram){
124  for(int r = 0 ; r < sizeR ; r++){
125  int bramCols = numberOfBRAMsBeforeCol[r][src.position.col + src.size.col] - numberOfBRAMsBeforeCol[r][src.position.col];
126  int srcCol = numberOfBRAMsBeforeCol[r][src.position.col];
127  int dstCol = numberOfBRAMsBeforeCol[r][dst.col];
128  for(int c = 0 ; c < bramCols ; c++){
129  for(int w = 0 ; w < WORDS_PER_FRAME * FRAMES_PER_BRAM_CONTENT_COLUMN ; w++){
130  switch(selectedOptions.op){
131  case MergeOP::SET:
132  bitstreamBRAM[dstRA + r][dstCol + c][w] = Endian::NativeToAnyEndianness32(srcBitstream->bitstreamBRAM[srcRA + r][srcCol + c][w], endianConversionNeeded);
133  break;
134  case MergeOP::XOR:
135  bitstreamBRAM[dstRA + r][dstCol + c][w] ^= Endian::NativeToAnyEndianness32(srcBitstream->bitstreamBRAM[srcRA + r][srcCol + c][w], endianConversionNeeded);
136  break;
137  case MergeOP::OR:
138  bitstreamBRAM[dstRA + r][dstCol + c][w] |= Endian::NativeToAnyEndianness32(srcBitstream->bitstreamBRAM[srcRA + r][srcCol + c][w], endianConversionNeeded);
139  break;
140  case MergeOP::AND:
141  bitstreamBRAM[dstRA + r][dstCol + c][w] &= Endian::NativeToAnyEndianness32(srcBitstream->bitstreamBRAM[srcRA + r][srcCol + c][w], endianConversionNeeded);
142  break;
143  }
144  }
145  }
146  }
147  }//-if(reloBRAM)
148  bitstreamHasValidData = true;
149 }
Endianness
< Endianness in byteman is represented not only by big/little endian, but also by potential bit swapp...
Definition: Endianness.h:47
virtual void ensureInitializedBitstreamArrays()=0
uint32_t * bitstreamCLB[MAX_ROWS][MAX_COLS]
uint32_t * bitstreamBRAM[MAX_ROWS][MAX_BRAM_COLS]
void ensureRegionCompatibility(Rect2D src, Coord2D dst)
Definition: inlineMerge.h:33
void fastMerge(XilinxConfigurationAccessPort *srcBitstream, Rect2D src, Coord2D dst)
Definition: inlineMerge.h:51
void flexiMerge(XilinxConfigurationAccessPort *srcBitstream, Endianness endianConversionNeeded, Rect2D src, Coord2D dst)
Definition: inlineMerge.h:86
void ensureRowCompatibility(Coord2D src, int offsetRow, int sizeCol, Coord2D dst)
Definition: inlineMerge.h:17
uint32_t NativeToAnyEndianness32(uint32_t x, Endianness e)
Definition: Endianness.h:246
Definition: Coords.h:23
int col
Definition: Coords.h:25
int row
Definition: Coords.h:24
Definition: Coords.h:29
Coord2D size
Definition: Coords.h:31
Coord2D position
Definition: Coords.h:30