46 #include <boost/format.hpp>
73 const string YES =
"yes";
86 dictionaryCreated_(
false) {
98 !compatibilityProgDone_) {
104 updateDictionary(*compatibilityProg);
105 delete compatibilityBin;
106 delete compatibilityProg;
107 compatibilityProgDone_ =
true;
110 string errorMsg =
"Unable to ensure programmability: " +
113 __FILE__, __LINE__,
__func__, errorMsg);
115 if (!dictionaryCreated_) {
118 unsigned int compressedImemWidth =
120 assert(compressedImemWidth <=
sizeof(
long long unsigned int)*8
121 &&
"Compressed instruction width is too big");
124 setImemWidth(compressedImemWidth);
126 startNewProgram(programName);
127 setAllInstructionsToStartAtBeginningOfMAU();
129 return programBits();
143 stream <<
"library ieee;" << endl;
144 stream <<
"use ieee.std_logic_1164.all;" << endl;
145 stream <<
"use ieee.std_logic_arith.all;" << endl << endl;
147 stream <<
"package " << entityStr <<
"_dict_init is" << endl << endl;
148 stream << indentation(1)
149 <<
"type std_logic_dict_matrix is array (natural range <>) "
150 <<
"of std_logic_vector(" << binaryEncoding().width() - 1
151 <<
" downto 0);" << endl << endl;
154 stream << indentation(1)
155 <<
"constant dict_init : std_logic_dict_matrix := (" << endl;
156 for (
unsigned int i = 0; i < dictionary_.size(); i++) {
157 BitVector instr = MapTools::keyForValue<BitVector>(
160 stream << indentation(2) <<
"\"";
163 if (i+1 < dictionary_.size()) {
164 stream <<
"," << endl;
166 stream <<
");" << endl;
169 stream <<
"end " << entityStr <<
"_dict_init;" << endl << endl;
171 stream <<
"library ieee;" << endl;
172 stream <<
"use ieee.std_logic_1164.all;" << endl;
173 stream <<
"use ieee.std_logic_arith.all;" << endl;
174 stream <<
"use work." << entityStr <<
"_globals.all;" << endl;
175 stream <<
"use work." << entityStr <<
"_dict_init.all;" << endl;
176 stream <<
"use work." << entityStr <<
"_imem_mau.all;" << endl << endl;
179 stream <<
"entity " << entityStr <<
"_decompressor is" << endl;
180 stream << indentation(1) <<
"port (" << endl;
181 stream << indentation(2) <<
"fetch_en : out std_logic;" << endl;
182 stream << indentation(2) <<
"lock : in std_logic;" << endl;
183 stream << indentation(2)
184 <<
"fetchblock : in std_logic_vector("
185 <<
"IMEMWIDTHINMAUS*IMEMMAUWIDTH-1 downto 0);" << endl;
186 stream << indentation(2)
187 <<
"instructionword : out std_logic_vector("
188 <<
"INSTRUCTIONWIDTH-1 downto 0);" << endl;
189 stream << indentation(2) <<
"glock : out std_logic;" << endl;
190 stream << indentation(2) <<
"lock_r : in std_logic;" << endl;
191 stream << indentation(2) <<
"clk : in std_logic;" << endl;
192 stream << indentation(2) <<
"rstx : in std_logic);" << endl << endl;
193 stream <<
"end " << entityStr <<
"_decompressor;" << endl << endl;
195 stream <<
"architecture simple_dict of " << entityStr
196 <<
"_decompressor is" << endl << endl;
198 stream << indentation(1)
199 <<
"subtype dict_index is integer range 0 to "
200 <<
"dict_init'length-1;" << endl;
201 stream << indentation(1) <<
"signal dict_line : dict_index;" << endl;
202 stream << indentation(1)
203 <<
"constant dict : std_logic_dict_matrix("
204 <<
"0 to dict_init'length-1) := dict_init;" << endl << endl;
206 stream <<
"begin" << endl << endl;
207 stream << indentation(1) <<
"glock <= lock;" << endl;
208 stream << indentation(1) <<
"fetch_en <= not lock_r;" << endl;
209 stream << indentation(1)
210 <<
"dict_line <= conv_integer(unsigned(fetchblock("
211 <<
"fetchblock'length-1 downto fetchblock'length-"
213 <<
")));" << endl << endl;
215 stream << indentation(1) <<
"process (dict_line)" << endl;
216 stream << indentation(1) <<
"begin" << endl;
217 stream << indentation(2) <<
"instructionword <= dict(dict_line);"
219 stream << indentation(1) <<
"end process;" << endl << endl;
220 stream <<
"end simple_dict;" << endl;
231 stream <<
"Generates the program image using instruction-based "
232 <<
"dictionary compression." << endl << endl
233 <<
"Warning! This compressor works correctly only when "
234 <<
"there is one instruction per MAU in the final program "
235 <<
"image. That is, the minimum addressable unit of the "
236 <<
"address space should be "
237 <<
"the same as the width of the compressed instructions or "
238 <<
"wider. Otherwise jump and call addresses are invalid in "
239 <<
"the code. This compressor creates the dictionary on the "
240 <<
"level of whole instruction." << endl << endl
241 <<
"Parameters accepted:" << endl
242 <<
"----------------------" << endl
243 <<
"ensure_programmability" << endl
244 <<
"If the value is 'yes', instructions that ensure "
245 <<
"programmability of the processor are added to the "
246 <<
"dictionary automatically." << endl;
259 for (
int i = 0; i < numberOfPrograms(); i++) {
260 TPEFMap::const_iterator iter = programElement(i);
261 string name = iter->first;
262 startNewProgram(name);
263 setAllInstructionsToStartAtBeginningOfMAU();
264 updateDictionary(currentProgram());
266 dictionaryCreated_ =
true;
268 std::size_t keyWidth =
270 std::size_t entrySize = binaryEncoding().width();
271 std::size_t entries = dictionary_.size();
274 "dictionary width: %d bits, entries: %d, "
275 "total size: %d bits (%d bytes)\n" )
276 % keyWidth % entries % (entries * entrySize)
277 % std::size_t(std::ceil(entries * entrySize / 8.0))).str();
289 unsigned int code = dictionary_.size();
291 std::pair<BitVector, unsigned int>(instructionBits, code));
302 while (instruction != &NullInstruction::instance()) {
305 addToDictionary(*instructionBits);
306 instruction = &
program.nextInstruction(*instruction);
316 Instruction* instruction = ¤tProgram().firstInstruction();
317 while (instruction != &NullInstruction::instance()) {
319 unsigned int code = MapTools::valueForKey<unsigned int>(
320 dictionary_, *bemBits);
323 static_cast<BitVector*
>(compressedInstruction)->pushBack(
324 code,
static_cast<int>(
326 addInstruction(*instruction, compressedInstruction);
327 instruction = ¤tProgram().nextInstruction(*instruction);