diff options
-rw-r--r-- | modexpng_fpga_model.py | 197 |
1 files changed, 117 insertions, 80 deletions
diff --git a/modexpng_fpga_model.py b/modexpng_fpga_model.py index cf4d7f8..0726eaa 100644 --- a/modexpng_fpga_model.py +++ b/modexpng_fpga_model.py @@ -77,9 +77,9 @@ _VECTOR_CLASS = "Vector" DUMP_VECTORS = False DUMP_INDICES = False DUMP_MACS_CLEARING = False -DUMP_MACS_ACCUMULATION = True +DUMP_MACS_ACCUMULATION = False DUMP_MULT_PARTS = False -DUMP_RCMB = False +DUMP_RCMB = True # @@ -232,7 +232,7 @@ class ModExpNG_PartRecombinator(): # dump if dump and DUMP_RCMB: print("RCMB -> push(): part = 0x%012x, word = 0x%04x" % (part, t)) - + # done return t @@ -241,7 +241,7 @@ class ModExpNG_PartRecombinator(): # empty results so far words_lsb = list() # n words words_msb = list() # n words - + # recombine the lower half (n parts) # the first tick produces null result, the last part # produces three words and needs two extra ticks @@ -249,37 +249,37 @@ class ModExpNG_PartRecombinator(): for i in range(ab_num_words + 1 + 2): next_part = parts[i] if i < ab_num_words else 0 next_word = self._push_pipeline(next_part, dump) - + if i > 0: words_lsb.append(next_word) - + # recombine the upper half (n-1 parts) # the first tick produces null result self._flush_pipeline(dump) for i in range(ab_num_words + 1): next_part = parts[i + ab_num_words] if i < (ab_num_words - 1) else 0 next_word = self._push_pipeline(next_part, dump) - + if i > 0: words_msb.append(next_word) - + # merge words words = list() - + # merge lower half for x in range(ab_num_words): next_word = words_lsb[x] words.append(next_word) - + # merge upper half adding the two overlapping words for x in range(ab_num_words): next_word = words_msb[x] if x < 2: next_word += words_lsb[x + ab_num_words] words.append(next_word) - + return words - + def recombine_triangle(self, parts, ab_num_words, dump): @@ -342,30 +342,39 @@ class ModExpNG_WordMultiplier(): self._mac_aux.append(0) self._index_aux.append(0) - def _clear_all_macs(self): + def _clear_all_macs(self, t, col, dump): for x in range(NUM_MULTS): self._macs[x] = 0 + if dump and DUMP_MACS_CLEARING: + print("t=%2d, col=%2d > clear > all" % (t, col)) + - def _clear_one_mac(self, x): + def _clear_one_mac(self, x, t, col, dump): self._macs[x] = 0 + if dump and DUMP_MACS_CLEARING: + print("t=%2d, col=%2d > clear > x=%d" % (t, col, x)) - def _clear_mac_aux(self): + + def _clear_mac_aux(self, t, col, dump): self._mac_aux[0] = 0 + if dump and DUMP_MACS_CLEARING: + print("t= 0, col=%2d > clear > aux" % (col)) + def _update_one_mac(self, x, a, b): - + if a > 0xFFFF: self._a_seen_17 = True if b > 0xFFFF: self._b_seen_17 = True - + if a > 0x1FFFF: raise("a > 0x1FFFF!") - + if b > 0x1FFFF: raise("b > 0x1FFFF!") - + p = a * b self._macs[x] += p @@ -379,6 +388,35 @@ class ModExpNG_WordMultiplier(): def _preset_index_aux(self, num_cols): self._index_aux[0] = num_cols * len(self._indices) + def _dump_macs_helper(self, t, col, aux=False): + print("t=%2d, col=%2d > "% (t, col), end='') + for i in range(NUM_MULTS): + if i > 0: print(" | ", end='') + print("mac[%d]: 0x%012x" % (i, self._macs[i]), end='') + if aux: + print(" | mac_aux[ 0]: 0x%012x" % (self._mac_aux[0]), end='') + print("") + + def _dump_macs(self, t, col): + self._dump_macs_helper(t, col) + + def _dump_macs_aux(self, t, col): + self._dump_macs_helper(t, col, True) + + def _dump_indices_helper(self, t, col, aux=False): + print("t=%2d, col=%2d > indices:" % (t, col), end='') + for i in range(NUM_MULTS): + print(" %2d" % self._indices[i], end='') + if aux: + print(" %2d" % self._index_aux[0], end='') + print("") + + def _dump_indices(self, t, col): + self._dump_indices_helper(t, col) + + def _dump_indices_aux(self, t, col): + self._dump_indices_helper(t, col, True) + def _rotate_indices(self, num_words): for x in range(len(self._indices)): if self._indices[x] > 0: @@ -400,7 +438,7 @@ class ModExpNG_WordMultiplier(): if dump and DUMP_MULT_PARTS: print("t=%2d, col=%2d > parts[%2d]: mac_aux[%d] = 0x%012x" % (time, column, part_index, mac_index, parts[part_index])) - + def multiply_square(self, a_wide, b_narrow, ab_num_words, dump=False): if dump: print("multiply_square()") @@ -415,26 +453,20 @@ class ModExpNG_WordMultiplier(): for t in range(ab_num_words): - if t == 0: self._preset_indices(col) + # take care of indices + if t == 0: self._preset_indices(col) else: self._rotate_indices(ab_num_words) + # take care of macs if t == 0: - self._clear_all_macs() - if dump and DUMP_MACS_CLEARING: - print("t= 0, col=%2d > clear > all" % (col)) + self._clear_all_macs(t, col, dump) else: t1 = t - 1 if (t1 // 8) == col: - self._clear_one_mac(t1 % NUM_MULTS) - if dump and DUMP_MACS_CLEARING: - print("t=%2d, col=%2d > clear > x=%d:" % (t, col, t1 % NUM_MULTS)) - + self._clear_one_mac(t1 % NUM_MULTS, t, col, dump) - if dump and DUMP_INDICES: - print("t=%2d, col=%2d > indices:" % (t, col), end='') - for i in range(NUM_MULTS): - print(" %2d" % self._indices[i], end='') - print("") + # debug output + if dump and DUMP_INDICES: self._dump_indices(t, col) # current b-word bt = b_narrow.words[t] @@ -448,12 +480,8 @@ class ModExpNG_WordMultiplier(): part_index = t self._mult_store_part(parts, t, col, part_index, x, dump) - if dump and DUMP_MACS_ACCUMULATION: - print("t=%2d, col=%2d > "% (t, col), end='') - for i in range(NUM_MULTS): - if i > 0: print(" | ", end='') - print("mac[%d]: 0x%012x" % (i, self._macs[i]), end='') - print("") + # debug output + if dump and DUMP_MACS_ACCUMULATION: self._dump_macs(t, col) # save the uppers part of product at end of column, # for the last column don't save the very last part @@ -481,25 +509,25 @@ class ModExpNG_WordMultiplier(): for t in range(ab_num_words + 1): - if t == 0: - self._preset_indices(col) - if last_col: - self._preset_index_aux(num_cols) - else: - self._rotate_indices(ab_num_words) - if last_col: - self._rotate_index_aux() - - if t == 0: - self._clear_all_macs() - if dump and DUMP_MACS_CLEARING: - print("t= 0, col=%2d > clear > all" % (col)) - - if last_col: - self._clear_mac_aux() - if dump and DUMP_MACS_CLEARING: - print("t= 0, col=%2d > clear > aux" % (col)) - + # take care of indices + if t == 0: self._preset_indices(col) + else: self._rotate_indices(ab_num_words) + + # take care of auxilary index + if last_col: + if t == 0: self._preset_index_aux(num_cols) + else: self._rotate_index_aux() + + # take care of macs + if t == 0: self._clear_all_macs(t, col, dump) + + # take care of auxilary mac + if last_col: + if t == 0: self._clear_mac_aux(t, col, dump) + + # debug output + if dump and DUMP_INDICES: self._dump_indices_aux(t, col) + # current b-word bt = b_narrow.words[t] @@ -521,23 +549,18 @@ class ModExpNG_WordMultiplier(): part_index = t self._mult_store_part_aux(parts, t, col, part_index, 0, dump) - if dump and DUMP_MACS_ACCUMULATION: - print("t=%2d, col=%2d > "% (t, col), end='') - for i in range(NUM_MULTS): - if i > 0: print(" | ", end='') - print("mac[%d]: 0x%012x" % (i, self._macs[i]), end='') - if last_col: - print(" | mac_aux[ 0]: 0x%012x" % (self._mac_aux[0]), end='') - print("") + # debug output + if dump and DUMP_MACS_ACCUMULATION: self._dump_macs_aux(t, col) - # shortcut if not last_col: if t == (NUM_MULTS * (col + 1) - 1): break return parts - def multiply_rectangle(self, a_wide, b_narrow, ab_num_words): + def multiply_rectangle(self, a_wide, b_narrow, ab_num_words, dump=False): + + if dump: print("multiply_rectangle()") num_cols = ab_num_words // NUM_MULTS @@ -547,10 +570,22 @@ class ModExpNG_WordMultiplier(): for col in range(num_cols): - self._clear_all_macs() - self._preset_indices(col) + for t in range(ab_num_words + 1): - for t in range(ab_num_words+1): + # take care of indices + if t == 0: self._preset_indices(col) + else: self._rotate_indices(ab_num_words) + + # take care of macs + if t == 0: + self._clear_all_macs(t, col, dump) + else: + t1 = t - 1 + if (t1 // 8) == col: + self._clear_one_mac(t1 % NUM_MULTS, t, col, dump) + + # debug output + if dump and DUMP_INDICES: self._dump_indices(t, col) # current b-word bt = b_narrow.words[t] @@ -562,15 +597,17 @@ class ModExpNG_WordMultiplier(): # don't save one value for the very last time instant per column if t < ab_num_words and t == (col * NUM_MULTS + x): - parts[t] = self._macs[x] - self._clear_one_mac(x) + part_index = t + self._mult_store_part(parts, t, col, part_index, x, dump) + + # debug output + if dump and DUMP_MACS_ACCUMULATION: self._dump_macs(t, col) - # save the uppers part of product at end of column + # save the upper parts of product at end of column if t == ab_num_words: for x in range(NUM_MULTS): - parts[ab_num_words + col * NUM_MULTS + x] = self._macs[x] - - self._rotate_indices(ab_num_words) + part_index = ab_num_words + col * NUM_MULTS + x + self._mult_store_part(parts, t, col, part_index, x, dump) return parts @@ -722,7 +759,7 @@ class ModExpNG_Worker(): q = ModExpNG_Operand(None, ab_num_words + 1, q_words) # 3. - m_parts = self.multiplier.multiply_rectangle(n, q, ab_num_words) + m_parts = self.multiplier.multiply_rectangle(n, q, ab_num_words, dump) m_words = self.recombinator.recombine_rectangle(m_parts, ab_num_words, dump) m = ModExpNG_Operand(None, 2 * ab_num_words + 1, m_words) @@ -813,7 +850,7 @@ if __name__ == "__main__": mp_blind_factor = worker.multiply(mp_blind, vector.p_factor, vector.p, vector.p_coeff, pq_num_words, dump=True) mq_blind_factor = worker.multiply(mq_blind, vector.q_factor, vector.q, vector.q_coeff, pq_num_words) - + sp_blind_factor = worker.exponentiate(ip_factor, mp_blind_factor, vector.dp, vector.p, vector.p_factor, vector.p_coeff, pq_num_words) sq_blind_factor = worker.exponentiate(iq_factor, mq_blind_factor, vector.dq, vector.q, vector.q_factor, vector.q_coeff, pq_num_words) @@ -827,7 +864,7 @@ if __name__ == "__main__": else: print("17-bit wide B's not detected.") - + sp_blind = worker.multiply(i, sp_blind_factor, vector.p, vector.p_coeff, pq_num_words) sq_blind = worker.multiply(i, sq_blind_factor, vector.q, vector.q_coeff, pq_num_words) |