[Cryptech-Commits] [core/math/modexp] 01/01: Updating modexp core to v 0.50. This version contains a working core that can perform sign and verify with big keys/values. The core builds ok in Altera and Xilinx FPGA tools. This commit also includes a new testgenerator capable of generating testbench for modexp with autgenerated test data of different lengths. The README has been updated with status and implementation results in for different FPGA devices.

git at cryptech.is git at cryptech.is
Mon Apr 27 09:17:23 UTC 2015


This is an automated email from the git hooks/post-receive script.

joachim at secworks.se pushed a commit to branch master
in repository core/math/modexp.

commit a315223f98fa6f1fdea2b1080c5f3e33352ebb13
Author: Joachim Strömbergson <joachim at secworks.se>
Date:   Mon Apr 27 11:17:08 2015 +0200

    Updating modexp core to v 0.50. This version contains a working core that can perform sign and verify with big keys/values. The core builds ok in Altera and Xilinx FPGA tools. This commit also includes a new testgenerator capable of generating testbench for modexp with autgenerated test data of different lengths. The README has been updated with status and implementation results in for different FPGA devices.
---
 .gitignore                                         |    2 +
 README.md                                          |   88 +-
 src/model/c/src/autogenerated_tests.c              |  154 ++
 src/model/c/src/montgomery_array.c                 |   23 +-
 src/model/c/src/montgomery_array.h                 |    2 +-
 src/model/python/modexp.py                         |  203 ++
 src/rtl/modexp.v                                   |  348 ++-
 src/rtl/montprod.v                                 |   12 +-
 src/tb/tb_modexp.v                                 |  466 +++-
 src/tb/tb_modexp_autogenerated.v                   | 2289 +++++++++++++++-----
 src/tb/tb_modexp_autogenerated_template.v          |   54 +-
 src/tb/tb_montprod.v                               |    6 +-
 src/tb/tb_residue.v                                |    8 +-
 .../modexp/testgenerator/TestGeneratorBasic.java   |   13 +-
 .../testgenerator/format/GeneratorVerilog.java     |  109 +-
 .../testgenerator/format/ModExpTestFormater.java   |    1 +
 toolruns/Makefile                                  |   15 +-
 17 files changed, 3058 insertions(+), 735 deletions(-)

diff --git a/.gitignore b/.gitignore
index 0836c09..11c1e07 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,5 @@ toolruns/montprod.sim
 toolruns/top.sim
 
 toolruns/residue.sim
+
+toolruns/modexp.autogenerated.sim
diff --git a/README.md b/README.md
index 199e074..19f6d97 100644
--- a/README.md
+++ b/README.md
@@ -4,19 +4,23 @@ modexp
 Modular exponentiation core for implementing public key algorithms such
 as RSA, DH, ElGamal etc.
 
-The core calculates the following functions:
+The core calculates the following function:
 
   C = M ** e mod N
-  M = C ** d mod N
 
-  d is the private key exponent.
   M is a message with a length of n bits
-  e is the exponent with a length of at most 32 bits
+  e is the exponent with a length of m bits
   N is the modulus  with a length of n bits
-  n is can be 32 and up to and including 8192 bits in steps
-  of 32 bits.
 
-The core has a 32-bit memory like interface.
+The size n be one and up to and including 8192 bits in steps of 32
+bits.
+
+The size m be one and up to and including 8192 bits in steps of 32
+bits.
+
+The core has a 32-bit memory like interface, but provides status signals
+to inform the system that a given operation has is done. Additionally,
+any errors will also be asserted.
 
 The core is written in Verilog 2001 and suitable for implementation in
 FPGA and ASIC devices. No vendor specific macros are used in the code.
@@ -24,39 +28,67 @@ FPGA and ASIC devices. No vendor specific macros are used in the code.
 
 ## Implementation details ##
 
-The core is using Montgomery multiplication with 32-bit operands. The
-core is iterative and will not be the fastest core on the
-planet. The residue calculation is done in a separate process and the
-calculated residue can be extracted and loaded by the application to
-improve performance.
+The core is iterative with 32-bit operands and not the fastest core on
+the planet.
+
+
+## Future developments ##
 
-The core will perform blinding to protect against side channel
-attacks.
+- The core will perform blinding to protect against side channel
+  attacks.
+
+- Increased operands to 64-, 128-, or possibly even 256 bits for
+  increased performance.
 
 
 ## FPGA-results ##
 
-No results yet.
+## Altera Cyclone-V ###
+
+- 203 registers
+- 387 ALMs
+- 106496 block memory bits
+- 107 MHz
+
+
+### Xilinx Artix-7 100T ###
+
+- 160 registers
+- 565 LUTs
+- 13 RAMB18E1 block memories
+- 160 MHz
+
+### Xilinx Spartan-6 LX45 ###
+
+- 169 registers
+- 589 LUTs
+- 13 RAMB8BWER block memories
+- 136 MHz
 
 
 ## Status ##
 
-***(2015-04-20)***
+***(2015-04-27)***
+
+Modexp simulation with exponent and modolus with up to 1280 bits
+simulates. The auto test generation system works. Implementation in
+different FPGA types and vendors works.
+
+
+***(2015-04-23)***
+
+The Montgomery multiplication module works. The Residue calculation
+module works. Top level integration and debugging is onging. The core
+does not yet work and there are dragons to be found.
 
-The Montgomery calculator has been implemented and debugged. The residue
-calculator has been implemeted and debugged. The top level is being
-developed and debugged.
 
+***(2014-12-07)***
 
-***(2015-03-13)***
+Renamed the core tom modexp from rsa to make it more clear that it
+provides generic modular exponentiation, not RSA.
 
-A working, bit exact C model with test cases has been developed and is
-used to drive the HW development. There is also a Java functional model
-available as support for high level undertanding.
 
-Development of the Montgomery product module started. Top level modexp
-module with memories for all operands are being worked on.
+***(2014-10-01)***
 
-The Montgomery calculator has been implemented and debugged. The residue
-calculator has been implemeted and debugged. The top level is being
-developed and debugged.
+Very early phase. Started to collect information and drawing some rough
+ideas on paper.
diff --git a/src/model/c/src/autogenerated_tests.c b/src/model/c/src/autogenerated_tests.c
index e9ec0b7..2a80c42 100644
--- a/src/model/c/src/autogenerated_tests.c
+++ b/src/model/c/src/autogenerated_tests.c
@@ -202,6 +202,146 @@ void autogenerated_BASIC_M7037130911981370263(void) {
   mod_exp_array(1, X, E, M, Z);
   assertArrayEquals(1, expected, Z);
 }
+void autogenerated_BASIC_5073338267670769216(void) {
+  printf("=== autogenerated_BASIC_5073338267670769216 ===\n");
+  uint32_t X[] = { 0x3028983f, 0xdc9bdc25, 0xa3fdfeda, 0x283f4463 };
+  uint32_t E[] = { 0x29493211, 0xc4252db0, 0x7775443d, 0x13e1d929 };
+  uint32_t M[] = { 0x2fb9ba2f, 0xa485d5f7, 0x3c6652c9, 0x670fdbfd };
+  uint32_t expected[] = { 0x2f45cdd6, 0x23f0e6f2, 0xaa4bd5d8, 0x6297da06 };
+  uint32_t Z[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
+  mod_exp_array(4, X, E, M, Z);
+  assertArrayEquals(4, expected, Z);
+}
+void autogenerated_BASIC_M1841989679506188752(void) {
+  printf("=== autogenerated_BASIC_M1841989679506188752 ===\n");
+  uint32_t X[] = { 0x29462882, 0x12caa2d5, 0xb80e1c66, 0x1006807f };
+  uint32_t E[] = { 0x3285c343, 0x2acbcb0f, 0x4d023228, 0x2ecc73db };
+  uint32_t M[] = { 0x267d2f2e, 0x51c216a7, 0xda752ead, 0x48d22d89 };
+  uint32_t expected[] = { 0x0ddc404d, 0x91600596, 0x7425a8d8, 0xa066ca56 };
+  uint32_t Z[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
+  mod_exp_array(4, X, E, M, Z);
+  assertArrayEquals(4, expected, Z);
+}
+void autogenerated_BASIC_M3339729654500648482(void) {
+  printf("=== autogenerated_BASIC_M3339729654500648482 ===\n");
+  uint32_t X[] = { 0x2963efb9, 0xc6f5d260, 0xa2d0fe74, 0x49726b57 };
+  uint32_t E[] = { 0x2f55c103, 0xbace4bf1, 0x2ab9fac2, 0x30aec7d3 };
+  uint32_t M[] = { 0x376cf9ae, 0xd9e988e8, 0xbd995f5c, 0xdeec42f5 };
+  uint32_t expected[] = { 0x0ce8cff7, 0x9f564e2c, 0x1b61e3d9, 0x717db9ef };
+  uint32_t Z[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
+  mod_exp_array(4, X, E, M, Z);
+  assertArrayEquals(4, expected, Z);
+}
+void autogenerated_BASIC_M6837928193394880512(void) {
+  printf("=== autogenerated_BASIC_M6837928193394880512 ===\n");
+  uint32_t X[] = { 0x2a9283cc, 0x5999f49d, 0xf8cf6ab2, 0x5f47bf25 };
+  uint32_t E[] = { 0x2c7564a0, 0x2d1fcda1, 0x2825318a, 0xae23c271 };
+  uint32_t M[] = { 0x32b892f9, 0x096c5ada, 0x43918370, 0x8398c7e3 };
+  uint32_t expected[] = { 0x27cf8839, 0x94004d82, 0xa0d69d86, 0x3f61a929 };
+  uint32_t Z[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
+  mod_exp_array(4, X, E, M, Z);
+  assertArrayEquals(4, expected, Z);
+}
+void autogenerated_BASIC_M7333111649825079555(void) {
+  printf("=== autogenerated_BASIC_M7333111649825079555 ===\n");
+  uint32_t X[] = { 0x246fa2ec, 0x405f234d, 0x39b93e77, 0xf16bcc91 };
+  uint32_t E[] = { 0x2807eb7a, 0x646df633, 0xeaa95a21, 0x85252adf };
+  uint32_t M[] = { 0x2cdd3307, 0x782e5711, 0x584f179b, 0x011087df };
+  uint32_t expected[] = { 0x02d6e42e, 0x46e2d304, 0x435170c1, 0x9f344f83 };
+  uint32_t Z[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
+  mod_exp_array(4, X, E, M, Z);
+  assertArrayEquals(4, expected, Z);
+}
+void autogenerated_BASIC_480186175131589607(void) {
+  printf("=== autogenerated_BASIC_480186175131589607 ===\n");
+  uint32_t X[] = { 0x300a5cf7, 0x269f6369, 0x02e025cb, 0xaf16fcfd };
+  uint32_t E[] = { 0x2cc4b1c0, 0x9205a8b4, 0xbc130ee2, 0x923f1f3f };
+  uint32_t M[] = { 0x2cd376d5, 0xd9e3b080, 0x2533288a, 0xd4b9bb37 };
+  uint32_t expected[] = { 0x0ae9c475, 0xf4fb4c63, 0xcf2c4f56, 0x902eba0c };
+  uint32_t Z[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
+  mod_exp_array(4, X, E, M, Z);
+  assertArrayEquals(4, expected, Z);
+}
+void autogenerated_BASIC_M5239159917778665002(void) {
+  printf("=== autogenerated_BASIC_M5239159917778665002 ===\n");
+  uint32_t X[] = { 0x3eaed5af, 0xa287db7e, 0x4ff07fee, 0x9bbda80b };
+  uint32_t E[] = { 0x3c077d49, 0xf3a131ab, 0x6289042a, 0xc15083cb };
+  uint32_t M[] = { 0x344b8538, 0xcf4f2576, 0xd28c1c52, 0xc83a8199 };
+  uint32_t expected[] = { 0x15028046, 0x5c12d235, 0x7580fd1b, 0x6bc76b24 };
+  uint32_t Z[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
+  mod_exp_array(4, X, E, M, Z);
+  assertArrayEquals(4, expected, Z);
+}
+void autogenerated_BASIC_228752064885223799(void) {
+  printf("=== autogenerated_BASIC_228752064885223799 ===\n");
+  uint32_t X[] = { 0x3904d7ab, 0x13937a4f, 0x926856d1, 0x6bdda621 };
+  uint32_t E[] = { 0x3d360083, 0xa50eaf0e, 0xffce2df2, 0xb1f51cef };
+  uint32_t M[] = { 0x2d32376f, 0x205555b3, 0x2c9daf8c, 0xe2b7cf81 };
+  uint32_t expected[] = { 0x08836692, 0xe6398828, 0x1eeccd57, 0x2c231153 };
+  uint32_t Z[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
+  mod_exp_array(4, X, E, M, Z);
+  assertArrayEquals(4, expected, Z);
+}
+void autogenerated_BASIC_856940511857911599(void) {
+  printf("=== autogenerated_BASIC_856940511857911599 ===\n");
+  uint32_t X[] = { 0x23e80223, 0x52b700ee, 0x6cb8a294, 0x47c6fac9 };
+  uint32_t E[] = { 0x253cebdb, 0xcc78dcb4, 0x925682b3, 0x490c424b };
+  uint32_t M[] = { 0x2f2885eb, 0x67987cee, 0x717298bd, 0x7a1baf7b };
+  uint32_t expected[] = { 0x2bb0b86c, 0xc854652b, 0x2b2bce27, 0xd2595a8e };
+  uint32_t Z[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
+  mod_exp_array(4, X, E, M, Z);
+  assertArrayEquals(4, expected, Z);
+}
+void autogenerated_BASIC_M6501553661140603953(void) {
+  printf("=== autogenerated_BASIC_M6501553661140603953 ===\n");
+  uint32_t X[] = { 0x287e9711, 0x4d346dab, 0x3ff5e6da, 0xa93edebd };
+  uint32_t E[] = { 0x3658192a, 0x4b5fac3f, 0x9a78bc81, 0x5ac8c667 };
+  uint32_t M[] = { 0x238cd95d, 0x298ee5e1, 0x320323da, 0x0a46ec21 };
+  uint32_t expected[] = { 0x0415fef6, 0x5fc81702, 0x8be83fd4, 0x4c7fbf24 };
+  uint32_t Z[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
+  mod_exp_array(4, X, E, M, Z);
+  assertArrayEquals(4, expected, Z);
+}
+void autogenerated_BASIC_M8496483018338900149(void) {
+  printf("=== autogenerated_BASIC_M8496483018338900149 ===\n");
+  uint32_t X[] = { 0x3b4511d5, 0x5f61da31, 0x4bf252e0, 0x3962f93c, 0x590171d0, 0xda31097f, 0x0f73fee3, 0x0ba1b379, 0x514b7d8f, 0x1e337cf9, 0x733512ac, 0x4f5b0b52, 0x40762697, 0xb3a30c84, 0x5563b4db, 0x59f7cef1 };
+  uint32_t E[] = { 0x271cb7c4, 0x11f07a63, 0x1df850e7, 0x8bf6df66, 0x7bc8fa0e, 0xa51002ce, 0xf16946c5, 0x96916dc7, 0xba1681b1, 0x5ca395ab, 0x7839780d, 0xc5e760c3, 0x578af4f9, 0xffbbbd8c, 0x8576c8fc, 0x518012a7 };
+  uint32_t M[] = { 0x3c0f154d, 0x7fc7750a, 0x03eb8968, 0xfbde501a, 0x63848fe5, 0xdcd7d883, 0x5131c9f9, 0xa9ca3399, 0xba581205, 0x4cf86f2a, 0xed928b92, 0x13a0e90f, 0x5b24c81a, 0xf4ac077c, 0x68b8ac70, 0xc58961fd };
+  uint32_t expected[] = { 0x30d0a0c1, 0x1be7b00f, 0x9ed921c6, 0x7a7f9a87, 0xb8ed7f88, 0xd81f20d5, 0xb3ba9839, 0x38dfdfb4, 0x70b1927c, 0xa4b9487b, 0x8d8d7e2c, 0xc706e737, 0x17e9c280, 0xbec0006a, 0xeea7dc97, 0x4f5badc9 };
+  uint32_t Z[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
+  mod_exp_array(16, X, E, M, Z);
+  assertArrayEquals(16, expected, Z);
+}
+void autogenerated_BASIC_6145567102166328515(void) {
+  printf("=== autogenerated_BASIC_6145567102166328515 ===\n");
+  uint32_t X[] = { 0x23446522, 0x9185c81e, 0x09283a50, 0x82c1f517, 0xd00d3159, 0x846c2c99, 0x261d1dcb, 0xde183d66, 0x98f8a990, 0xd295bd50, 0x09ef8644, 0xadcf9cdb, 0x5eec13a3, 0x92baa627, 0x18caa215, 0x8836480f };
+  uint32_t E[] = { 0x397f2b38, 0xa95cc0bc, 0xc13b26cf, 0xa20dda3c, 0xf8801c39, 0x00731abe, 0x2ad0afc4, 0xdb247141, 0xc29b5a2d, 0x9e51a3ed, 0xcf364a51, 0x90b761d5, 0xfa0624d3, 0x3a0b27c7, 0xa36bc66c, 0x6423efd3 };
+  uint32_t M[] = { 0x3ad2464f, 0x75da362c, 0x6e5c37b4, 0x432cc6b7, 0x6f48b57c, 0xebb87e14, 0x0a3d3f4d, 0xfa4c32c0, 0x165a5892, 0x742f720d, 0x8b4e1b43, 0x281d5390, 0xff2f77dc, 0x698dbc05, 0xdee97a68, 0xde2c176d };
+  uint32_t expected[] = { 0x083aa822, 0x7c70341a, 0xa2cbc9a8, 0xd116bc41, 0x79a81ba7, 0x584c91c8, 0x5b87c314, 0xc5e6f4f9, 0x601ebead, 0x054bf14b, 0x65b48a4a, 0xf8aa2700, 0xa765ee1d, 0xb6c638cd, 0x7e529f23, 0x0d4adfff };
+  uint32_t Z[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
+  mod_exp_array(16, X, E, M, Z);
+  assertArrayEquals(16, expected, Z);
+}
+void autogenerated_BASIC_7216348574014690328(void) {
+  printf("=== autogenerated_BASIC_7216348574014690328 ===\n");
+  uint32_t X[] = { 0x35baa860, 0x4e47ad49, 0xc6c4a7c0, 0x7857335b, 0x9b81d24f, 0x7be86e34, 0xf84f7560, 0x484b20db, 0xb83b4f9e, 0x694c6987, 0x7d3232f5, 0x18ee8603, 0x94eca5ef, 0x5179ef69, 0xf6600efb, 0xfc71deab, 0xdb939552, 0x642db1e0, 0x78e11e39, 0x924f0dbd, 0xdb225803, 0x449bbb35, 0xfc40ee05, 0x9b19931c, 0x8b8af884, 0xb5f96476, 0xf97ad419, 0xcc7543f9, 0xce25ed83, 0x94da3499, 0x4f37f331, 0xe64e7799 };
+  uint32_t E[] = { 0x3a7570f2, 0x38cb0f2f, 0x2e6c8989, 0xcf7c2665, 0xa0fce3d0, 0x12c7a8eb, 0x40fab1ea, 0x39eb4809, 0x822fa6cc, 0x4ef9d604, 0x2ca1cd3b, 0xa9b23cdb, 0x17e823ce, 0x5fea5198, 0x1ab12946, 0xcec748b5, 0x752a3a6f, 0x73421a9a, 0x7138d7a4, 0xa47327c0, 0x17475543, 0xe841c19a, 0x3085410a, 0x06438b4c, 0xe0d4b918, 0xfeccca17, 0x9ed86072, 0x86db4a93, 0x60c7d437, 0xcdfe77e3, 0x2631f264, 0x80c9b645 };
+  uint32_t M[] = { 0x34d90901, 0xf192009c, 0xc34f345f, 0x63f592b2, 0xaba32d7a, 0x161d1510, 0x2c264dec, 0x07306f1d, 0x3e61c031, 0xacd4eba0, 0xff1318ff, 0x09a78cf4, 0x97bace67, 0xc8fcecf4, 0x3b3901a3, 0x5d447957, 0xc0397708, 0x7e7e48f9, 0x571db58a, 0x80d65921, 0x68a025e0, 0x4f85f776, 0xaa8450c7, 0x15c42f52, 0xe65507f2, 0xdfeed660, 0x0db8eddb, 0xb1e48d93, 0x7e314a2f, 0xea81ccb1, 0xbe22cc03, 0xf2928621 };
+  uint32_t expected[] = { 0x14c07087, 0x3e92a437, 0xbfd5a5b3, 0xec017ed5, 0xacf23e12, 0x6e48a51f, 0xe1fdbde9, 0x43fade6b, 0x98935c7a, 0xaff9b1e5, 0x3adaa120, 0xcbaa5af5, 0x344fabb2, 0x8d2987c7, 0xfb83d342, 0x3f85bbfc, 0xc30e755a, 0x37f20fa4, 0x7fb5621b, 0xcd1cef03, 0x664ccb56, 0xce0a28b9, 0xa9cbdd51, 0xad12eb24, 0xacc08c8d, 0x5d9fe7f5, 0x018c1e1e, 0x2115bba8, 0x22b52262, 0xaee3bf8a, 0x91824a22, 0xde48a1f3 };
+  uint32_t Z[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
+  mod_exp_array(32, X, E, M, Z);
+  assertArrayEquals(32, expected, Z);
+}
+void autogenerated_BASIC_M5663191947183200100(void) {
+  printf("=== autogenerated_BASIC_M5663191947183200100 ===\n");
+  uint32_t X[] = { 0x21558179, 0x3e2914b1, 0xefe95957, 0x965fdead, 0xe766d8fc, 0x136eadf4, 0xa6106a2a, 0x88b2df7e, 0xe0b0eaae, 0x2c17946a, 0x6f5b5563, 0x228052ae, 0x7fc40d80, 0xf81354db, 0xfceecd1a, 0xa5e4c97d, 0x433ecfcd, 0xc20d1e4d, 0x2a748fe3, 0x1d9e63f0, 0xdc6c25d6, 0xdae5c8be, 0x1d8c5431, 0xb1d7d270, 0xed5b2566, 0x1463b0fd, 0xa9e26cf7, 0x3dd6fbd7, 0x1347c8f7, 0x76c2cc37, 0xf382b786, 0x1d5ac517, 0x26b96692, 0x2c1fe6f8, 0x5852dbf8, 0x4bcabda2, 0xbedb2f5f, 0xbfe58158, 0x8cd5d15f, 0xac7 [...]
+  uint32_t E[] = { 0x2519837b, 0xe73a9031, 0xe241606d, 0x21e70fa2, 0x7881f254, 0x4e60831d, 0x266f408e, 0x4a83e6ed, 0xa7741995, 0x32b477ba, 0x91bdf5d0, 0x4acd7a06, 0x51e344b9, 0xdf376e4e, 0x8494e625, 0xa0cc9697, 0x817a0c93, 0x3b68cefb, 0x46de14c1, 0x52229965, 0x329645bd, 0xf4176adc, 0x29a8bc50, 0x44900fec, 0x1558d492, 0xf838a8e7, 0xea207abd, 0xcd21a28c, 0x91e6b02f, 0x2a490ea8, 0x5d99663b, 0x87c92fb6, 0x0a185325, 0x5256a7a3, 0x496b7288, 0x6688b6c8, 0x650e1776, 0x54cd429f, 0x90ea3b18, 0x0b7 [...]
+  uint32_t M[] = { 0x2c5337a9, 0x3f2e1ca6, 0x91de65ea, 0xc3f9a3c2, 0xdc9099e0, 0x64ebe412, 0xf4583fae, 0x1fc8e8dd, 0x92dcbbfb, 0x9159239e, 0xdbbec456, 0x8735a660, 0x8248dbbc, 0x76f01415, 0x3cb8a897, 0x7cc09280, 0x6cc6db51, 0x9c2544da, 0x316564ce, 0x4b6d9b3b, 0x3e0e123f, 0x942a4a3c, 0x1f128873, 0x5ad14862, 0xdde8e6dd, 0x73da31fb, 0x1a8a2046, 0xc3ff18c6, 0x24e31d54, 0x7d8a1796, 0x88ab346c, 0x262bb321, 0x2cada5dc, 0x1fb2284c, 0x042375fd, 0xba10d309, 0xcda978ec, 0x229ee156, 0x8470728a, 0xa58 [...]
+  uint32_t expected[] = { 0x24665860, 0x4b150493, 0xc0834602, 0xc0b99ab5, 0xbe649545, 0xa7d8b1ca, 0x55c1b98a, 0x1dce374b, 0x65750415, 0x573dfed7, 0x95df9943, 0x58a4aea0, 0x5fb40a92, 0x1408d9c2, 0xb5e23fc9, 0x225eb60b, 0x41d33a41, 0xbf958f7f, 0x619f5ac1, 0x207647f3, 0x223e56f8, 0x26afd4ae, 0x6a297840, 0x830947db, 0xbc5af940, 0x4c97ebb1, 0xca38b220, 0x04c9a26d, 0x49a16b72, 0x0882c658, 0x2dbc50e0, 0x67e2d057, 0x4b8ef356, 0x4ba5eac3, 0x17237d9f, 0x27c111a8, 0xc1b1944e, 0xe91fd6b6, 0xa78d9747 [...]
+  uint32_t Z[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000 [...]
+  mod_exp_array(64, X, E, M, Z);
+  assertArrayEquals(64, expected, Z);
+}
 void autogenerated_tests(void) {
   autogenerated_BASIC_M4962768465676381896();
   autogenerated_BASIC_8982867242010371843();
@@ -223,5 +363,19 @@ void autogenerated_tests(void) {
   autogenerated_BASIC_M2453278165832221565();
   autogenerated_BASIC_M1847183855567461116();
   autogenerated_BASIC_M7037130911981370263();
+  autogenerated_BASIC_5073338267670769216();
+  autogenerated_BASIC_M1841989679506188752();
+  autogenerated_BASIC_M3339729654500648482();
+  autogenerated_BASIC_M6837928193394880512();
+  autogenerated_BASIC_M7333111649825079555();
+  autogenerated_BASIC_480186175131589607();
+  autogenerated_BASIC_M5239159917778665002();
+  autogenerated_BASIC_228752064885223799();
+  autogenerated_BASIC_856940511857911599();
+  autogenerated_BASIC_M6501553661140603953();
+  autogenerated_BASIC_M8496483018338900149();
+  autogenerated_BASIC_6145567102166328515();
+  autogenerated_BASIC_7216348574014690328();
+  autogenerated_BASIC_M5663191947183200100();
 
 }
diff --git a/src/model/c/src/montgomery_array.c b/src/model/c/src/montgomery_array.c
index 0ddc742..c3579a9 100644
--- a/src/model/c/src/montgomery_array.c
+++ b/src/model/c/src/montgomery_array.c
@@ -3,22 +3,15 @@
 #include "bignum_uint32_t.h"
 #include "montgomery_array.h"
 
-void mont_prod_array(uint32_t length, uint32_t *A, uint32_t *B, uint32_t *M,
-		uint32_t *temp, uint32_t *s) {
+void mont_prod_array(uint32_t length, uint32_t *A, uint32_t *B, uint32_t *M, uint32_t *s) {
 	zero_array(length, s);
 	for (int32_t wordIndex = ((int32_t) length) - 1; wordIndex >= 0; wordIndex--) {
 		for (int i = 0; i < 32; i++) {
 
-			int b = (B[wordIndex] >> i) & 1;
+			uint32_t b = (B[wordIndex] >> i) & 1;
 
 			//q = (s - b * A) & 1;
-			sub_array(length, s, A, temp);
-			int q;
-			if (b == 1) {
-				q = temp[length - 1] & 1;
-			} else {
-				q = s[length - 1] & 1;
-			}
+			uint32_t q = (s[length-1] ^ (A[length-1] & b)) & 1; // int q = (s - b * A) & 1;
 
 			// s = (s + q*M + b*A) >>> 1;
 			if (q == 1) {
@@ -77,11 +70,11 @@ void mont_exp_array(uint32_t length, uint32_t *X, uint32_t *E, uint32_t *M,
 	// 2. Z0 := MontProd( 1, Nr, M )
 	zero_array(length, ONE);
 	ONE[length - 1] = 1;
-	mont_prod_array(length, ONE, Nr, M, temp, Z);
+	mont_prod_array(length, ONE, Nr, M, Z);
 	//debugArray("Z0", length, Z);
 
 	// 3. P0 := MontProd( X, Nr, M );
-	mont_prod_array(length, X, Nr, M, temp, P);
+	mont_prod_array(length, X, Nr, M, P);
 	//debugArray("P0", length, P);
 
 	// 4. for i = 0 to n-1 loop
@@ -91,18 +84,18 @@ void mont_exp_array(uint32_t length, uint32_t *X, uint32_t *E, uint32_t *M,
 		uint32_t ei = (ei_ >> (i % 32)) & 1;
 		// 6. if (ei = 1) then Zi+1 := MontProd ( Zi, Pi, M) else Zi+1 := Zi
 		if (ei == 1) {
-			mont_prod_array(length, Z, P, M, temp, temp2);
+			mont_prod_array(length, Z, P, M, temp2);
 			copy_array(length, temp2, Z);
 			//debugArray("Z ", length, Z);
 		}
 		// 5. Pi+1 := MontProd( Pi, Pi, M );
-		mont_prod_array(length, P, P, M, temp, temp2);
+		mont_prod_array(length, P, P, M, temp2);
 		copy_array(length, temp2, P);
 		//debugArray("P ", length, P);
 		// 7. end for
 	}
 	// 8. Zn := MontProd( 1, Zn, M );
-	mont_prod_array(length, ONE, Z, M, temp, temp2);
+	mont_prod_array(length, ONE, Z, M, temp2);
 	copy_array(length, temp2, Z);
 	//debugArray("Z ", length, Z);
 	// 9. RETURN Zn
diff --git a/src/model/c/src/montgomery_array.h b/src/model/c/src/montgomery_array.h
index 82ef9de..984bc07 100644
--- a/src/model/c/src/montgomery_array.h
+++ b/src/model/c/src/montgomery_array.h
@@ -9,7 +9,7 @@
 #define MONTGOMERY_ARRAY_H_
 
 void mont_prod_array(uint32_t length, uint32_t *A, uint32_t *B, uint32_t *M,
-		uint32_t *temp, uint32_t *s);
+		uint32_t *s);
 void mod_exp_array(uint32_t length, uint32_t *X, uint32_t *E, uint32_t *M, uint32_t *Z);
 
 #endif /* MONTGOMERY_ARRAY_H_ */
diff --git a/src/model/python/modexp.py b/src/model/python/modexp.py
new file mode 100755
index 0000000..97aab0b
--- /dev/null
+++ b/src/model/python/modexp.py
@@ -0,0 +1,203 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#=======================================================================
+#
+# modexp.py
+# ---------
+# A python model for doing modular exponention.
+#
+#
+# Author: Joachim Strömbergson
+# Copyright (c) 2014, Secworks Sweden AB
+#
+# Redistribution and use in source and binary forms, with or
+# without modification, are permitted provided that the following
+# conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in
+#    the documentation and/or other materials provided with the
+#    distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+#=======================================================================
+
+#-------------------------------------------------------------------
+# Python module imports.
+#-------------------------------------------------------------------
+import sys
+
+
+#-------------------------------------------------------------------
+# Defines.
+#-------------------------------------------------------------------
+VERBOSE = False
+
+
+#-------------------------------------------------------------------
+# iter_mult()
+#
+# Iterative multiplier (i*j) with operands that are bitlen
+# number of bits.
+#-------------------------------------------------------------------
+def iter_mult(i, j, bitlen):
+    print("Mult of 0x%08x and 0x%08x of max 0x%08x bits" %
+          (i, j, bitlen))
+
+    r = 0
+    max = 2**bitlen - 1
+
+    for bit in range(bitlen):
+        mask = ((j & (1 << bit)))
+        r = (r + (i * mask)) & max
+        print("bit: 0x%08x, mask = 0x%01x, r = 0x%08x" %
+              (bit, mask, r))
+    return r
+
+
+#-------------------------------------------------------------------
+# iter_exp()
+#
+# Iterative exponentiator (i ** j) with operands that are
+# bitlen number of bits.
+#-------------------------------------------------------------------
+def iter_exp(i, j, bitlen):
+    print("Exp of 0x%08x and 0x%08x of max 0x%08x bits" %
+          (i, j, bitlen))
+
+    n = i
+    for bit in range(j):
+        n = iter_mult(n, n, bitlen)
+    return n
+
+
+#-------------------------------------------------------------------
+# gen_keypair()
+#
+# Generate a keypair (and exponent) with n bits in length.
+#-------------------------------------------------------------------
+def gen_keypair(bitlen):
+    print("Generating keys with %d bits" % (bitlen))
+    print("")
+
+    e = 3
+    pub = 2**bitlen - 1
+    priv = pub - 2
+
+    return (pub, priv, e)
+
+
+#-------------------------------------------------------------------
+# keytest()
+#-------------------------------------------------------------------
+def keytest():
+    print("key encryption and decryption")
+    print("-----------------------------")
+
+    p = 11
+    q = 13
+    n = p * q
+    tiotent = (p - 1) * (q - 1)
+
+    print("p = %d, q = %d, n = %d, tiotent = %d" % (p, q, n, tiotent))
+
+    e = 7
+    d = 103
+
+    print("e = %d, d = %d" % (e, d))
+
+    print("Public key: e, n = %d, %d" % (e, n))
+    print("private key: d = %d" % (d))
+
+    m = 9
+    cm = modexp(m, e, n)
+    m2 = modexp(cm, d, n)
+    print("Encryption of message m  = %d -> cm = %d" % (m, cm))
+    print("Decryption of message cm = %d -> m  = %d" % (cm, m2))
+
+
+#-------------------------------------------------------------------
+# modtest()
+#-------------------------------------------------------------------
+def modtest():
+    print("modular exponentition")
+    print("---------------------")
+
+    M = 12345
+    e = 3
+    N = 12347
+
+    print("M = %d, e = %d, N = %d" % (M, e, N))
+    print(modexp(M, e, N))
+    print("")
+
+    M = 2**8192 - 37
+    e = 3
+    N = 2**8192 - 1
+
+    print("M = %d, e = %d, N = %d" % (M, e, N))
+    print(modexp(M, e, N))
+    print("")
+
+
+#-------------------------------------------------------------------
+# modexp()
+#
+# Perform generic modular exponention of the given message M
+# using the exponent e and modulus N.
+#-------------------------------------------------------------------
+def modexp(M, e, N):
+    return (M ** e) % N
+
+
+#-------------------------------------------------------------------
+# main()
+#
+# Parse any arguments and run the tests.
+#-------------------------------------------------------------------
+def main():
+#    my_keypair = gen_keypair(12)
+#    print(my_keypair)
+#    modtest()
+#    keytest()
+
+    # test of iterative multiply.
+    print(iter_mult(2, 3, 4))
+    print(iter_mult(2, 3, 5))
+    print(iter_mult(2543, 1201, 12))
+    print(iter_mult(2543, 1201, 16))
+    print(iter_mult(2543, 1201, 23))
+
+    # test of iterative exponentiation.
+    print(iter_exp(2, 3, 12))
+    print(iter_exp(8, 8, 4))
+
+
+#-------------------------------------------------------------------
+# __name__
+# Python thingy which allows the file to be run standalone as
+# well as parsed from within a Python interpreter.
+#-------------------------------------------------------------------
+if __name__=="__main__":
+    # Run the main function.
+    sys.exit(main())
+
+
+#=======================================================================
+# EOF modexp.py
+#=======================================================================
diff --git a/src/rtl/modexp.v b/src/rtl/modexp.v
index d64a556..9f3d4f0 100644
--- a/src/rtl/modexp.v
+++ b/src/rtl/modexp.v
@@ -71,35 +71,38 @@ module modexp(
   localparam ADDR_NAME0          = 8'h00;
   localparam ADDR_NAME1          = 8'h01;
   localparam ADDR_VERSION        = 8'h02;
-  localparam ADDR_CTRL           = 8'h03;
 
+  localparam ADDR_CTRL           = 8'h08;
   localparam CTRL_INIT_BIT       = 0;
   localparam CTRL_NEXT_BIT       = 1;
 
   localparam ADDR_STATUS         = 8'h09;
+  localparam STATUS_READY_BIT    = 0;
+
+  localparam ADDR_MODULUS_LENGTH  = 8'h20;
+  localparam ADDR_EXPONENT_LENGTH = 8'h21;
+  localparam ADDR_LENGTH          = 8'h22; // Should be deprecated.
 
-  localparam ADDR_MODSIZE        = 8'h20;
-  localparam ADDR_LENGTH         = 8'h21;
-  localparam ADDR_EXPONENT       = 8'h22;
 
   localparam MODULUS_PREFIX      = 4'h1;
   localparam ADDR_MODULUS_START  = 8'h00;
   localparam ADDR_MODULUS_END    = 8'hff;
 
+
   localparam EXPONENT_PREFIX     = 4'h2;
   localparam ADDR_EXPONENT_START = 8'h00;
   localparam ADDR_EXPONENT_END   = 8'hff;
 
+
   localparam MESSAGE_PREFIX      = 4'h3;
   localparam MESSAGE_START       = 8'h00;
   localparam MESSAGE_END         = 8'hff;
 
+
   localparam RESULT_PREFIX       = 4'h4;
   localparam RESULT_START        = 8'h00;
   localparam RESULT_END          = 8'hff;
 
-  localparam LENGTH_PREFIX       = 4'h5;
-
   localparam DEFAULT_MODLENGTH   = 8'h80;
   localparam DEFAULT_EXPLENGTH   = 8'h80;
 
@@ -107,7 +110,7 @@ module modexp(
   localparam MONTPROD_SELECT_X_NR   = 3'h1;
   localparam MONTPROD_SELECT_Z_P    = 3'h2;
   localparam MONTPROD_SELECT_P_P    = 3'h3;
-  localparam MONTPROD_SELECT_ONE_Z  = 3'h4;
+  localparam MONTPROD_SELECT_Z_ONE  = 3'h4;
 
   localparam MONTPROD_DEST_Z        = 2'b00;
   localparam MONTPROD_DEST_P        = 2'b01;
@@ -124,53 +127,36 @@ module modexp(
   localparam CTRL_CALCULATE_ZN   = 4'h8;
   localparam CTRL_DONE           = 4'h9;
 
+  localparam EXPONATION_MODE_SECRET_SECURE = 1'b0;
+  localparam EXPONATION_MODE_PUBLIC_FAST   = 1'b1; //for rsa, c=M^65537 etc, there is no need to slow down to hide the exponent
+
+
   localparam CORE_NAME0          = 32'h6d6f6465; // "mode"
   localparam CORE_NAME1          = 32'h78702020; // "xp  "
-  localparam CORE_VERSION        = 32'h302e3031; // "0.01"
+  localparam CORE_VERSION        = 32'h302e3530; // "0.50"
 
 
   //----------------------------------------------------------------
   // Registers including update variables and write enable.
   //----------------------------------------------------------------
-  reg [07 : 0]  modulus_mem_int_rd_addr;
-  wire [31 : 0] modulus_mem_int_rd_data;
-  wire [31 : 0] modulus_mem_api_rd_data;
-  reg           modulus_mem_api_we;
-
-  reg [07 : 0]  message_mem_int_rd_addr;
-  wire [31 : 0] message_mem_int_rd_data;
-  wire [31 : 0] message_mem_api_rd_data;
-  reg           message_mem_api_we;
-
-  reg [07 : 0]  exponent_mem_int_rd_addr;
-  wire [31 : 0] exponent_mem_int_rd_data;
-  wire [31 : 0] exponent_mem_api_rd_data;
-  reg           exponent_mem_api_we;
+  reg [07 : 0] exponent_length_reg;
+  reg [07 : 0] exponent_length_new;
+  reg          exponent_length_we;
 
-  wire [31 : 0] result_mem_api_rd_data;
-  reg  [07 : 0] result_mem_int_rd_addr;
-  wire [31 : 0] result_mem_int_rd_data;
-  reg  [07 : 0] result_mem_int_wr_addr;
-  reg  [31 : 0] result_mem_int_wr_data;
-  reg           result_mem_int_we;
-
-  reg  [07 : 0] p_mem_rd0_addr;
-  wire [31 : 0] p_mem_rd0_data;
-  reg  [07 : 0] p_mem_rd1_addr;
-  wire [31 : 0] p_mem_rd1_data;
-  reg  [07 : 0] p_mem_wr_addr;
-  reg  [31 : 0] p_mem_wr_data;
-  reg           p_mem_we;
+  reg [07 : 0] modulus_length_reg;
+  reg [07 : 0] modulus_length_new;
+  reg          modulus_length_we;
 
   reg [07 : 0] length_reg;
+  reg [07 : 0] length_new;
   reg [07 : 0] length_m1_reg;
-  reg [07 : 0] length_new;    //TODO: API should write length!!!
-  reg [07 : 0] length_m1_new; //TODO: API should write length-1 when writing length!!!
-  reg          length_we;     //TODO: API should enable length_we!!!
+  reg [07 : 0] length_m1_new;
+  reg          length_we;
 
   reg          start_reg;
-  reg          start_new; //TODO: API should start operations!!!
-  reg          start_we;  //TODO: API should start operations!!!
+  reg          start_new;
+  reg          start_we;
+  reg          clear_start;
 
   reg          ready_reg;
   reg          ready_new;
@@ -187,22 +173,61 @@ module modexp(
   reg [3 : 0]  modexp_ctrl_new;
   reg          modexp_ctrl_we;
 
-  reg [31 : 0] one;
+  reg [31 : 0] one_reg;
   reg [31 : 0] one_new;
+  reg [31 : 0] b_one_reg;
+  reg [31 : 0] b_one_new;
 
   reg [12 : 0] loop_counter_reg;
   reg [12 : 0] loop_counter_new;
   reg          loop_counter_we;
+
   reg [07 : 0] E_word_index;
   reg [04 : 0] E_bit_index;
   reg          last_iteration;
+
   reg          ei_reg;
   reg          ei_new;
   reg          ei_we;
 
+  reg          exponation_mode_reg;
+  reg          exponation_mode_new;
+  reg          exponation_mode_we;
+
+
   //----------------------------------------------------------------
   // Wires.
   //----------------------------------------------------------------
+  reg [07 : 0]  modulus_mem_int_rd_addr;
+  wire [31 : 0] modulus_mem_int_rd_data;
+  wire [31 : 0] modulus_mem_api_rd_data;
+  reg           modulus_mem_api_we;
+
+  reg [07 : 0]  message_mem_int_rd_addr;
+  wire [31 : 0] message_mem_int_rd_data;
+  wire [31 : 0] message_mem_api_rd_data;
+  reg           message_mem_api_we;
+
+  reg [07 : 0]  exponent_mem_int_rd_addr;
+  wire [31 : 0] exponent_mem_int_rd_data;
+  wire [31 : 0] exponent_mem_api_rd_data;
+  reg           exponent_mem_api_we;
+
+  wire [31 : 0] result_mem_api_rd_data;
+  reg  [07 : 0] result_mem_int_rd_addr;
+  wire [31 : 0] result_mem_int_rd_data;
+  reg  [07 : 0] result_mem_int_wr_addr;
+  reg  [31 : 0] result_mem_int_wr_data;
+  reg           result_mem_int_we;
+
+  reg  [07 : 0] p_mem_rd0_addr;
+  wire [31 : 0] p_mem_rd0_data;
+  reg  [07 : 0] p_mem_rd1_addr;
+  wire [31 : 0] p_mem_rd1_data;
+  reg  [07 : 0] p_mem_wr_addr;
+  reg  [31 : 0] p_mem_wr_data;
+  reg           p_mem_we;
+
   reg [31 : 0]  tmp_read_data;
   //reg           tmp_error;
 
@@ -225,7 +250,7 @@ module modexp(
 
   reg            residue_calculate;
   wire           residue_ready;
-  reg  [14 : 0]  residue_nn;
+  reg [14 : 0]   residue_nn;
   reg  [07 : 0]  residue_length;
   wire [07 : 0]  residue_opa_rd_addr;
   wire [31 : 0]  residue_opa_rd_data;
@@ -238,6 +263,11 @@ module modexp(
   reg  [07 : 0] residue_mem_montprod_read_addr;
   wire [31 : 0] residue_mem_montprod_read_data;
 
+  reg           residue_valid_reg;
+  reg           residue_valid_new;
+  reg           invalidate_residue;
+  reg           residue_valid_int_validated;
+
   //----------------------------------------------------------------
   // Concurrent connectivity for ports etc.
   //----------------------------------------------------------------
@@ -368,18 +398,37 @@ module modexp(
     begin
       if (!reset_n)
         begin
+          exponent_length_reg <= DEFAULT_EXPLENGTH;
+          modulus_length_reg  <= DEFAULT_MODLENGTH;
+          start_reg           <= 1'b0;
           ready_reg           <= 1'b1;
           montprod_select_reg <= MONTPROD_SELECT_ONE_NR;
           montprod_dest_reg   <= MONTPROD_DEST_NOWHERE;
           modexp_ctrl_reg     <= CTRL_IDLE;
-          one                 <= 32'h0;
+          one_reg             <= 32'h0;
+          b_one_reg           <= 32'h0;
           length_reg          <= 8'h0;
           length_m1_reg       <= 8'h0;
           loop_counter_reg    <= 13'b0;
           ei_reg              <= 1'b0;
+          residue_valid_reg   <= 1'b0;
+          exponation_mode_reg <= EXPONATION_MODE_SECRET_SECURE;
         end
       else
         begin
+          one_reg <= one_new;
+          b_one_reg <= b_one_new;
+          residue_valid_reg <= residue_valid_new;
+
+          if (exponent_length_we)
+            exponent_length_reg <= exponent_length_new;
+
+          if (modulus_length_we)
+            modulus_length_reg <= modulus_length_new;
+
+          if (start_we)
+            start_reg <= start_new;
+
           if (ready_we)
             ready_reg <= ready_new;
 
@@ -394,8 +443,8 @@ module modexp(
 
           if (length_we)
             begin
-              length_reg    <= write_data[7 : 0];
-              length_m1_reg <= write_data[7 : 0] - 8'h1;
+              length_reg    <= length_new;
+              length_m1_reg <= length_m1_new;
             end
 
           if (loop_counter_we)
@@ -404,7 +453,8 @@ module modexp(
           if (ei_we)
             ei_reg <= ei_new;
 
-          one <= one_new;
+          if (exponation_mode_we)
+            exponation_mode_reg <= exponation_mode_new;
         end
     end // reg_update
 
@@ -416,12 +466,35 @@ module modexp(
   //----------------------------------------------------------------
   always @*
     begin : api
+      modulus_length_we   = 1'b0;
+      exponent_length_we  = 1'b0;
+      start_new           = 1'b0;
+      start_we            = 1'b0;
       modulus_mem_api_we  = 1'b0;
       exponent_mem_api_we = 1'b0;
       message_mem_api_we  = 1'b0;
       length_we           = 1'b0;
+      invalidate_residue  = 1'b0;
+
+      //TODO: Add API code to enable fast exponation for working with public exponents.
+      exponation_mode_we  = 1'b0;
+
+      exponation_mode_new = EXPONATION_MODE_SECRET_SECURE;
+      modulus_length_new  = write_data[7 : 0];
+      exponent_length_new = write_data[7 : 0];
+      length_new          = write_data[7 : 0];
+      length_m1_new       = write_data[7 : 0] - 8'h1;
+
       tmp_read_data       = 32'h00000000;
 
+      // We need to be able to clear start bit after we have
+      // started a modexp operation.
+      if (clear_start)
+        begin
+          start_new = 1'b0;
+          start_we  = 1'b1;
+        end
+
       if (cs)
         begin
           case (address[11 : 8])
@@ -430,8 +503,26 @@ module modexp(
                 if (we)
                   begin
                     case (address[7 : 0])
+                      ADDR_CTRL:
+                        begin
+                          start_new = write_data[0];
+                          start_we  = 1'b1;
+                        end
+
                       ADDR_LENGTH:
-                        length_we = 1'b1;
+                        begin
+                          length_we = 1'b1;
+                        end
+
+                      ADDR_MODULUS_LENGTH:
+                        begin
+                          modulus_length_we = 1'b1;
+                        end
+
+                      ADDR_EXPONENT_LENGTH:
+                        begin
+                          exponent_length_we = 1'b1;
+                        end
 
                       default:
                         begin
@@ -451,10 +542,16 @@ module modexp(
                         tmp_read_data = CORE_VERSION;
 
                       ADDR_CTRL:
-                        tmp_read_data = 32'h00000000;
+                        tmp_read_data = {31'h00000000, start_reg};
 
                       ADDR_STATUS:
-                        tmp_read_data = 32'h00000000;
+                        tmp_read_data = {31'h00000000, ready_reg};
+
+                      ADDR_MODULUS_LENGTH:
+                        tmp_read_data = {24'h000000, modulus_length_reg};
+
+                      ADDR_EXPONENT_LENGTH:
+                        tmp_read_data = {24'h000000, exponent_length_reg};
 
                       ADDR_LENGTH:
                         tmp_read_data = {24'h000000, length_reg};
@@ -471,6 +568,7 @@ module modexp(
                 if (we)
                   begin
                     modulus_mem_api_we = 1'b1;
+                    invalidate_residue = 1'b1;
                   end
                 else
                   begin
@@ -522,15 +620,19 @@ module modexp(
   // generates the big integer one ( 00... 01 )
   //----------------------------------------------------------------
   always @*
-    begin : one_process;
+    begin : one_process
+      one_new = 32'h00000000;
+      b_one_new = 32'h00000000;
       if (montprod_opa_addr == length_m1_reg)
         one_new = 32'h00000001;
-      else
-        one_new = 32'h00000000;
+      if (montprod_opb_addr == length_m1_reg)
+        b_one_new = 32'h00000001;
     end
 
+
   //----------------------------------------------------------------
-  // read mux for modulus, since it is being addressed by two sources
+  // Read mux for modulus. Needed since it is being
+  // addressed by two sources.
   //----------------------------------------------------------------
   always @*
     begin : modulus_mem_reader_process
@@ -540,21 +642,38 @@ module modexp(
         modulus_mem_int_rd_addr = montprod_opm_addr;
     end
 
+
   //----------------------------------------------------------------
-  // feeds residue calculator
+  // Feeds residue calculator.
   //----------------------------------------------------------------
   always @*
-    begin : residue_process;
-      residue_nn = { 1'b0, length_reg, 6'h0 }; //N*2, N=length*32, *32 = shl5, *64 = shl6
+    begin : residue_process
+      //N*2, N=length*32, *32 = shl5, *64 = shl6
+      residue_nn = { 1'b0, length_reg, 6'h0 };
       residue_length = length_reg;
       residue_opm_data = modulus_mem_int_rd_data;
     end
 
+
+  //----------------------------------------------------------------
+  // Sets the register that decides if residue is valid or not.
+  //----------------------------------------------------------------
+  always @*
+    begin : residue_valid_process
+      if (invalidate_residue)
+        residue_valid_new = 1'b0;
+      else if ( residue_valid_int_validated == 1'b1)
+        residue_valid_new = 1'b1;
+     else
+        residue_valid_new = residue_valid_reg;
+    end
+
+
   //----------------------------------------------------------------
   // montprod_op_select
   //
   // Select operands used during montprod calculations depending
-  // on what operation we want to do
+  // on what operation we want to do.
   //----------------------------------------------------------------
   always @*
     begin : montprod_op_select
@@ -572,7 +691,7 @@ module modexp(
       case (montprod_select_reg)
         MONTPROD_SELECT_ONE_NR:
           begin
-            montprod_opa_data       = one;
+            montprod_opa_data       = one_reg;
             montprod_opb_data       = residue_mem_montprod_read_data;
           end
 
@@ -594,10 +713,10 @@ module modexp(
             montprod_opb_data       = p_mem_rd1_data;
           end
 
-        MONTPROD_SELECT_ONE_Z:
+        MONTPROD_SELECT_Z_ONE:
           begin
-            montprod_opa_data       = one;
-            montprod_opb_data       = result_mem_int_rd_data;
+            montprod_opa_data       = result_mem_int_rd_data;
+            montprod_opb_data       = b_one_reg;
           end
 
         default:
@@ -612,7 +731,7 @@ module modexp(
   //----------------------------------------------------------------
   // memory write mux
   //
-  // direct memory write signals to correct memory
+  // Direct memory write signals to correct memory.
   //----------------------------------------------------------------
   always @*
     begin : memory_write_process
@@ -643,11 +762,12 @@ module modexp(
   //----------------------------------------------------------------
   // loop_counter
   //
-  // Calculate the loop counter and related variables
+  // Calculate the loop counter and related variables.
   //----------------------------------------------------------------
   always @*
     begin : loop_counters_process
-      E_bit_index      = loop_counter_reg[ 04 : 0 ];
+      loop_counter_new = 13'b0;
+      loop_counter_we  = 1'b0;
 
       if (loop_counter_reg == { length_m1_reg, 5'b11111 })
         last_iteration = 1'b1;
@@ -669,7 +789,7 @@ module modexp(
 
         default:
           begin
-            loop_counter_new = 13'b0;
+            loop_counter_new = loop_counter_reg;
             loop_counter_we  = 1'b0;
           end
 
@@ -680,12 +800,15 @@ module modexp(
   //----------------------------------------------------------------
   // exponent
   //
-  // reads the exponent
+  // Reads the exponent.
   //----------------------------------------------------------------
   always @*
     begin : exponent_process
-      // accessing new instead of reg - pick up update at CTRL_ITERATE_NEW to remove a pipeline stall
-      E_word_index  = loop_counter_new[ 12 : 5 ];
+      // Accessing new instead of reg - pick up update at
+      // CTRL_ITERATE_NEW to remove a pipeline stall.
+      E_word_index  = length_m1_reg - loop_counter_new[ 12 : 5 ];
+
+      E_bit_index   = loop_counter_reg[ 04 : 0 ];
 
       exponent_mem_int_rd_addr = E_word_index;
 
@@ -705,48 +828,70 @@ module modexp(
   //----------------------------------------------------------------
   always @*
     begin
-      ready_new           = 0;
-      ready_we            = 0;
+      ready_new           = 1'b0;
+      ready_we            = 1'b0;
       montprod_select_new = MONTPROD_SELECT_ONE_NR;
       montprod_select_we  = 0;
       montprod_dest_new   = MONTPROD_DEST_NOWHERE;
       montprod_dest_we    = 0;
       montprod_calc       = 0;
       modexp_ctrl_new     = CTRL_IDLE;
-      modexp_ctrl_we      = 0;
+      modexp_ctrl_we      = 1'b0;
+      clear_start         = 1'b0;
 
       residue_calculate = 1'b0;
 
+      residue_valid_int_validated = 1'b0;
+
       case (modexp_ctrl_reg)
         CTRL_IDLE:
           begin
-            ready_new           = 0;
-            ready_we            = 1;
-            if (start_reg == 1'b1)
+            if (start_reg)
               begin
-                modexp_ctrl_new = CTRL_RESIDUE;
-                modexp_ctrl_we  = 1;
-                residue_calculate = 1'b1;
+                ready_new       = 1'b0;
+                ready_we        = 1'b1;
+                modexp_ctrl_new = CTRL_DONE;
+                modexp_ctrl_we  = 1'b1;
+
+                if (residue_valid_reg)
+                  begin
+                    //residue has alrady been calculated, start with MONTPROD( 1, Nr, MODULUS )
+                    montprod_select_new = MONTPROD_SELECT_ONE_NR;
+                    montprod_select_we  = 1;
+                    montprod_dest_new   = MONTPROD_DEST_Z;
+                    montprod_dest_we    = 1;
+                    montprod_calc       = 1;
+                    modexp_ctrl_new     = CTRL_CALCULATE_Z0;
+                    modexp_ctrl_we      = 1;
+                  end
+                else
+                  begin
+                    //modulus has been written and residue (Nr) must be calculated
+                    modexp_ctrl_new = CTRL_RESIDUE;
+                    modexp_ctrl_we  = 1;
+                    residue_calculate = 1'b1;
+                  end
               end
           end
 
         CTRL_RESIDUE:
           begin
-            if (residue_ready == 1'b1)
+            if (residue_ready)
               begin
                 montprod_select_new = MONTPROD_SELECT_ONE_NR;
                 montprod_select_we  = 1;
                 montprod_dest_new   = MONTPROD_DEST_Z;
                 montprod_dest_we    = 1;
                 montprod_calc       = 1;
-                modexp_ctrl_new = CTRL_CALCULATE_Z0;
-                modexp_ctrl_we  = 1;
+                modexp_ctrl_new     = CTRL_CALCULATE_Z0;
+                modexp_ctrl_we      = 1;
+                residue_valid_int_validated = 1'b1; //update registers telling residue is valid
               end
           end
 
         CTRL_CALCULATE_Z0:
           begin
-            if (montprod_ready == 1'b1)
+            if (montprod_ready)
               begin
                 montprod_select_new = MONTPROD_SELECT_X_NR;
                 montprod_select_we  = 1;
@@ -774,20 +919,28 @@ module modexp(
             montprod_dest_new   = MONTPROD_DEST_Z;
             montprod_dest_we    = 1;
             montprod_calc       = 1;
-            modexp_ctrl_new = CTRL_ITERATE_Z_P;
-            modexp_ctrl_we  = 1;
+            modexp_ctrl_new     = CTRL_ITERATE_Z_P;
+            modexp_ctrl_we      = 1;
+
+            if (ei_new == 1'b0 && exponation_mode_reg == EXPONATION_MODE_PUBLIC_FAST)
+              begin
+                //Skip the fake montgomery calculation, exponation_mode_reg optimizing for speed not blinding.
+                montprod_select_new = MONTPROD_SELECT_P_P;
+                montprod_dest_new   = MONTPROD_DEST_P;
+                modexp_ctrl_new     = CTRL_ITERATE_P_P;
+              end
           end
 
         CTRL_ITERATE_Z_P:
-            if (montprod_ready == 1'b1)
+            if (montprod_ready)
               begin
                 montprod_select_new = MONTPROD_SELECT_P_P;
                 montprod_select_we  = 1;
                 montprod_dest_new   = MONTPROD_DEST_P;
                 montprod_dest_we    = 1;
                 montprod_calc       = 1;
-                modexp_ctrl_new = CTRL_ITERATE_P_P;
-                modexp_ctrl_we  = 1;
+                modexp_ctrl_new     = CTRL_ITERATE_P_P;
+                modexp_ctrl_we      = 1;
               end
 
         CTRL_ITERATE_P_P:
@@ -799,24 +952,26 @@ module modexp(
 
         CTRL_ITERATE_END:
           begin
-            if (last_iteration == 1'b0)
+            if (!last_iteration)
               begin
                 modexp_ctrl_new = CTRL_ITERATE;
                 modexp_ctrl_we  = 1;
               end
             else
               begin
-                montprod_select_new = MONTPROD_SELECT_ONE_Z;
+                montprod_select_new = MONTPROD_SELECT_Z_ONE;
                 montprod_select_we  = 1;
+                montprod_dest_new   = MONTPROD_DEST_Z;
+                montprod_dest_we    = 1;
                 montprod_calc       = 1;
-                modexp_ctrl_new = CTRL_CALCULATE_ZN;
-                modexp_ctrl_we  = 1;
+                modexp_ctrl_new     = CTRL_CALCULATE_ZN;
+                modexp_ctrl_we      = 1;
               end
           end
 
         CTRL_CALCULATE_ZN:
           begin
-            if (montprod_ready == 1'b1)
+            if (montprod_ready)
               begin
                 modexp_ctrl_new = CTRL_DONE;
                 modexp_ctrl_we  = 1;
@@ -825,10 +980,11 @@ module modexp(
 
         CTRL_DONE:
           begin
-            ready_new           = 1;
-            ready_we            = 1;
-            modexp_ctrl_new     = CTRL_IDLE;
-            modexp_ctrl_we      = 1;
+            clear_start     = 1'b1;
+            ready_new       = 1'b1;
+            ready_we        = 1'b1;
+            modexp_ctrl_new = CTRL_IDLE;
+            modexp_ctrl_we  = 1;
           end
 
         default:
diff --git a/src/rtl/montprod.v b/src/rtl/montprod.v
index 32bbdec..2ed1f5d 100644
--- a/src/rtl/montprod.v
+++ b/src/rtl/montprod.v
@@ -63,6 +63,7 @@ module montprod(
   //----------------------------------------------------------------
   // Internal constant and parameter definitions.
   //----------------------------------------------------------------
+
   localparam CTRL_IDLE           = 4'h0;
   localparam CTRL_INIT_S         = 4'h1;
   localparam CTRL_LOOP_INIT      = 4'h2;
@@ -217,9 +218,11 @@ module montprod(
         SMUX_SHR:
           s_mem_new = shr_adiv2;
       endcase
-      $display("SMUX%x: %x", s_mux_reg, s_mem_new);
+      if (DEBUG)
+        $display("SMUX%x: %x", s_mux_reg, s_mem_new);
     end
 
+
   //----------------------------------------------------------------
   // reg_update
   //
@@ -286,7 +289,8 @@ module montprod(
            //opa_addr will point to length-1 to get A LSB.
            //s_read_addr will point to length-1
            q = s_mem_read_data[0] ^ (opa_data[0] & b);
-           $display("s_mem_read_data: %x opa_data %x b %x q %x B_bit_index_reg %x", s_mem_read_data, opa_data, b, q, B_bit_index_reg);
+           if (DEBUG)
+             $display("s_mem_read_data: %x opa_data %x b %x q %x B_bit_index_reg %x", s_mem_read_data, opa_data, b, q, B_bit_index_reg);
         end
    end
 
@@ -296,6 +300,7 @@ module montprod(
   //----------------------------------------------------------------
   always @*
    begin : loop_counter_process
+     loop_counter_new  = loop_counter;
       length_m1        = length - 1'b1;
       loop_counter_dec = loop_counter - 1'b1;
       B_word_index     = loop_counter[12:5];
@@ -560,7 +565,8 @@ module montprod(
 
         CTRL_EMIT_S:
            begin
-             $display("EMIT_S word_index: %d", word_index);
+             if (DEBUG)
+               $display("EMIT_S word_index: %d", word_index);
              if (word_index_prev == 8'h0)
                begin
                  montprod_ctrl_new = CTRL_DONE;
diff --git a/src/tb/tb_modexp.v b/src/tb/tb_modexp.v
index c07d3d5..a7159b7 100644
--- a/src/tb/tb_modexp.v
+++ b/src/tb/tb_modexp.v
@@ -50,19 +50,43 @@ module tb_modexp();
   //----------------------------------------------------------------
   // Internal constant and parameter definitions.
   //----------------------------------------------------------------
-  parameter DEBUG     = 0;
+  parameter DEBUG = 0;
+  parameter DEBUG_EI = 1;
 
   localparam CLK_HALF_PERIOD = 1;
   localparam CLK_PERIOD      = 2 * CLK_HALF_PERIOD;
 
   // The DUT address map.
-  localparam ADDR_NAME0       = 8'h00;
-  localparam ADDR_NAME1       = 8'h01;
-  localparam ADDR_VERSION     = 8'h02;
+  localparam GENERAL_PREFIX      = 4'h0;
+  localparam ADDR_NAME0          = 8'h00;
+  localparam ADDR_NAME1          = 8'h01;
+  localparam ADDR_VERSION        = 8'h02;
 
-  localparam ADDR_CTRL        = 8'h08;
-  localparam CTRL_INIT_BIT    = 0;
-  localparam CTRL_NEXT_BIT    = 1;
+  localparam ADDR_CTRL           = 8'h08;
+  localparam CTRL_START_BIT      = 0;
+
+  localparam ADDR_STATUS         = 8'h09;
+  localparam STATUS_READY_BIT    = 0;
+
+  localparam ADDR_MODULUS_LENGTH  = 8'h20;
+  localparam ADDR_MESSAGE_LENGTH  = 8'h21;
+  localparam ADDR_EXPONENT_LENGTH = 8'h22;
+
+  localparam MODULUS_PREFIX      = 4'h1;
+  localparam ADDR_MODULUS_START  = 8'h00;
+  localparam ADDR_MODULUS_END    = 8'hff;
+
+  localparam EXPONENT_PREFIX     = 4'h2;
+  localparam ADDR_EXPONENT_START = 8'h00;
+  localparam ADDR_EXPONENT_END   = 8'hff;
+
+  localparam MESSAGE_PREFIX      = 4'h3;
+  localparam MESSAGE_START       = 8'h00;
+  localparam MESSAGE_END         = 8'hff;
+
+  localparam RESULT_PREFIX       = 4'h4;
+  localparam RESULT_START        = 8'h00;
+  localparam RESULT_END          = 8'hff;
 
 
   //----------------------------------------------------------------
@@ -79,7 +103,7 @@ module tb_modexp();
   reg           tb_reset_n;
   reg           tb_cs;
   reg           tb_we;
-  reg [11  : 0]  tb_address;
+  reg [11  : 0] tb_address;
   reg [31 : 0]  tb_write_data;
   wire [31 : 0] tb_read_data;
   wire          tb_error;
@@ -129,6 +153,25 @@ module tb_modexp();
         end
     end
 
+  //----------------------------------------------------------------
+  // ei_monitor()
+  //
+  // Displays ei_new, the most important variable for determining
+  // what modexp will do (i.e. should Z=MONTPROD( Z, P, M) be 
+  // performed 
+  //----------------------------------------------------------------
+  always @*
+    begin : ei_monitor
+      if (DEBUG_EI)
+        if (dut.modexp_ctrl_reg == dut.CTRL_ITERATE_Z_P)
+          $display("loop counter %d: ei = %d", dut.loop_counter_reg, dut.ei_reg);
+    end
+
+  always @*
+    begin : z_monitor
+      $display("result_mem[0][1] = %x %x",dut.result_mem.mem[0],dut.result_mem.mem[1]);
+    end
+
 
   //----------------------------------------------------------------
   // dump_dut_state()
@@ -140,8 +183,23 @@ module tb_modexp();
       $display("cycle: 0x%016x", cycle_ctr);
       $display("State of DUT");
       $display("------------");
+      $display("Inputs and outputs:");
+      $display("cs   = 0x%01x, we = 0x%01x", tb_cs, tb_we);
+      $display("addr = 0x%08x, read_data = 0x%08x, write_data = 0x%08x",
+               tb_address, tb_read_data, tb_write_data);
       $display("");
 
+      $display("State:");
+      $display("ready_reg = 0x%01x, start_reg = 0x%01x, start_new = 0x%01x, start_we = 0x%01x",
+               dut.ready_reg, dut.start_reg, dut.start_new, dut.start_we);
+      $display("residue_valid = 0x%01x", dut.residue_valid_reg);
+      $display("loop_counter_reg = 0x%08x", dut.loop_counter_reg);
+      $display("exponent_length_reg = 0x%02x, modulus_length_reg = 0x%02x",
+               dut.exponent_length_reg, dut.modulus_length_reg);
+      $display("length_reg = 0x%02x, length_m1_reg = 0x%02x",
+               dut.length_reg, dut.length_m1_reg);
+      $display("ctrl_reg = 0x%04x", dut.modexp_ctrl_reg);
+      $display("");
     end
   endtask // dump_dut_state
 
@@ -207,16 +265,41 @@ module tb_modexp();
 
 
   //----------------------------------------------------------------
+  // read_word()
+  //
+  // Read a data word from the given address in the DUT.
+  // the word read will be available in the global variable
+  // read_data.
+  //----------------------------------------------------------------
+  task read_word(input [11 : 0] address);
+    begin
+      tb_address = address;
+      tb_cs = 1;
+      tb_we = 0;
+      #(CLK_PERIOD);
+      read_data = tb_read_data;
+      tb_cs = 0;
+
+      if (DEBUG)
+        begin
+          $display("*** (read_word) Reading 0x%08x from 0x%02x.", read_data, address);
+          $display("");
+        end
+    end
+  endtask // read_word
+
+
+  //----------------------------------------------------------------
   // write_word()
   //
   // Write the given word to the DUT using the DUT interface.
   //----------------------------------------------------------------
-  task write_word(input [11 : 0]  address,
+  task write_word(input [11 : 0] address,
                   input [31 : 0] word);
     begin
       if (DEBUG)
         begin
-          $display("*** Writing 0x%08x to 0x%02x.", word, address);
+          $display("*** (write_word) Writing 0x%08x to 0x%02x.", word, address);
           $display("");
         end
 
@@ -232,28 +315,359 @@ module tb_modexp();
 
 
   //----------------------------------------------------------------
-  // read_word()
+  // wait_ready()
   //
-  // Read a data word from the given address in the DUT.
-  // the word read will be available in the global variable
-  // read_data.
+  // Wait until the ready flag in the core is set.
   //----------------------------------------------------------------
-  task read_word(input [11 : 0]  address);
+  task wait_ready();
     begin
-      tb_address = address;
-      tb_cs = 1;
-      tb_we = 0;
-      #(CLK_PERIOD);
-      read_data = tb_read_data;
-      tb_cs = 0;
+      while (tb_read_data != 32'h00000001)
+          read_word({GENERAL_PREFIX, ADDR_STATUS});
 
       if (DEBUG)
+        $display("*** (wait_ready) Ready flag has been set.");
+    end
+  endtask // wait_ready
+
+
+  //----------------------------------------------------------------
+  // dump_message_mem()
+  //
+  // Dump the contents of the message memory.
+  //----------------------------------------------------------------
+  task dump_message_mem();
+    reg [8 : 0] i;
+    begin
+      $display("Contents of the message memory:");
+      for (i = 0 ; i < 256 ; i = i + 8)
+        begin
+          $display("message_mem[0x%02x .. 0x%02x] = 0x%08x 0x%08x 0x%08x 0x%08x  0x%08x 0x%08x 0x%08x 0x%08x",
+                   i[7 : 0], (i[7 : 0] + 8'h07),
+                   dut.message_mem.mem[(i[7 : 0] + 0)], dut.message_mem.mem[(i[7 : 0] + 1)],
+                   dut.message_mem.mem[(i[7 : 0] + 2)], dut.message_mem.mem[(i[7 : 0] + 3)],
+                   dut.message_mem.mem[(i[7 : 0] + 4)], dut.message_mem.mem[(i[7 : 0] + 5)],
+                   dut.message_mem.mem[(i[7 : 0] + 6)], dut.message_mem.mem[(i[7 : 0] + 7)],
+                   );
+        end
+      $display("");
+    end
+  endtask // dump_message_mem
+
+
+  //----------------------------------------------------------------
+  // dump_exponent_mem()
+  //
+  // Dump the contents of the exponent memory.
+  //----------------------------------------------------------------
+  task dump_exponent_mem();
+    reg [8 : 0] i;
+    begin
+      $display("Contents of the exponent memory:");
+      for (i = 0 ; i < 256 ; i = i + 8)
+        begin
+          $display("exponent_mem[0x%02x .. 0x%02x] = 0x%08x 0x%08x 0x%08x 0x%08x  0x%08x 0x%08x 0x%08x 0x%08x",
+                   i[7 : 0], (i[7 : 0] + 8'h07),
+                   dut.exponent_mem.mem[(i[7 : 0] + 0)], dut.exponent_mem.mem[(i[7 : 0] + 1)],
+                   dut.exponent_mem.mem[(i[7 : 0] + 2)], dut.exponent_mem.mem[(i[7 : 0] + 3)],
+                   dut.exponent_mem.mem[(i[7 : 0] + 4)], dut.exponent_mem.mem[(i[7 : 0] + 5)],
+                   dut.exponent_mem.mem[(i[7 : 0] + 6)], dut.exponent_mem.mem[(i[7 : 0] + 7)],
+                   );
+        end
+      $display("");
+    end
+  endtask // dump_exponent_mem
+
+
+  //----------------------------------------------------------------
+  // dump_modulus_mem()
+  //
+  // Dump the contents of the modulus memory.
+  //----------------------------------------------------------------
+  task dump_modulus_mem();
+    reg [8 : 0] i;
+    begin
+      $display("Contents of the modulus memory:");
+      for (i = 0 ; i < 256 ; i = i + 8)
+        begin
+          $display("modulus_mem[0x%02x .. 0x%02x] = 0x%08x 0x%08x 0x%08x 0x%08x  0x%08x 0x%08x 0x%08x 0x%08x",
+                   i[7 : 0], (i[7 : 0] + 8'h07),
+                   dut.modulus_mem.mem[(i[7 : 0] + 0)], dut.modulus_mem.mem[(i[7 : 0] + 1)],
+                   dut.modulus_mem.mem[(i[7 : 0] + 2)], dut.modulus_mem.mem[(i[7 : 0] + 3)],
+                   dut.modulus_mem.mem[(i[7 : 0] + 4)], dut.modulus_mem.mem[(i[7 : 0] + 5)],
+                   dut.modulus_mem.mem[(i[7 : 0] + 6)], dut.modulus_mem.mem[(i[7 : 0] + 7)],
+                   );
+        end
+      $display("");
+    end
+  endtask // dump_modulus_mem
+
+
+  //----------------------------------------------------------------
+  // dump_residue_mem()
+  //
+  // Dump the contents of the residue memory.
+  //----------------------------------------------------------------
+  task dump_residue_mem();
+    reg [8 : 0] i;
+    begin
+      $display("Contents of the residue memory:");
+      for (i = 0 ; i < 256 ; i = i + 8)
+        begin
+          $display("residue_mem[0x%02x .. 0x%02x] = 0x%08x 0x%08x 0x%08x 0x%08x  0x%08x 0x%08x 0x%08x 0x%08x",
+                   i[7 : 0], (i[7 : 0] + 8'h07),
+                   dut.residue_mem.mem[(i[7 : 0] + 0)], dut.residue_mem.mem[(i[7 : 0] + 1)],
+                   dut.residue_mem.mem[(i[7 : 0] + 2)], dut.residue_mem.mem[(i[7 : 0] + 3)],
+                   dut.residue_mem.mem[(i[7 : 0] + 4)], dut.residue_mem.mem[(i[7 : 0] + 5)],
+                   dut.residue_mem.mem[(i[7 : 0] + 6)], dut.residue_mem.mem[(i[7 : 0] + 7)],
+                   );
+        end
+      $display("");
+    end
+  endtask // dump_residue_mem
+
+
+  //----------------------------------------------------------------
+  // dump_result_mem()
+  //
+  // Dump the contents of the result memory.
+  //----------------------------------------------------------------
+  task dump_result_mem();
+    reg [8 : 0] i;
+    begin
+      $display("Contents of the result memory:");
+      for (i = 0 ; i < 256 ; i = i + 8)
         begin
-          $display("*** Reading 0x%08x from 0x%02x.", read_data, address);
+          $display("result_mem[0x%02x .. 0x%02x] = 0x%08x 0x%08x 0x%08x 0x%08x  0x%08x 0x%08x 0x%08x 0x%08x",
+                   i[7 : 0], (i[7 : 0] + 8'h07),
+                   dut.result_mem.mem[(i[7 : 0] + 0)], dut.result_mem.mem[(i[7 : 0] + 1)],
+                   dut.result_mem.mem[(i[7 : 0] + 2)], dut.result_mem.mem[(i[7 : 0] + 3)],
+                   dut.result_mem.mem[(i[7 : 0] + 4)], dut.result_mem.mem[(i[7 : 0] + 5)],
+                   dut.result_mem.mem[(i[7 : 0] + 6)], dut.result_mem.mem[(i[7 : 0] + 7)],
+                   );
+        end
+      $display("");
+    end
+  endtask // dump_result_mem
+
+
+  //----------------------------------------------------------------
+  // dump_memories()
+  //
+  // Dump the contents of the memories in the dut.
+  //----------------------------------------------------------------
+  task dump_memories();
+    begin
+      dump_message_mem();
+      dump_exponent_mem();
+      dump_modulus_mem();
+      dump_residue_mem();
+      dump_result_mem();
+    end
+  endtask // dump_memories
+
+
+  //----------------------------------------------------------------
+  // tc1
+  //
+  // A first, very simple testcase where we want to do:
+  // c = m ** e % N with the following (decimal) test values:
+  //  m = 3
+  //  e = 7
+  //  n = 11
+  //  c = 3 ** 7 % 11 = 9
+  //----------------------------------------------------------------
+  task tc1();
+    reg [31 : 0] read_data;
+
+    begin
+      tc_ctr = tc_ctr + 1;
+      $display("TC1: Trying to calculate 3**7 mod 11 = 9");
+
+      // Write 3 to message memory.
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h00000003);
+
+      // Write 7 to exponent memory and set length to one word.
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h00000007);
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001);
+
+      // Write 11 to modulus memory and set length to one word.
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h0000000b);
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000001);
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      // Read out result word and check result.
+      read_word({RESULT_PREFIX, 8'h00});
+      read_data = tb_read_data;
+
+      if (read_data == 32'h00000009)
+        begin
+          $display("*** TC1 successful.");
           $display("");
         end
+      else
+        begin
+          $display("*** ERROR: TC1 NOT successful.");
+          $display("Expected: 0x09, got 0x%08x", read_data);
+          error_ctr = error_ctr + 1;
+          dump_memories();
+        end
     end
-  endtask // read_word
+  endtask // tc1
+
+
+  //----------------------------------------------------------------
+  // tc2
+  //
+  // c = m ** e % N with the following (decimal) test values:
+  //  m = 251
+  //  e = 251
+  //  n = 257
+  //  c = 251 ** 251 % 257 = 183
+  //----------------------------------------------------------------
+  task tc2();
+    reg [31 : 0] read_data;
+
+    begin
+      tc_ctr = tc_ctr + 1;
+      $display("TC2: Trying to calculate 251**251 mod 257 = 183");
+
+      // Write 13 to (m)esaage memory.
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h000000fb);
+
+      // Write 11 to exponent memory and set length to one word.
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h000000fb);
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001);
+
+      // Write 7 to modulus memory and set length to one word.
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h00000101);
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000001);
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      // Read out result word and check result.
+      read_word({RESULT_PREFIX, 8'h00});
+      read_data = tb_read_data;
+
+      if (read_data == 32'h000000b7)
+        begin
+          $display("*** TC2 successful.");
+          $display("");
+        end
+      else
+        begin
+          $display("*** ERROR: TC2 NOT successful.");
+          $display("Expected: 0x06, got 0x%08x", read_data);
+          error_ctr = error_ctr + 1;
+        end
+    end
+  endtask // tc2
+
+
+  //----------------------------------------------------------------
+  // tc3
+  //
+  // c = m ** e % N with the following (decimal) test values:
+  //  m = 0x81
+  //  e = 0x41
+  //  n = 0x87
+  //  c = 0x81 ** 0x41 % 0x87 = 0x36
+  //----------------------------------------------------------------
+  task tc3();
+    reg [31 : 0] read_data;
+
+    begin
+      tc_ctr = tc_ctr + 1;
+      $display("TC3: Trying to calculate 0x81 ** 0x41 mod 0x87 = 0x36");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h00000081);
+
+      // Write 11 to exponent memory and set length to one word.
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h00000041);
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001);
+
+      // Write 7 to modulus memory and set length to one word.
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h00000087);
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000001);
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      // Read out result word and check result.
+      read_word({RESULT_PREFIX, 8'h00});
+      read_data = tb_read_data;
+
+      if (read_data == 32'h00000036)
+        begin
+          $display("*** TC3 successful.");
+          $display("");
+        end
+      else
+        begin
+          $display("*** ERROR: TC3 NOT successful.");
+          $display("Expected: 0x06, got 0x%08x", read_data);
+          error_ctr = error_ctr + 1;
+        end
+    end
+  endtask // tc3
+
+  function assertEquals(
+      input [31:0] expected,
+      input [31:0] actual
+    );
+    begin
+      if (expected === actual)
+        begin
+          assertEquals = 1; // success
+        end
+      else
+        begin
+          $display("Expected: 0x%08x, got 0x%08x", expected, actual);
+          assertEquals = 0; // failure
+        end
+    end
+  endfunction // assertEquals
+
+  integer success;
+
+  task autogenerated_BASIC_M4962768465676381896();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_M4962768465676381896: 00000001946473e1 ** h000000010e85e74f mod 0000000170754797 ");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'h946473e1); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'h0e85e74f); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'h70754797); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000002); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000002); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h00000000, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'h7761ed4f, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_M4962768465676381896 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_M4962768465676381896 success.");
+    end
+  endtask // autogenerated_BASIC_M4962768465676381896
 
 
   //----------------------------------------------------------------
@@ -273,7 +687,13 @@ module tb_modexp();
       reset_dut();
       dump_dut_state();
 
+      tc1();
+      tc2();
+      tc3();
+      autogenerated_BASIC_M4962768465676381896(); // add a broken random test for debugging
+
       display_test_results();
+//      dump_memories();
 
       $display("");
       $display("*** modexp simulation done. ***");
diff --git a/src/tb/tb_modexp_autogenerated.v b/src/tb/tb_modexp_autogenerated.v
index 65cbeef..25eaebd 100644
--- a/src/tb/tb_modexp_autogenerated.v
+++ b/src/tb/tb_modexp_autogenerated.v
@@ -50,7 +50,7 @@ module tb_modexp_autogenerated();
   //----------------------------------------------------------------
   // Internal constant and parameter definitions.
   //----------------------------------------------------------------
-  parameter DEBUG = 1;
+  parameter DEBUG = 0;
 
   localparam CLK_HALF_PERIOD = 1;
   localparam CLK_PERIOD      = 2 * CLK_HALF_PERIOD;
@@ -445,516 +445,1769 @@ module tb_modexp_autogenerated();
     end
   endtask // dump_memories
 
-task autogenerated_BASIC_M4962768465676381896();
-reg [31 : 0] read_data;
-begin
-tc_ctr = tc_ctr + 1;
-$display("autogenerated_BASIC_M4962768465676381896");
-write_word({MESSAGE_PREFIX, 8'h00}, 32'h00000001);
-write_word({MESSAGE_PREFIX, 8'h01}, 32'h946473e1);
-write_word({EXPONENT_PREFIX, 8'h00}, 32'h00000001);
-write_word({EXPONENT_PREFIX, 8'h01}, 32'h0e85e74f);
-write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000002););
-write_word({MODULUS_PREFIX, 8'h00}, 32'h00000001);
-write_word({MODULUS_PREFIX, 8'h01}, 32'h70754797);
-write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000002););
-dump_memories()
-write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000002);
-wait_ready();
-read_word({RESULT_PREFIX,8'h00});
-read_data = tb_read_data;
-if (read_data !== 32'h00000000))
-  begin
-    $display("Expected: 0x00000000, got 0x%08x", read_data);
-  end
-read_word({RESULT_PREFIX,8'h01});
-read_data = tb_read_data;
-if (read_data !== 32'h7761ed4f))
-  begin
-    $display("Expected: 0x7761ed4f, got 0x%08x", read_data);
-  end
-end
-endtask // autogenerated_BASIC_M4962768465676381896
-task autogenerated_BASIC_8982867242010371843();
-reg [31 : 0] read_data;
-begin
-tc_ctr = tc_ctr + 1;
-$display("autogenerated_BASIC_8982867242010371843");
-write_word({MESSAGE_PREFIX, 8'h00}, 32'h00000001);
-write_word({MESSAGE_PREFIX, 8'h01}, 32'h6eb4ac2d);
-write_word({EXPONENT_PREFIX, 8'h00}, 32'h00000001);
-write_word({EXPONENT_PREFIX, 8'h01}, 32'hbb200e41);
-write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000002););
-write_word({MODULUS_PREFIX, 8'h00}, 32'h00000001);
-write_word({MODULUS_PREFIX, 8'h01}, 32'h27347dc3);
-write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000002););
-dump_memories()
-write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000002);
-wait_ready();
-read_word({RESULT_PREFIX,8'h00});
-read_data = tb_read_data;
-if (read_data !== 32'h00000000))
-  begin
-    $display("Expected: 0x00000000, got 0x%08x", read_data);
-  end
-read_word({RESULT_PREFIX,8'h01});
-read_data = tb_read_data;
-if (read_data !== 32'h87d16204))
-  begin
-    $display("Expected: 0x87d16204, got 0x%08x", read_data);
-  end
-end
-endtask // autogenerated_BASIC_8982867242010371843
-task autogenerated_BASIC_5090788032873075449();
-reg [31 : 0] read_data;
-begin
-tc_ctr = tc_ctr + 1;
-$display("autogenerated_BASIC_5090788032873075449");
-write_word({MESSAGE_PREFIX, 8'h00}, 32'h00000001);
-write_word({MESSAGE_PREFIX, 8'h01}, 32'h9e504a03);
-write_word({EXPONENT_PREFIX, 8'h00}, 32'h00000001);
-write_word({EXPONENT_PREFIX, 8'h01}, 32'h9bc057ef);
-write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000002););
-write_word({MODULUS_PREFIX, 8'h00}, 32'h00000001);
-write_word({MODULUS_PREFIX, 8'h01}, 32'hc8b53fe5);
-write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000002););
-dump_memories()
-write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000002);
-wait_ready();
-read_word({RESULT_PREFIX,8'h00});
-read_data = tb_read_data;
-if (read_data !== 32'h00000001))
-  begin
-    $display("Expected: 0x00000001, got 0x%08x", read_data);
-  end
-read_word({RESULT_PREFIX,8'h01});
-read_data = tb_read_data;
-if (read_data !== 32'hc1a6494c))
-  begin
-    $display("Expected: 0xc1a6494c, got 0x%08x", read_data);
-  end
-end
-endtask // autogenerated_BASIC_5090788032873075449
-task autogenerated_BASIC_8448510918869952728();
-reg [31 : 0] read_data;
-begin
-tc_ctr = tc_ctr + 1;
-$display("autogenerated_BASIC_8448510918869952728");
-write_word({MESSAGE_PREFIX, 8'h00}, 32'h00000001);
-write_word({MESSAGE_PREFIX, 8'h01}, 32'h73f7b309);
-write_word({EXPONENT_PREFIX, 8'h00}, 32'h00000001);
-write_word({EXPONENT_PREFIX, 8'h01}, 32'h91c10f7f);
-write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000002););
-write_word({MODULUS_PREFIX, 8'h00}, 32'h00000001);
-write_word({MODULUS_PREFIX, 8'h01}, 32'h4be322c9);
-write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000002););
-dump_memories()
-write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000002);
-wait_ready();
-read_word({RESULT_PREFIX,8'h00});
-read_data = tb_read_data;
-if (read_data !== 32'h00000000))
-  begin
-    $display("Expected: 0x00000000, got 0x%08x", read_data);
-  end
-read_word({RESULT_PREFIX,8'h01});
-read_data = tb_read_data;
-if (read_data !== 32'h9a155286))
-  begin
-    $display("Expected: 0x9a155286, got 0x%08x", read_data);
-  end
-end
-endtask // autogenerated_BASIC_8448510918869952728
-task autogenerated_BASIC_4036237668019554146();
-reg [31 : 0] read_data;
-begin
-tc_ctr = tc_ctr + 1;
-$display("autogenerated_BASIC_4036237668019554146");
-write_word({MESSAGE_PREFIX, 8'h00}, 32'h00000001);
-write_word({MESSAGE_PREFIX, 8'h01}, 32'hd0f3961d);
-write_word({EXPONENT_PREFIX, 8'h00}, 32'h00000001);
-write_word({EXPONENT_PREFIX, 8'h01}, 32'hcdbc9c9d);
-write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000002););
-write_word({MODULUS_PREFIX, 8'h00}, 32'h00000001);
-write_word({MODULUS_PREFIX, 8'h01}, 32'h30367d5b);
-write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000002););
-dump_memories()
-write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000002);
-wait_ready();
-read_word({RESULT_PREFIX,8'h00});
-read_data = tb_read_data;
-if (read_data !== 32'h00000001))
-  begin
-    $display("Expected: 0x00000001, got 0x%08x", read_data);
-  end
-read_word({RESULT_PREFIX,8'h01});
-read_data = tb_read_data;
-if (read_data !== 32'h15a9c15d))
-  begin
-    $display("Expected: 0x15a9c15d, got 0x%08x", read_data);
-  end
-end
-endtask // autogenerated_BASIC_4036237668019554146
-task autogenerated_BASIC_M8925041444689012509();
-reg [31 : 0] read_data;
-begin
-tc_ctr = tc_ctr + 1;
-$display("autogenerated_BASIC_M8925041444689012509");
-write_word({MESSAGE_PREFIX, 8'h00}, 32'h00000001);
-write_word({MESSAGE_PREFIX, 8'h01}, 32'h34130e17);
-write_word({EXPONENT_PREFIX, 8'h00}, 32'h00000001);
-write_word({EXPONENT_PREFIX, 8'h01}, 32'hf45e52c9);
-write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000002););
-write_word({MODULUS_PREFIX, 8'h00}, 32'h00000001);
-write_word({MODULUS_PREFIX, 8'h01}, 32'h9cb5c68d);
-write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000002););
-dump_memories()
-write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000002);
-wait_ready();
-read_word({RESULT_PREFIX,8'h00});
-read_data = tb_read_data;
-if (read_data !== 32'h00000000))
-  begin
-    $display("Expected: 0x00000000, got 0x%08x", read_data);
-  end
-read_word({RESULT_PREFIX,8'h01});
-read_data = tb_read_data;
-if (read_data !== 32'h7c129d37))
-  begin
-    $display("Expected: 0x7c129d37, got 0x%08x", read_data);
-  end
-end
-endtask // autogenerated_BASIC_M8925041444689012509
-task autogenerated_BASIC_M5713608137760059379();
-reg [31 : 0] read_data;
-begin
-tc_ctr = tc_ctr + 1;
-$display("autogenerated_BASIC_M5713608137760059379");
-write_word({MESSAGE_PREFIX, 8'h00}, 32'h00000001);
-write_word({MESSAGE_PREFIX, 8'h01}, 32'h77505dbd);
-write_word({EXPONENT_PREFIX, 8'h00}, 32'h00000001);
-write_word({EXPONENT_PREFIX, 8'h01}, 32'hdb808627);
-write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000002););
-write_word({MODULUS_PREFIX, 8'h00}, 32'h00000001);
-write_word({MODULUS_PREFIX, 8'h01}, 32'had1fed09);
-write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000002););
-dump_memories()
-write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000002);
-wait_ready();
-read_word({RESULT_PREFIX,8'h00});
-read_data = tb_read_data;
-if (read_data !== 32'h00000001))
-  begin
-    $display("Expected: 0x00000001, got 0x%08x", read_data);
-  end
-read_word({RESULT_PREFIX,8'h01});
-read_data = tb_read_data;
-if (read_data !== 32'h842cd733))
-  begin
-    $display("Expected: 0x842cd733, got 0x%08x", read_data);
-  end
-end
-endtask // autogenerated_BASIC_M5713608137760059379
-task autogenerated_BASIC_6816968587684568101();
-reg [31 : 0] read_data;
-begin
-tc_ctr = tc_ctr + 1;
-$display("autogenerated_BASIC_6816968587684568101");
-write_word({MESSAGE_PREFIX, 8'h00}, 32'h00000001);
-write_word({MESSAGE_PREFIX, 8'h01}, 32'h3272b6ef);
-write_word({EXPONENT_PREFIX, 8'h00}, 32'h00000001);
-write_word({EXPONENT_PREFIX, 8'h01}, 32'h2cb6c09b);
-write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000002););
-write_word({MODULUS_PREFIX, 8'h00}, 32'h00000001);
-write_word({MODULUS_PREFIX, 8'h01}, 32'hefbc64fd);
-write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000002););
-dump_memories()
-write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000002);
-wait_ready();
-read_word({RESULT_PREFIX,8'h00});
-read_data = tb_read_data;
-if (read_data !== 32'h00000001))
-  begin
-    $display("Expected: 0x00000001, got 0x%08x", read_data);
-  end
-read_word({RESULT_PREFIX,8'h01});
-read_data = tb_read_data;
-if (read_data !== 32'h59c3b603))
-  begin
-    $display("Expected: 0x59c3b603, got 0x%08x", read_data);
-  end
-end
-endtask // autogenerated_BASIC_6816968587684568101
-task autogenerated_BASIC_4168013900853404774();
-reg [31 : 0] read_data;
-begin
-tc_ctr = tc_ctr + 1;
-$display("autogenerated_BASIC_4168013900853404774");
-write_word({MESSAGE_PREFIX, 8'h00}, 32'h00000001);
-write_word({MESSAGE_PREFIX, 8'h01}, 32'h3c20bbcf);
-write_word({EXPONENT_PREFIX, 8'h00}, 32'h00000001);
-write_word({EXPONENT_PREFIX, 8'h01}, 32'ha495d8ab);
-write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000002););
-write_word({MODULUS_PREFIX, 8'h00}, 32'h00000001);
-write_word({MODULUS_PREFIX, 8'h01}, 32'h75ddb9ef);
-write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000002););
-dump_memories()
-write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000002);
-wait_ready();
-read_word({RESULT_PREFIX,8'h00});
-read_data = tb_read_data;
-if (read_data !== 32'h00000001))
-  begin
-    $display("Expected: 0x00000001, got 0x%08x", read_data);
-  end
-read_word({RESULT_PREFIX,8'h01});
-read_data = tb_read_data;
-if (read_data !== 32'h1413eac7))
-  begin
-    $display("Expected: 0x1413eac7, got 0x%08x", read_data);
-  end
-end
-endtask // autogenerated_BASIC_4168013900853404774
-task autogenerated_BASIC_M8394821325674331878();
-reg [31 : 0] read_data;
-begin
-tc_ctr = tc_ctr + 1;
-$display("autogenerated_BASIC_M8394821325674331878");
-write_word({MESSAGE_PREFIX, 8'h00}, 32'h00000001);
-write_word({MESSAGE_PREFIX, 8'h01}, 32'h93d3d0d3);
-write_word({EXPONENT_PREFIX, 8'h00}, 32'h00000001);
-write_word({EXPONENT_PREFIX, 8'h01}, 32'h43c2dfef);
-write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000002););
-write_word({MODULUS_PREFIX, 8'h00}, 32'h00000001);
-write_word({MODULUS_PREFIX, 8'h01}, 32'h7443cbf1);
-write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000002););
-dump_memories()
-write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000002);
-wait_ready();
-read_word({RESULT_PREFIX,8'h00});
-read_data = tb_read_data;
-if (read_data !== 32'h00000000))
-  begin
-    $display("Expected: 0x00000000, got 0x%08x", read_data);
-  end
-read_word({RESULT_PREFIX,8'h01});
-read_data = tb_read_data;
-if (read_data !== 32'hc2eda7c3))
-  begin
-    $display("Expected: 0xc2eda7c3, got 0x%08x", read_data);
-  end
-end
-endtask // autogenerated_BASIC_M8394821325674331878
-task autogenerated_BASIC_M2919828800172604435();
-reg [31 : 0] read_data;
-begin
-tc_ctr = tc_ctr + 1;
-$display("autogenerated_BASIC_M2919828800172604435");
-write_word({MESSAGE_PREFIX, 8'h00}, 32'h3d746ec5);
-write_word({EXPONENT_PREFIX, 8'h00}, 32'h3f7ea6d5);
-write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001););
-write_word({MODULUS_PREFIX, 8'h00}, 32'h29b6675f);
-write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000001););
-dump_memories()
-write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
-wait_ready();
-read_word({RESULT_PREFIX,8'h00});
-read_data = tb_read_data;
-if (read_data !== 32'h040c43d8))
-  begin
-    $display("Expected: 0x040c43d8, got 0x%08x", read_data);
-  end
-end
-endtask // autogenerated_BASIC_M2919828800172604435
-task autogenerated_BASIC_4770912732078070597();
-reg [31 : 0] read_data;
-begin
-tc_ctr = tc_ctr + 1;
-$display("autogenerated_BASIC_4770912732078070597");
-write_word({MESSAGE_PREFIX, 8'h00}, 32'h200c0f45);
-write_word({EXPONENT_PREFIX, 8'h00}, 32'h24774bab);
-write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001););
-write_word({MODULUS_PREFIX, 8'h00}, 32'h234ca073);
-write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000001););
-dump_memories()
-write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
-wait_ready();
-read_word({RESULT_PREFIX,8'h00});
-read_data = tb_read_data;
-if (read_data !== 32'h14505436))
-  begin
-    $display("Expected: 0x14505436, got 0x%08x", read_data);
-  end
-end
-endtask // autogenerated_BASIC_4770912732078070597
-task autogenerated_BASIC_3593487472385409519();
-reg [31 : 0] read_data;
-begin
-tc_ctr = tc_ctr + 1;
-$display("autogenerated_BASIC_3593487472385409519");
-write_word({MESSAGE_PREFIX, 8'h00}, 32'h248819d1);
-write_word({EXPONENT_PREFIX, 8'h00}, 32'h2ad2b6ed);
-write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001););
-write_word({MODULUS_PREFIX, 8'h00}, 32'h269cc6bf);
-write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000001););
-dump_memories()
-write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
-wait_ready();
-read_word({RESULT_PREFIX,8'h00});
-read_data = tb_read_data;
-if (read_data !== 32'h0f09d466))
-  begin
-    $display("Expected: 0x0f09d466, got 0x%08x", read_data);
-  end
-end
-endtask // autogenerated_BASIC_3593487472385409519
-task autogenerated_BASIC_4981749054780354961();
-reg [31 : 0] read_data;
-begin
-tc_ctr = tc_ctr + 1;
-$display("autogenerated_BASIC_4981749054780354961");
-write_word({MESSAGE_PREFIX, 8'h00}, 32'h27bec4e7);
-write_word({EXPONENT_PREFIX, 8'h00}, 32'h36fe540f);
-write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001););
-write_word({MODULUS_PREFIX, 8'h00}, 32'h25a46d61);
-write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000001););
-dump_memories()
-write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
-wait_ready();
-read_word({RESULT_PREFIX,8'h00});
-read_data = tb_read_data;
-if (read_data !== 32'h0bab2269))
-  begin
-    $display("Expected: 0x0bab2269, got 0x%08x", read_data);
-  end
-end
-endtask // autogenerated_BASIC_4981749054780354961
-task autogenerated_BASIC_7702189670289360961();
-reg [31 : 0] read_data;
-begin
-tc_ctr = tc_ctr + 1;
-$display("autogenerated_BASIC_7702189670289360961");
-write_word({MESSAGE_PREFIX, 8'h00}, 32'h302def29);
-write_word({EXPONENT_PREFIX, 8'h00}, 32'h25b9c233);
-write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001););
-write_word({MODULUS_PREFIX, 8'h00}, 32'h33af5461);
-write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000001););
-dump_memories()
-write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
-wait_ready();
-read_word({RESULT_PREFIX,8'h00});
-read_data = tb_read_data;
-if (read_data !== 32'h0229dc08))
-  begin
-    $display("Expected: 0x0229dc08, got 0x%08x", read_data);
-  end
-end
-endtask // autogenerated_BASIC_7702189670289360961
-task autogenerated_BASIC_M5169634701858105792();
-reg [31 : 0] read_data;
-begin
-tc_ctr = tc_ctr + 1;
-$display("autogenerated_BASIC_M5169634701858105792");
-write_word({MESSAGE_PREFIX, 8'h00}, 32'h240d8cf5);
-write_word({EXPONENT_PREFIX, 8'h00}, 32'h2a6a7381);
-write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001););
-write_word({MODULUS_PREFIX, 8'h00}, 32'h3471d1e9);
-write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000001););
-dump_memories()
-write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
-wait_ready();
-read_word({RESULT_PREFIX,8'h00});
-read_data = tb_read_data;
-if (read_data !== 32'h244dec19))
-  begin
-    $display("Expected: 0x244dec19, got 0x%08x", read_data);
-  end
-end
-endtask // autogenerated_BASIC_M5169634701858105792
-task autogenerated_BASIC_6469444563916025786();
-reg [31 : 0] read_data;
-begin
-tc_ctr = tc_ctr + 1;
-$display("autogenerated_BASIC_6469444563916025786");
-write_word({MESSAGE_PREFIX, 8'h00}, 32'h3cc9270b);
-write_word({EXPONENT_PREFIX, 8'h00}, 32'h27858fdd);
-write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001););
-write_word({MODULUS_PREFIX, 8'h00}, 32'h21e65001);
-write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000001););
-dump_memories()
-write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
-wait_ready();
-read_word({RESULT_PREFIX,8'h00});
-read_data = tb_read_data;
-if (read_data !== 32'h17200d8c))
-  begin
-    $display("Expected: 0x17200d8c, got 0x%08x", read_data);
-  end
-end
-endtask // autogenerated_BASIC_6469444563916025786
-task autogenerated_BASIC_M2453278165832221565();
-reg [31 : 0] read_data;
-begin
-tc_ctr = tc_ctr + 1;
-$display("autogenerated_BASIC_M2453278165832221565");
-write_word({MESSAGE_PREFIX, 8'h00}, 32'h30ca6ceb);
-write_word({EXPONENT_PREFIX, 8'h00}, 32'h212c387b);
-write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001););
-write_word({MODULUS_PREFIX, 8'h00}, 32'h2e07a7bb);
-write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000001););
-dump_memories()
-write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
-wait_ready();
-read_word({RESULT_PREFIX,8'h00});
-read_data = tb_read_data;
-if (read_data !== 32'h0fc15a1f))
-  begin
-    $display("Expected: 0x0fc15a1f, got 0x%08x", read_data);
-  end
-end
-endtask // autogenerated_BASIC_M2453278165832221565
-task autogenerated_BASIC_M1847183855567461116();
-reg [31 : 0] read_data;
-begin
-tc_ctr = tc_ctr + 1;
-$display("autogenerated_BASIC_M1847183855567461116");
-write_word({MESSAGE_PREFIX, 8'h00}, 32'h3d02c5a1);
-write_word({EXPONENT_PREFIX, 8'h00}, 32'h35f12b45);
-write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001););
-write_word({MODULUS_PREFIX, 8'h00}, 32'h32f0b03f);
-write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000001););
-dump_memories()
-write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
-wait_ready();
-read_word({RESULT_PREFIX,8'h00});
-read_data = tb_read_data;
-if (read_data !== 32'h2340f96f))
-  begin
-    $display("Expected: 0x2340f96f, got 0x%08x", read_data);
-  end
-end
-endtask // autogenerated_BASIC_M1847183855567461116
-task autogenerated_BASIC_M7037130911981370263();
-reg [31 : 0] read_data;
-begin
-tc_ctr = tc_ctr + 1;
-$display("autogenerated_BASIC_M7037130911981370263");
-write_word({MESSAGE_PREFIX, 8'h00}, 32'h2692d1cd);
-write_word({EXPONENT_PREFIX, 8'h00}, 32'h3b21ef8d);
-write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001););
-write_word({MODULUS_PREFIX, 8'h00}, 32'h2042c76d);
-write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000001););
-dump_memories()
-write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
-wait_ready();
-read_word({RESULT_PREFIX,8'h00});
-read_data = tb_read_data;
-if (read_data !== 32'h1b753aea))
-  begin
-    $display("Expected: 0x1b753aea, got 0x%08x", read_data);
-  end
-end
-endtask // autogenerated_BASIC_M7037130911981370263
+  function assertEquals(
+      input [31:0] expected,
+      input [31:0] actual
+    );
+    begin
+      if (expected === actual)
+        begin
+          assertEquals = 1; // success
+        end
+      else
+        begin
+          $display("Expected: 0x%08x, got 0x%08x", expected, actual);
+          assertEquals = 0; // failure
+        end
+    end
+  endfunction // assertEquals
+
+  integer success;
+
+
+  task autogenerated_BASIC_M4962768465676381896();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_M4962768465676381896");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'h946473e1); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'h0e85e74f); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'h70754797); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000002); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000002); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h00000000, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'h7761ed4f, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_M4962768465676381896 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_M4962768465676381896 success.");
+    end
+  endtask // autogenerated_BASIC_M4962768465676381896
+
+
+
+  task autogenerated_BASIC_8982867242010371843();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_8982867242010371843");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'h6eb4ac2d); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'hbb200e41); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'h27347dc3); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000002); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000002); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h00000000, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'h87d16204, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_8982867242010371843 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_8982867242010371843 success.");
+    end
+  endtask // autogenerated_BASIC_8982867242010371843
+
+
+
+  task autogenerated_BASIC_5090788032873075449();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_5090788032873075449");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'h9e504a03); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'h9bc057ef); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'hc8b53fe5); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000002); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000002); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h00000001, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'hc1a6494c, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_5090788032873075449 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_5090788032873075449 success.");
+    end
+  endtask // autogenerated_BASIC_5090788032873075449
+
+
+
+  task autogenerated_BASIC_8448510918869952728();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_8448510918869952728");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'h73f7b309); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'h91c10f7f); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'h4be322c9); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000002); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000002); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h00000000, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'h9a155286, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_8448510918869952728 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_8448510918869952728 success.");
+    end
+  endtask // autogenerated_BASIC_8448510918869952728
+
+
+
+  task autogenerated_BASIC_4036237668019554146();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_4036237668019554146");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'hd0f3961d); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'hcdbc9c9d); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'h30367d5b); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000002); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000002); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h00000001, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'h15a9c15d, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_4036237668019554146 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_4036237668019554146 success.");
+    end
+  endtask // autogenerated_BASIC_4036237668019554146
+
+
+
+  task autogenerated_BASIC_M8925041444689012509();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_M8925041444689012509");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'h34130e17); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'hf45e52c9); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'h9cb5c68d); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000002); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000002); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h00000000, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'h7c129d37, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_M8925041444689012509 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_M8925041444689012509 success.");
+    end
+  endtask // autogenerated_BASIC_M8925041444689012509
+
+
+
+  task autogenerated_BASIC_M5713608137760059379();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_M5713608137760059379");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'h77505dbd); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'hdb808627); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'had1fed09); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000002); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000002); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h00000001, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'h842cd733, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_M5713608137760059379 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_M5713608137760059379 success.");
+    end
+  endtask // autogenerated_BASIC_M5713608137760059379
+
+
+
+  task autogenerated_BASIC_6816968587684568101();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_6816968587684568101");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'h3272b6ef); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'h2cb6c09b); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'hefbc64fd); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000002); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000002); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h00000001, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'h59c3b603, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_6816968587684568101 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_6816968587684568101 success.");
+    end
+  endtask // autogenerated_BASIC_6816968587684568101
+
+
+
+  task autogenerated_BASIC_4168013900853404774();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_4168013900853404774");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'h3c20bbcf); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'ha495d8ab); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'h75ddb9ef); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000002); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000002); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h00000001, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'h1413eac7, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_4168013900853404774 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_4168013900853404774 success.");
+    end
+  endtask // autogenerated_BASIC_4168013900853404774
+
+
+
+  task autogenerated_BASIC_M8394821325674331878();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_M8394821325674331878");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'h93d3d0d3); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'h43c2dfef); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h00000001); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'h7443cbf1); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000002); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000002); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h00000000, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'hc2eda7c3, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_M8394821325674331878 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_M8394821325674331878 success.");
+    end
+  endtask // autogenerated_BASIC_M8394821325674331878
+
+
+
+  task autogenerated_BASIC_M2919828800172604435();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_M2919828800172604435");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h3d746ec5); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h3f7ea6d5); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h29b6675f); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000001); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h040c43d8, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_M2919828800172604435 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_M2919828800172604435 success.");
+    end
+  endtask // autogenerated_BASIC_M2919828800172604435
+
+
+
+  task autogenerated_BASIC_4770912732078070597();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_4770912732078070597");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h200c0f45); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h24774bab); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h234ca073); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000001); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h14505436, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_4770912732078070597 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_4770912732078070597 success.");
+    end
+  endtask // autogenerated_BASIC_4770912732078070597
+
+
+
+  task autogenerated_BASIC_3593487472385409519();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_3593487472385409519");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h248819d1); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h2ad2b6ed); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h269cc6bf); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000001); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h0f09d466, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_3593487472385409519 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_3593487472385409519 success.");
+    end
+  endtask // autogenerated_BASIC_3593487472385409519
+
+
+
+  task autogenerated_BASIC_4981749054780354961();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_4981749054780354961");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h27bec4e7); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h36fe540f); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h25a46d61); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000001); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h0bab2269, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_4981749054780354961 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_4981749054780354961 success.");
+    end
+  endtask // autogenerated_BASIC_4981749054780354961
+
+
+
+  task autogenerated_BASIC_7702189670289360961();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_7702189670289360961");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h302def29); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h25b9c233); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h33af5461); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000001); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h0229dc08, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_7702189670289360961 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_7702189670289360961 success.");
+    end
+  endtask // autogenerated_BASIC_7702189670289360961
+
+
+
+  task autogenerated_BASIC_M5169634701858105792();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_M5169634701858105792");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h240d8cf5); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h2a6a7381); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h3471d1e9); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000001); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h244dec19, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_M5169634701858105792 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_M5169634701858105792 success.");
+    end
+  endtask // autogenerated_BASIC_M5169634701858105792
+
+
+
+  task autogenerated_BASIC_6469444563916025786();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_6469444563916025786");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h3cc9270b); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h27858fdd); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h21e65001); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000001); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h17200d8c, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_6469444563916025786 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_6469444563916025786 success.");
+    end
+  endtask // autogenerated_BASIC_6469444563916025786
+
+
+
+  task autogenerated_BASIC_M2453278165832221565();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_M2453278165832221565");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h30ca6ceb); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h212c387b); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h2e07a7bb); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000001); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h0fc15a1f, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_M2453278165832221565 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_M2453278165832221565 success.");
+    end
+  endtask // autogenerated_BASIC_M2453278165832221565
+
+
+
+  task autogenerated_BASIC_M1847183855567461116();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_M1847183855567461116");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h3d02c5a1); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h35f12b45); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h32f0b03f); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000001); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h2340f96f, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_M1847183855567461116 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_M1847183855567461116 success.");
+    end
+  endtask // autogenerated_BASIC_M1847183855567461116
+
+
+
+  task autogenerated_BASIC_M7037130911981370263();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_M7037130911981370263");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h2692d1cd); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h3b21ef8d); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h2042c76d); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000001); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h1b753aea, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_M7037130911981370263 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_M7037130911981370263 success.");
+    end
+  endtask // autogenerated_BASIC_M7037130911981370263
+
+
+
+  task autogenerated_BASIC_5073338267670769216();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_5073338267670769216");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h3028983f); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'hdc9bdc25); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h02}, 32'ha3fdfeda); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h03}, 32'h283f4463); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h29493211); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'hc4252db0); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h02}, 32'h7775443d); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h03}, 32'h13e1d929); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h2fb9ba2f); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'ha485d5f7); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h02}, 32'h3c6652c9); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h03}, 32'h670fdbfd); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000004); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000004); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h2f45cdd6, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'h23f0e6f2, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h02}); read_data = tb_read_data; success = success & assertEquals(32'haa4bd5d8, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h03}); read_data = tb_read_data; success = success & assertEquals(32'h6297da06, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_5073338267670769216 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_5073338267670769216 success.");
+    end
+  endtask // autogenerated_BASIC_5073338267670769216
+
+
+
+  task autogenerated_BASIC_M1841989679506188752();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_M1841989679506188752");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h29462882); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'h12caa2d5); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h02}, 32'hb80e1c66); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h03}, 32'h1006807f); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h3285c343); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'h2acbcb0f); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h02}, 32'h4d023228); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h03}, 32'h2ecc73db); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h267d2f2e); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'h51c216a7); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h02}, 32'hda752ead); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h03}, 32'h48d22d89); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000004); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000004); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h0ddc404d, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'h91600596, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h02}); read_data = tb_read_data; success = success & assertEquals(32'h7425a8d8, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h03}); read_data = tb_read_data; success = success & assertEquals(32'ha066ca56, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_M1841989679506188752 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_M1841989679506188752 success.");
+    end
+  endtask // autogenerated_BASIC_M1841989679506188752
+
+
+
+  task autogenerated_BASIC_M3339729654500648482();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_M3339729654500648482");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h2963efb9); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'hc6f5d260); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h02}, 32'ha2d0fe74); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h03}, 32'h49726b57); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h2f55c103); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'hbace4bf1); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h02}, 32'h2ab9fac2); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h03}, 32'h30aec7d3); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h376cf9ae); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'hd9e988e8); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h02}, 32'hbd995f5c); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h03}, 32'hdeec42f5); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000004); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000004); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h0ce8cff7, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'h9f564e2c, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h02}); read_data = tb_read_data; success = success & assertEquals(32'h1b61e3d9, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h03}); read_data = tb_read_data; success = success & assertEquals(32'h717db9ef, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_M3339729654500648482 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_M3339729654500648482 success.");
+    end
+  endtask // autogenerated_BASIC_M3339729654500648482
+
+
+
+  task autogenerated_BASIC_M6837928193394880512();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_M6837928193394880512");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h2a9283cc); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'h5999f49d); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h02}, 32'hf8cf6ab2); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h03}, 32'h5f47bf25); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h2c7564a0); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'h2d1fcda1); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h02}, 32'h2825318a); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h03}, 32'hae23c271); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h32b892f9); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'h096c5ada); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h02}, 32'h43918370); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h03}, 32'h8398c7e3); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000004); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000004); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h27cf8839, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'h94004d82, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h02}); read_data = tb_read_data; success = success & assertEquals(32'ha0d69d86, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h03}); read_data = tb_read_data; success = success & assertEquals(32'h3f61a929, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_M6837928193394880512 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_M6837928193394880512 success.");
+    end
+  endtask // autogenerated_BASIC_M6837928193394880512
+
+
+
+  task autogenerated_BASIC_M7333111649825079555();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_M7333111649825079555");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h246fa2ec); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'h405f234d); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h02}, 32'h39b93e77); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h03}, 32'hf16bcc91); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h2807eb7a); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'h646df633); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h02}, 32'heaa95a21); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h03}, 32'h85252adf); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h2cdd3307); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'h782e5711); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h02}, 32'h584f179b); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h03}, 32'h011087df); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000004); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000004); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h02d6e42e, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'h46e2d304, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h02}); read_data = tb_read_data; success = success & assertEquals(32'h435170c1, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h03}); read_data = tb_read_data; success = success & assertEquals(32'h9f344f83, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_M7333111649825079555 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_M7333111649825079555 success.");
+    end
+  endtask // autogenerated_BASIC_M7333111649825079555
+
+
+
+  task autogenerated_BASIC_480186175131589607();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_480186175131589607");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h300a5cf7); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'h269f6369); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h02}, 32'h02e025cb); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h03}, 32'haf16fcfd); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h2cc4b1c0); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'h9205a8b4); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h02}, 32'hbc130ee2); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h03}, 32'h923f1f3f); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h2cd376d5); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'hd9e3b080); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h02}, 32'h2533288a); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h03}, 32'hd4b9bb37); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000004); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000004); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h0ae9c475, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'hf4fb4c63, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h02}); read_data = tb_read_data; success = success & assertEquals(32'hcf2c4f56, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h03}); read_data = tb_read_data; success = success & assertEquals(32'h902eba0c, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_480186175131589607 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_480186175131589607 success.");
+    end
+  endtask // autogenerated_BASIC_480186175131589607
+
+
+
+  task autogenerated_BASIC_M5239159917778665002();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_M5239159917778665002");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h3eaed5af); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'ha287db7e); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h02}, 32'h4ff07fee); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h03}, 32'h9bbda80b); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h3c077d49); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'hf3a131ab); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h02}, 32'h6289042a); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h03}, 32'hc15083cb); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h344b8538); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'hcf4f2576); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h02}, 32'hd28c1c52); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h03}, 32'hc83a8199); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000004); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000004); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h15028046, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'h5c12d235, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h02}); read_data = tb_read_data; success = success & assertEquals(32'h7580fd1b, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h03}); read_data = tb_read_data; success = success & assertEquals(32'h6bc76b24, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_M5239159917778665002 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_M5239159917778665002 success.");
+    end
+  endtask // autogenerated_BASIC_M5239159917778665002
+
+
+
+  task autogenerated_BASIC_228752064885223799();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_228752064885223799");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h3904d7ab); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'h13937a4f); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h02}, 32'h926856d1); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h03}, 32'h6bdda621); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h3d360083); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'ha50eaf0e); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h02}, 32'hffce2df2); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h03}, 32'hb1f51cef); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h2d32376f); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'h205555b3); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h02}, 32'h2c9daf8c); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h03}, 32'he2b7cf81); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000004); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000004); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h08836692, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'he6398828, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h02}); read_data = tb_read_data; success = success & assertEquals(32'h1eeccd57, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h03}); read_data = tb_read_data; success = success & assertEquals(32'h2c231153, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_228752064885223799 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_228752064885223799 success.");
+    end
+  endtask // autogenerated_BASIC_228752064885223799
+
+
+
+  task autogenerated_BASIC_856940511857911599();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_856940511857911599");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h23e80223); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'h52b700ee); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h02}, 32'h6cb8a294); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h03}, 32'h47c6fac9); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h253cebdb); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'hcc78dcb4); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h02}, 32'h925682b3); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h03}, 32'h490c424b); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h2f2885eb); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'h67987cee); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h02}, 32'h717298bd); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h03}, 32'h7a1baf7b); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000004); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000004); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h2bb0b86c, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'hc854652b, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h02}); read_data = tb_read_data; success = success & assertEquals(32'h2b2bce27, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h03}); read_data = tb_read_data; success = success & assertEquals(32'hd2595a8e, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_856940511857911599 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_856940511857911599 success.");
+    end
+  endtask // autogenerated_BASIC_856940511857911599
+
+
+
+  task autogenerated_BASIC_M6501553661140603953();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_M6501553661140603953");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h287e9711); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'h4d346dab); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h02}, 32'h3ff5e6da); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h03}, 32'ha93edebd); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h3658192a); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'h4b5fac3f); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h02}, 32'h9a78bc81); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h03}, 32'h5ac8c667); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h238cd95d); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'h298ee5e1); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h02}, 32'h320323da); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h03}, 32'h0a46ec21); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000004); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000004); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h0415fef6, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'h5fc81702, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h02}); read_data = tb_read_data; success = success & assertEquals(32'h8be83fd4, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h03}); read_data = tb_read_data; success = success & assertEquals(32'h4c7fbf24, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_M6501553661140603953 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_M6501553661140603953 success.");
+    end
+  endtask // autogenerated_BASIC_M6501553661140603953
+
+
+
+  task autogenerated_BASIC_M8496483018338900149();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_M8496483018338900149");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h3b4511d5); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'h5f61da31); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h02}, 32'h4bf252e0); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h03}, 32'h3962f93c); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h04}, 32'h590171d0); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h05}, 32'hda31097f); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h06}, 32'h0f73fee3); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h07}, 32'h0ba1b379); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h08}, 32'h514b7d8f); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h09}, 32'h1e337cf9); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h0a}, 32'h733512ac); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h0b}, 32'h4f5b0b52); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h0c}, 32'h40762697); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h0d}, 32'hb3a30c84); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h0e}, 32'h5563b4db); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h0f}, 32'h59f7cef1); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h271cb7c4); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'h11f07a63); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h02}, 32'h1df850e7); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h03}, 32'h8bf6df66); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h04}, 32'h7bc8fa0e); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h05}, 32'ha51002ce); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h06}, 32'hf16946c5); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h07}, 32'h96916dc7); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h08}, 32'hba1681b1); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h09}, 32'h5ca395ab); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h0a}, 32'h7839780d); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h0b}, 32'hc5e760c3); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h0c}, 32'h578af4f9); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h0d}, 32'hffbbbd8c); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h0e}, 32'h8576c8fc); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h0f}, 32'h518012a7); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h3c0f154d); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'h7fc7750a); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h02}, 32'h03eb8968); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h03}, 32'hfbde501a); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h04}, 32'h63848fe5); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h05}, 32'hdcd7d883); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h06}, 32'h5131c9f9); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h07}, 32'ha9ca3399); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h08}, 32'hba581205); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h09}, 32'h4cf86f2a); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h0a}, 32'hed928b92); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h0b}, 32'h13a0e90f); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h0c}, 32'h5b24c81a); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h0d}, 32'hf4ac077c); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h0e}, 32'h68b8ac70); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h0f}, 32'hc58961fd); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000010); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000010); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h30d0a0c1, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'h1be7b00f, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h02}); read_data = tb_read_data; success = success & assertEquals(32'h9ed921c6, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h03}); read_data = tb_read_data; success = success & assertEquals(32'h7a7f9a87, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h04}); read_data = tb_read_data; success = success & assertEquals(32'hb8ed7f88, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h05}); read_data = tb_read_data; success = success & assertEquals(32'hd81f20d5, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h06}); read_data = tb_read_data; success = success & assertEquals(32'hb3ba9839, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h07}); read_data = tb_read_data; success = success & assertEquals(32'h38dfdfb4, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h08}); read_data = tb_read_data; success = success & assertEquals(32'h70b1927c, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h09}); read_data = tb_read_data; success = success & assertEquals(32'ha4b9487b, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h0a}); read_data = tb_read_data; success = success & assertEquals(32'h8d8d7e2c, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h0b}); read_data = tb_read_data; success = success & assertEquals(32'hc706e737, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h0c}); read_data = tb_read_data; success = success & assertEquals(32'h17e9c280, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h0d}); read_data = tb_read_data; success = success & assertEquals(32'hbec0006a, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h0e}); read_data = tb_read_data; success = success & assertEquals(32'heea7dc97, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h0f}); read_data = tb_read_data; success = success & assertEquals(32'h4f5badc9, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_M8496483018338900149 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_M8496483018338900149 success.");
+    end
+  endtask // autogenerated_BASIC_M8496483018338900149
+
+
+
+  task autogenerated_BASIC_6145567102166328515();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_6145567102166328515");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h23446522); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'h9185c81e); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h02}, 32'h09283a50); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h03}, 32'h82c1f517); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h04}, 32'hd00d3159); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h05}, 32'h846c2c99); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h06}, 32'h261d1dcb); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h07}, 32'hde183d66); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h08}, 32'h98f8a990); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h09}, 32'hd295bd50); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h0a}, 32'h09ef8644); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h0b}, 32'hadcf9cdb); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h0c}, 32'h5eec13a3); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h0d}, 32'h92baa627); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h0e}, 32'h18caa215); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h0f}, 32'h8836480f); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h397f2b38); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'ha95cc0bc); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h02}, 32'hc13b26cf); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h03}, 32'ha20dda3c); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h04}, 32'hf8801c39); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h05}, 32'h00731abe); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h06}, 32'h2ad0afc4); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h07}, 32'hdb247141); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h08}, 32'hc29b5a2d); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h09}, 32'h9e51a3ed); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h0a}, 32'hcf364a51); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h0b}, 32'h90b761d5); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h0c}, 32'hfa0624d3); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h0d}, 32'h3a0b27c7); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h0e}, 32'ha36bc66c); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h0f}, 32'h6423efd3); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h3ad2464f); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'h75da362c); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h02}, 32'h6e5c37b4); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h03}, 32'h432cc6b7); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h04}, 32'h6f48b57c); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h05}, 32'hebb87e14); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h06}, 32'h0a3d3f4d); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h07}, 32'hfa4c32c0); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h08}, 32'h165a5892); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h09}, 32'h742f720d); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h0a}, 32'h8b4e1b43); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h0b}, 32'h281d5390); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h0c}, 32'hff2f77dc); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h0d}, 32'h698dbc05); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h0e}, 32'hdee97a68); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h0f}, 32'hde2c176d); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000010); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000010); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h083aa822, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'h7c70341a, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h02}); read_data = tb_read_data; success = success & assertEquals(32'ha2cbc9a8, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h03}); read_data = tb_read_data; success = success & assertEquals(32'hd116bc41, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h04}); read_data = tb_read_data; success = success & assertEquals(32'h79a81ba7, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h05}); read_data = tb_read_data; success = success & assertEquals(32'h584c91c8, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h06}); read_data = tb_read_data; success = success & assertEquals(32'h5b87c314, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h07}); read_data = tb_read_data; success = success & assertEquals(32'hc5e6f4f9, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h08}); read_data = tb_read_data; success = success & assertEquals(32'h601ebead, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h09}); read_data = tb_read_data; success = success & assertEquals(32'h054bf14b, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h0a}); read_data = tb_read_data; success = success & assertEquals(32'h65b48a4a, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h0b}); read_data = tb_read_data; success = success & assertEquals(32'hf8aa2700, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h0c}); read_data = tb_read_data; success = success & assertEquals(32'ha765ee1d, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h0d}); read_data = tb_read_data; success = success & assertEquals(32'hb6c638cd, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h0e}); read_data = tb_read_data; success = success & assertEquals(32'h7e529f23, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h0f}); read_data = tb_read_data; success = success & assertEquals(32'h0d4adfff, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_6145567102166328515 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_6145567102166328515 success.");
+    end
+  endtask // autogenerated_BASIC_6145567102166328515
+
+
+
+  task autogenerated_BASIC_7216348574014690328();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_7216348574014690328");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h35baa860); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'h4e47ad49); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h02}, 32'hc6c4a7c0); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h03}, 32'h7857335b); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h04}, 32'h9b81d24f); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h05}, 32'h7be86e34); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h06}, 32'hf84f7560); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h07}, 32'h484b20db); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h08}, 32'hb83b4f9e); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h09}, 32'h694c6987); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h0a}, 32'h7d3232f5); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h0b}, 32'h18ee8603); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h0c}, 32'h94eca5ef); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h0d}, 32'h5179ef69); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h0e}, 32'hf6600efb); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h0f}, 32'hfc71deab); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h10}, 32'hdb939552); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h11}, 32'h642db1e0); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h12}, 32'h78e11e39); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h13}, 32'h924f0dbd); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h14}, 32'hdb225803); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h15}, 32'h449bbb35); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h16}, 32'hfc40ee05); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h17}, 32'h9b19931c); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h18}, 32'h8b8af884); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h19}, 32'hb5f96476); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h1a}, 32'hf97ad419); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h1b}, 32'hcc7543f9); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h1c}, 32'hce25ed83); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h1d}, 32'h94da3499); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h1e}, 32'h4f37f331); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h1f}, 32'he64e7799); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h3a7570f2); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'h38cb0f2f); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h02}, 32'h2e6c8989); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h03}, 32'hcf7c2665); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h04}, 32'ha0fce3d0); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h05}, 32'h12c7a8eb); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h06}, 32'h40fab1ea); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h07}, 32'h39eb4809); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h08}, 32'h822fa6cc); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h09}, 32'h4ef9d604); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h0a}, 32'h2ca1cd3b); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h0b}, 32'ha9b23cdb); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h0c}, 32'h17e823ce); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h0d}, 32'h5fea5198); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h0e}, 32'h1ab12946); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h0f}, 32'hcec748b5); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h10}, 32'h752a3a6f); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h11}, 32'h73421a9a); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h12}, 32'h7138d7a4); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h13}, 32'ha47327c0); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h14}, 32'h17475543); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h15}, 32'he841c19a); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h16}, 32'h3085410a); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h17}, 32'h06438b4c); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h18}, 32'he0d4b918); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h19}, 32'hfeccca17); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h1a}, 32'h9ed86072); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h1b}, 32'h86db4a93); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h1c}, 32'h60c7d437); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h1d}, 32'hcdfe77e3); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h1e}, 32'h2631f264); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h1f}, 32'h80c9b645); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h34d90901); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'hf192009c); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h02}, 32'hc34f345f); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h03}, 32'h63f592b2); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h04}, 32'haba32d7a); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h05}, 32'h161d1510); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h06}, 32'h2c264dec); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h07}, 32'h07306f1d); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h08}, 32'h3e61c031); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h09}, 32'hacd4eba0); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h0a}, 32'hff1318ff); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h0b}, 32'h09a78cf4); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h0c}, 32'h97bace67); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h0d}, 32'hc8fcecf4); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h0e}, 32'h3b3901a3); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h0f}, 32'h5d447957); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h10}, 32'hc0397708); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h11}, 32'h7e7e48f9); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h12}, 32'h571db58a); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h13}, 32'h80d65921); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h14}, 32'h68a025e0); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h15}, 32'h4f85f776); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h16}, 32'haa8450c7); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h17}, 32'h15c42f52); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h18}, 32'he65507f2); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h19}, 32'hdfeed660); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h1a}, 32'h0db8eddb); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h1b}, 32'hb1e48d93); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h1c}, 32'h7e314a2f); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h1d}, 32'hea81ccb1); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h1e}, 32'hbe22cc03); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h1f}, 32'hf2928621); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000020); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000020); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h14c07087, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'h3e92a437, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h02}); read_data = tb_read_data; success = success & assertEquals(32'hbfd5a5b3, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h03}); read_data = tb_read_data; success = success & assertEquals(32'hec017ed5, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h04}); read_data = tb_read_data; success = success & assertEquals(32'hacf23e12, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h05}); read_data = tb_read_data; success = success & assertEquals(32'h6e48a51f, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h06}); read_data = tb_read_data; success = success & assertEquals(32'he1fdbde9, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h07}); read_data = tb_read_data; success = success & assertEquals(32'h43fade6b, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h08}); read_data = tb_read_data; success = success & assertEquals(32'h98935c7a, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h09}); read_data = tb_read_data; success = success & assertEquals(32'haff9b1e5, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h0a}); read_data = tb_read_data; success = success & assertEquals(32'h3adaa120, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h0b}); read_data = tb_read_data; success = success & assertEquals(32'hcbaa5af5, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h0c}); read_data = tb_read_data; success = success & assertEquals(32'h344fabb2, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h0d}); read_data = tb_read_data; success = success & assertEquals(32'h8d2987c7, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h0e}); read_data = tb_read_data; success = success & assertEquals(32'hfb83d342, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h0f}); read_data = tb_read_data; success = success & assertEquals(32'h3f85bbfc, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h10}); read_data = tb_read_data; success = success & assertEquals(32'hc30e755a, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h11}); read_data = tb_read_data; success = success & assertEquals(32'h37f20fa4, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h12}); read_data = tb_read_data; success = success & assertEquals(32'h7fb5621b, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h13}); read_data = tb_read_data; success = success & assertEquals(32'hcd1cef03, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h14}); read_data = tb_read_data; success = success & assertEquals(32'h664ccb56, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h15}); read_data = tb_read_data; success = success & assertEquals(32'hce0a28b9, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h16}); read_data = tb_read_data; success = success & assertEquals(32'ha9cbdd51, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h17}); read_data = tb_read_data; success = success & assertEquals(32'had12eb24, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h18}); read_data = tb_read_data; success = success & assertEquals(32'hacc08c8d, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h19}); read_data = tb_read_data; success = success & assertEquals(32'h5d9fe7f5, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h1a}); read_data = tb_read_data; success = success & assertEquals(32'h018c1e1e, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h1b}); read_data = tb_read_data; success = success & assertEquals(32'h2115bba8, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h1c}); read_data = tb_read_data; success = success & assertEquals(32'h22b52262, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h1d}); read_data = tb_read_data; success = success & assertEquals(32'haee3bf8a, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h1e}); read_data = tb_read_data; success = success & assertEquals(32'h91824a22, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h1f}); read_data = tb_read_data; success = success & assertEquals(32'hde48a1f3, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_7216348574014690328 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_7216348574014690328 success.");
+    end
+  endtask // autogenerated_BASIC_7216348574014690328
+
+
+
+  task autogenerated_BASIC_M5663191947183200100();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("autogenerated_BASIC_M5663191947183200100");
+
+      write_word({MESSAGE_PREFIX, 8'h00}, 32'h21558179); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h01}, 32'h3e2914b1); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h02}, 32'hefe95957); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h03}, 32'h965fdead); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h04}, 32'he766d8fc); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h05}, 32'h136eadf4); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h06}, 32'ha6106a2a); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h07}, 32'h88b2df7e); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h08}, 32'he0b0eaae); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h09}, 32'h2c17946a); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h0a}, 32'h6f5b5563); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h0b}, 32'h228052ae); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h0c}, 32'h7fc40d80); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h0d}, 32'hf81354db); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h0e}, 32'hfceecd1a); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h0f}, 32'ha5e4c97d); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h10}, 32'h433ecfcd); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h11}, 32'hc20d1e4d); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h12}, 32'h2a748fe3); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h13}, 32'h1d9e63f0); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h14}, 32'hdc6c25d6); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h15}, 32'hdae5c8be); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h16}, 32'h1d8c5431); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h17}, 32'hb1d7d270); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h18}, 32'hed5b2566); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h19}, 32'h1463b0fd); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h1a}, 32'ha9e26cf7); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h1b}, 32'h3dd6fbd7); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h1c}, 32'h1347c8f7); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h1d}, 32'h76c2cc37); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h1e}, 32'hf382b786); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h1f}, 32'h1d5ac517); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h20}, 32'h26b96692); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h21}, 32'h2c1fe6f8); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h22}, 32'h5852dbf8); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h23}, 32'h4bcabda2); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h24}, 32'hbedb2f5f); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h25}, 32'hbfe58158); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h26}, 32'h8cd5d15f); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h27}, 32'hac7c7f4c); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h28}, 32'hf8ba47d2); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h29}, 32'h86c6571d); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h2a}, 32'h06a4760b); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h2b}, 32'ha6afa0e1); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h2c}, 32'h7a819f62); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h2d}, 32'h5cdbfe15); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h2e}, 32'h9b2d10b5); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h2f}, 32'hf508b1fd); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h30}, 32'hb3f0462a); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h31}, 32'h92f45a64); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h32}, 32'h69b6ec58); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h33}, 32'hbfad8fab); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h34}, 32'h6799260f); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h35}, 32'h27415db5); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h36}, 32'hf6ac7832); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h37}, 32'he547826d); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h38}, 32'h6a9806a5); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h39}, 32'h36c62a88); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h3a}, 32'h98bee14d); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h3b}, 32'h9b8c2648); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h3c}, 32'habdbbd3d); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h3d}, 32'haf59eea1); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h3e}, 32'h164eacb5); //TEMPLATE_MESSAGE_VALES
+      write_word({MESSAGE_PREFIX, 8'h3f}, 32'h3a18e427); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h00}, 32'h2519837b); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h01}, 32'he73a9031); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h02}, 32'he241606d); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h03}, 32'h21e70fa2); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h04}, 32'h7881f254); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h05}, 32'h4e60831d); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h06}, 32'h266f408e); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h07}, 32'h4a83e6ed); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h08}, 32'ha7741995); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h09}, 32'h32b477ba); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h0a}, 32'h91bdf5d0); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h0b}, 32'h4acd7a06); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h0c}, 32'h51e344b9); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h0d}, 32'hdf376e4e); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h0e}, 32'h8494e625); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h0f}, 32'ha0cc9697); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h10}, 32'h817a0c93); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h11}, 32'h3b68cefb); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h12}, 32'h46de14c1); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h13}, 32'h52229965); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h14}, 32'h329645bd); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h15}, 32'hf4176adc); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h16}, 32'h29a8bc50); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h17}, 32'h44900fec); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h18}, 32'h1558d492); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h19}, 32'hf838a8e7); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h1a}, 32'hea207abd); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h1b}, 32'hcd21a28c); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h1c}, 32'h91e6b02f); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h1d}, 32'h2a490ea8); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h1e}, 32'h5d99663b); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h1f}, 32'h87c92fb6); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h20}, 32'h0a185325); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h21}, 32'h5256a7a3); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h22}, 32'h496b7288); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h23}, 32'h6688b6c8); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h24}, 32'h650e1776); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h25}, 32'h54cd429f); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h26}, 32'h90ea3b18); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h27}, 32'h0b72ae61); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h28}, 32'hcc8651b3); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h29}, 32'ha488742d); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h2a}, 32'h93c401ef); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h2b}, 32'h5a2220ff); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h2c}, 32'haee1f257); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h2d}, 32'hf9d1e29a); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h2e}, 32'hd47151fe); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h2f}, 32'h4978342b); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h30}, 32'h0927048a); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h31}, 32'h404b0689); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h32}, 32'hdc9df8cc); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h33}, 32'hfba9845f); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h34}, 32'heb8a39b0); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h35}, 32'hd3f24ae2); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h36}, 32'h5ea9ca0a); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h37}, 32'h0c064f94); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h38}, 32'h35368ae2); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h39}, 32'heab6c035); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h3a}, 32'h9baa39c6); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h3b}, 32'h2ef6259d); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h3c}, 32'ha2577555); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h3d}, 32'h514c7d98); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h3e}, 32'h0890d44f); //TEMPLATE_EXPONENT_VALES
+      write_word({EXPONENT_PREFIX, 8'h3f}, 32'hf416fbdd); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h00}, 32'h2c5337a9); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h01}, 32'h3f2e1ca6); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h02}, 32'h91de65ea); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h03}, 32'hc3f9a3c2); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h04}, 32'hdc9099e0); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h05}, 32'h64ebe412); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h06}, 32'hf4583fae); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h07}, 32'h1fc8e8dd); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h08}, 32'h92dcbbfb); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h09}, 32'h9159239e); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h0a}, 32'hdbbec456); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h0b}, 32'h8735a660); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h0c}, 32'h8248dbbc); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h0d}, 32'h76f01415); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h0e}, 32'h3cb8a897); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h0f}, 32'h7cc09280); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h10}, 32'h6cc6db51); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h11}, 32'h9c2544da); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h12}, 32'h316564ce); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h13}, 32'h4b6d9b3b); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h14}, 32'h3e0e123f); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h15}, 32'h942a4a3c); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h16}, 32'h1f128873); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h17}, 32'h5ad14862); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h18}, 32'hdde8e6dd); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h19}, 32'h73da31fb); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h1a}, 32'h1a8a2046); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h1b}, 32'hc3ff18c6); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h1c}, 32'h24e31d54); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h1d}, 32'h7d8a1796); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h1e}, 32'h88ab346c); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h1f}, 32'h262bb321); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h20}, 32'h2cada5dc); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h21}, 32'h1fb2284c); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h22}, 32'h042375fd); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h23}, 32'hba10d309); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h24}, 32'hcda978ec); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h25}, 32'h229ee156); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h26}, 32'h8470728a); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h27}, 32'ha58017fd); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h28}, 32'h65727801); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h29}, 32'h1ea396a6); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h2a}, 32'hbd9a4bc1); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h2b}, 32'h8e97c08f); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h2c}, 32'hd7529796); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h2d}, 32'h2c8339e9); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h2e}, 32'hc5340a83); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h2f}, 32'h6f7d1f9c); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h30}, 32'hd6014fec); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h31}, 32'hdffa2265); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h32}, 32'hfa9906a9); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h33}, 32'hafbd424a); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h34}, 32'h631994ae); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h35}, 32'h73a9b3f1); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h36}, 32'h2284f999); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h37}, 32'h6f8c87f6); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h38}, 32'h93136a66); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h39}, 32'h47c81e45); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h3a}, 32'hd35f0e41); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h3b}, 32'h238d6960); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h3c}, 32'h96cf337d); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h3d}, 32'h8865e4cc); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h3e}, 32'h15039c40); //TEMPLATE_MODULUS_VALUES
+      write_word({MODULUS_PREFIX, 8'h3f}, 32'h65ee7211); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000040); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000040); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h00}); read_data = tb_read_data; success = success & assertEquals(32'h24665860, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h01}); read_data = tb_read_data; success = success & assertEquals(32'h4b150493, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h02}); read_data = tb_read_data; success = success & assertEquals(32'hc0834602, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h03}); read_data = tb_read_data; success = success & assertEquals(32'hc0b99ab5, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h04}); read_data = tb_read_data; success = success & assertEquals(32'hbe649545, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h05}); read_data = tb_read_data; success = success & assertEquals(32'ha7d8b1ca, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h06}); read_data = tb_read_data; success = success & assertEquals(32'h55c1b98a, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h07}); read_data = tb_read_data; success = success & assertEquals(32'h1dce374b, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h08}); read_data = tb_read_data; success = success & assertEquals(32'h65750415, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h09}); read_data = tb_read_data; success = success & assertEquals(32'h573dfed7, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h0a}); read_data = tb_read_data; success = success & assertEquals(32'h95df9943, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h0b}); read_data = tb_read_data; success = success & assertEquals(32'h58a4aea0, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h0c}); read_data = tb_read_data; success = success & assertEquals(32'h5fb40a92, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h0d}); read_data = tb_read_data; success = success & assertEquals(32'h1408d9c2, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h0e}); read_data = tb_read_data; success = success & assertEquals(32'hb5e23fc9, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h0f}); read_data = tb_read_data; success = success & assertEquals(32'h225eb60b, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h10}); read_data = tb_read_data; success = success & assertEquals(32'h41d33a41, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h11}); read_data = tb_read_data; success = success & assertEquals(32'hbf958f7f, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h12}); read_data = tb_read_data; success = success & assertEquals(32'h619f5ac1, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h13}); read_data = tb_read_data; success = success & assertEquals(32'h207647f3, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h14}); read_data = tb_read_data; success = success & assertEquals(32'h223e56f8, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h15}); read_data = tb_read_data; success = success & assertEquals(32'h26afd4ae, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h16}); read_data = tb_read_data; success = success & assertEquals(32'h6a297840, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h17}); read_data = tb_read_data; success = success & assertEquals(32'h830947db, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h18}); read_data = tb_read_data; success = success & assertEquals(32'hbc5af940, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h19}); read_data = tb_read_data; success = success & assertEquals(32'h4c97ebb1, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h1a}); read_data = tb_read_data; success = success & assertEquals(32'hca38b220, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h1b}); read_data = tb_read_data; success = success & assertEquals(32'h04c9a26d, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h1c}); read_data = tb_read_data; success = success & assertEquals(32'h49a16b72, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h1d}); read_data = tb_read_data; success = success & assertEquals(32'h0882c658, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h1e}); read_data = tb_read_data; success = success & assertEquals(32'h2dbc50e0, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h1f}); read_data = tb_read_data; success = success & assertEquals(32'h67e2d057, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h20}); read_data = tb_read_data; success = success & assertEquals(32'h4b8ef356, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h21}); read_data = tb_read_data; success = success & assertEquals(32'h4ba5eac3, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h22}); read_data = tb_read_data; success = success & assertEquals(32'h17237d9f, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h23}); read_data = tb_read_data; success = success & assertEquals(32'h27c111a8, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h24}); read_data = tb_read_data; success = success & assertEquals(32'hc1b1944e, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h25}); read_data = tb_read_data; success = success & assertEquals(32'he91fd6b6, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h26}); read_data = tb_read_data; success = success & assertEquals(32'ha78d9747, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h27}); read_data = tb_read_data; success = success & assertEquals(32'h61e946d3, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h28}); read_data = tb_read_data; success = success & assertEquals(32'h0078fe23, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h29}); read_data = tb_read_data; success = success & assertEquals(32'h7770a088, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h2a}); read_data = tb_read_data; success = success & assertEquals(32'h6d5762af, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h2b}); read_data = tb_read_data; success = success & assertEquals(32'h435ac5f9, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h2c}); read_data = tb_read_data; success = success & assertEquals(32'h36cde9d5, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h2d}); read_data = tb_read_data; success = success & assertEquals(32'hc313804d, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h2e}); read_data = tb_read_data; success = success & assertEquals(32'ha4623760, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h2f}); read_data = tb_read_data; success = success & assertEquals(32'hb1c37572, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h30}); read_data = tb_read_data; success = success & assertEquals(32'h2b22486d, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h31}); read_data = tb_read_data; success = success & assertEquals(32'h8af131e3, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h32}); read_data = tb_read_data; success = success & assertEquals(32'h3e5fc3ea, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h33}); read_data = tb_read_data; success = success & assertEquals(32'h0d9c9ba0, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h34}); read_data = tb_read_data; success = success & assertEquals(32'h218bcc8f, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h35}); read_data = tb_read_data; success = success & assertEquals(32'h8bcdfea2, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h36}); read_data = tb_read_data; success = success & assertEquals(32'hcf55a599, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h37}); read_data = tb_read_data; success = success & assertEquals(32'h57b9fcbc, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h38}); read_data = tb_read_data; success = success & assertEquals(32'h5c087f62, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h39}); read_data = tb_read_data; success = success & assertEquals(32'hec130a15, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h3a}); read_data = tb_read_data; success = success & assertEquals(32'h7e8bd1f5, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h3b}); read_data = tb_read_data; success = success & assertEquals(32'h60eaaa51, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h3c}); read_data = tb_read_data; success = success & assertEquals(32'h020dd89b, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h3d}); read_data = tb_read_data; success = success & assertEquals(32'h890cc6ea, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h3e}); read_data = tb_read_data; success = success & assertEquals(32'h042d0054, read_data); //TEMPLATE_EXPECTED_VALUES 
+      read_word({RESULT_PREFIX, 8'h3f}); read_data = tb_read_data; success = success & assertEquals(32'h74055863, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: autogenerated_BASIC_M5663191947183200100 was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** autogenerated_BASIC_M5663191947183200100 success.");
+    end
+  endtask // autogenerated_BASIC_M5663191947183200100
+
+
 
   //----------------------------------------------------------------
   // main
@@ -993,6 +2246,20 @@ autogenerated_BASIC_6469444563916025786();
 autogenerated_BASIC_M2453278165832221565();
 autogenerated_BASIC_M1847183855567461116();
 autogenerated_BASIC_M7037130911981370263();
+autogenerated_BASIC_5073338267670769216();
+autogenerated_BASIC_M1841989679506188752();
+autogenerated_BASIC_M3339729654500648482();
+autogenerated_BASIC_M6837928193394880512();
+autogenerated_BASIC_M7333111649825079555();
+autogenerated_BASIC_480186175131589607();
+autogenerated_BASIC_M5239159917778665002();
+autogenerated_BASIC_228752064885223799();
+autogenerated_BASIC_856940511857911599();
+autogenerated_BASIC_M6501553661140603953();
+autogenerated_BASIC_M8496483018338900149();
+autogenerated_BASIC_6145567102166328515();
+autogenerated_BASIC_7216348574014690328();
+autogenerated_BASIC_M5663191947183200100();
 
       display_test_results();
 
diff --git a/src/tb/tb_modexp_autogenerated_template.v b/src/tb/tb_modexp_autogenerated_template.v
index 62ab7dc..eea4e7f 100644
--- a/src/tb/tb_modexp_autogenerated_template.v
+++ b/src/tb/tb_modexp_autogenerated_template.v
@@ -50,7 +50,7 @@ module tb_modexp_autogenerated();
   //----------------------------------------------------------------
   // Internal constant and parameter definitions.
   //----------------------------------------------------------------
-  parameter DEBUG = 1;
+  parameter DEBUG = 0;
 
   localparam CLK_HALF_PERIOD = 1;
   localparam CLK_PERIOD      = 2 * CLK_HALF_PERIOD;
@@ -445,8 +445,60 @@ module tb_modexp_autogenerated();
     end
   endtask // dump_memories
 
+  function assertEquals(
+      input [31:0] expected,
+      input [31:0] actual
+    );
+    begin
+      if (expected === actual)
+        begin
+          assertEquals = 1; // success
+        end
+      else
+        begin
+          $display("Expected: 0x%08x, got 0x%08x", expected, actual);
+          assertEquals = 0; // failure
+        end
+    end
+  endfunction // assertEquals
+
+  integer success;
+
 // ===TEMPLATE_HEADER_END===
 
+  task TEMPLATE_TASK_NAME();
+    reg [31 : 0] read_data;
+    begin
+      success = 32'h1;
+      tc_ctr = tc_ctr + 1;
+      $display("TEMPLATE_TASK_NAME");
+
+      write_word({MESSAGE_PREFIX, 8'h#TI#}, 32'h#TD#); //TEMPLATE_MESSAGE_VALES
+      write_word({EXPONENT_PREFIX, 8'h#TI#}, 32'h#TD#); //TEMPLATE_EXPONENT_VALES
+      write_word({MODULUS_PREFIX, 8'h#TI#}, 32'h#TD#); //TEMPLATE_MODULUS_VALUES
+
+      write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h#TL#); //TEMPLATE_MESSAGE_LENGTH
+      write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h#TL#); //TEMPLATE_MODULUS_LENGTH
+
+      // Start processing and wait for ready.
+      write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001);
+      wait_ready();
+
+      read_word({RESULT_PREFIX, 8'h#TI#}); read_data = tb_read_data; success = success & assertEquals(32'h#TD#, read_data); //TEMPLATE_EXPECTED_VALUES 
+     
+      if (success !== 1)
+        begin  
+          $display("*** ERROR: TEMPLATE_TASK_NAME was NOT successful.");
+          error_ctr = error_ctr + 1;
+        end
+      else
+        $display("*** TEMPLATE_TASK_NAME success.");
+    end
+  endtask // TEMPLATE_TASK_NAME
+
+
+// ===TEMPLATE_TEST_DEFINITION_END===
+
   //----------------------------------------------------------------
   // main
   //
diff --git a/src/tb/tb_montprod.v b/src/tb/tb_montprod.v
index 59ec72e..601e7f8 100644
--- a/src/tb/tb_montprod.v
+++ b/src/tb/tb_montprod.v
@@ -220,7 +220,7 @@ task reset_dut();
   begin
     $display("*** Toggle reset.");
     tb_reset_n = 0;
-    #(4 * CLK_HALF_PERIOD);
+    #(2 * CLK_PERIOD);
     tb_reset_n = 1;
   end
 endtask // reset_dut
@@ -260,7 +260,7 @@ task wait_ready();
       integer i;
       for (i=0; i<1000000; i=i+1)
         if (tb_ready == 0)
-          #(2 * CLK_HALF_PERIOD);
+          #(CLK_PERIOD);
     end
     if (tb_ready == 0)
        begin
@@ -276,7 +276,7 @@ task signal_calculate();
   begin
     $display("*** signal_calculate");
     tb_calculate = 1;
-    #(2 * CLK_HALF_PERIOD);
+    #(CLK_PERIOD);
     tb_calculate = 0;
   end
 endtask // signal_calculate
diff --git a/src/tb/tb_residue.v b/src/tb/tb_residue.v
index 4978bf9..4bb2922 100644
--- a/src/tb/tb_residue.v
+++ b/src/tb/tb_residue.v
@@ -203,7 +203,7 @@ task reset_dut();
   begin
     $display("*** Toggle reset.");
     tb_reset_n = 0;
-    #(4 * CLK_HALF_PERIOD);
+    #(2 * CLK_PERIOD);
     tb_reset_n = 1;
   end
 endtask // reset_dut
@@ -242,9 +242,9 @@ task wait_ready();
       integer i;
       for (i=0; i<100000000; i=i+1)
         if (tb_ready == 0)
-          #(2 * CLK_HALF_PERIOD);
+          #(CLK_PERIOD);
         else if (tb_ready === 1)
-          i = 100000000000000000000;
+          i = 1000000000;
     end
     if (tb_ready == 0)
        begin
@@ -263,7 +263,7 @@ task signal_calculate();
   begin
     $display("*** signal_calculate");
     tb_calculate = 1;
-    #(2 * CLK_HALF_PERIOD);
+    #(CLK_PERIOD);
     tb_calculate = 0;
   end
 endtask // signal_calculate
diff --git a/src/testgenerator/src/org/crypttech/modexp/testgenerator/TestGeneratorBasic.java b/src/testgenerator/src/org/crypttech/modexp/testgenerator/TestGeneratorBasic.java
index 71b56ac..e78fea3 100644
--- a/src/testgenerator/src/org/crypttech/modexp/testgenerator/TestGeneratorBasic.java
+++ b/src/testgenerator/src/org/crypttech/modexp/testgenerator/TestGeneratorBasic.java
@@ -14,12 +14,22 @@ public class TestGeneratorBasic {
 		generateTestVectors(rng, list, 30, 1);
 		//generateTestVectors(rng, list, 32, 1); //will generate failing tests in C model 
 		//generateTestVectors(rng, list, 31, 1); //will generate failing tests in C model 
+		generateTestVectors(rng, list, 126, 4);
+		generateTestVectors(rng, list, 510, 16, 2);
+		generateTestVectors(rng, list, 1022, 32, 1);
+		generateTestVectors(rng, list, 2046, 64, 1);
 		return list;
 	}
 
 	private static void generateTestVectors(Random rng,
 			ArrayList<TestVector> list, int bitLength, int wordLength) {
-		for(int i = 0; i < 10; i++) {
+		int max = 10;
+		generateTestVectors(rng, list, bitLength, wordLength, max);
+	}
+
+	private static void generateTestVectors(Random rng,
+			ArrayList<TestVector> list, int bitLength, int wordLength, int max) {
+		for(int i = 0; i < max; i++) {
 			final long seed = rng.nextLong();
 			rng.setSeed(seed);
 			BigInteger m = BigInteger.probablePrime(bitLength, rng);
@@ -28,6 +38,7 @@ public class TestGeneratorBasic {
 			BigInteger z = x.modPow(e, m);
 			TestVector tv = Util.generateTestVector("BASIC", Long.toString(seed), wordLength, m, x, e, z);
 			list.add(tv);
+			System.out.printf("%s Generated test: bits: %d seed: %x\n", TestGeneratorBasic.class.getName(), bitLength, seed);
 		}
 	}
 
diff --git a/src/testgenerator/src/org/crypttech/modexp/testgenerator/format/GeneratorVerilog.java b/src/testgenerator/src/org/crypttech/modexp/testgenerator/format/GeneratorVerilog.java
index 18efaa8..3a581da 100644
--- a/src/testgenerator/src/org/crypttech/modexp/testgenerator/format/GeneratorVerilog.java
+++ b/src/testgenerator/src/org/crypttech/modexp/testgenerator/format/GeneratorVerilog.java
@@ -14,7 +14,8 @@ import org.crypttech.modexp.testgenerator.TestVector;
 public class GeneratorVerilog extends ModExpTestFormater {
 	private BufferedReader br;
 	private List<String> taskCalls = new ArrayList<String>();
-	private boolean headerEmitted = false;
+	private boolean initilized = false;
+	private List<String> taskTemplate = new ArrayList<String>();
 
 	public GeneratorVerilog(String templateFile, String destinationFile)
 			throws FileNotFoundException {
@@ -26,56 +27,59 @@ public class GeneratorVerilog extends ModExpTestFormater {
 
 	@Override
 	public void format(TestVector testVector) {
-		emitHeader();
+		init();
 
 		String testname = ("autogenerated_" + testVector.generator + "_" + testVector.seed)
 				.replace("-", "M");
 		taskCalls.add(testname + "();");
 
-		out("task " + testname + "();");
-		out("reg [31 : 0] read_data;");
-		out("begin");
-		out("tc_ctr = tc_ctr + 1;");
-		out("$display(\"" + testname + "\");");
-
-		for (int i = 0; i < testVector.X.length; i++)
-			out("write_word({MESSAGE_PREFIX, 8'h%02x}, 32'h%08x);", i,
-					testVector.X[i]);
-
-		for (int i = 0; i < testVector.E.length; i++)
-			out("write_word({EXPONENT_PREFIX, 8'h%02x}, 32'h%08x);", i,
-					testVector.E[i]);
-
-		out("write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h%08x););",
-				testVector.E.length);
-
-		for (int i = 0; i < testVector.M.length; i++)
-			out("write_word({MODULUS_PREFIX, 8'h%02x}, 32'h%08x);", i,
-					testVector.M[i]);
-
-		out("write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h%08x););",
-				testVector.E.length);
-
-		out("dump_memories()");
+		for (String line : taskTemplate) {
+			line = line.replace("TEMPLATE_TASK_NAME", testname);
+			if (line.contains("TEMPLATE_EXPECTED_VALUES"))
+				emitArray(line, testVector.expected);
+			else if (line.contains("TEMPLATE_MESSAGE_VALES"))
+				emitArray(line, testVector.X);
+			else if (line.contains("TEMPLATE_EXPONENT_VALES"))
+				emitArray(line, testVector.E);
+			else if (line.contains("TEMPLATE_MODULUS_VALUES"))
+				emitArray(line, testVector.M);
+			else if (line.contains("TEMPLATE_EXPECTED_LENGTH"))
+				emitLength(line, testVector.expected);
+			else if (line.contains("TEMPLATE_MESSAGE_LENGTH"))
+				emitLength(line, testVector.X);
+			else if (line.contains("TEMPLATE_EXPONENT_LENGTH"))
+				emitLength(line, testVector.E);
+			else if (line.contains("TEMPLATE_MODULUS_LENGTH"))
+				emitLength(line, testVector.M);
+			else
+				out(line);
+		}
+	}
 
-		out("write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h%08x);",
-				testVector.length);
-		out("wait_ready();");
+	private void emitLength(String pattern, int[] array) {
+		String lengthHexString = hex32(array.length);
+		String line = pattern.replace("#TL#", lengthHexString);
+		out(line);
+	}
 
-		for (int i = 0; i < testVector.expected.length; i++) {
-			out("read_word({RESULT_PREFIX,8'h%02x});", i);
-			out("read_data = tb_read_data;");
-			out("if (read_data !== 32'h%08x))", testVector.expected[i]);
-			out("  begin");
-			out("    $display(\"Expected: 0x%08x, got 0x%%08x\", read_data);",
-					testVector.expected[i]);
-			out("  end");
+	private void emitArray(String pattern, int[] array) {
+		for (int i = 0; i < array.length; i++) {
+			String indexHexString = hex8(i);
+			String arrayHexString = hex32(array[i]);
+			String line = pattern.replace("#TI#", indexHexString).replace(
+					"#TD#", arrayHexString);
+			out(line);
 		}
-		out("end");
-		out("endtask // " + testname);
+	}
 
+	private String hex8(int data) {
+		return String.format("%02x", data);
 	}
 
+	private String hex32(int data) {
+		return String.format("%08x", data);
+	}
+	
 	@Override
 	public void close() throws Exception {
 		emitMiddle();
@@ -87,10 +91,15 @@ public class GeneratorVerilog extends ModExpTestFormater {
 		super.close();
 	}
 
-	private void emitHeader() {
-		if (headerEmitted == true)
+	private void init() {
+		if (initilized == true)
 			return;
-		headerEmitted = true;
+		initilized = true;
+		emitHeader();
+		taskTemplate.addAll(consumeTemplate("TEMPLATE_TEST_DEFINITION_END"));
+	}
+
+	private void emitHeader() {
 		String terminatingLine = "===TEMPLATE_HEADER_END===";
 		emitTemplateSection(terminatingLine);
 	}
@@ -106,17 +115,23 @@ public class GeneratorVerilog extends ModExpTestFormater {
 	}
 
 	private void emitTemplateSection(String terminatingLine) {
+		List<String> lines = consumeTemplate(terminatingLine);
+		for (String line : lines)
+			out(line);
+	}
+
+	private List<String> consumeTemplate(String terminatingLine) {
+		List<String> lines = new ArrayList<String>();
 		String line;
 		try {
 			while ((line = br.readLine()) != null) {
 				if (line.contains(terminatingLine))
-					return;
-				out(line);
+					break;
+				lines.add(line);
 			}
 		} catch (IOException e) {
 			throw new RuntimeException(e);
-		} finally {
 		}
+		return lines;
 	}
-
 }
diff --git a/src/testgenerator/src/org/crypttech/modexp/testgenerator/format/ModExpTestFormater.java b/src/testgenerator/src/org/crypttech/modexp/testgenerator/format/ModExpTestFormater.java
index 7f9bbb3..f0104f4 100644
--- a/src/testgenerator/src/org/crypttech/modexp/testgenerator/format/ModExpTestFormater.java
+++ b/src/testgenerator/src/org/crypttech/modexp/testgenerator/format/ModExpTestFormater.java
@@ -33,5 +33,6 @@ public abstract class ModExpTestFormater implements AutoCloseable {
 	@Override
 	public void close() throws Exception {
 		pw.close();
+		System.out.printf("%s closing...\n", this.getClass().getName());
 	}
 }
diff --git a/toolruns/Makefile b/toolruns/Makefile
index 64aed4f..1f7c155 100755
--- a/toolruns/Makefile
+++ b/toolruns/Makefile
@@ -55,20 +55,22 @@ MONTPROD_SRC = ../src/rtl/montprod.v
 
 MODEXP_SRC=../src/rtl/modexp.v $(MONTPROD_SRC) $(RESIDUE_SRC) $(COMMON_SRC)
 MODEXP_TB=../src/tb/tb_modexp.v
+MODEXP_AUTOGENERATED_TB = ../src/tb/tb_modexp_autogenerated.v
 
 
 # Rules.
-all: modexp.sim montprod.sim residue.sim
+all: modexp.sim modexp.autogenerated.sim montprod.sim residue.sim
 
 
 modexp.sim: $(MODEXP_TB) $(MODEXP_SRC)
 	$(CC) $(CCFLAGS) -o modexp.sim $(MODEXP_TB) $(MODEXP_SRC)
 
+modexp.autogenerated.sim: $(MODEXP_AUTOGENERATED_TB) $(MODEXP_SRC)
+	$(CC) $(CCFLAGS) -o modexp.autogenerated.sim $(MODEXP_AUTOGENERATED_TB) $(MODEXP_SRC)
 
 montprod.sim: $(MONTPROD_TB) $(MONTPROD_SRC) $(COMMON_SRC)
 	$(CC) $(CCFLAGS) -o montprod.sim $(MONTPROD_TB) $(MONTPROD_SRC) $(COMMON_SRC)
 
-
 residue.sim: $(RESIDUE_TB) $(RESIDUE_SRC) $(COMMON_SRC)
 	$(CC) $(CCFLAGS) -o residue.sim $(RESIDUE_TB) $(RESIDUE_SRC) $(COMMON_SRC)
 
@@ -76,6 +78,9 @@ residue.sim: $(RESIDUE_TB) $(RESIDUE_SRC) $(COMMON_SRC)
 sim-modexp: modexp.sim
 	./modexp.sim
 
+# run autogenerate-tests manually to renew ../src/tb/tb_montprod_autogenerated.v
+sim-modexp-autogenerated: modexp.autogenerated.sim
+	./modexp.autogenerated.sim
 
 sim-montprod: montprod.sim
 	./montprod.sim
@@ -105,6 +110,7 @@ autogenerate-tests:
 
 clean:
 	rm -f modexp.sim
+	rm -f modexp.autogenerated.sim
 	rm -f montprod.sim
 	rm -f residue.sim
 
@@ -123,6 +129,11 @@ help:
 	@echo "sim-montprod: Run montprod simulation."
 	@echo "sim-residue:  Run residue simulation."
 	@echo "clean:        Delete all built files."
+	@echo ""
+	@echo "Supported autogeneration targets:"
+	@echo "autogenerate-tests       - rebuild autogenerated tests source code"
+	@echo "modexp.autogenerated.sim - run autogenerated test bench"
+	@echo "sim-modexp-autogenerated - simulate autogenerated tests"
 
 #===================================================================
 # EOF Makefile



More information about the Commits mailing list