⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 invmod.v

📁 verilog实现的1024位的大数模逆算法
💻 V
📖 第 1 页 / 共 2 页
字号:
/*
	
	m: 60 - 7F
	a: 80 - 9F
	u: 120 - 13F
	v: 140 - 15F
	B: 160 - 17F
	D: 180 - 19F
*/

`define u_base_addr 10'b01_0010_0000
`define v_base_addr 10'b01_0100_0000
`define m_base_addr 10'b00_0110_0000
`define B_base_addr 10'b01_0110_0000

module InvMod(
				clk,
				Rst_n,
				
				InvMod_wren,
				InvMod_rden,
				InvMod_wraddr,
				InvMod_rdaddr,
				InvMod_q,
				InvMod_data,
				
				InvMod_valid,
				InvMod_start,
				InvMod_done,
				
				InvMod_a_addr,
				InvMod_D_addr
				);

input clk,Rst_n;
input InvMod_start;
input [9:0] InvMod_a_addr,InvMod_D_addr;
input [31:0]	InvMod_q;

output InvMod_wren,InvMod_rden;
output [9:0] InvMod_rdaddr,InvMod_wraddr;
output InvMod_valid,InvMod_done;

output [31:0]	InvMod_data; 
reg  InvMod_valid,InvMod_done;

reg  [9:0]	temp_rdaddr,temp_wraddr;
reg  temp_rden,temp_wren;
reg	 [31:0]	temp_data;
reg  [31:0]	temp_reg;
reg  [1:0]  temp_reg1;
reg  [33:0] temp_reg2;
reg  flagB,flagD;

assign InvMod_wraddr = temp_wraddr;
assign InvMod_rdaddr = temp_rdaddr;
assign InvMod_data   = temp_data;
assign InvMod_rden   = temp_rden;
assign InvMod_wren   = temp_wren;

parameter
			Idel = 7'd1,
			start= 7'd2,
			read_m0 = 7'd3,
			read_m1 = 7'd4,
			rd_m_wr_u = 7'd5,
			wr_u_rd_a = 7'd6,
			rd_a_wr_v = 7'd7,
			wr_v = 7'd8,
			write_B0 = 7'd9,
			write_D_1 = 7'd10,
			write_D_0 = 7'd11,
			read_u0 = 7'd12,
			read_u1 = 7'd13,
			Judge_u0 = 7'd14,
			Div_u_1  = 7'd15,
			Div_u_0  = 7'd16,
			read_B0  = 7'd17,
			B_div_2  = 7'd18,
			B_div_1  = 7'd19,
			B_div_0  = 7'd20,
			B_minus_m_s0 = 7'd21,
			B_minus_m_s1 = 7'd22,
			B_minus_m_s2 = 7'd23,
			B_minus_m_s3 = 7'd24,
			B_minus_div_s0 = 7'd25,
			B_minus_div_s1 = 7'd26,
			
			read_v0 = 7'd27,
			read_v1 = 7'd28,
			Judge_v0 = 7'd29,
			Div_v_1  = 7'd30,
			Div_v_0  = 7'd31,
			read_D0  = 7'd32,
			D_div_2  = 7'd33,
			D_div_1  = 7'd34,
			D_div_0  = 7'd35,
			D_minus_a_s0 = 7'd36,
			D_minus_a_s1 = 7'd37,
			D_minus_a_s2 = 7'd38,
			D_minus_a_s3 = 7'd39,
			D_minus_div_s0 = 7'd40,
			D_minus_div_s1 = 7'd41,
			
			Judge_u_v_s0 = 7'd42,
			Judge_u_v_s1 = 7'd43,
			Judge_u_v_s2 = 7'd44,
			Judge_u_v_s3 = 7'd45,
			Judge_u_v_s4 = 7'd46,
			v_minus_u = 7'd47,
			u_minus_v = 7'd48,
			minus_uv_s0 = 7'd49,
			minus_uv_s1 = 7'd50,
			minus_uv_s2 = 7'd51,
			minus_uv_s3 = 7'd52,
			minus_uv_s4 = 7'd53,
			minus_BD_s0 = 7'd54,
			minus_BD_s1 = 7'd55,
			minus_BD_s2 = 7'd56,
			minus_BD_s3 = 7'd57,
			minus_BD_s4 = 7'd58,
			Get_Result = 7'd59,
			Judge_u0_0 = 7'd60, 
			Judge_u0_1 = 7'd61,
			Judge_u0_2 =  7'd62,
			Judge_u0_3 = 7'd63,
			done = 7'd64;
			
reg  [6:0]	cs;
reg  [4:0]  cnt;
reg  [9:0]  m_addr,a_addr,uvBD_addr,temp_addr;

always @ (posedge clk)
	if(!Rst_n)
		begin
			cs <= Idel;
			temp_wren <= 1'b0;
			temp_rden <= 1'b0;
		end 
	else
		case(cs)
			Idel:
				begin
					InvMod_valid <= 1'b0;
					InvMod_done  <= 1'b0;
					cnt <= 5'd0;
					if(InvMod_start == 1'b1)
						cs <= start;
					else
						cs <= Idel;
				end
			start:
				begin
					InvMod_valid <= 1'b1;
					m_addr     <= `m_base_addr;
					a_addr     <= InvMod_a_addr;
					uvBD_addr    <= `u_base_addr;
					flagB <= 1'b0;
					flagD <= 1'b0;
					cs <= read_m0;
				end
			read_m0:
				begin
					temp_rdaddr <= m_addr;
					temp_rden <= 1'b1;
					temp_wren <= 1'b0;
					m_addr <= m_addr + 1'b1;
					cs <= read_m1;
				end	
			read_m1:
				begin
					temp_rdaddr <= m_addr;
					m_addr <= m_addr + 1'b1;
					temp_rden <= 1'b1;
					temp_wren <= 1'b0;
					cs <= rd_m_wr_u;
				end
			rd_m_wr_u:
				begin
					temp_wren <= 1'b1;
					temp_rden <= 1'b1;
					temp_data <= InvMod_q;
					temp_wraddr <= uvBD_addr;
					uvBD_addr <= uvBD_addr + 1'b1;
					m_addr <= m_addr + 1'b1;
					temp_rdaddr <= m_addr;
					cnt <= cnt + 1'b1;
					if(cnt == 5'd29)
						begin
							cs <= wr_u_rd_a; 
						end
					else
						cs <= rd_m_wr_u;
				end
			wr_u_rd_a:
				begin
					temp_wren <= 1'b1;
					temp_rden <= 1'b1;
					temp_data <= InvMod_q;
					temp_wraddr <= uvBD_addr;
					temp_rdaddr <= a_addr;
					a_addr <= a_addr + 1'b1;
					uvBD_addr <= uvBD_addr + 1'b1;
					if(cnt == 5'd31)
						begin
							cnt <= 5'd0;
							cs <= rd_a_wr_v;
						end
					else
						begin
							cnt <= cnt + 1'b1;
							cs <= wr_u_rd_a;
						end
				end			
			rd_a_wr_v:
				begin
					temp_rden <= 1'b1;
					temp_wren <= 1'b1;
					temp_rdaddr <= a_addr;
					a_addr <= a_addr + 1'b1;
					temp_wraddr <= uvBD_addr;
					uvBD_addr <= uvBD_addr + 1'b1;
					temp_data <= InvMod_q;
					cnt <= cnt + 1'b1;
					if(cnt == 5'd29)
						cs <= wr_v;
					else
						cs <= rd_a_wr_v;
				end
			wr_v:
				begin
					temp_rden <= 1'b0;
					temp_wren <= 1'b1;
					temp_wraddr <= uvBD_addr;
					uvBD_addr <= uvBD_addr + 1'b1;
					temp_data <= InvMod_q;
					cnt <= cnt + 1'b1;
					if(cnt == 5'd31)
						begin
							cs <= write_B0;
							cnt <= 5'd0;
						end
					else
					 cs <= wr_v;
				end
			write_B0:
				begin
					temp_wren <= 1'b1;
					temp_rden <= 1'b0;
					temp_wraddr <= uvBD_addr;
					temp_data  <= 32'd0;
					uvBD_addr <= uvBD_addr + 1'b1;
					cnt <= cnt + 1'b1;
					if(cnt == 5'd31)
						begin
							cs <= write_D_1;
							cnt <= 5'd0; 
						end
					else
						cs <= write_B0;
				end
			write_D_1:
				begin
					temp_wren <= 1'b1;
					temp_wraddr <= uvBD_addr;
					uvBD_addr <= uvBD_addr + 1'b1;
					temp_data <= 32'd1;
					cnt <= cnt + 1'b1;
					cs <= write_D_0;
				end
			write_D_0:
				begin
					temp_wren <= 1'b1;
					temp_wraddr <= uvBD_addr;
					uvBD_addr <= uvBD_addr + 1'b1;
					temp_data <= 32'd0;
					cnt <= cnt + 1'b1;
					if(cnt == 5'd31)
						begin
							cnt <= 5'd0;
							cs <= read_u0;
						end
					else
						cs <= write_D_0;
				end
				
				//第一部分 read u
			read_u0:                                             
				begin
					cnt <= 5'd0;
					temp_rden <= 1'b1;
					temp_wren <= 1'b0;
					temp_rdaddr <=`u_base_addr;
					uvBD_addr <= `u_base_addr + 1'b1;
					cs <= read_u1;		
				end	
			read_u1:
				begin
					temp_rdaddr <= uvBD_addr;
					uvBD_addr <= uvBD_addr + 1'b1;
					cs <= Judge_u0;
				end
			Judge_u0:
				begin
					temp_reg[30:0] <= InvMod_q[31:1];
					temp_rdaddr <= uvBD_addr;
					uvBD_addr <= uvBD_addr + 1'b1;
					if(InvMod_q[0]==0)
						cs <= Div_u_1;
					else
						cs <= read_v0;						
				end
			Div_u_1:
				begin
					temp_rden <= 1'b1;
					temp_wren <= 1'b1;
					temp_rdaddr <= uvBD_addr;
					temp_wraddr <= uvBD_addr - 2'd3;
					uvBD_addr <= uvBD_addr + 1'b1;
					temp_data <= {InvMod_q[0],temp_reg[30:0]};
					temp_reg [30:0] <= InvMod_q[31:1];
					cnt <= cnt + 1'b1;
					if(cnt==5'd30)
						cs <= Div_u_0;
					else
						cs <= Div_u_1;
				end
			Div_u_0:                        
				begin
					temp_rden <= 1'b1;
					temp_wren <= 1'b1;
					temp_rdaddr <= `B_base_addr;   //read B0
					temp_wraddr <= uvBD_addr - 2'd3;
					uvBD_addr <= `B_base_addr + 1'b1;
					temp_data <= {temp_reg[30],temp_reg[30:0]};
					cs <= read_B0;
				end
			read_B0:                         //start from here
				begin
				if(InvMod_q[0]==1'b0)
					begin
					cnt <= 1'b0;
					temp_wren <= 1'b0;
					temp_rden <= 1'b1;
					temp_rdaddr <= uvBD_addr; //read_B1
					uvBD_addr <= uvBD_addr + 1'b1;
						cs <= B_div_2;
					end
				else
					begin
						temp_wren <= 1'b0;
						temp_rden <= 1'b1;
						temp_rdaddr <= `m_base_addr;
						m_addr <= `m_base_addr + 1'b1;
						cs <= B_minus_m_s0;
					end
				end
			B_div_2:
				begin
					temp_wren <= 1'b0;
					temp_rden <= 1'b1;
					temp_rdaddr <= uvBD_addr; //read_B2
					uvBD_addr <= uvBD_addr + 1'b1;
					temp_reg[30:0] <= InvMod_q[31:1];
					cs <= B_div_1;
				end
			B_div_1:
				begin
					temp_rden <= 1'b1;
					temp_wren <= 1'b1;
					temp_rdaddr <= uvBD_addr;
					uvBD_addr <= uvBD_addr + 1'b1;
					temp_wraddr <= uvBD_addr - 2'd3;
					temp_data <= {InvMod_q[0],temp_reg[30:0]};
					temp_reg[30:0] <= InvMod_q[31:1];
					cnt <= cnt + 1'b1;
					if(cnt == 5'd28)
						cs <= B_div_0;
					else
						cs <= B_div_1;
				end
			B_div_0:
				begin
					temp_rden <= 1'b0;
					temp_wren <= 1'b1;
					temp_data <= {temp_reg[30],temp_reg[30:0]};
					temp_wraddr <= uvBD_addr - 2'd3;
					uvBD_addr <= uvBD_addr + 1'b1;
					cnt <= cnt + 1'b1;
					if(cnt == 5'd31)
						cs <= read_u0;
					else
						cs <= B_div_0;
					
				end
			B_minus_m_s0:
				begin
						uvBD_addr <= `B_base_addr + 1'b1;
						temp_rden <= 1'b1;
						temp_wren <= 1'b0;
						temp_rdaddr <= `B_base_addr;
						temp_reg1 <= 2'd1;                //read B0
						temp_addr <= `B_base_addr;
						cnt <= 5'd0;
						cs <= B_minus_m_s1;
				end
			B_minus_m_s1:
				begin
					temp_rden <= 1'b0;
					temp_wren <= 1'b0;	
					temp_reg <= ~InvMod_q;			
					cs <=  B_minus_m_s2;
				end
			B_minus_m_s2:
				begin
					if(cnt == 5'd31)
						begin
							temp_rden <= 1'b1;
							temp_rdaddr <= `B_base_addr;
							uvBD_addr <= `B_base_addr + 1'b1; //read B0				
							cs <= B_minus_div_s0;
						end
					else
						begin
							temp_rden <= 1'b1;		
							temp_wren <= 1'b1;       
							temp_reg2 <=  temp_reg + temp_reg1 + InvMod_q;    //write get B0
							temp_data <=  temp_reg + temp_reg1 + InvMod_q;
							temp_rdaddr <= m_addr;
							m_addr <= m_addr + 1'b1;
							temp_wraddr <= temp_addr;
							temp_addr <= temp_addr + 1'b1;         //read mi
							cs <= B_minus_m_s3;
						end
				end
			B_minus_m_s3:
				begin	
					temp_rden <= 1'b1;
					temp_wren <= 1'b0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -