From e48040122cddd4374d5600b24807ef8189f1c0c2 Mon Sep 17 00:00:00 2001
From: "Pavel V. Shatov (Meister)" <meisterpaul1@yandex.ru>
Date: Fri, 11 Aug 2017 01:16:48 +0300
Subject: Work in progress.

---
 src/tb/modexp_fpga_model_vectors.v |  80 +++++++++++++++++++++
 src/tb/tb_exponentiator.v          | 139 +++++++++++++++++++++++++++++++++++--
 2 files changed, 215 insertions(+), 4 deletions(-)

(limited to 'src/tb')

diff --git a/src/tb/modexp_fpga_model_vectors.v b/src/tb/modexp_fpga_model_vectors.v
index d5284c9..c86f7ba 100644
--- a/src/tb/modexp_fpga_model_vectors.v
+++ b/src/tb/modexp_fpga_model_vectors.v
@@ -40,6 +40,46 @@ localparam [383:0] S_384 =
 	 32'ha76b945b, 32'h49a3f645, 32'h76801499, 32'hb98e6a16, 
 	 32'hd2467b6a, 32'h75b7d614, 32'h0fff0fde, 32'hb31d1819};
 
+localparam [191:0] P_192 =
+	{32'he9ac4cf6, 32'h03b2d80a, 32'h7f1d091e, 32'h49d5f1a0, 
+	 32'hac2ae4ff, 32'hbf9bf375};
+
+localparam [191:0] Q_192 =
+	{32'hc1468f3e, 32'hc6909231, 32'h5a4d74ba, 32'h477b303f, 
+	 32'h4b2e10d1, 32'h1f44e815};
+
+localparam [191:0] P_COEFF_192 =
+	{32'h8ba8d46c, 32'hb4ed830d, 32'hfbb97c6e, 32'h72d150d3, 
+	 32'h72d21392, 32'h70d2fb23};
+
+localparam [191:0] Q_COEFF_192 =
+	{32'hd863905a, 32'hc1541c8a, 32'h25952b0e, 32'ha62b0348, 
+	 32'h837f149f, 32'hd6cc58c3};
+
+localparam [191:0] FACTOR_P_192 =
+	{32'h886bad59, 32'h9bf7a46e, 32'h482ed232, 32'he55164cf, 
+	 32'hcb46a9e8, 32'he9bd888b};
+
+localparam [191:0] FACTOR_Q_192 =
+	{32'h324b776e, 32'h3734d186, 32'h73dc8796, 32'h9e1aba2c, 
+	 32'h4d5df285, 32'he97656b7};
+
+localparam [191:0] DP_192 =
+	{32'h69b6c286, 32'h95fbc613, 32'h51988034, 32'h8cb0d684, 
+	 32'h9aff38e4, 32'h9ef9ddb5};
+
+localparam [191:0] DQ_192 =
+	{32'h1eda82b7, 32'h84bf4377, 32'h39712ff7, 32'h24be179f, 
+	 32'ha302c190, 32'h80ab6159};
+
+localparam [191:0] MP_192 =
+	{32'h9e163bb5, 32'h35e718cb, 32'hcde52b7b, 32'h5db8552b, 
+	 32'h46a300e0, 32'h34f91e6b};
+
+localparam [191:0] MQ_192 =
+	{32'h7b01a724, 32'h90f0d5f9, 32'h9e237ce5, 32'h6d31fd28, 
+	 32'h4ecb9dad, 32'h58bf366a};
+
 localparam [511:0] M_512 =
 	{32'h005536b6, 32'h43ea651f, 32'h2fd3c70a, 32'ha83659cb, 
 	 32'hd0c1f47b, 32'ha8033730, 32'h29c6b082, 32'h6db48613, 
@@ -88,3 +128,43 @@ localparam [511:0] S_512 =
 	 32'hfd1e029d, 32'hfe887387, 32'h4312635f, 32'hb2b54b8d, 
 	 32'h5d3b379e, 32'h161eaa4f, 32'hedfd932b, 32'h780f0203};
 
+localparam [255:0] P_256 =
+	{32'hfedea889, 32'h97cfdb79, 32'hcca87074, 32'he5abcda1, 
+	 32'h3be201c4, 32'hc416fd15, 32'hf2130931, 32'h61ff5937};
+
+localparam [255:0] Q_256 =
+	{32'hf0889147, 32'h5aa60f93, 32'hb9927d86, 32'h8f795c5c, 
+	 32'h8e98dcf2, 32'had3aad74, 32'h9441583a, 32'h967dce41};
+
+localparam [255:0] P_COEFF_256 =
+	{32'h7af63ffc, 32'h428d9408, 32'h86e79fb9, 32'h018dad77, 
+	 32'h4ff704df, 32'h93effb1e, 32'h265d181a, 32'h47ae5379};
+
+localparam [255:0] Q_COEFF_256 =
+	{32'hd27f8aa0, 32'h9f2b9800, 32'h2dfd2392, 32'h4f868b9d, 
+	 32'h0fc51e1d, 32'h022de65b, 32'ha55f9ad1, 32'h0676be3f};
+
+localparam [255:0] FACTOR_P_256 =
+	{32'h1a5f27a1, 32'h8d16b0cb, 32'h8c2751b8, 32'h106a099c, 
+	 32'ha6efbadd, 32'hcb313a5f, 32'hf530eeb6, 32'hbbc7d8f5};
+
+localparam [255:0] FACTOR_Q_256 =
+	{32'h6794987c, 32'h932203a6, 32'h8c5b1e68, 32'h18d458e6, 
+	 32'h6737f12a, 32'h664d4187, 32'hc4ec03ba, 32'h4bd3d0c2};
+
+localparam [255:0] DP_256 =
+	{32'h2504d437, 32'hfffbe9e5, 32'hfc0aef22, 32'h9b8563bd, 
+	 32'haa83fe3b, 32'hc53b8d91, 32'h15731c5f, 32'hb6db2eeb};
+
+localparam [255:0] DQ_256 =
+	{32'hd3265fba, 32'h2eb65638, 32'h4d106ec7, 32'h000dfe69, 
+	 32'h75f87505, 32'h47d299d0, 32'h1c115cdd, 32'h599ca8c1};
+
+localparam [255:0] MP_256 =
+	{32'h23359955, 32'hcad299b6, 32'h049bb248, 32'h3828b6a5, 
+	 32'h74c85825, 32'h7dd8e109, 32'h07edbda9, 32'h4980c2c9};
+
+localparam [255:0] MQ_256 =
+	{32'h8578120b, 32'h91f4ca9e, 32'h371d3e70, 32'h0005bb89, 
+	 32'hd31ed864, 32'h477bd9cf, 32'h65a1f03b, 32'h606d3bc8};
+
diff --git a/src/tb/tb_exponentiator.v b/src/tb/tb_exponentiator.v
index 16be0a5..440fedc 100644
--- a/src/tb/tb_exponentiator.v
+++ b/src/tb/tb_exponentiator.v
@@ -63,6 +63,8 @@ module tb_exponentiator;
 	reg				rst_n;
 	reg				ena;
 	
+	reg				crt;
+	
 	reg	[ 3: 0]	n_num_words;
 	reg	[ 8: 0]	d_num_bits;
 
@@ -170,6 +172,8 @@ module tb_exponentiator;
 		.ena						(ena), 
 		.rdy						(rdy), 
 		
+		.crt						(crt),
+		
 		.m_bram_addr			(core_m_addr),
 		.d_bram_addr			(core_d_addr),
 		.f_bram_addr			(core_f_addr),
@@ -206,9 +210,14 @@ module tb_exponentiator;
 		#200;		
 		rst_n = 1'b1;
 		#100;
-		
-		test_exponent_384(M_384, D_384, FACTOR_384, N_384, N_COEFF_384, S_384);
-		test_exponent_512(M_512, D_512, FACTOR_512, N_512, N_COEFF_512, S_512);
+
+			// test "honest" exponentiation
+//		test_exponent_384(M_384, D_384, FACTOR_384, N_384, N_COEFF_384, S_384);
+//		test_exponent_512(M_512, D_512, FACTOR_512, N_512, N_COEFF_512, S_512);
+
+			// test crt mode
+		test_exponent_192(M_384, DP_192, FACTOR_P_192, P_192, P_COEFF_192, MP_192);
+		//test_exponent_192(M_384, DQ_192, FACTOR_Q_192, Q_192, Q_COEFF_192, MQ_192);
 		
 	end
       
@@ -216,7 +225,6 @@ module tb_exponentiator;
 		//
 		// Test Tasks
 		//
-		
 	task test_exponent_384;
 		//
 		input	[383:0] m;
@@ -234,6 +242,8 @@ module tb_exponentiator;
 			n_num_words = 4'd11;								// set number of words
 			d_num_bits = 9'd383;								// set number of bits
 			//
+			crt = 0;												// disable crt mode
+			//
 			write_memory_384(m, d, f, n, n_coeff);		// fill memory
 			
 			ena = 1;												// start operation
@@ -276,6 +286,8 @@ module tb_exponentiator;
 			n_num_words = 4'd15;								// set number of words
 			d_num_bits = 9'd511;								// set number of bits
 			//
+			crt = 0;												// disable crt mode
+			//
 			write_memory_512(m, d, f, n, n_coeff);		// fill memory
 			
 			ena = 1;												// start operation
@@ -301,6 +313,49 @@ module tb_exponentiator;
 		//
 	endtask
 
+	task test_exponent_192;
+		//
+		input	[383:0] m;
+		input	[191:0] d;
+		input [191:0] f;
+		input	[191:0] n;
+		input	[191:0] n_coeff;
+		input	[191:0] s;
+		reg   [191:0] r;
+		//
+		integer i;
+		//
+		begin
+			//						
+			n_num_words = 4'd5;								// set number of words
+			d_num_bits = 9'd191;								// set number of bits
+			//
+			crt = 1;												// enable crt mode
+			//
+			write_memory_192(m, d, f, n, n_coeff);		// fill memory
+			
+			ena = 1;												// start operation
+			#10;													//
+			ena = 0;												// clear flag
+			
+			while (!rdy) #10;									// wait for operation to complete
+			read_memory_192(r);								// get result from memory
+						
+			$display("    calculated: %x", r);			// display result
+			$display("    expected:   %x", s);			//
+							
+				// check calculated value
+			if (r === s) begin
+				$display("        OK");
+				$display("SUCCESS: Test passed.");
+			end else begin
+				$display("        ERROR");
+				$display("FAILURE: Test not passed.");
+			end
+			//
+		end
+		//
+	endtask
 
 	//
 	// write_memory_384
@@ -408,6 +463,59 @@ module tb_exponentiator;
 	endtask
 
 
+	//
+	// write_memory_192
+	//
+	task write_memory_192;
+		//
+		input	[383:0] m;
+		input	[191:0] d;
+		input	[191:0] f;
+		input	[191:0] n;
+		input	[191:0] n_coeff;
+		reg	[383:0] m_shreg;
+		reg	[191:0] f_shreg;
+		reg	[191:0] d_shreg;
+		reg	[191:0] n_shreg;
+		reg	[191:0] n_coeff_shreg;
+		//
+		begin
+			//
+			tb_mdfn_wren	= 1;			// start filling memories
+			m_shreg			= m;			// preload shift register
+			d_shreg			= d;			// preload shift register
+			f_shreg			= f;			// preload shift register
+			n_shreg			= n;			// preload shift register
+			n_coeff_shreg	= n_coeff;	// preload shift register
+			//
+			for (w=0; w<NUM_WORDS_384; w=w+1) begin							// write all words
+				tb_mdfn_addr		= w[3:0];											// set address
+				tb_m_data			= m_shreg[31:0];									// set data
+				tb_d_data			= d_shreg[31:0];									// set data
+				tb_f_data			= f_shreg[31:0];									// set data
+				tb_n_data			= n_shreg[31:0];									// set data
+				tb_n_coeff_data	= n_coeff_shreg[31:0];							// set data
+				m_shreg				= {{32{1'bX}}, m_shreg[383:32]};				// update shift register
+				d_shreg				= {{32{1'bX}}, d_shreg[191:32]};				// update shift register
+				f_shreg				= {{32{1'bX}}, f_shreg[191:32]};				// update shift register
+				n_shreg				= {{32{1'bX}}, n_shreg[191:32]};				// update shift register
+				n_coeff_shreg		= {{32{1'bX}}, n_coeff_shreg[191:32]};		// update shift register
+				#10;																			// wait for 1 clock tick
+			end
+			//
+			tb_mdfn_addr		= {4{1'bX}};	// wipe addresses
+			tb_m_data			= {32{1'bX}};	// wipe data
+			tb_d_data			= {32{1'bX}};	// wipe data
+			tb_f_data			= {32{1'bX}};	// wipe data
+			tb_n_data			= {32{1'bX}};	// wipe data
+			tb_n_coeff_data	= {32{1'bX}};	// wipe data
+			tb_mdfn_wren	= 0;				// stop filling memory
+			//
+		end
+		//
+	endtask
+
+
 	//
 	// read_memory_384
 	//
@@ -455,6 +563,29 @@ module tb_exponentiator;
 		//
 	endtask
 
+	//
+	// read_memory_192
+	//
+	task read_memory_192;
+		//
+		output	[191:0] r;
+		reg		[191:0] r_shreg;
+		//
+		begin
+			//
+			for (w=0; w<NUM_WORDS_384/2; w=w+1) begin		// read result word-by-word
+				tb_r_addr	= w[3:0];							// set address
+				#10;													// wait for 1 clock tick
+				r_shreg = {tb_r_data, r_shreg[191:32]};	// store data word
+			end
+			//
+			tb_r_addr = {4{1'bX}};								// wipe address
+			r = r_shreg;											// return
+			//
+		end
+		//
+	endtask
+
 
 endmodule
 
-- 
cgit v1.2.3