aboutsummaryrefslogtreecommitdiff
path: root/rtl/modexpng_core_top.v
diff options
context:
space:
mode:
authorPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2019-10-21 12:46:22 +0300
committerPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2019-10-21 12:46:22 +0300
commit3213b3ef3c1d40dfa416b6be409cfa3d15af0930 (patch)
treef776ddb5b44a9f9e4f1b2b9da56a4b645570fdb1 /rtl/modexpng_core_top.v
parent1e3303286bdb0d400d78d9d8b0aa90b29949c4a3 (diff)
Added "MERGE_LH" micro-operation. To be able to do Garner's formula we need
regular (not modular) multiplication. We're doing this by telling the modular multiplier to stop after the "square" step, which computes A*B. The problem is that the multiplier stores the lower part of the product in the internal bank L and the upper part in the internal bank H, but we need to be able to do operations on the product as a whole. MERGE_LH that combines the two halves of the product into one bank.
Diffstat (limited to 'rtl/modexpng_core_top.v')
-rw-r--r--rtl/modexpng_core_top.v41
1 files changed, 39 insertions, 2 deletions
diff --git a/rtl/modexpng_core_top.v b/rtl/modexpng_core_top.v
index dea7f0a..4c1f065 100644
--- a/rtl/modexpng_core_top.v
+++ b/rtl/modexpng_core_top.v
@@ -83,13 +83,15 @@ module modexpng_core_top
wire uop_opcode_is_ladder = (uop_data_opcode == UOP_OPCODE_LADDER_INIT ) ||
(uop_data_opcode == UOP_OPCODE_LADDER_STEP ) ;
wire uop_opcode_is_mmm = (uop_data_opcode == UOP_OPCODE_MODULAR_MULTIPLY ) ||
- (uop_data_opcode == UOP_OPCODE_MODULAR_REDUCE_PROC ) ;
+ (uop_data_opcode == UOP_OPCODE_MODULAR_REDUCE_PROC ) ||
+ (uop_data_opcode == UOP_OPCODE_REGULAR_MULTIPLY ) ;
wire uop_opcode_is_wrk = (uop_data_opcode == UOP_OPCODE_PROPAGATE_CARRIES ) ||
(uop_data_opcode == UOP_OPCODE_COPY_CRT_Y2X ) ||
(uop_data_opcode == UOP_OPCODE_MODULAR_REDUCE_INIT ) ||
(uop_data_opcode == UOP_OPCODE_COPY_LADDERS_X2Y ) ||
(uop_data_opcode == UOP_OPCODE_CROSS_LADDERS_X2Y ) ||
- (uop_data_opcode == UOP_OPCODE_MODULAR_SUBTRACT ) ;
+ (uop_data_opcode == UOP_OPCODE_MODULAR_SUBTRACT ) ||
+ (uop_data_opcode == UOP_OPCODE_MERGE_LH ) ;
wire uop_loop_now;
@@ -716,6 +718,9 @@ module modexpng_core_top
reg mmm_only_reduce_x;
reg mmm_only_reduce_y;
+ reg mmm_just_multiply_x;
+ reg mmm_just_multiply_y;
+
wire rdct_ena_x;
wire rdct_ena_y;
wire rdct_rdy_x;
@@ -734,6 +739,7 @@ module modexpng_core_top
.word_index_last_minus1 (mmm_word_index_last_minus1_x),
.force_unity_b (mmm_force_unity_b_x),
.only_reduce (mmm_only_reduce_x),
+ .just_multiply (mmm_just_multiply_x),
.sel_wide_in (mmm_sel_wide_in_x),
.sel_narrow_in (mmm_sel_narrow_in_x),
@@ -790,6 +796,7 @@ module modexpng_core_top
.word_index_last_minus1 (mmm_word_index_last_minus1_y),
.force_unity_b (mmm_force_unity_b_y),
.only_reduce (mmm_only_reduce_y),
+ .just_multiply (mmm_just_multiply_y),
.sel_wide_in (mmm_sel_wide_in_y),
.sel_narrow_in (mmm_sel_narrow_in_y),
@@ -1088,6 +1095,7 @@ module modexpng_core_top
UOP_LADDER_PQ: {mmm_ladder_mode_x, mmm_ladder_mode_y} <= {io_mgr_ladder_p, io_mgr_ladder_q};
endcase
//
+ {mmm_just_multiply_x, mmm_just_multiply_y } <= {2{1'b0}};
{mmm_only_reduce_x, mmm_only_reduce_y } <= {2{1'b0}};
{mmm_force_unity_b_x, mmm_force_unity_b_y } <= {2{uop_aux_is_1 ? 1'b0 : 1'b1}};
{mmm_sel_wide_in_x, mmm_sel_wide_in_y } <= {2{uop_data_sel_wide_in }};
@@ -1110,6 +1118,20 @@ module modexpng_core_top
//
end
//
+ UOP_OPCODE_REGULAR_MULTIPLY: begin
+ //
+ {mmm_ladder_mode_x, mmm_ladder_mode_y } <= {2{1'b1}};
+ //
+ {mmm_just_multiply_x, mmm_just_multiply_y } <= {2{1'b1}};
+ {mmm_only_reduce_x, mmm_only_reduce_y } <= {2{1'b0}};
+ {mmm_force_unity_b_x, mmm_force_unity_b_y } <= {2{uop_aux_is_1 ? 1'b0 : 1'b1}};
+ {mmm_sel_wide_in_x, mmm_sel_wide_in_y } <= {2{uop_data_sel_wide_in }};
+ {mmm_sel_narrow_in_x, mmm_sel_narrow_in_y } <= {2{uop_data_sel_narrow_in }};
+ {rdct_sel_wide_out_x, rdct_sel_wide_out_y } <= {2{uop_data_sel_wide_out }};
+ {rdct_sel_narrow_out_x, rdct_sel_narrow_out_y} <= {2{uop_data_sel_narrow_out }};
+ //
+ end
+ //
UOP_OPCODE_PROPAGATE_CARRIES: begin
wrk_sel_narrow_in <= uop_data_sel_narrow_in;
wrk_sel_narrow_out <= uop_data_sel_narrow_out;
@@ -1121,6 +1143,10 @@ module modexpng_core_top
wrk_sel_narrow_out <= uop_data_sel_narrow_out;
end
//
+ UOP_OPCODE_MERGE_LH: begin
+ wrk_sel_narrow_out <= uop_data_sel_narrow_out;
+ end
+ //
UOP_OPCODE_COPY_CRT_Y2X,
UOP_OPCODE_COPY_LADDERS_X2Y,
UOP_OPCODE_CROSS_LADDERS_X2Y: begin
@@ -1181,10 +1207,21 @@ module modexpng_core_top
{rdct_word_index_last_x, rdct_word_index_last_y } <= {2{word_index_last_pq }};
end
//
+ UOP_OPCODE_REGULAR_MULTIPLY: begin
+ {mmm_word_index_last_x, mmm_word_index_last_y } <= {2{word_index_last_pq }};
+ {mmm_word_index_last_minus1_x, mmm_word_index_last_minus1_y} <= {2{word_index_last_pq_minus1}};
+ {rdct_word_index_last_x, rdct_word_index_last_y } <= {2{word_index_last_pq }};
+ end
+ //
UOP_OPCODE_MODULAR_SUBTRACT: begin
wrk_word_index_last <= uop_npq_is_n ? word_index_last_n : word_index_last_pq;
end
//
+ UOP_OPCODE_MERGE_LH: begin
+ wrk_word_index_last <= word_index_last_n;
+ wrk_word_index_last_half <= word_index_last_pq;
+ end
+ //
UOP_OPCODE_LADDER_INIT: begin
io_mgr_word_index_last <= OP_ADDR_LADDER_LAST;
io_mgr_ladder_steps <= crt_mode ? bit_index_last_pq : bit_index_last_n;