www.pudn.com > hmac-zy.rar > datapadunit.v, change:2006-12-30,size:16580b


///////////////////////////////////////////////////////
//    				module describe
// name: 			datapadunit
// function:	data padding including keypad
// writer:		zy
// data:			2006/11/08
// version:		1.1
// feature:		the lenth of the message (by bits)  is 
//						not obligatory, but it must be the 
//						multiple of 8.
// address: 	0 - ctrl word
//						1 - keyin
//						2 - lengthin
//						3 - datain
//						4 - status
//						5-9 - digest out
//						15 - mask
////////////////////////////////////////////////////////


module datapadunit(en,clk,reset,wr,padflg,datain,addr,hashover,modsel,md1in,paddata,dataready,expadflgreg,lenerror,procsel,keyreadyreg,digestreadyreg);
//general input
input en,clk,reset,wr;
input [31:0] datain;
input [3:0]  addr;
//intermodule input
input padflg;
input hashover;
input modsel;
input [159:0] md1in;
//output
output [511:0] paddata;
output dataready;
output expadflgreg;
output lenerror;
output [1:0] procsel;
output keyreadyreg;
output digestreadyreg;

//for the output
reg [511:0] paddata;
reg dataready;
reg expadflgreg;
reg lenerror;
reg [1:0] procsel;
reg digestreadyreg;
//reg keyready;
 
//use for the module
reg [2:0] keycnt;
reg [3:0] datacnt;
reg [63:0] datalength;
reg [159:0] keyreg;
//reg lenerror;
reg keyreadyreg;
reg expadflg;
reg fulllengthreg;

reg [31:0] datatmp;

//ctrl signal
reg keyinc;
reg keycntclr;
reg datainc;
reg datacntclr;
reg ikeyready;
reg okeyready;
reg paddataready;
reg error;
reg md1ready;
reg resultready;
reg fulllength;
reg expadflgclr;

//use for the state machine
reg [4:0] currentstate;
reg [4:0] nextstate;

//state define
parameter idle = 0;
parameter rxkey = 1;
parameter sendikey = 2;
parameter waitiv1 = 3;
parameter sendokey = 4;
parameter waitiv2 = 5;
parameter rxlength = 6;
parameter rxdata = 7;
parameter datapad = 8;
parameter lengthpad = 9;
parameter senddata = 10;
parameter expad = 11;
parameter sendmd1 = 12;
parameter waitmd2 = 13;
parameter digestready = 14;
parameter lengtherror =15;
parameter hmackeyready = 16;

//parameter define
parameter ipad = 8'b00110110;
parameter opad = 8'b01011100;

//store the inputdata in the datatmp;
always @(posedge clk)
begin
	if (reset)
		datatmp <= 0;
	else if (en && ((addr == 1) || (addr == 2) || (addr == 3)))
		datatmp <= datain;
end
//expad reg
always @(posedge clk)
begin
	if (reset)
		expadflgreg <= 0;
	else if (expadflg)
		expadflgreg <= 1;
	else if (expadflgclr)
		expadflgreg <= 0;
end

//fulllength reg
always @(posedge clk)
begin
	if (reset)
		fulllengthreg <= 0;
	else if (fulllength)
		fulllengthreg <= 1;
	else if (resultready)
		fulllengthreg <= 0;
end

//lenerror reg
always @(posedge clk)
begin
	if (reset)
		lenerror <= 0;
	else
		lenerror <= error;
end
		
//count the key block
always @(posedge clk)
begin
	if (reset)
		keycnt <= 0;
	else if (keyinc)
		keycnt <= keycnt+1;
	else if (keycntclr)
		keycnt <= 0;
	else
		keycnt <= keycnt;
end

//count the data block
always @(posedge clk)
begin
	if (reset)
		datacnt <= 0;
	else if (datainc)
		datacnt <= datacnt+1;
	else if (datacntclr)
		datacnt <= 0;
	else
		datacnt <= datacnt;
end

//control dataready signal
always @(posedge clk)
begin
	if (reset)
		dataready <= 0;
	else if (ikeyready || okeyready || paddataready || md1ready)
		dataready <= 1;
	else
		dataready <=0;
end

//digestready reg
always @(posedge clk)
begin
	if (reset)
		digestreadyreg <= 0;
	else if (resultready)
		digestreadyreg <= 1;
	else if (en && wr && addr==9)
		digestreadyreg <= 0;
end

//state machine description

always @(posedge clk)
begin
	if (reset)
		currentstate <= idle;
	else
		currentstate <= nextstate;
end

always @(*)
begin	
	nextstate = idle;
	keyinc = 0;
	datainc = 0;
	ikeyready = 0;
	okeyready = 0;
	paddataready = 0;
	error = 0;
	md1ready = 0;
	resultready = 0;
	expadflg = 0;
	keycntclr = 0;
	datacntclr = 0;
	fulllength = 0;
	expadflgclr = 0;
	case (currentstate)
		idle:
			begin
				if (en && !wr && (addr == 1) && (modsel == 1))
					nextstate = rxkey;
				else if (en && !wr && (addr == 2) && !lenerror)
					nextstate = rxlength;
				else if (en && !wr && (addr == 3))
					nextstate = rxdata;
				else if (expadflgreg && hashover && padflg)
					nextstate = expad;
				else if (hashover && modsel && padflg)
					nextstate = sendmd1;
				else if (hashover && fulllengthreg)
					nextstate = expad;
				else if (hashover && ((!modsel && padflg && !expadflgreg) || (!padflg)))
					nextstate = digestready;
				else if ((!padflg && (datalength[8:0]!=0)) || (datalength[2:0] != 0))
					nextstate = lengtherror;
				else
					nextstate = idle;
			end
		rxkey:
			begin
				keyinc = 1;
				if (keycnt==4)
					begin
						nextstate = sendikey;
					end
				else if (en && !wr && (addr == 1))//in case of the writting operation followed clk by clk
					nextstate = rxkey;
				else 
					nextstate = idle;				
			end
		sendikey:
			begin
				ikeyready = 1;
				keycntclr = 1;
				nextstate = waitiv1;
			end
		waitiv1:
			begin
			keycntclr = 0;
			ikeyready = 0;
				if (hashover)
					begin
						nextstate = sendokey;
					end
				else
					nextstate = waitiv1;
			end
		sendokey:
			begin
				okeyready = 1;
				nextstate = waitiv2;
			end
		waitiv2:
			begin
				if (hashover)
					begin
						nextstate = hmackeyready;
					end
				else
					nextstate = waitiv2;
			end
		hmackeyready:
			begin
				nextstate = idle;
			end
		rxlength:
			begin
//				if((datain==0) && padflg)
//					nextstate = datapad;
//				else
					nextstate = idle;
			end
		rxdata:
			begin
				datainc =1;
				if (en && !wr && (addr == 3))
					nextstate = rxdata;
				else if ((datacnt==15) && !padflg)
					nextstate = senddata;
				else if (((datacnt == datalength[8:5]-1) && (datalength[4:3]==0) && padflg) || ((datacnt == datalength[8:5]) && (datalength[4:3]!=0  && padflg)))
					nextstate = datapad;
				else if (padflg && (datacnt == 15))
					begin
						nextstate = senddata;
						fulllength = 1;
					end
				else
					nextstate = idle;
			end
		datapad:
		 	begin
		 		datainc = 0;
		 		if ((datalength[8:6] == 7) || (datalength[8:0] == 0))
		 			begin
		 				expadflg = 1;
		 				nextstate = senddata;
		 			end
		 		else
		 			nextstate = lengthpad;
		 	end
		lengthpad:
			begin
				nextstate = senddata;
			end
		senddata:
			begin
				datainc = 0;
				datacntclr = 1;
				paddataready = 1;
				nextstate = idle;
			end
		expad:
			begin
				paddataready = 1;
				expadflgclr = 1;
				nextstate = idle;
			end
		sendmd1:
			begin
				md1ready =1;
				nextstate = waitmd2;
			end
		waitmd2:
			begin
				if (hashover)
					nextstate = digestready;
				else 
					nextstate = waitmd2;
			end
		digestready:
			begin
				resultready = 1;
				nextstate = idle;
			end
		lengtherror:
			begin
				error = 1;
				if (en && !wr && (addr == 2) && lenerror)
					nextstate = idle;
				else
					nextstate = lengtherror;
			end
	endcase		
end

//receive the key and process the key
always @(posedge clk)
	begin
		if (reset)
			begin
				keyreg <= 0;	
				keyreadyreg <= 0;
			end
		else if (currentstate == rxkey)
			begin
				case (keycnt)
					0: keyreg[159:128] <= datatmp;
					1: keyreg[127:96]  <= datatmp;
					2: keyreg[95:64]   <= datatmp;
					3: keyreg[63:32]   <= datatmp;
					4: keyreg[31:0]    <= datatmp;
				endcase
			end
		else if (currentstate == hmackeyready)
			keyreadyreg <= 1;
		else
			begin
				keyreg <= keyreg;
				keyreadyreg <= keyreadyreg;
			end
	end

//receive the datalength and comput the whole length automatically
always @(posedge clk)
	begin
		if (reset)
			begin
				datalength <= 0;
			end
		else if ((currentstate == rxlength) && !padflg)
			begin
				datalength[63:9] <= datalength[63:9] + 1;
			end
		else if ((currentstate == rxlength) && padflg && !modsel)
			begin
				datalength[8:0] <= datalength[8:0] + datatmp[8:0];
			end
		else if ((currentstate == rxlength) && padflg && modsel)
			begin
				datalength[8:0] <= datalength[8:0] + datatmp[8:0];
				datalength[63:9] <= datalength[63:9] + 1;
			end
		else if (digestreadyreg && padflg)
			datalength <= 0;
		else
			begin
				datalength <= datalength;
			end
	end
	
//receive data and pad data
always @(posedge clk)
	begin
		if (reset)
			begin
				paddata <= 0;
				procsel <= 0;
			end
		else
			begin
				case (currentstate)
					idle,rxkey: 
							begin
								paddata <= paddata;
								procsel <= 0;
							end
					sendikey:
						begin
							paddata[511:352] <= keyreg ^ {20{ipad}};
							paddata[351:0]   <= {44{ipad}};
							procsel <=1;
						end
					waitiv1: paddata <= paddata;
					sendokey:
						begin
							paddata[511:352] <= keyreg ^ {20{opad}};
							paddata[351:0]   <= {44{opad}};
							procsel <=2;
						end
					waitiv2:
						begin
							procsel <= 2;
						end
					hmackeyready,rxlength: paddata <= paddata;
					rxdata:
						case (datacnt)
							0:  paddata[511:480] <= datatmp;
							1:  paddata[479:448] <= datatmp;
							2:  paddata[447:416] <= datatmp;
							3:  paddata[415:384] <= datatmp;
							4:  paddata[383:352] <= datatmp;
							5:  paddata[351:320] <= datatmp;
							6:  paddata[319:288] <= datatmp;
							7:  paddata[287:256] <= datatmp;
							8:  paddata[255:224] <= datatmp;
							9:  paddata[223:192] <= datatmp;
							10: paddata[191:160] <= datatmp;
							11: paddata[159:128] <= datatmp;
							12: paddata[127:096] <= datatmp;
							13: paddata[095:064] <= datatmp;
							14: paddata[063:032] <= datatmp;
							15: paddata[031:000] <= datatmp;
						endcase
					datapad:
						begin
							case (datalength[8:5])
								0: 
									begin
										case (datalength[4:3])
													0: paddata[511:480] <= 32'h80000000;
													1: paddata[511:480] <= paddata[511:480] + 32'h00800000;
													2: paddata[511:480] <= paddata[511:480] + 32'h00008000;
													3: paddata[511:480] <= paddata[511:480] + 32'h00000080;
										endcase
										paddata[479:0] <= 0;	
											
									end
								1: 
									begin
										case (datalength[4:3])
											0: paddata[479:448] <= 32'h80000000;
											1: paddata[479:448] <= paddata[479:448] + 32'h00800000;
											2: paddata[479:448] <= paddata[479:448] + 32'h00008000;
											3: paddata[479:448] <= paddata[479:448] + 32'h00000080;
										endcase
										paddata[447:0] <= 0;	
									end
								2: 
									begin
										case (datalength[4:3])
											0: paddata[447:416] <= 32'h80000000;
											1: paddata[447:416] <= paddata[447:416] + 32'h00800000;
											2: paddata[447:416] <= paddata[447:416] + 32'h00008000;
											3: paddata[447:416] <= paddata[447:416] + 32'h00000080;
										endcase
										paddata[415:0] <= 0;
									end
								3: 
									begin
										case (datalength[4:3])
											0: paddata[415:384] <= 32'h80000000;
											1: paddata[415:384] <= paddata[415:384] + 32'h00800000;
											2: paddata[415:384] <= paddata[415:384] + 32'h00008000;
											3: paddata[415:384] <= paddata[415:384] + 32'h00000080;
										endcase
										paddata[383:0] <= 0;
									end
								4: 
									begin
										case (datalength[4:3])
											0: paddata[383:352] <= 32'h80000000;
											1: paddata[383:352] <= paddata[383:352] + 32'h00800000;
											2: paddata[383:352] <= paddata[383:352] + 32'h00008000;
											3: paddata[383:352] <= paddata[383:352] + 32'h00000080;
										endcase
										paddata[351:0] <= 0;
									end
								5: 
									begin
										case (datalength[4:3])
											0: paddata[351:320] <= 32'h80000000;
											1: paddata[351:320] <= paddata[351:320] + 32'h00800000;
											2: paddata[351:320] <= paddata[351:320] + 32'h00008000;
											3: paddata[351:320] <= paddata[351:320] + 32'h00000080;
										endcase
										paddata[319:0] <= 0;
									end
								6: 
									begin
										case (datalength[4:3])
											0: paddata[319:288] <= 32'h80000000;
											1: paddata[319:288] <= paddata[319:288] + 32'h00800000;
											2: paddata[319:288] <= paddata[319:288] + 32'h00008000;
											3: paddata[319:288] <= paddata[319:288] + 32'h00000080;
										endcase
										paddata[287:0] <= 0;
									end
								7: 
									begin
										case (datalength[4:3])
											0: paddata[287:256] <= 32'h80000000;
											1: paddata[287:256] <= paddata[287:256] + 32'h00800000;
											2: paddata[287:256] <= paddata[287:256] + 32'h00008000;
											3: paddata[287:256] <= paddata[287:256] + 32'h00000080;
										endcase
										paddata[255:0] <= 0;
									end
								8: 
									begin
										case (datalength[4:3])
											0: paddata[255:224] <= 32'h80000000;
											1: paddata[255:224] <= paddata[255:224] + 32'h00800000;
											2: paddata[255:224] <= paddata[255:224] + 32'h00008000;
											3: paddata[255:224] <= paddata[255:224] + 32'h00000080;
										endcase
										paddata[223:0] <= 0;
									end
								9: 
									begin
										case (datalength[4:3])
											0: paddata[223:192] <= 32'h80000000;
											1: paddata[223:192] <= paddata[223:192] + 32'h00800000;
											2: paddata[223:192] <= paddata[223:192] + 32'h00008000;
											3: paddata[223:192] <= paddata[223:192] + 32'h00000080;
										endcase
										paddata[191:0] <= 0;
									end
								10: 
									begin
										case (datalength[4:3])
											0: paddata[191:160] <= 32'h80000000;
											1: paddata[191:160] <= paddata[191:160] + 32'h00800000;
											2: paddata[191:160] <= paddata[191:160] + 32'h00008000;
											3: paddata[191:160] <= paddata[191:160] + 32'h00000080;
										endcase
										paddata[159:0] <= 0;
									end
								11: 
									begin
										case (datalength[4:3])
											0: paddata[159:128] <= 32'h80000000;
											1: paddata[159:128] <= paddata[159:128] + 32'h00800000;
											2: paddata[159:128] <= paddata[159:128] + 32'h00008000;
											3: paddata[159:128] <= paddata[159:128] + 32'h00000080;
										endcase
										paddata[127:0] <= 0;
									end
								12: 
									begin
										case (datalength[4:3])
											0: paddata[127:096] <= 32'h80000000;
											1: paddata[127:096] <= paddata[127:096] + 32'h00800000;
											2: paddata[127:096] <= paddata[127:096] + 32'h00008000;
											3: paddata[127:096] <= paddata[127:096] + 32'h00000080;
										endcase
										paddata[95:0] <= 0;
									end
								13: 
									begin
										case (datalength[4:3])
											0: paddata[095:064] <= 32'h80000000;
											1: paddata[095:064] <= paddata[095:064] + 32'h00800000;
											2: paddata[095:064] <= paddata[095:064] + 32'h00008000;
											3: paddata[095:064] <= paddata[095:064] + 32'h00000080;
										endcase
										paddata[63:0] <= 0;
									end
								14: 
									begin
										case (datalength[4:3])
											0: paddata[063:032] <= 32'h80000000;
											1: paddata[063:032] <= paddata[063:032] + 32'h00800000;
											2: paddata[063:032] <= paddata[063:032] + 32'h00008000;
											3: paddata[063:032] <= paddata[063:032] + 32'h00000080;
										endcase
										paddata[031:000] <= 0;
									end
								15: 
									begin
										case (datalength[4:3])
											0: paddata[031:000] <= 32'h80000000;
											1: paddata[031:000] <= paddata[031:000] + 32'h00800000;
											2: paddata[031:000] <= paddata[031:000] + 32'h00008000;
											3: paddata[031:000] <= paddata[031:000] + 32'h00000080;
										endcase
									end
							endcase
						end
						lengthpad:
							begin
								paddata[63:0] <= datalength;
							end
						senddata:
							begin
								paddata <= paddata;
							end
						expad:
							begin
								if (datalength[8:3]==0)
									begin
										paddata[511] <= 1;
										paddata[510:64] <= 0;
										paddata[63:0] <= datalength;
									end
								else
									begin
										paddata[511:64] <= 0;
										paddata[63:0] <= datalength;
									end
							end
						sendmd1:
							begin
								paddata[511:352] <= md1in;
								paddata[351] <=1;
								paddata[350:64] <=0;
								paddata[63:0] <=32'h000002a0;
								procsel <= 3;
							end
						//receive the digest from hashunit, and send it to the wtprounit
						//waitmd2://this state may be reduced
						//digestready://set the digestready flag in status reg
						//lengtherror://set the lengtherror flag in status reg
						//hmackeyready://set the hmackeyready flag in status reg
						waitmd2:
							begin
								procsel <= 3;
								paddata <= paddata;
							end
						digestready,lengtherror,hmackeyready: paddata <= paddata;
				endcase
			end
	end
endmodule