Update Fp6 logic to use formulas

This commit is contained in:
bsdevlin 2019-07-20 23:33:34 +08:00
parent 82ed9c4dd9
commit c25d20a2ce
2 changed files with 263 additions and 326 deletions

View File

@ -52,6 +52,7 @@ module ec_fe6_arithmetic
if_axi_stream.sink i_sub_fe6_if if_axi_stream.sink i_sub_fe6_if
); );
localparam NUM_OVR_WRT_BIT = 5;
if_axi_stream #(.DAT_BITS($bits(FE2_TYPE)), .CTL_BITS(CTL_BITS)) add_if_fe2_i [1:0] (i_clk); if_axi_stream #(.DAT_BITS($bits(FE2_TYPE)), .CTL_BITS(CTL_BITS)) add_if_fe2_i [1:0] (i_clk);
if_axi_stream #(.DAT_BITS(2*$bits(FE2_TYPE)), .CTL_BITS(CTL_BITS)) add_if_fe2_o [1:0] (i_clk); if_axi_stream #(.DAT_BITS(2*$bits(FE2_TYPE)), .CTL_BITS(CTL_BITS)) add_if_fe2_o [1:0] (i_clk);
@ -82,7 +83,7 @@ always_ff @ (posedge i_clk) begin
add_if_fe2_o[0].copy_if({i_add_fe6_if.dat[$bits(FE6_TYPE) +: $bits(FE2_TYPE)], add_if_fe2_o[0].copy_if({i_add_fe6_if.dat[$bits(FE6_TYPE) +: $bits(FE2_TYPE)],
i_add_fe6_if.dat[0 +: $bits(FE2_TYPE)]}, i_add_fe6_if.dat[0 +: $bits(FE2_TYPE)]},
i_add_fe6_if.val, 1, 1, i_add_fe6_if.err, i_add_fe6_if.mod, i_add_fe6_if.ctl); i_add_fe6_if.val, 1, 1, i_add_fe6_if.err, i_add_fe6_if.mod, i_add_fe6_if.ctl);
add_if_fe2_o[0].ctl[OVR_WRT_BIT +: 2] <= add_cnt; add_if_fe2_o[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= add_cnt;
if (i_add_fe6_if.val) add_cnt <= 1; if (i_add_fe6_if.val) add_cnt <= 1;
end end
end end
@ -91,7 +92,7 @@ always_ff @ (posedge i_clk) begin
add_if_fe2_o[0].copy_if({i_add_fe6_if.dat[$bits(FE6_TYPE)+$bits(FE2_TYPE) +: $bits(FE2_TYPE)], add_if_fe2_o[0].copy_if({i_add_fe6_if.dat[$bits(FE6_TYPE)+$bits(FE2_TYPE) +: $bits(FE2_TYPE)],
i_add_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)]}, i_add_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)]},
i_add_fe6_if.val, 1, 1, i_add_fe6_if.err, i_add_fe6_if.mod, i_add_fe6_if.ctl); i_add_fe6_if.val, 1, 1, i_add_fe6_if.err, i_add_fe6_if.mod, i_add_fe6_if.ctl);
add_if_fe2_o[0].ctl[OVR_WRT_BIT +: 2] <= add_cnt; add_if_fe2_o[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= add_cnt;
if (i_add_fe6_if.val) add_cnt <= 2; if (i_add_fe6_if.val) add_cnt <= 2;
end end
end end
@ -100,7 +101,7 @@ always_ff @ (posedge i_clk) begin
add_if_fe2_o[0].copy_if({i_add_fe6_if.dat[$bits(FE6_TYPE)+2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)], add_if_fe2_o[0].copy_if({i_add_fe6_if.dat[$bits(FE6_TYPE)+2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)],
i_add_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]}, i_add_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]},
i_add_fe6_if.val, 1, 1, i_add_fe6_if.err, i_add_fe6_if.mod, i_add_fe6_if.ctl); i_add_fe6_if.val, 1, 1, i_add_fe6_if.err, i_add_fe6_if.mod, i_add_fe6_if.ctl);
add_if_fe2_o[0].ctl[OVR_WRT_BIT +: 2] <= add_cnt; add_if_fe2_o[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= add_cnt;
if (i_add_fe6_if.val) add_cnt <= 0; if (i_add_fe6_if.val) add_cnt <= 0;
end end
end end
@ -109,11 +110,11 @@ always_ff @ (posedge i_clk) begin
// One process to assign outputs // One process to assign outputs
if (~o_add_fe6_if.val || (o_add_fe6_if.val && o_add_fe6_if.rdy)) begin if (~o_add_fe6_if.val || (o_add_fe6_if.val && o_add_fe6_if.rdy)) begin
o_add_fe6_if.ctl <= add_if_fe2_i[0].ctl; o_add_fe6_if.ctl <= add_if_fe2_i[0].ctl;
o_add_fe6_if.ctl[OVR_WRT_BIT +: 2] <= 0; o_add_fe6_if.ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= 0;
if (add_if_fe2_i[0].ctl[OVR_WRT_BIT +: 2] == 0) begin if (add_if_fe2_i[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] == 0) begin
if (add_if_fe2_i[0].val) if (add_if_fe2_i[0].val)
o_add_fe6_if.dat[0 +: $bits(FE2_TYPE)] <= add_if_fe2_i[0].dat; o_add_fe6_if.dat[0 +: $bits(FE2_TYPE)] <= add_if_fe2_i[0].dat;
end else if (add_if_fe2_i[0].ctl[OVR_WRT_BIT +: 2] == 1) begin end else if (add_if_fe2_i[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] == 1) begin
if (add_if_fe2_i[0].val) if (add_if_fe2_i[0].val)
o_add_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= add_if_fe2_i[0].dat; o_add_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= add_if_fe2_i[0].dat;
end else begin end else begin
@ -150,7 +151,7 @@ always_ff @ (posedge i_clk) begin
sub_if_fe2_o[0].copy_if({i_sub_fe6_if.dat[$bits(FE6_TYPE) +: $bits(FE2_TYPE)], sub_if_fe2_o[0].copy_if({i_sub_fe6_if.dat[$bits(FE6_TYPE) +: $bits(FE2_TYPE)],
i_sub_fe6_if.dat[0 +: $bits(FE2_TYPE)]}, i_sub_fe6_if.dat[0 +: $bits(FE2_TYPE)]},
i_sub_fe6_if.val, 1, 1, i_sub_fe6_if.err, i_sub_fe6_if.mod, i_sub_fe6_if.ctl); i_sub_fe6_if.val, 1, 1, i_sub_fe6_if.err, i_sub_fe6_if.mod, i_sub_fe6_if.ctl);
sub_if_fe2_o[0].ctl[OVR_WRT_BIT +: 2] <= sub_cnt; sub_if_fe2_o[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= sub_cnt;
if (i_sub_fe6_if.val) sub_cnt <= 1; if (i_sub_fe6_if.val) sub_cnt <= 1;
end end
end end
@ -159,7 +160,7 @@ always_ff @ (posedge i_clk) begin
sub_if_fe2_o[0].copy_if({i_sub_fe6_if.dat[$bits(FE6_TYPE)+$bits(FE2_TYPE) +: $bits(FE2_TYPE)], sub_if_fe2_o[0].copy_if({i_sub_fe6_if.dat[$bits(FE6_TYPE)+$bits(FE2_TYPE) +: $bits(FE2_TYPE)],
i_sub_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)]}, i_sub_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)]},
i_sub_fe6_if.val, 1, 1, i_sub_fe6_if.err, i_sub_fe6_if.mod, i_sub_fe6_if.ctl); i_sub_fe6_if.val, 1, 1, i_sub_fe6_if.err, i_sub_fe6_if.mod, i_sub_fe6_if.ctl);
sub_if_fe2_o[0].ctl[OVR_WRT_BIT +: 2] <= sub_cnt; sub_if_fe2_o[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= sub_cnt;
if (i_sub_fe6_if.val) sub_cnt <= 2; if (i_sub_fe6_if.val) sub_cnt <= 2;
end end
end end
@ -168,7 +169,7 @@ always_ff @ (posedge i_clk) begin
sub_if_fe2_o[0].copy_if({i_sub_fe6_if.dat[$bits(FE6_TYPE)+2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)], sub_if_fe2_o[0].copy_if({i_sub_fe6_if.dat[$bits(FE6_TYPE)+2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)],
i_sub_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]}, i_sub_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]},
i_sub_fe6_if.val, 1, 1, i_sub_fe6_if.err, i_sub_fe6_if.mod, i_sub_fe6_if.ctl); i_sub_fe6_if.val, 1, 1, i_sub_fe6_if.err, i_sub_fe6_if.mod, i_sub_fe6_if.ctl);
sub_if_fe2_o[0].ctl[OVR_WRT_BIT +: 2] <= sub_cnt; sub_if_fe2_o[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= sub_cnt;
if (i_sub_fe6_if.val) sub_cnt <= 0; if (i_sub_fe6_if.val) sub_cnt <= 0;
end end
end end
@ -176,337 +177,221 @@ always_ff @ (posedge i_clk) begin
// One process to assign outputs // One process to assign outputs
if (~o_sub_fe6_if.val || (o_sub_fe6_if.val && o_sub_fe6_if.rdy)) begin if (~o_sub_fe6_if.val || (o_sub_fe6_if.val && o_sub_fe6_if.rdy)) begin
if (sub_if_fe2_i[0].ctl[OVR_WRT_BIT +: 2] == 0 && sub_if_fe2_i[0].val) begin if (sub_if_fe2_i[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] == 0 && sub_if_fe2_i[0].val) begin
o_sub_fe6_if.dat[0 +: $bits(FE2_TYPE)] <= sub_if_fe2_i[0].dat; o_sub_fe6_if.dat[0 +: $bits(FE2_TYPE)] <= sub_if_fe2_i[0].dat;
o_sub_fe6_if.ctl <= sub_if_fe2_i[0].ctl; o_sub_fe6_if.ctl <= sub_if_fe2_i[0].ctl;
end else if (sub_if_fe2_i[0].ctl[OVR_WRT_BIT +: 2] == 1 && sub_if_fe2_i[0].val) begin end else if (sub_if_fe2_i[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] == 1 && sub_if_fe2_i[0].val) begin
o_sub_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= sub_if_fe2_i[0].dat; o_sub_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= sub_if_fe2_i[0].dat;
end else if (sub_if_fe2_i[0].ctl[OVR_WRT_BIT +: 2] == 2 && sub_if_fe2_i[0].val) begin end else if (sub_if_fe2_i[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] == 2 && sub_if_fe2_i[0].val) begin
o_sub_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= sub_if_fe2_i[0].dat; o_sub_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= sub_if_fe2_i[0].dat;
o_sub_fe6_if.val <= 1; o_sub_fe6_if.val <= 1;
end end
end end
o_sub_fe6_if.ctl[OVR_WRT_BIT +: 2] <= 0; o_sub_fe6_if.ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= 0;
end end
end end
// Multiplications are calculated using the formula in bls12_381.pkg::fe6_mul() // Multiplications are calculated using the formula in bls12_381.pkg::fe6_mul()
FE2_TYPE a_a, b_b, c_c, t;
logic [3:0] mul_cnt, add_mul_cnt, sub_mul_cnt, mnr_cnt; logic [22:0] eq_val, eq_wait;
logic [2:0] mul_val; logic rdy_l;
FE2_TYPE a_a, b_b, c_c;
always_comb begin
case(i_mul_fe2_if.ctl[OVR_WRT_BIT +: 4]) inside
0, 1, 2: i_mul_fe2_if.rdy = 1;
3: i_mul_fe2_if.rdy = sub_mul_cnt == 0 && (~sub_if_fe2_o[1].val || (sub_if_fe2_o[1].val && sub_if_fe2_o[1].rdy));
4: i_mul_fe2_if.rdy = sub_mul_cnt == 2 && (~sub_if_fe2_o[1].val || (sub_if_fe2_o[1].val && sub_if_fe2_o[1].rdy));
5: i_mul_fe2_if.rdy = sub_mul_cnt == 3 && (~sub_if_fe2_o[1].val || (sub_if_fe2_o[1].val && sub_if_fe2_o[1].rdy));
default: i_mul_fe2_if.rdy = 0;
endcase
case(add_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4]) inside
0: add_if_fe2_i[1].rdy = mul_cnt == 3 && (~o_mul_fe2_if.val || (o_mul_fe2_if.val && o_mul_fe2_if.rdy));
1: add_if_fe2_i[1].rdy = mul_cnt == 3 && (~o_mul_fe2_if.val || (o_mul_fe2_if.val && o_mul_fe2_if.rdy));
2: add_if_fe2_i[1].rdy = mul_cnt == 4 && (~o_mul_fe2_if.val || (o_mul_fe2_if.val && o_mul_fe2_if.rdy));
3: add_if_fe2_i[1].rdy = mul_cnt == 4 && (~o_mul_fe2_if.val || (o_mul_fe2_if.val && o_mul_fe2_if.rdy));
4: add_if_fe2_i[1].rdy = mul_cnt == 5 && (~o_mul_fe2_if.val || (o_mul_fe2_if.val && o_mul_fe2_if.rdy));
5: add_if_fe2_i[1].rdy = mul_cnt == 5 && (~o_mul_fe2_if.val || (o_mul_fe2_if.val && o_mul_fe2_if.rdy));
6: add_if_fe2_i[1].rdy = sub_mul_cnt == 5 && (~sub_if_fe2_o[1].val || (sub_if_fe2_o[1].val && sub_if_fe2_o[1].rdy));
7, 8: add_if_fe2_i[1].rdy = ~o_mul_fe6_if.val || (o_mul_fe6_if.val && o_mul_fe6_if.rdy);
default: add_if_fe2_i[1].rdy = 0;
endcase
case(sub_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4]) inside
0: sub_if_fe2_i[1].rdy = sub_mul_cnt == 1 && (~sub_if_fe2_o[1].val || (sub_if_fe2_o[1].val && sub_if_fe2_o[1].rdy));
1: sub_if_fe2_i[1].rdy = mnr_cnt == 0 && (~o_mnr_fe2_if.val || (o_mnr_fe2_if.val && o_mnr_fe2_if.rdy));
2: sub_if_fe2_i[1].rdy = add_mul_cnt == 6 && (~add_if_fe2_o[1].val || (add_if_fe2_o[1].val && add_if_fe2_o[1].rdy));
3: sub_if_fe2_i[1].rdy = sub_mul_cnt == 4 && (~sub_if_fe2_o[1].val || (sub_if_fe2_o[1].val && sub_if_fe2_o[1].rdy));
4: sub_if_fe2_i[1].rdy = add_mul_cnt == 8 && i_mnr_fe2_if.val && i_mnr_fe2_if.ctl[OVR_WRT_BIT +: 4] == 1 && (~add_if_fe2_o[1].val || (add_if_fe2_o[1].val && add_if_fe2_o[1].rdy));
5: sub_if_fe2_i[1].rdy = ~mul_val[2];
default: sub_if_fe2_i[1].rdy = 0;
endcase
case(i_mnr_fe2_if.ctl[OVR_WRT_BIT +: 4]) inside
0: i_mnr_fe2_if.rdy = add_mul_cnt == 7 && (~add_if_fe2_o[1].val || (add_if_fe2_o[1].val && add_if_fe2_o[1].rdy));
1: i_mnr_fe2_if.rdy = add_mul_cnt == 8 && sub_if_fe2_i[1].val && sub_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 4 && (~add_if_fe2_o[1].val || (add_if_fe2_o[1].val && add_if_fe2_o[1].rdy));
default: i_mnr_fe2_if.rdy = 0;
endcase
o_mul_fe6_if.val <= &mul_val;
end
logic output_done;
always_ff @ (posedge i_clk) begin always_ff @ (posedge i_clk) begin
if (i_rst) begin if (i_rst) begin
o_mul_fe6_if.ctl <= 0; o_mul_fe6_if.copy_if(0, 0, 1, 1, 0, 0, 0);
o_mul_fe6_if.mod <= 0;
o_mul_fe6_if.err <= 0;
o_mul_fe6_if.sop <= 1;
o_mul_fe6_if.eop <= 1;
o_mul_fe6_if.dat <= 0;
o_mnr_fe2_if.copy_if(0, 0, 1, 1, 0, 0, 0); o_mnr_fe2_if.copy_if(0, 0, 1, 1, 0, 0, 0);
mul_cnt <= 0;
add_mul_cnt <= 0;
sub_mul_cnt <= 0;
mnr_cnt <= 0;
o_mul_fe2_if.copy_if(0, 0, 1, 1, 0, 0, 0); o_mul_fe2_if.copy_if(0, 0, 1, 1, 0, 0, 0);
sub_if_fe2_o[1].copy_if(0, 0, 1, 1, 0, 0, 0); sub_if_fe2_o[1].copy_if(0, 0, 1, 1, 0, 0, 0);
add_if_fe2_o[1].copy_if(0, 0, 1, 1, 0, 0, 0); add_if_fe2_o[1].copy_if(0, 0, 1, 1, 0, 0, 0);
i_mul_fe6_if.rdy <= 0;
i_mul_fe2_if.rdy <= 0;
sub_if_fe2_i[1].rdy <= 0;
add_if_fe2_i[1].rdy <= 0;
i_mnr_fe2_if.rdy <= 0;
eq_val <= 0;
eq_wait <= 0;
rdy_l <= 0;
a_a <= 0; a_a <= 0;
b_b <= 0; b_b <= 0;
c_c <= 0; c_c <= 0;
i_mul_fe6_if.rdy <= 0; t <= 0;
mul_val <= 0;
output_done <= 1;
end else begin end else begin
i_mul_fe2_if.rdy <= 1;
sub_if_fe2_i[1].rdy <= 1;
add_if_fe2_i[1].rdy <= 1;
i_mnr_fe2_if.rdy <= 1;
i_mul_fe6_if.rdy <= 0; i_mul_fe6_if.rdy <= 0;
if (o_mul_fe6_if.rdy) o_mul_fe6_if.val <= 0;
if (o_mul_fe2_if.rdy) o_mul_fe2_if.val <= 0;
if (sub_if_fe2_o[1].rdy) sub_if_fe2_o[1].val <= 0;
if (add_if_fe2_o[1].rdy) add_if_fe2_o[1].val <= 0;
if (o_mnr_fe2_if.rdy) o_mnr_fe2_if.val <= 0;
if (eq_val[22] && eq_val[20] && eq_val[19])
o_mul_fe6_if.val <= 1;
if (o_mul_fe6_if.val && o_mul_fe6_if.rdy) begin if (o_mul_fe6_if.val && o_mul_fe6_if.rdy) begin
mul_val <= 0; eq_val <= 0;
output_done <= 1; eq_wait <= 0;
end rdy_l <= 0;
if (o_mul_fe2_if.val && o_mul_fe2_if.rdy) o_mul_fe2_if.val <= 0; a_a <= 0;
if (sub_if_fe2_o[1].val && sub_if_fe2_o[1].rdy) sub_if_fe2_o[1].val <= 0; b_b <= 0;
if (add_if_fe2_o[1].val && add_if_fe2_o[1].rdy) add_if_fe2_o[1].val <= 0; c_c <= 0;
if (o_mnr_fe2_if.val && o_mnr_fe2_if.rdy) o_mnr_fe2_if.val <= 0; t <= 0;
o_mul_fe6_if.val <= 0;
// Multiplications
if (~o_mul_fe2_if.val || (o_mul_fe2_if.val && o_mul_fe2_if.rdy)) begin
case(mul_cnt)
0: begin
o_mul_fe2_if.copy_if({i_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)],
i_mul_fe6_if.dat[$bits(FE6_TYPE) +: $bits(FE2_TYPE)]},
i_mul_fe6_if.val && output_done, 1, 1, i_mul_fe6_if.err, i_mul_fe6_if.mod, i_mul_fe6_if.ctl);
if (i_mul_fe6_if.val && output_done) mul_cnt <= mul_cnt + 1;
end
1: begin
o_mul_fe2_if.copy_if({i_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)],
i_mul_fe6_if.dat[$bits(FE6_TYPE) + $bits(FE2_TYPE) +: $bits(FE2_TYPE)]},
1, 1, 1, i_mul_fe6_if.err, i_mul_fe6_if.mod, i_mul_fe6_if.ctl);
mul_cnt <= mul_cnt + 1;
end
2: begin
o_mul_fe2_if.copy_if({i_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)],
i_mul_fe6_if.dat[$bits(FE6_TYPE) + 2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]},
1, 1, 1, i_mul_fe6_if.err, i_mul_fe6_if.mod, i_mul_fe6_if.ctl);
mul_cnt <= mul_cnt + 1;
end
3: begin
if (add_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 0 && add_if_fe2_i[1].val)
o_mul_fe2_if.dat[0 +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat;
if (add_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 1 && add_if_fe2_i[1].val) begin
o_mul_fe2_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat;
o_mul_fe2_if.val <= 1;
mul_cnt <= mul_cnt + 1;
end
end
4: begin
if (add_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 2 && add_if_fe2_i[1].val)
o_mul_fe2_if.dat[0 +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat;
if (add_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 3 && add_if_fe2_i[1].val) begin
o_mul_fe2_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat;
o_mul_fe2_if.val <= 1;
mul_cnt <= mul_cnt + 1;
end
end
5: begin
if (add_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 4 && add_if_fe2_i[1].val)
o_mul_fe2_if.dat[0 +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat;
if (add_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 5 && add_if_fe2_i[1].val) begin
o_mul_fe2_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat;
o_mul_fe2_if.val <= 1;
mul_cnt <= 0;
end
end
endcase
o_mul_fe2_if.ctl[OVR_WRT_BIT +: 4] <= mul_cnt;
end
// Additions
if (~add_if_fe2_o[1].val || (add_if_fe2_o[1].val && add_if_fe2_o[1].rdy)) begin
case (add_mul_cnt)
0: begin
add_if_fe2_o[1].copy_if({i_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)],
i_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]},
i_mul_fe6_if.val && output_done, 1, 1, i_mul_fe6_if.err, i_mul_fe6_if.mod, i_mul_fe6_if.ctl);
if (i_mul_fe6_if.val && output_done) add_mul_cnt <= add_mul_cnt + 1;
end
1: begin
add_if_fe2_o[1].copy_if({i_mul_fe6_if.dat[$bits(FE6_TYPE) + $bits(FE2_TYPE) +: $bits(FE2_TYPE)],
i_mul_fe6_if.dat[$bits(FE6_TYPE) + 2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]},
1, 1, 1, i_mul_fe6_if.err, i_mul_fe6_if.mod, i_mul_fe6_if.ctl);
add_mul_cnt <= add_mul_cnt + 1;
end
2: begin
add_if_fe2_o[1].copy_if({i_mul_fe6_if.dat[$bits(FE6_TYPE) +: $bits(FE2_TYPE)],
i_mul_fe6_if.dat[$bits(FE6_TYPE) + 2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]},
1, 1, 1, i_mul_fe6_if.err, i_mul_fe6_if.mod, i_mul_fe6_if.ctl);
add_mul_cnt <= add_mul_cnt + 1;
end
3: begin
add_if_fe2_o[1].copy_if({i_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)],
i_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]},
1, 1, 1, i_mul_fe6_if.err, i_mul_fe6_if.mod, i_mul_fe6_if.ctl);
add_mul_cnt <= add_mul_cnt + 1;
end
4: begin
add_if_fe2_o[1].copy_if({i_mul_fe6_if.dat[$bits(FE6_TYPE) +: $bits(FE2_TYPE)],
i_mul_fe6_if.dat[$bits(FE6_TYPE) + $bits(FE2_TYPE) +: $bits(FE2_TYPE)]},
1, 1, 1, i_mul_fe6_if.err, i_mul_fe6_if.mod, i_mul_fe6_if.ctl);
add_mul_cnt <= add_mul_cnt + 1;
end
5: begin
add_if_fe2_o[1].copy_if({i_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)],
i_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)]},
1, 1, 1, i_mul_fe6_if.err, i_mul_fe6_if.mod, i_mul_fe6_if.ctl);
add_mul_cnt <= add_mul_cnt + 1;
i_mul_fe6_if.rdy <= 1; // Release input here
output_done <= 0;
end
6: begin
add_if_fe2_o[1].dat[0 +: $bits(FE2_TYPE)] <= b_b;
if (sub_if_fe2_i[1].val) begin
add_if_fe2_o[1].dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= sub_if_fe2_i[1].dat;
add_if_fe2_o[1].ctl <= sub_if_fe2_i[1].ctl;
end
if (sub_if_fe2_i[1].val && sub_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 2) begin
add_mul_cnt <= add_mul_cnt + 1;
add_if_fe2_o[1].val <= 1;
end
end
7: begin
add_if_fe2_o[1].dat[0 +: $bits(FE2_TYPE)] <= a_a;
if (i_mnr_fe2_if.val) begin
add_if_fe2_o[1].dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= i_mnr_fe2_if.dat;
add_if_fe2_o[1].ctl <= i_mnr_fe2_if.ctl;
end
if (i_mnr_fe2_if.val && i_mnr_fe2_if.ctl[OVR_WRT_BIT +: 4] == 0) begin
add_mul_cnt <= add_mul_cnt + 1;
add_if_fe2_o[1].val <= 1;
end
end
8: begin
if (sub_if_fe2_i[1].val && sub_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 4 &&
i_mnr_fe2_if.val && i_mnr_fe2_if.ctl[OVR_WRT_BIT +: 4] == 1) begin
add_if_fe2_o[1].dat[0 +: $bits(FE2_TYPE)] <= sub_if_fe2_i[1].dat;
add_if_fe2_o[1].ctl <= sub_if_fe2_i[1].ctl;
add_if_fe2_o[1].dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= i_mnr_fe2_if.dat;
add_mul_cnt <= 0;
add_if_fe2_o[1].val <= 1;
end
end
endcase
add_if_fe2_o[1].ctl[OVR_WRT_BIT +: 4] <= add_mul_cnt;
end end
// Subtractions if (eq_wait[0] && eq_wait[1] && eq_wait[2] && eq_wait[13] && eq_wait[14] && ~rdy_l) begin
if (~sub_if_fe2_o[1].val || (sub_if_fe2_o[1].val && sub_if_fe2_o[1].rdy)) begin i_mul_fe6_if.rdy <= 1;
case (sub_mul_cnt) o_mul_fe6_if.ctl <= i_mul_fe6_if.ctl;
0: begin rdy_l <= 1;
if (i_mul_fe2_if.ctl[OVR_WRT_BIT +: 4] == 3) begin
sub_if_fe2_o[1].dat <= {b_b, i_mul_fe2_if.dat};
sub_if_fe2_o[1].val <= i_mul_fe2_if.val;
sub_if_fe2_o[1].ctl <= i_mul_fe2_if.ctl;
if (i_mul_fe2_if.val) sub_mul_cnt <= sub_mul_cnt + 1;
end
end
1: begin
if (sub_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 0) begin
sub_if_fe2_o[1].dat <= {c_c, sub_if_fe2_i[1].dat};
sub_if_fe2_o[1].val <= sub_if_fe2_i[1].val;
sub_if_fe2_o[1].ctl <= sub_if_fe2_i[1].ctl;
if (sub_if_fe2_i[1].val) sub_mul_cnt <= sub_mul_cnt + 1;
end
end
2: begin
if (i_mul_fe2_if.ctl[OVR_WRT_BIT +: 4] == 4) begin
sub_if_fe2_o[1].dat <= {a_a, i_mul_fe2_if.dat};
sub_if_fe2_o[1].val <= i_mul_fe2_if.val;
sub_if_fe2_o[1].ctl <= i_mul_fe2_if.ctl;
if (i_mul_fe2_if.val) sub_mul_cnt <= sub_mul_cnt + 1;
end
end
3: begin
if (i_mul_fe2_if.ctl[OVR_WRT_BIT +: 4] == 5) begin
sub_if_fe2_o[1].dat <= {a_a, i_mul_fe2_if.dat};
sub_if_fe2_o[1].val <= i_mul_fe2_if.val;
sub_if_fe2_o[1].ctl <= i_mul_fe2_if.ctl;
if (i_mul_fe2_if.val) sub_mul_cnt <= sub_mul_cnt + 1;
end
end
4: begin
if (sub_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 3) begin
sub_if_fe2_o[1].dat <= {b_b, sub_if_fe2_i[1].dat};
sub_if_fe2_o[1].val <= sub_if_fe2_i[1].val;
sub_if_fe2_o[1].ctl <= sub_if_fe2_i[1].ctl;
if (sub_if_fe2_i[1].val) sub_mul_cnt <= sub_mul_cnt + 1;
end
end
5: begin
if (add_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 6) begin
sub_if_fe2_o[1].dat <= {c_c, add_if_fe2_i[1].dat};
sub_if_fe2_o[1].val <= add_if_fe2_i[1].val;
sub_if_fe2_o[1].ctl <= add_if_fe2_i[1].ctl;
if (add_if_fe2_i[1].val) sub_mul_cnt <= 0;
end
end
endcase
sub_if_fe2_o[1].ctl[OVR_WRT_BIT +: 4] <= sub_mul_cnt;
end end
// Non-residue // Check any results from multiplier
if (~o_mnr_fe2_if.val || (o_mnr_fe2_if.val && o_mnr_fe2_if.rdy)) begin
case(mnr_cnt)
0: begin
if (sub_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 1 && sub_if_fe2_i[1].val) begin
o_mnr_fe2_if.dat <= sub_if_fe2_i[1].dat;
o_mnr_fe2_if.val <= sub_if_fe2_i[1].val;
o_mnr_fe2_if.ctl <= 0;
o_mnr_fe2_if.ctl[OVR_WRT_BIT +: 4] <= mnr_cnt;
mnr_cnt <= mnr_cnt + 1;
end
end
1: begin
o_mnr_fe2_if.dat <= c_c;
o_mnr_fe2_if.val <= 1;
o_mnr_fe2_if.ctl <= 0;
o_mnr_fe2_if.ctl[OVR_WRT_BIT +: 4] <= mnr_cnt;
mnr_cnt <= 0;
end
endcase
end
// Take results from multiplications to save a_a, b_b, c_c
if (i_mul_fe2_if.val && i_mul_fe2_if.rdy) begin if (i_mul_fe2_if.val && i_mul_fe2_if.rdy) begin
case (i_mul_fe2_if.ctl[OVR_WRT_BIT +: 4]) eq_val[i_mul_fe2_if.ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT]] <= 1;
0: a_a <= i_mul_fe2_if.dat; case(i_mul_fe2_if.ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT]) inside
1: b_b <= i_mul_fe2_if.dat; 0: a_a <= i_mul_fe2_if.dat;
2: c_c <= i_mul_fe2_if.dat; 1: b_b <= i_mul_fe2_if.dat;
2: c_c <= i_mul_fe2_if.dat;
5: o_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)] <= i_mul_fe2_if.dat;
10: o_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= i_mul_fe2_if.dat;
15: o_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= i_mul_fe2_if.dat;
default: o_mul_fe6_if.err <= 1;
endcase endcase
end end
// Final output valid // Check any results from mnr
if (sub_if_fe2_i[1].val && sub_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 5 && ~mul_val[2]) begin if (i_mnr_fe2_if.val && i_mnr_fe2_if.rdy) begin
o_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= sub_if_fe2_i[1].dat; eq_val[i_mnr_fe2_if.ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT]] <= 1;
o_mul_fe6_if.ctl <= sub_if_fe2_i[1].ctl; case(i_mnr_fe2_if.ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT]) inside
mul_val[2] <= 1; 18: o_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)] <= i_mnr_fe2_if.dat;
21: c_c <= i_mnr_fe2_if.dat;
default: o_mul_fe6_if.err <= 1;
endcase
end end
if (add_if_fe2_i[1].val && add_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 8 && ~mul_val[1]) begin
o_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat; // Check any results from sub
o_mul_fe6_if.ctl <= add_if_fe2_i[1].ctl; if (sub_if_fe2_i[1].val && sub_if_fe2_i[1].rdy) begin
mul_val[1] <= 1; eq_val[sub_if_fe2_i[1].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT]] <= 1;
case(sub_if_fe2_i[1].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT]) inside
6: o_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)] <= sub_if_fe2_i[1].dat;
7: o_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)] <= sub_if_fe2_i[1].dat;
11: o_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= sub_if_fe2_i[1].dat;
16: o_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= sub_if_fe2_i[1].dat;
17: o_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= sub_if_fe2_i[1].dat;
20: o_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= sub_if_fe2_i[1].dat;
default: o_mul_fe6_if.err <= 1;
endcase
end end
if (add_if_fe2_i[1].val && add_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 7 && ~mul_val[0]) begin
o_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat; // Check any results from add
o_mul_fe6_if.ctl <= add_if_fe2_i[1].ctl; if (add_if_fe2_i[1].val && add_if_fe2_i[1].rdy) begin
mul_val[0] <= 1; eq_val[add_if_fe2_i[1].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT]] <= 1;
case(add_if_fe2_i[1].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT]) inside
3: o_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat;
4: t <= add_if_fe2_i[1].dat;
8: o_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat;
9: t <= add_if_fe2_i[1].dat;
12: o_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat;
13: o_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat;
14: t <= add_if_fe2_i[1].dat;
19: o_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat;
22: begin
o_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat;
end
default: o_mul_fe6_if.err <= 1;
endcase
end
// Issue new multiplies
if (~eq_wait[0] && i_mul_fe6_if.val) begin // 0. a_a = fe2_mul(a[0], b[0])
fe2_multiply(0, i_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)],
i_mul_fe6_if.dat[$bits(FE6_TYPE) +: $bits(FE2_TYPE)]);
end else
if (~eq_wait[1] && i_mul_fe6_if.val) begin // 1. b_b = fe2_mul(a[1], b[1])
fe2_multiply(1, i_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)],
i_mul_fe6_if.dat[$bits(FE6_TYPE) + $bits(FE2_TYPE) +: $bits(FE2_TYPE)]);
end else
if (~eq_wait[2] && i_mul_fe6_if.val) begin // 2. c_c = fe2_mul(a[2], b[2])
fe2_multiply(2, i_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)],
i_mul_fe6_if.dat[$bits(FE6_TYPE) + 2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]);
end else
if (~eq_wait[5] && eq_val[3] && eq_val[4]) begin // 5. fe6_mul[0] = fe2_mul(fe6_mul[0], t) [3, 4]
fe2_multiply(5, o_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)], t);
end else
if (~eq_wait[10] && eq_val[8] && eq_val[9]) begin // 10. fe6_mul[2] = fe2_mul(fe6_mul[2], t) [8, 9]
fe2_multiply(10, o_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)], t);
end else
if (~eq_wait[15] && eq_val[13] && eq_val[14]) begin // 15. fe6_mul[1] = fe2_mul(fe6_mul[1], t) [13, 14]
fe2_multiply(15, o_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)], t);
end
// Issue new adds
if (~eq_wait[3] && i_mul_fe6_if.val) begin // 3. fe6_mul[0] = fe2_add(a[1], a[2])
fe2_addition(3, i_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)],
i_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]);
end else
if (~eq_wait[4] && i_mul_fe6_if.val) begin // 4. t = fe2_add(b[1], b[2])
fe2_addition(4, i_mul_fe6_if.dat[$bits(FE6_TYPE) + $bits(FE2_TYPE) +: $bits(FE2_TYPE)],
i_mul_fe6_if.dat[$bits(FE6_TYPE) + 2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]);
end else
if (~eq_wait[8] && i_mul_fe6_if.val) begin // 8. fe6_mul[2] = fe2_add(b[0], b[2])
fe2_addition(8, i_mul_fe6_if.dat[$bits(FE6_TYPE) +: $bits(FE2_TYPE)],
i_mul_fe6_if.dat[$bits(FE6_TYPE) + 2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]);
end else
if (~eq_wait[9] && eq_wait[5] && i_mul_fe6_if.val) begin // 9. t = fe2_add(a[0], a[2]) [wait 5]
fe2_addition(9, i_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)],
i_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]);
end else
if (~eq_wait[12] && eq_val[11] && eq_val[1]) begin // 12. fe6_mul[2] = fe2_add(fe6_mul[2], b_b) [11, 1]
fe2_addition(12, o_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)], b_b);
end else
if (~eq_wait[13] && i_mul_fe6_if.val) begin // 13. fe6_mul[1] = fe2_add(b[0], b[1])
fe2_addition(13, i_mul_fe6_if.dat[$bits(FE6_TYPE) +: $bits(FE2_TYPE)],
i_mul_fe6_if.dat[$bits(FE6_TYPE) + $bits(FE2_TYPE) +: $bits(FE2_TYPE)]);
end else
if (~eq_wait[14] && eq_wait[10] && i_mul_fe6_if.val) begin // 14. t = fe2_add(a[0], a[1]) [wait 10]
fe2_addition(14, i_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)],
i_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)]);
end else
if (~eq_wait[19] && eq_val[18] && eq_val[0]) begin // 19. fe6_mul[0] = fe2_add(fe6_mul[0], a_a) [18, 0]
fe2_addition(19, o_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)], a_a);
end else
if (~eq_wait[22] && eq_val[17] && eq_val[21]) begin // 22. fe6_mul[1] = fe2_add(c_c, fe6_mul[1]) [17, 21]
fe2_addition(22, o_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)], c_c);
end
// Issue new sub
if (~eq_wait[6] && eq_val[5] && eq_val[1]) begin // 6. fe6_mul[0] = fe2_sub(fe6_mul[0], b_b) [5, 1]
fe2_subtraction(6, o_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)], b_b);
end else
if (~eq_wait[7] && eq_val[6] && eq_val[2]) begin // 7. fe6_mul[0] = fe2_sub(fe6_mul[0], c_c) [6, 2]
fe2_subtraction(7, o_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)], c_c);
end else
if (~eq_wait[11] && eq_val[10] && eq_val[0]) begin // 11. fe6_mul[2] = fe2_sub(fe6_mul[2], a_a) [10, 0]
fe2_subtraction(11, o_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)], a_a);
end else
if (~eq_wait[16] && eq_val[15] && eq_val[0]) begin // 16. fe6_mul[1] = fe2_sub(fe6_mul[1], a_a) [15, 0]
fe2_subtraction(16, o_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)], a_a);
end else
if (~eq_wait[17] && eq_val[16] && eq_val[1]) begin // 17. fe6_mul[1] = fe2_sub(fe6_mul[1], b_b) [16, 1]
fe2_subtraction(17, o_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)], b_b);
end else
if (~eq_wait[20] && eq_val[12] && eq_val[2]) begin // 20. fe6_mul[2] = fe2_sub(fe6_mul[2], c_c) [12, 2]
fe2_subtraction(20, o_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)], c_c);
end
// Issue new mnr
if (~eq_wait[18] && eq_val[7]) begin // 18. fe6_mul[0] = fe2_mul_by_nonresidue(fe6_mul[0]) [7]
fe2_mnr(18, o_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)]);
end else
if (~eq_wait[21] && eq_wait[20]) begin // 21. c_c = fe2_mul_by_nonresidue(c_c) [20]
fe2_mnr(21, c_c);
end end
o_mul_fe6_if.ctl[OVR_WRT_BIT +: 4] <= 0;
end end
end end
@ -515,7 +400,7 @@ resource_share # (
.NUM_IN ( 2 ), .NUM_IN ( 2 ),
.DAT_BITS ( 2*$bits(FE2_TYPE) ), .DAT_BITS ( 2*$bits(FE2_TYPE) ),
.CTL_BITS ( CTL_BITS ), .CTL_BITS ( CTL_BITS ),
.OVR_WRT_BIT ( OVR_WRT_BIT+4 ), .OVR_WRT_BIT ( OVR_WRT_BIT+NUM_OVR_WRT_BIT ),
.PIPELINE_IN ( 0 ), .PIPELINE_IN ( 0 ),
.PIPELINE_OUT ( 0 ) .PIPELINE_OUT ( 0 )
) )
@ -532,7 +417,7 @@ resource_share # (
.NUM_IN ( 2 ), .NUM_IN ( 2 ),
.DAT_BITS ( 2*$bits(FE2_TYPE) ), .DAT_BITS ( 2*$bits(FE2_TYPE) ),
.CTL_BITS ( CTL_BITS ), .CTL_BITS ( CTL_BITS ),
.OVR_WRT_BIT ( OVR_WRT_BIT+4 ), .OVR_WRT_BIT ( OVR_WRT_BIT+NUM_OVR_WRT_BIT ),
.PIPELINE_IN ( 0 ), .PIPELINE_IN ( 0 ),
.PIPELINE_OUT ( 0 ) .PIPELINE_OUT ( 0 )
) )
@ -545,4 +430,50 @@ resource_share_add (
.o_axi ( add_if_fe2_i[1:0] ) .o_axi ( add_if_fe2_i[1:0] )
); );
// Task for subtractions
task fe2_subtraction(input int unsigned ctl, input FE2_TYPE a, b);
if (~sub_if_fe2_o[1].val || (sub_if_fe2_o[1].val && sub_if_fe2_o[1].rdy)) begin
sub_if_fe2_o[1].val <= 1;
sub_if_fe2_o[1].dat[0 +: $bits(FE2_TYPE)] <= a;
sub_if_fe2_o[1].dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= b;
sub_if_fe2_o[1].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= ctl;
eq_wait[ctl] <= 1;
end
endtask
// Task for addition
task fe2_addition(input int unsigned ctl, input FE2_TYPE a, b);
if (~add_if_fe2_o[1].val || (add_if_fe2_o[1].val && add_if_fe2_o[1].rdy)) begin
add_if_fe2_o[1].val <= 1;
add_if_fe2_o[1].dat[0 +: $bits(FE2_TYPE)] <= a;
add_if_fe2_o[1].dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= b;
add_if_fe2_o[1].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= ctl;
eq_wait[ctl] <= 1;
end
endtask
// Task for using mult
task fe2_multiply(input int unsigned ctl, input FE2_TYPE a, b, input logic [1:0] en = 2'b11);
if (~o_mul_fe2_if.val || (o_mul_fe2_if.val && o_mul_fe2_if.rdy)) begin
o_mul_fe2_if.val <= 1;
if (en[0])
o_mul_fe2_if.dat[0 +: $bits(FE2_TYPE)] <= a;
if (en[1])
o_mul_fe2_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= b;
o_mul_fe2_if.ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= ctl;
eq_wait[ctl] <= 1;
end
endtask
// Task for using mnr
task fe2_mnr(input int unsigned ctl, input FE2_TYPE a, input logic en = 1'b1);
if (~o_mnr_fe2_if.val || (o_mnr_fe2_if.val && o_mnr_fe2_if.rdy)) begin
o_mnr_fe2_if.val <= 1;
if (en)
o_mnr_fe2_if.dat <= a;
o_mnr_fe2_if.ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= ctl;
eq_wait[ctl] <= 1;
end
endtask
endmodule endmodule

View File

@ -417,32 +417,38 @@ package bls12_381_pkg;
endfunction endfunction
function fe6_t fe6_mul(fe6_t a, b); function fe6_t fe6_mul(fe6_t a, b);
fe2_t a_a, b_b, c_c; fe2_t a_a, b_b, c_c, t;
a_a = fe2_mul(a[0], b[0]); a_a = fe2_mul(a[0], b[0]); // 0. a_a = fe2_mul(a[0], b[0])
b_b = fe2_mul(a[1], b[1]); b_b = fe2_mul(a[1], b[1]); // 1. b_b = fe2_mul(a[1], b[1])
c_c = fe2_mul(a[2], b[2]); c_c = fe2_mul(a[2], b[2]); // 2. c_c = fe2_mul(a[2], b[2])
fe6_mul[0] = fe2_mul(fe2_add(a[1], a[2]), fe2_add(b[1], b[2])); fe6_mul[0] = fe2_add(a[1], a[2]); // 3. fe6_mul[0] = fe2_add(a[1], a[2])
fe6_mul[2] = fe2_mul(fe2_add(b[0], b[2]), fe2_add(a[0], a[2])); t = fe2_add(b[1], b[2]); // 4. t = fe2_add(b[1], b[2])
fe6_mul[1] = fe2_mul(fe2_add(b[0], b[1]), fe2_add(a[0], a[1])); fe6_mul[0] = fe2_mul(fe6_mul[0], t); // 5. fe6_mul[0] = fe2_mul(fe6_mul[0], t) [3, 4]
fe6_mul[0] = fe2_sub(fe6_mul[0], b_b); // 6. fe6_mul[0] = fe2_sub(fe6_mul[0], b_b) [5, 1]
fe6_mul[0] = fe2_sub(fe6_mul[0], c_c); // 7. fe6_mul[0] = fe2_sub(fe6_mul[0], c_c) [6, 2]
fe6_mul[0] = fe2_sub(fe6_mul[0], b_b); fe6_mul[2] = fe2_add(b[0], b[2]); // 8. fe6_mul[2] = fe2_add(b[0], b[2])
fe6_mul[0] = fe2_sub(fe6_mul[0], c_c); t = fe2_add(a[0], a[2]); // 9. t = fe2_add(a[0], a[2]) [wait 5]
fe6_mul[2] = fe2_mul(fe6_mul[2], t); // 10. fe6_mul[2] = fe2_mul(fe6_mul[2], t) [8, 9]
fe6_mul[2] = fe2_sub(fe6_mul[2], a_a); // 11. fe6_mul[2] = fe2_sub(fe6_mul[2], a_a) [10, 0]
fe6_mul[2] = fe2_add(fe6_mul[2], b_b); // 12. fe6_mul[2] = fe2_add(fe6_mul[2], b_b) [11, 1]
fe6_mul[2] = fe2_sub(fe6_mul[2], a_a); fe6_mul[1] = fe2_add(b[0], b[1]); // 13. fe6_mul[1] = fe2_add(b[0], b[1])
fe6_mul[2] = fe2_add(fe6_mul[2], b_b); t = fe2_add(a[0], a[1]); // 14. t = fe2_add(a[0], a[1]) [wait 10] - can release input here
fe6_mul[1] = fe2_mul(fe6_mul[1], t); // 15. fe6_mul[1] = fe2_mul(fe6_mul[1], t) [13, 14]
fe6_mul[1] = fe2_sub(fe6_mul[1], a_a); // 16. fe6_mul[1] = fe2_sub(fe6_mul[1], a_a) [15, 0]
fe6_mul[1] = fe2_sub(fe6_mul[1], b_b); // 17. fe6_mul[1] = fe2_sub(fe6_mul[1], b_b) [16, 1]
fe6_mul[1] = fe2_sub(fe6_mul[1], a_a); fe6_mul[0] = fe2_mul_by_nonresidue(fe6_mul[0]); // 18. fe6_mul[0] = fe2_mul_by_nonresidue(fe6_mul[0]) [7]
fe6_mul[1] = fe2_sub(fe6_mul[1], b_b); fe6_mul[0] = fe2_add(fe6_mul[0], a_a); // 19. fe6_mul[0] = fe2_add(fe6_mul[0], a_a) [18, 0]
fe6_mul[0] = fe2_mul_by_nonresidue(fe6_mul[0]); fe6_mul[2] = fe2_sub(fe6_mul[2], c_c); // 20. fe6_mul[2] = fe2_sub(fe6_mul[2], c_c) [12, 2]
fe6_mul[2] = fe2_sub(fe6_mul[2], c_c); c_c = fe2_mul_by_nonresidue(c_c); // 21. c_c = fe2_mul_by_nonresidue(c_c) [20]
c_c = fe2_mul_by_nonresidue(c_c);
fe6_mul[0] = fe2_add(fe6_mul[0], a_a); fe6_mul[1] = fe2_add(c_c, fe6_mul[1]); // 22. fe6_mul[1] = fe2_add(c_c, fe6_mul[1]) [17, 21]
fe6_mul[1] = fe2_add(c_c, fe6_mul[1]);
endfunction endfunction
function fe12_t fe12_add(fe12_t a, b); function fe12_t fe12_add(fe12_t a, b);
for(int i = 0; i < 2; i++) for(int i = 0; i < 2; i++)
fe12_add[i] = fe6_add(a[i], b[i]); fe12_add[i] = fe6_add(a[i], b[i]);
@ -457,14 +463,14 @@ package bls12_381_pkg;
fe6_t aa, bb; fe6_t aa, bb;
aa = fe6_mul(a[0], b[0]); // 0. add_i0 = mul(a[0], b[0]) aa = fe6_mul(a[0], b[0]); // 0. add_i0 = mul(a[0], b[0])
bb = fe6_mul(a[1], b[1]); // 1. bb = mul(a[1], b[1]) bb = fe6_mul(a[1], b[1]); // 1. bb = mul(a[1], b[1])
fe12_mul[1] = fe6_add(a[1], a[0]); // 2. fe6_mul[1] = add(a[1], a[0]) fe12_mul[1] = fe6_add(a[1], a[0]); // 2. fe6_mul[1] = add(a[1], a[0])
fe12_mul[0] = fe6_add(b[0], b[1]); // 3. fe6_mul[0] = add(b[0], b[1]) fe12_mul[0] = fe6_add(b[0], b[1]); // 3. fe6_mul[0] = add(b[0], b[1])
fe12_mul[1] = fe6_mul(fe12_mul[1], fe12_mul[0]); // 4. fe6_mul[1] = mul(fe6_mul[1], fe6_mul[0]) [2, 3] fe12_mul[1] = fe6_mul(fe12_mul[1], fe12_mul[0]); // 4. fe6_mul[1] = mul(fe6_mul[1], fe6_mul[0]) [2, 3]
fe12_mul[1] = fe6_sub(fe12_mul[1], aa); // 5. fe6_mul[1] = sub(fe6_mul[1], add_i0) [4, 0] fe12_mul[1] = fe6_sub(fe12_mul[1], aa); // 5. fe6_mul[1] = sub(fe6_mul[1], add_i0) [4, 0]
fe12_mul[1] = fe6_sub(fe12_mul[1], bb); // 6. fe6_mul[1] = sub(fe6_mul[1], bb) [5, 1] fe12_mul[1] = fe6_sub(fe12_mul[1], bb); // 6. fe6_mul[1] = sub(fe6_mul[1], bb) [5, 1]
bb = fe6_mul_by_nonresidue(bb); // 7. bb = mnr(bb) [6] bb = fe6_mul_by_nonresidue(bb); // 7. bb = mnr(bb) [6]
fe12_mul[0] = fe6_add(bb, aa); // 8. fe6_mul[0] = add(add_i0, bb) [0, 1, 7] fe12_mul[0] = fe6_add(bb, aa); // 8. fe6_mul[0] = add(add_i0, bb) [0, 1, 7]
endfunction endfunction