46 #include <boost/format.hpp>
86 for (
unsigned int i = 0; i < dictionary_.size(); i++) {
87 if (dictionary_.at(i) != NULL) {
88 delete dictionary_.at(i);
98 if (!dictionaryCreated_) {
102 for (
unsigned int i = 0; i < dictionary_.size(); i++) {
108 imemWidth += firstMoveSlotIndex();
109 compressedWidth_ = imemWidth;
110 setImemWidth(compressedWidth_);
116 startNewProgram(programName);
117 setAllInstructionsToStartAtBeginningOfMAU();
119 return programBits();
132 generateDictionaryVhdl(stream, entityStr);
133 generateDecompressorEntity(stream, entityStr);
134 generateDecompressorArchitecture(stream, entityStr);
144 stream <<
"Generates the program image using move slot based "
145 <<
"dictionary compression." << endl << endl
146 <<
"Warning! This compressor works correctly only when "
147 <<
"there is one instruction per MAU in the final program "
148 <<
"image. That is, the MAU of the address space should be "
149 <<
"the same as the width of the compressed instructions or "
150 <<
"wider. Otherwise jump and call addresses are invalid in "
151 <<
"the code. This compressor creates the dictionary on the "
152 <<
"move slot level." << endl << endl;
163 for (
int i = 0; i < moveSlotCount(); i++) {
167 for (
int i = 0; i < numberOfPrograms(); i++) {
168 TPEFMap::const_iterator iter = programElement(i);
169 string name = iter->first;
170 startNewProgram(name);
171 setAllInstructionsToStartAtBeginningOfMAU();
172 updateDictionary(currentProgram());
175 dictionaryCreated_ =
true;
184 while (instruction != &NullInstruction::instance()) {
187 unsigned int begin = firstMoveSlotIndex();
188 unsigned int end = begin;
189 for (
int i = 0; i < moveSlotCount(); i++) {
190 end = begin + moveSlotWidth(i) - 1;
191 BitVector moveSlot(*instructionBits, begin, end);
192 addToDictionary(moveSlot, i);
195 instruction = &
program.nextInstruction(*instruction);
196 delete instructionBits;
209 *(dictionary_.at(slotIndex)), instructionBits)) {
210 unsigned int code = dictionary_.at(slotIndex)->size();
211 dictionary_.at(slotIndex)->insert(
212 std::pair<BitVector, unsigned int>(instructionBits, code));
221 Instruction* instruction = ¤tProgram().firstInstruction();
222 while (instruction != &NullInstruction::instance()) {
229 static_cast<BitVector*
>(compressedInstruction);
232 if (firstMoveSlotIndex() != 0) {
233 for (
int i = 0; i < firstMoveSlotIndex(); i++) {
235 compressPtr->
pushBack(bemBits->at(i) != 0);
238 unsigned int begin = firstMoveSlotIndex();
239 unsigned int end = begin;
240 for (
int i = 0; i < moveSlotCount(); i++) {
241 end = begin + moveSlotWidth(i)-1;
242 BitVector moveSlot(*bemBits, begin, end);
243 unsigned int code = MapTools::valueForKey<unsigned int>(
244 *(dictionary_.at(i)), moveSlot);
251 addInstruction(*instruction, compressedInstruction);
252 instruction = ¤tProgram().nextInstruction(*instruction);
258 stream <<
"library ieee;" << endl;
259 stream <<
"use ieee.std_logic_1164.all;" << endl;
260 stream <<
"use ieee.std_logic_arith.all;" << endl << endl;
262 TCEString packageName = entityStr +
"_dict_init";
264 stream <<
"package " << packageName <<
" is" << endl << endl;
266 for (
int i = 0; i < moveSlotCount(); i++) {
267 if (dictionary_.at(i)->size() > 1) {
268 stream << indentation(1)
269 <<
"type std_logic_dict_matrix_" << i
270 <<
" is array (natural range <>) "
271 <<
"of std_logic_vector(" << moveSlotWidth(i)-1
272 <<
" downto 0);" << endl << endl;
277 for (
int i = 0; i < moveSlotCount(); i++) {
278 if (dictionary_.at(i)->size() > 1) {
279 stream << indentation(1)
280 <<
"constant dict_init_slot_" << i
281 <<
" : std_logic_dict_matrix_" << i <<
" := (" << endl;
282 for (
unsigned int j = 0; j < dictionary_.at(i)->size(); j++) {
283 BitVector instr = MapTools::keyForValue<BitVector>(
284 *(dictionary_.at(i)), j);
286 stream << indentation(2) <<
"\"";
289 if (j+1 < dictionary_.at(i)->size()) {
290 stream <<
"," << endl;
292 stream <<
");" << endl;
297 unsigned int index = 0;
298 BitVector instr = MapTools::keyForValue<BitVector>(
299 *(dictionary_.at(i)), index);
301 stream << indentation(1)
302 <<
"constant dict_init_slot_" << i
303 <<
" : std_logic_vector("
304 << moveSlotWidth(i) <<
"-1 downto 0) := (" << endl
305 << indentation(2) <<
"\"";
307 stream <<
"\");" << endl;
311 stream <<
"end " << packageName <<
";" << endl << endl;
316 stream <<
"library ieee;" << endl;
317 stream <<
"use ieee.std_logic_1164.all;" << endl;
318 stream <<
"use ieee.std_logic_arith.all;" << endl;
319 stream <<
"use work." << entityStr <<
"_globals.all;" << endl;
320 stream <<
"use work." << entityStr <<
"_dict_init.all;" << endl;
321 stream <<
"use work." << entityStr <<
"_imem_mau.all;" << endl << endl;
323 stream <<
"entity " << entityStr <<
"_decompressor is" << endl;
324 stream << indentation(1) <<
"port (" << endl;
325 stream << indentation(2) <<
"fetch_en : out std_logic;" << endl;
326 stream << indentation(2) <<
"lock : in std_logic;" << endl;
327 stream << indentation(2)
328 <<
"fetchblock : in std_logic_vector("
329 <<
"IMEMWIDTHINMAUS*IMEMMAUWIDTH-1 downto 0);" << endl;
330 stream << indentation(2)
331 <<
"instructionword : out std_logic_vector("
332 <<
"INSTRUCTIONWIDTH-1 downto 0);" << endl;
333 stream << indentation(2) <<
"glock : out std_logic;" << endl;
334 stream << indentation(2) <<
"lock_r : in std_logic;" << endl;
335 stream << indentation(2) <<
"clk : in std_logic;" << endl;
336 stream << indentation(2) <<
"rstx : in std_logic);" << endl << endl;
337 stream <<
"end " << entityStr <<
"_decompressor;" << endl << endl;
341 std::ostream& stream,
TCEString entityStr) {
342 stream <<
"architecture move_slot_dict of " << entityStr
343 <<
"_decompressor is" << endl << endl;
345 bool haveLimm =
false;
346 generateDecompressorSignals(stream,haveLimm);
348 generateDecompressorBody(stream, haveLimm);
350 stream <<
"end move_slot_dict;" << endl;
355 for (
int i = 0; i < moveSlotCount(); i++) {
356 if (dictionary_.at(i)->size() > 1) {
357 stream << indentation(1)
358 <<
"subtype dict_index_"<< i
359 <<
" is integer range 0 to "
360 <<
"dict_init_slot_" << i
361 <<
"'length-1;" << endl;
362 stream << indentation(1)
363 <<
"signal dict_line_"
364 << i <<
" : dict_index_" << i <<
";" << endl;
365 stream << indentation(1)
366 <<
"constant dict_" << i
367 <<
" : std_logic_dict_matrix_"
368 << i <<
"(0 to dict_init_slot_" << i
369 <<
"'length-1) := dict_init_slot_"
370 << i <<
";" << endl << endl;
372 stream << indentation(1)
373 <<
"constant dict_" << i
374 <<
" : std_logic_vector("
376 <<
"-1 downto 0) := dict_init_slot_"
377 << i <<
";" << endl << endl;
381 int limmEndIndex = 0;
382 if (firstMoveSlotIndex() != 0) {
384 limmEndIndex = firstMoveSlotIndex();
385 stream << indentation(1)
386 <<
"signal limm_field : std_logic_vector("
387 << limmEndIndex <<
"-1 downto 0);" << endl << endl;
392 stream << indentation(1) <<
"begin" << endl << endl;
393 stream << indentation(1) <<
"glock <= lock;" << endl;
394 stream << indentation(1) <<
"fetch_en <= not lock_r;" << endl << endl;
398 int limmEndIndex = firstMoveSlotIndex();
399 stream << indentation(1)
400 <<
"limm_field <= fetchblock(fetchblock'length-1 downto "
401 <<
"fetchblock'length-" << limmEndIndex <<
");" << endl
405 vector<pair<int,int> > moveSlotBoundaries;
406 evaluateMoveSlotBoundaries(moveSlotBoundaries);
408 for (
int i = 0; i < moveSlotCount(); i++) {
409 if (dictionary_.at(i)->size() > 1) {
410 stream << indentation(1)
412 <<
" <= conv_integer(unsigned(fetchblock("
413 <<
"fetchblock'length-"
414 << moveSlotBoundaries.at(i).first
415 <<
" downto fetchblock'length-"
416 << moveSlotBoundaries.at(i).second
417 <<
")));" << endl << endl;
421 generateDecompressorProcess(stream, haveLimm);
425 for (
int i = 0; i < moveSlotCount(); i++) {
427 if (boundaries.size() == 0) {
428 temp = firstMoveSlotIndex();
431 temp = boundaries.at(boundaries.size()-1).second;
433 int begin = temp + 1;
435 boundaries.push_back(std::make_pair(begin,end));
440 stream << indentation(1) <<
"process (";
442 stream <<
"limm_field, ";
444 for (
int i = 0; i < moveSlotCount(); i++) {
445 if (dictionary_.at(i)->size() > 1) {
446 stream <<
"dict_line_" << i;
447 if (i+1 < moveSlotCount()
448 && dictionary_.at(i+1)->size() > 1) {
453 stream <<
")" << endl
454 << indentation(1) <<
"begin" << endl
455 << indentation(2) <<
"instructionword <= ";
457 stream <<
"limm_field&";
459 for (
int i = 0; i < moveSlotCount(); i++) {
460 if (dictionary_.at(i)->size() > 1) {
461 stream <<
"dict_" << i <<
"(dict_line_" << i <<
")";
463 stream <<
"dict_" << i;
465 if (i+1 < moveSlotCount()) {
469 stream <<
";" << endl
470 << indentation(1) <<
"end process;" << endl << endl;
474 int widthInBytes =
static_cast<int>(
475 std::ceil(compressedWidth_ / 8.0));
477 << compressedWidth_ <<
" ("
478 << widthInBytes <<
" bytes)" << endl;
479 std::size_t totalSize = 0;
480 for (
unsigned int i = 0; i < dictionary_.size(); i++) {
481 std::size_t index =
static_cast<std::size_t
>(i);
482 std::size_t keyWidth =
484 std::size_t entrySize = binaryEncoding().width();
485 std::size_t entries = dictionary_.at(i)->size();
486 totalSize += entries * entrySize;
490 "dictionary width: %d bits, entries: %d, "
491 "dictionary size: %d bits (%d bytes)\n")
492 % index % keyWidth % entries % (entries * entrySize)
494 std::ceil(entries * entrySize / 8.0))).str();
498 "Total dictionary size: %d bits (%d bytes)\n\n")
500 % std::size_t(std::ceil(totalSize / 8.0))).str();