Bug fix for control bit widths

This commit is contained in:
bsdevlin 2019-07-21 10:12:23 +08:00
parent c25d20a2ce
commit 0b26ad7372
5 changed files with 359 additions and 275 deletions

View File

@ -23,7 +23,8 @@ module ec_fp2_point_add
#(
parameter type FP2_TYPE, // Should have FE2_TYPE elements
parameter type FE_TYPE,
parameter type FE2_TYPE
parameter type FE2_TYPE,
parameter CTL_BITS
)(
input i_clk, i_rst,
input i_fp_mode, // Operate in Fp mode
@ -48,12 +49,12 @@ module ec_fp2_point_add
if_axi_stream.sink i_sub_if
);
if_axi_stream #(.DAT_BITS(2*$bits(FE2_TYPE)), .CTL_BITS(8)) mul_if_fe2_i(i_clk);
if_axi_stream #(.DAT_BITS($bits(FE2_TYPE)), .CTL_BITS(8)) mul_if_fe2_o(i_clk);
if_axi_stream #(.DAT_BITS(2*$bits(FE2_TYPE)), .CTL_BITS(8)) add_if_fe2_i(i_clk);
if_axi_stream #(.DAT_BITS($bits(FE2_TYPE)), .CTL_BITS(8)) add_if_fe2_o(i_clk);
if_axi_stream #(.DAT_BITS(2*$bits(FE2_TYPE)), .CTL_BITS(8)) sub_if_fe2_i(i_clk);
if_axi_stream #(.DAT_BITS($bits(FE2_TYPE)), .CTL_BITS(8)) sub_if_fe2_o(i_clk);
if_axi_stream #(.DAT_BITS(2*$bits(FE2_TYPE)), .CTL_BITS(CTL_BITS)) mul_if_fe2_i(i_clk);
if_axi_stream #(.DAT_BITS($bits(FE2_TYPE)), .CTL_BITS(CTL_BITS)) mul_if_fe2_o(i_clk);
if_axi_stream #(.DAT_BITS(2*$bits(FE2_TYPE)), .CTL_BITS(CTL_BITS)) add_if_fe2_i(i_clk);
if_axi_stream #(.DAT_BITS($bits(FE2_TYPE)), .CTL_BITS(CTL_BITS)) add_if_fe2_o(i_clk);
if_axi_stream #(.DAT_BITS(2*$bits(FE2_TYPE)), .CTL_BITS(CTL_BITS)) sub_if_fe2_i(i_clk);
if_axi_stream #(.DAT_BITS($bits(FE2_TYPE)), .CTL_BITS(CTL_BITS)) sub_if_fe2_o(i_clk);
ec_point_add #(
.FP_TYPE ( FP2_TYPE ),
@ -81,8 +82,10 @@ ec_point_add (
ec_fe2_arithmetic
#(
.FE_TYPE ( FE_TYPE ),
.FE2_TYPE ( FE2_TYPE )
.FE_TYPE ( FE_TYPE ),
.FE2_TYPE ( FE2_TYPE ),
.CTL_BITS ( 16 ),
.OVR_WRT_BIT ( 8 )
)
ec_fe2_arithmetic (
.i_clk ( i_clk ),

View File

@ -23,7 +23,8 @@ module ec_fp2_point_dbl
#(
parameter type FP2_TYPE, // Should have FE2_TYPE elements
parameter type FE_TYPE,
parameter type FE2_TYPE
parameter type FE2_TYPE,
parameter CTL_BITS
)(
input i_clk, i_rst,
input i_fp_mode, // Operate in Fp mode
@ -47,12 +48,12 @@ module ec_fp2_point_dbl
if_axi_stream.sink i_sub_if
);
if_axi_stream #(.DAT_BITS(2*$bits(FE2_TYPE)), .CTL_BITS(8)) mul_if_fe2_i(i_clk);
if_axi_stream #(.DAT_BITS($bits(FE2_TYPE)), .CTL_BITS(8)) mul_if_fe2_o(i_clk);
if_axi_stream #(.DAT_BITS(2*$bits(FE2_TYPE)), .CTL_BITS(8)) add_if_fe2_i(i_clk);
if_axi_stream #(.DAT_BITS($bits(FE2_TYPE)), .CTL_BITS(8)) add_if_fe2_o(i_clk);
if_axi_stream #(.DAT_BITS(2*$bits(FE2_TYPE)), .CTL_BITS(8)) sub_if_fe2_i(i_clk);
if_axi_stream #(.DAT_BITS($bits(FE2_TYPE)), .CTL_BITS(8)) sub_if_fe2_o(i_clk);
if_axi_stream #(.DAT_BITS(2*$bits(FE2_TYPE)), .CTL_BITS(CTL_BITS)) mul_if_fe2_i(i_clk);
if_axi_stream #(.DAT_BITS($bits(FE2_TYPE)), .CTL_BITS(CTL_BITS)) mul_if_fe2_o(i_clk);
if_axi_stream #(.DAT_BITS(2*$bits(FE2_TYPE)), .CTL_BITS(CTL_BITS)) add_if_fe2_i(i_clk);
if_axi_stream #(.DAT_BITS($bits(FE2_TYPE)), .CTL_BITS(CTL_BITS)) add_if_fe2_o(i_clk);
if_axi_stream #(.DAT_BITS(2*$bits(FE2_TYPE)), .CTL_BITS(CTL_BITS)) sub_if_fe2_i(i_clk);
if_axi_stream #(.DAT_BITS($bits(FE2_TYPE)), .CTL_BITS(CTL_BITS)) sub_if_fe2_o(i_clk);
ec_point_dbl #(
.FP_TYPE ( FP2_TYPE ),
@ -79,8 +80,10 @@ ec_point_dbl (
ec_fe2_arithmetic
#(
.FE_TYPE ( FE_TYPE ),
.FE2_TYPE ( FE2_TYPE )
.FE_TYPE ( FE_TYPE ),
.FE2_TYPE ( FE2_TYPE ),
.CTL_BITS ( 16 ),
.OVR_WRT_BIT ( 8 )
)
ec_fe2_arithmetic (
.i_clk ( i_clk ),

View File

@ -1,7 +1,7 @@
/*
This provides the interface to perform
Fp^6 point logic (adding, subtracting, multiplication), over a Fp2 tower.
Fq6 is constructed as Fq2(v) / (v3 - ξ) where ξ = u + 1
Fq6 is constructed as Fq2(v) / (v3 - e) where e = u + 1
TODO: Input control should be added to allow for sparse multiplication.
@ -52,7 +52,6 @@ module ec_fe6_arithmetic
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(2*$bits(FE2_TYPE)), .CTL_BITS(CTL_BITS)) add_if_fe2_o [1:0] (i_clk);
@ -83,7 +82,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)],
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);
add_if_fe2_o[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= add_cnt;
add_if_fe2_o[0].ctl[OVR_WRT_BIT +: 2] <= add_cnt;
if (i_add_fe6_if.val) add_cnt <= 1;
end
end
@ -92,7 +91,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)],
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);
add_if_fe2_o[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= add_cnt;
add_if_fe2_o[0].ctl[OVR_WRT_BIT +: 2] <= add_cnt;
if (i_add_fe6_if.val) add_cnt <= 2;
end
end
@ -101,7 +100,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)],
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);
add_if_fe2_o[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= add_cnt;
add_if_fe2_o[0].ctl[OVR_WRT_BIT +: 2] <= add_cnt;
if (i_add_fe6_if.val) add_cnt <= 0;
end
end
@ -110,11 +109,11 @@ always_ff @ (posedge i_clk) begin
// One process to assign outputs
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[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= 0;
if (add_if_fe2_i[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] == 0) begin
o_add_fe6_if.ctl[OVR_WRT_BIT +: 2] <= 0;
if (add_if_fe2_i[0].ctl[OVR_WRT_BIT +: 2] == 0) begin
if (add_if_fe2_i[0].val)
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 +: NUM_OVR_WRT_BIT] == 1) begin
end else if (add_if_fe2_i[0].ctl[OVR_WRT_BIT +: 2] == 1) begin
if (add_if_fe2_i[0].val)
o_add_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= add_if_fe2_i[0].dat;
end else begin
@ -151,7 +150,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)],
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);
sub_if_fe2_o[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= sub_cnt;
sub_if_fe2_o[0].ctl[OVR_WRT_BIT +: 2] <= sub_cnt;
if (i_sub_fe6_if.val) sub_cnt <= 1;
end
end
@ -160,7 +159,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)],
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);
sub_if_fe2_o[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= sub_cnt;
sub_if_fe2_o[0].ctl[OVR_WRT_BIT +: 2] <= sub_cnt;
if (i_sub_fe6_if.val) sub_cnt <= 2;
end
end
@ -169,7 +168,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)],
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);
sub_if_fe2_o[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= sub_cnt;
sub_if_fe2_o[0].ctl[OVR_WRT_BIT +: 2] <= sub_cnt;
if (i_sub_fe6_if.val) sub_cnt <= 0;
end
end
@ -177,221 +176,337 @@ always_ff @ (posedge i_clk) begin
// One process to assign outputs
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 +: NUM_OVR_WRT_BIT] == 0 && sub_if_fe2_i[0].val) begin
if (sub_if_fe2_i[0].ctl[OVR_WRT_BIT +: 2] == 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.ctl <= sub_if_fe2_i[0].ctl;
end else if (sub_if_fe2_i[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] == 1 && sub_if_fe2_i[0].val) begin
end else if (sub_if_fe2_i[0].ctl[OVR_WRT_BIT +: 2] == 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;
end else if (sub_if_fe2_i[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] == 2 && sub_if_fe2_i[0].val) begin
end else if (sub_if_fe2_i[0].ctl[OVR_WRT_BIT +: 2] == 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.val <= 1;
end
end
o_sub_fe6_if.ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= 0;
o_sub_fe6_if.ctl[OVR_WRT_BIT +: 2] <= 0;
end
end
// Multiplications are calculated using the formula in bls12_381.pkg::fe6_mul()
FE2_TYPE a_a, b_b, c_c, t;
logic [22:0] eq_val, eq_wait;
logic rdy_l;
logic [3:0] mul_cnt, add_mul_cnt, sub_mul_cnt, mnr_cnt;
logic [2:0] mul_val;
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
if (i_rst) begin
o_mul_fe6_if.copy_if(0, 0, 1, 1, 0, 0, 0);
o_mul_fe6_if.ctl <= 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);
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);
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);
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;
b_b <= 0;
c_c <= 0;
t <= 0;
i_mul_fe6_if.rdy <= 0;
mul_val <= 0;
output_done <= 1;
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;
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
eq_val <= 0;
eq_wait <= 0;
rdy_l <= 0;
a_a <= 0;
b_b <= 0;
c_c <= 0;
t <= 0;
o_mul_fe6_if.val <= 0;
mul_val <= 0;
output_done <= 1;
end
if (o_mul_fe2_if.val && o_mul_fe2_if.rdy) o_mul_fe2_if.val <= 0;
if (sub_if_fe2_o[1].val && sub_if_fe2_o[1].rdy) sub_if_fe2_o[1].val <= 0;
if (add_if_fe2_o[1].val && add_if_fe2_o[1].rdy) add_if_fe2_o[1].val <= 0;
if (o_mnr_fe2_if.val && o_mnr_fe2_if.rdy) o_mnr_fe2_if.val <= 0;
if (eq_wait[0] && eq_wait[1] && eq_wait[2] && eq_wait[13] && eq_wait[14] && ~rdy_l) begin
i_mul_fe6_if.rdy <= 1;
o_mul_fe6_if.ctl <= i_mul_fe6_if.ctl;
rdy_l <= 1;
end
// Check any results from multiplier
if (i_mul_fe2_if.val && i_mul_fe2_if.rdy) begin
eq_val[i_mul_fe2_if.ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT]] <= 1;
case(i_mul_fe2_if.ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT]) inside
0: a_a <= 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
end
// Check any results from mnr
if (i_mnr_fe2_if.val && i_mnr_fe2_if.rdy) begin
eq_val[i_mnr_fe2_if.ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT]] <= 1;
case(i_mnr_fe2_if.ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT]) inside
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
// Check any results from sub
if (sub_if_fe2_i[1].val && sub_if_fe2_i[1].rdy) begin
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
// Check any results from add
if (add_if_fe2_i[1].val && add_if_fe2_i[1].rdy) begin
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;
// 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
// Subtractions
if (~sub_if_fe2_o[1].val || (sub_if_fe2_o[1].val && sub_if_fe2_o[1].rdy)) begin
case (sub_mul_cnt)
0: begin
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
// Non-residue
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
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);
// Take results from multiplications to save a_a, b_b, c_c
if (i_mul_fe2_if.val && i_mul_fe2_if.rdy) begin
case (i_mul_fe2_if.ctl[OVR_WRT_BIT +: 4])
0: a_a <= i_mul_fe2_if.dat;
1: b_b <= i_mul_fe2_if.dat;
2: c_c <= i_mul_fe2_if.dat;
endcase
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);
// Final output valid
if (sub_if_fe2_i[1].val && sub_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 5 && ~mul_val[2]) begin
o_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= sub_if_fe2_i[1].dat;
o_mul_fe6_if.ctl <= sub_if_fe2_i[1].ctl;
mul_val[2] <= 1;
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;
o_mul_fe6_if.ctl <= add_if_fe2_i[1].ctl;
mul_val[1] <= 1;
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;
o_mul_fe6_if.ctl <= add_if_fe2_i[1].ctl;
mul_val[0] <= 1;
end
o_mul_fe6_if.ctl[OVR_WRT_BIT +: 4] <= 0;
// 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
end
@ -400,7 +515,7 @@ resource_share # (
.NUM_IN ( 2 ),
.DAT_BITS ( 2*$bits(FE2_TYPE) ),
.CTL_BITS ( CTL_BITS ),
.OVR_WRT_BIT ( OVR_WRT_BIT+NUM_OVR_WRT_BIT ),
.OVR_WRT_BIT ( OVR_WRT_BIT+4 ),
.PIPELINE_IN ( 0 ),
.PIPELINE_OUT ( 0 )
)
@ -417,7 +532,7 @@ resource_share # (
.NUM_IN ( 2 ),
.DAT_BITS ( 2*$bits(FE2_TYPE) ),
.CTL_BITS ( CTL_BITS ),
.OVR_WRT_BIT ( OVR_WRT_BIT+NUM_OVR_WRT_BIT ),
.OVR_WRT_BIT ( OVR_WRT_BIT+4 ),
.PIPELINE_IN ( 0 ),
.PIPELINE_OUT ( 0 )
)
@ -430,50 +545,4 @@ resource_share_add (
.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

View File

@ -27,6 +27,8 @@ package bls12_381_pkg;
fe_t Gx = 381'h17F1D3A73197D7942695638C4FA9AC0FC3688C4F9774B905A14E3A3F171BAC586C55E83FF97A1AEFFB3AF00ADB22C6BB;
fe_t Gy = 381'h08B3F481E3AAA0F1A09E30ED741D8AE4FCF5E095D5D00AF600DB18CB2C04B3EDD03CC744A2888AE40CAA232946C5E7E1;
logic [63:0] ATE_X = 64'hd201000000010000;
typedef enum logic [2:0] {
SCALAR = 0,
FE = 1,

View File

@ -69,13 +69,18 @@ if_axi_stream #(.DAT_BITS($bits(bls12_381_pkg::fp2_jb_point_t))) add_o_if(i_clk)
if_axi_stream #(.DAT_BITS($bits(bls12_381_pkg::fp2_jb_point_t))) dbl_i_if(i_clk);
if_axi_stream #(.DAT_BITS($bits(bls12_381_pkg::fp2_jb_point_t))) dbl_o_if(i_clk);
localparam CTL_BITS = 32;
// Access to shared 381bit multiplier / adder / subtractor
if_axi_stream #(.DAT_BITS(2*$bits(bls12_381_pkg::fe_t)), .CTL_BITS(16)) mul_in_if [4:0] (i_clk) ;
if_axi_stream #(.DAT_BITS($bits(bls12_381_pkg::fe_t)), .CTL_BITS(16)) mul_out_if [4:0](i_clk);
if_axi_stream #(.DAT_BITS(2*$bits(bls12_381_pkg::fe_t)), .CTL_BITS(16)) add_in_if [4:0] (i_clk);
if_axi_stream #(.DAT_BITS($bits(bls12_381_pkg::fe_t)), .CTL_BITS(16)) add_out_if [4:0] (i_clk);
if_axi_stream #(.DAT_BITS(2*$bits(bls12_381_pkg::fe_t)), .CTL_BITS(16)) sub_in_if [4:0] (i_clk);
if_axi_stream #(.DAT_BITS($bits(bls12_381_pkg::fe_t)), .CTL_BITS(16)) sub_out_if [4:0] (i_clk);
// Fp logic uses control bits 7:0
// Fp2 15:8
// Fp6 23:16
// Top level muxes 31:24
if_axi_stream #(.DAT_BITS(2*$bits(bls12_381_pkg::fe_t)), .CTL_BITS(CTL_BITS)) mul_in_if [4:0] (i_clk) ;
if_axi_stream #(.DAT_BITS($bits(bls12_381_pkg::fe_t)), .CTL_BITS(CTL_BITS)) mul_out_if [4:0](i_clk);
if_axi_stream #(.DAT_BITS(2*$bits(bls12_381_pkg::fe_t)), .CTL_BITS(CTL_BITS)) add_in_if [4:0] (i_clk);
if_axi_stream #(.DAT_BITS($bits(bls12_381_pkg::fe_t)), .CTL_BITS(CTL_BITS)) add_out_if [4:0] (i_clk);
if_axi_stream #(.DAT_BITS(2*$bits(bls12_381_pkg::fe_t)), .CTL_BITS(CTL_BITS)) sub_in_if [4:0] (i_clk);
if_axi_stream #(.DAT_BITS($bits(bls12_381_pkg::fe_t)), .CTL_BITS(CTL_BITS)) sub_out_if [4:0] (i_clk);
if_axi_stream #(.DAT_BITS($bits(bls12_381_pkg::fe_t))) binv_i_if(i_clk);
if_axi_stream #(.DAT_BITS($bits(bls12_381_pkg::fe_t))) binv_o_if(i_clk);
@ -279,7 +284,8 @@ ec_point_mult (
ec_fp2_point_add #(
.FP2_TYPE ( bls12_381_pkg::fp2_jb_point_t ),
.FE_TYPE ( bls12_381_pkg::fe_t ),
.FE2_TYPE ( bls12_381_pkg::fe2_t )
.FE2_TYPE ( bls12_381_pkg::fe2_t ),
.CTL_BITS ( CTL_BITS )
)
ec_fp2_point_add (
.i_clk ( i_clk ),
@ -303,8 +309,9 @@ ec_fp2_point_add (
ec_fp2_point_dbl #(
.FP2_TYPE ( bls12_381_pkg::fp2_jb_point_t ),
.FE_TYPE ( bls12_381_pkg::fe_t ),
.FE2_TYPE ( bls12_381_pkg::fe2_t )
.FE_TYPE ( bls12_381_pkg::fe_t ),
.FE2_TYPE ( bls12_381_pkg::fe2_t ),
.CTL_BITS ( CTL_BITS )
)
ec_fp2_point_dbl (
.i_clk ( i_clk ),
@ -328,10 +335,10 @@ ec_fp2_point_dbl (
resource_share # (
.NUM_IN ( 4 ),
.DAT_BITS ( 2*$bits(bls12_381_pkg::fe_t) ),
.CTL_BITS ( 16 ),
.OVR_WRT_BIT ( 14 ),
.CTL_BITS ( CTL_BITS ),
.OVR_WRT_BIT ( 24 ),
.PIPELINE_IN ( 1 ),
.PIPELINE_OUT ( 1 )
.PIPELINE_OUT ( 0 )
)
resource_share_mul (
.i_clk ( i_clk ),
@ -345,10 +352,10 @@ resource_share_mul (
resource_share # (
.NUM_IN ( 4 ),
.DAT_BITS ( 2*$bits(bls12_381_pkg::fe_t) ),
.CTL_BITS ( 16 ),
.OVR_WRT_BIT ( 14 ),
.CTL_BITS ( CTL_BITS ),
.OVR_WRT_BIT ( 24 ),
.PIPELINE_IN ( 1 ),
.PIPELINE_OUT ( 1 )
.PIPELINE_OUT ( 0 )
)
resource_share_sub (
.i_clk ( i_clk ),
@ -362,10 +369,10 @@ resource_share_sub (
resource_share # (
.NUM_IN ( 4 ),
.DAT_BITS ( 2*$bits(bls12_381_pkg::fe_t) ),
.CTL_BITS ( 16 ),
.OVR_WRT_BIT ( 14 ),
.CTL_BITS ( CTL_BITS ),
.OVR_WRT_BIT ( 24 ),
.PIPELINE_IN ( 1 ),
.PIPELINE_OUT ( 1 )
.PIPELINE_OUT ( 0 )
)
resource_share_add (
.i_clk ( i_clk ),
@ -379,7 +386,7 @@ resource_share_add (
ec_fp_mult_mod #(
.P ( bls12_381_pkg::P ),
.KARATSUBA_LVL ( 3 ),
.CTL_BITS ( 16 )
.CTL_BITS ( CTL_BITS )
)
ec_fp_mult_mod (
.i_clk( i_clk ),
@ -390,7 +397,7 @@ ec_fp_mult_mod (
adder_pipe # (
.P ( bls12_381_pkg::P ),
.CTL_BITS ( 16 ),
.CTL_BITS ( CTL_BITS ),
.LEVEL ( 2 )
)
adder_pipe (
@ -402,7 +409,7 @@ adder_pipe (
subtractor_pipe # (
.P ( bls12_381_pkg::P ),
.CTL_BITS ( 16 ),
.CTL_BITS ( CTL_BITS ),
.LEVEL ( 2 )
)
subtractor_pipe (