蒙哥马利基2的算法的Verilog 硬件实现(大数模乘)
Posted 摆渡沧桑
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蒙哥马利基2的算法的Verilog 硬件实现(大数模乘)相关的知识,希望对你有一定的参考价值。
基于蒙哥马利基2的算法的 的python 语言参考上一篇博客 蒙哥马利基2的Python算法实现(大数模乘)
下面提供基于蒙哥马利算法实现基2 的硬件verilog语言编写,提供给大家学习,参考。
`timescale 1ns / 1ps
module montgomery #(parameter WIDTH =1024)
(
input clk,
input rstn,
input start_flag,
input [(WIDTH-1):0] in_a,
input [(WIDTH-1):0] in_b,
input [(WIDTH-1):0] in_m,
output [(WIDTH-1):0] result,
output done_flag
);
`define FUNC(x) \\
(x < 2 ) ? 1 : \\
(x < 4 ) ? 2 : \\
(x < 8 ) ? 3 : \\
(x < 16 ) ? 4 : \\
(x < 32 ) ? 5 : \\
(x < 64 ) ? 6 : \\
(x < 128 ) ? 7 : \\
(x < 256 ) ? 8 : \\
(x < 512 ) ? 9 : \\
(x < 1024 ) ? 10 : \\
(x < 2048 ) ? 11 : \\
(x < 4096 ) ? 12 : \\
-1
//PARAMETER WIDTH = 1024;
localparam CNT_WIDTH = `FUNC(WIDTH+1);
parameter IDLE = 3'b000;
parameter START = 3'b001;
parameter WAIT1 = 3'b010;
parameter CHECK = 3'b011;
parameter WAIT2 = 3'b100;
parameter DONE = 3'b101;
reg [(WIDTH + 1):0] reg_A, reg_B; //1026bit
reg [(WIDTH - 1):0] reg_M;
reg [(WIDTH + 2):0] add_a, add_b;
reg [CNT_WIDTH :0] cnt;
reg [(WIDTH + 2):0] r_result;
reg [(WIDTH + 2):0] C;
reg done, subtract, add_start;
reg [2:0] state, next_state;
//wire [WIDTH:0] a, b;
wire [(WIDTH + 2):0] add_result;
wire add_done, shift;
assign shift = 0;
adder_sim #(.ADD_WIDTH(WIDTH)) u_adder
(.in_a (add_a),
.in_b (add_b),
.subtract (subtract),
.start (add_start),
.result (add_result),
.done (add_done),
.clk (clk),
.resetn (rstn),
.shift (shift)
);
//cnt
always @(posedge clk or negedge rstn)
begin
if (!rstn)
cnt <= 0;
else if ((state == IDLE) | (state == DONE ))
cnt <= 0;
else if (state == CHECK)
cnt <= cnt + 1'b1;
end
wire reg_C_0; //LSB
assign reg_C_0 = C[0]; //^ (reg_A[cnt] & reg_B[0]);
reg start_dly;
wire start;
always @(posedge clk or negedge rstn)
if(!rstn)
start_dly <= 1'b0;
else
start_dly <= start_flag;
assign start = start_flag & (! start_dly);
//A,B,M
always @(posedge clk or negedge rstn)
if (!rstn)
begin
reg_A <= 0;
reg_B <= 0;
reg_M <= 0;
end
else if (start == 1'b1)
begin
reg_A <= 2'b00,in_a;
reg_B <= 2'b00,in_b;
reg_M <= in_m;
end
//fsm contrl
always @(posedge clk or negedge rstn)
if(!rstn)
state <= 3'b000;
else
state <= next_state;
always @(*)
begin
case(state)
IDLE: begin//IDLE
if (start == 1)
next_state = START;
else
next_state = IDLE;
end
START: begin//START
if (cnt == (WIDTH+2))
next_state = DONE;
else
begin
if (reg_A[cnt] == 1)
next_state = WAIT1;
else
next_state = CHECK;
end
end
WAIT1: begin//WAIT1
if (add_done == 1)
next_state = CHECK;
else
next_state = WAIT1;
end
CHECK: begin// Check
if (reg_C_0 == 0)
next_state = START;
else
next_state = WAIT2;
end
WAIT2: begin//WAIT2
if (add_done == 1)
next_state = START;
else
next_state = WAIT2;
end
DONE: begin//DONE
next_state = IDLE;
end
default:begin
next_state = IDLE;
end
endcase
end
//reg_c
always @(posedge clk or negedge rstn)
if (!rstn)
C <= 0;
else if (state == IDLE)
C <= 0;
else if (state == WAIT1 & add_done == 1)
C <= add_result;
else if (state == CHECK & reg_C_0 == 0)
C <= C >> 1;
else if (state == WAIT2 & add_done == 1)
C <= add_result >> 1;
//add_flag
always @(*)
if (!rstn)
begin
add_start = 0;
add_a = 0;
add_b = 0;
end
else if (state == START & reg_A[cnt] == 1 )
begin
add_start =1;
add_a = C;
add_b = reg_B[(WIDTH-1):0];
end
else if (state == CHECK & reg_C_0 != 0 )
begin
add_a = C;
add_b = reg_M;
add_start = 1;
end
else if (state == DONE | state == WAIT1 | state == WAIT2 )
add_start = 0;
//done_flag
always @(posedge clk or negedge rstn)
if (!rstn)
begin
done <= 0;
r_result <= 0;
end
else if (next_state == START )
done <= 0;
else if (state == DONE )
begin
done <= 1'b1;
r_result <= C;
end
assign result = r_result[(WIDTH-1):0];
assign done_flag = done;
endmodule
以上是关于蒙哥马利基2的算法的Verilog 硬件实现(大数模乘)的主要内容,如果未能解决你的问题,请参考以下文章
[从零开始学习FPGA编程-9]:快速入门篇 - 操作步骤2 - 硬件电路图形化描述与文本硬件描述语言Verilog HDL与VHDL语言以及比较
[从零开始学习FPGA编程-10]:快速入门篇 - 操作步骤2 - Verilog HDL语言Module与硬件电路对应关系快速概览
[从零开始学习FPGA编程-16]:快速入门篇 - 操作步骤2-4- Verilog HDL语言描述语言基本语法(软件程序员和硬件工程师都能看懂)