如果a,b GF(P),則加法運算a+b=r (mod p),其中r滿足0<r<p-1,即a+b除以p的餘數,該操作成為模p加法。對於模減運算可以視為另類的模加運算,即a+(-b)=k (mod p)。本模組將模加和模減集中在同一模組中,由外部訊號控制選擇使用模減或者模減運算。


                                                                                                                              

訊號名

方向

位寬

埠定義

clk

Input

1

時鐘

reset

Input

1

復位訊號

add_en

Input

1

運算使能訊號

op

Input

1

模加減選擇訊號

a

Input

256

整數a輸入

b

Input

256

整數b輸入

sum

Output

256

運算結果

mod_add_done

Output

1

模加減完成標識

  程式碼如下:

  1. // op = 1, a-b mod p
  2. // op = 0, a+b mod p
  3.  
  4. module mod_add(
  5. input clk,
  6. input reset,
  7. input en,
  8. input [255:0] a,
  9. input [255:0] b,
  10. input op,
  11. output reg [255:0] sum,
  12. output reg mod_add_done
  13. );
  14. parameter params_p=256'd15424654874903;
  15. //parameter params_p = 256'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F;
  16.  
  17. reg [256:0] temp1;//temp2; //the [256] is the sign bit
  18.  
  19. reg [1:0] cs,ns;
  20. parameter idle = 0;
  21. parameter s1 = 1;
  22. parameter s2 = 2;
  23. parameter s3 = 3;
  24.  
  25. always@(posedge clk) begin
  26. if(reset)
  27. cs <= idle;
  28. else
  29. cs <= ns;
  30. end
  31.  
  32. always@(*) begin
  33. case(cs)
  34. idle:
  35. ns <= s1;
  36. s1:
  37. ns <= s2;
  38. s2:
  39. if(temp1[256])
  40. ns <= s2;
  41. else if(temp1 >= params_p)
  42. ns <= s2;
  43. else
  44. ns <= s3;
  45. s3:
  46. ns <= en ? idle : s3;
  47. endcase
  48. end
  49.  
  50. always@(*) begin
  51. case(cs)
  52. idle: begin
  53. sum <= 0;
  54. mod_add_done <= 0;
  55. end
  56. s1:
  57. if(op) begin
  58. temp1 <= a - b;
  59. //temp2 = temp1 + params_p;
  60. end
  61. else begin
  62. temp1 <= a + b;
  63. //temp2 = temp1 - params_p;
  64. end
  65. s2:
  66. if(op) begin
  67. if(temp1[256]) begin //if temp1[256] is 1, 'a<b', 'a-b mod p' = 'params_p+(b-a)'
  68. temp1 <= temp1 + params_p;
  69. end
  70. else if(temp1 >= params_p)
  71. temp1 <= temp1 - params_p;
  72. end
  73. else begin
  74. if(temp1 >= params_p) //if temp1[256] is 1, 'a<b', 'a-b mod p' = 'params_p-(b-a)'
  75. temp1 <= temp1 - params_p;
  76. //else
  77. //temp2 = temp1;
  78. end
  79. s3: begin
  80. sum <= temp1[255:0];
  81. mod_add_done <= 1;
  82. end
  83. endcase
  84. end
  85.  
  86. endmodule

選用的曲線引數如下:https://blog.csdn.net/cccchhhh6819/article/details/100660139

testbeach:

  1. `timescale 1ns/1ns
  2.  
  3. module mod_add_tb();
  4.  
  5. reg clk, reset,en;
  6. reg [255:0] a, b;
  7. wire [255:0] sum;
  8. reg op;
  9. wire mod_add_done;
  10.  
  11. mod_add add0(
  12. .clk(clk),
  13. .reset(reset),
  14. .en(en),
  15. .a(a),
  16. .b(b),
  17. .sum(sum),
  18. .op(op),
  19. .mod_add_done(mod_add_done)
  20. );
  21.  
  22. always #5 clk = ~clk;
  23.  
  24. initial begin
  25. clk = 0;
  26.  
  27. reset = 1'b1;
  28. en = 0;
  29.  
  30. #20
  31. reset = 1'b0;
  32. op = 1;//P=29
  33. a = 256'd15424654874903;
  34. b =256'd15424654874906;
         #10000 $stop;

    end endmodule

本次模擬計算的是a-b(mod p)  也即15424654874903 - 15424654874906(mod 15424654874903 )的結果,相當於是-3 mod 15424654874903 。

模擬結果如下:為15424654874900。負數模運算規則 比如-2 mod 5 = -2+5=3 。-6 mod 5 = -6+5+5=4。所有結論正常。

當然我們更關注的是整個演算法消耗的資源,這裡博主還沒學到綜合那裡去,後續會跟進這部分。當然該演算法應該會佔用較大的資源,比較用到了兩個位寬的暫存器直接相加,會延遲暫存器之間的關鍵路徑,導致最後時鐘頻率跑不上去。