From 502f0f429a261628fe5e43582280012541c40804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20Stro=CC=88mbergson?= Date: Fri, 24 Apr 2015 15:16:23 +0200 Subject: (1) Adding auto generated testbench for verilog. (2) Update of the test generator. (3) Update of the Makefile to run test generator. --- .../modexp/testgenerator/TestGenerator.java | 31 +++++- .../modexp/testgenerator/format/GeneratorC.java | 53 ++++----- .../testgenerator/format/GeneratorVerilog.java | 122 +++++++++++++++++++++ .../testgenerator/format/ModExpTestFormater.java | 25 +++-- 4 files changed, 190 insertions(+), 41 deletions(-) create mode 100644 src/testgenerator/src/org/crypttech/modexp/testgenerator/format/GeneratorVerilog.java (limited to 'src/testgenerator') diff --git a/src/testgenerator/src/org/crypttech/modexp/testgenerator/TestGenerator.java b/src/testgenerator/src/org/crypttech/modexp/testgenerator/TestGenerator.java index af5850b..6ca48c1 100644 --- a/src/testgenerator/src/org/crypttech/modexp/testgenerator/TestGenerator.java +++ b/src/testgenerator/src/org/crypttech/modexp/testgenerator/TestGenerator.java @@ -1,19 +1,40 @@ package org.crypttech.modexp.testgenerator; -import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import org.crypttech.modexp.testgenerator.format.GeneratorC; +import org.crypttech.modexp.testgenerator.format.GeneratorVerilog; +import org.crypttech.modexp.testgenerator.format.ModExpTestFormater; public class TestGenerator { public static void main(String[] argv) throws Exception { + String basePath; + if (argv.length == 1) + basePath = argv[0]; + else + basePath = ".."; + + System.out.println("Generating modexp test values."); + List vectors = new ArrayList(); vectors.addAll(TestGeneratorBasic.getTestVectors()); - PrintWriter pw = new PrintWriter("../model/c/src/autogenerated_tests.c"); - try (GeneratorC genC = new GeneratorC(pw)) { - for (TestVector vector : vectors) - genC.format(vector); + try (GeneratorC genC = new GeneratorC( + basePath + "/model/c/src/autogenerated_tests.c")) { + try (GeneratorVerilog genVerilog = new GeneratorVerilog( + basePath + "/tb/tb_modexp_autogenerated_template.v", + basePath + "/tb/tb_modexp_autogenerated.v")) { + + emitTests(vectors, genC, genVerilog); + } } + + } + + private static void emitTests(List vectors, + ModExpTestFormater... generators) { + for (ModExpTestFormater generator : generators) + for (TestVector vector : vectors) + generator.format(vector); } } diff --git a/src/testgenerator/src/org/crypttech/modexp/testgenerator/format/GeneratorC.java b/src/testgenerator/src/org/crypttech/modexp/testgenerator/format/GeneratorC.java index fbfd852..449557e 100644 --- a/src/testgenerator/src/org/crypttech/modexp/testgenerator/format/GeneratorC.java +++ b/src/testgenerator/src/org/crypttech/modexp/testgenerator/format/GeneratorC.java @@ -1,18 +1,17 @@ package org.crypttech.modexp.testgenerator.format; +import java.io.FileNotFoundException; import java.io.PrintWriter; import org.crypttech.modexp.testgenerator.TestVector; public class GeneratorC extends ModExpTestFormater { - private static final char LF = (char) 10; - - public GeneratorC(PrintWriter pw) { - super(pw); - out("#include " + LF); - out("#include " + LF); - out("#include \"montgomery_array.h\"" + LF); - out("#include \"bignum_uint32_t.h\"" + LF); + public GeneratorC(String file) throws FileNotFoundException { + super(new PrintWriter(file), true); + out("#include "); + out("#include "); + out("#include \"montgomery_array.h\""); + out("#include \"bignum_uint32_t.h\""); } StringBuilder footer = new StringBuilder(); @@ -21,40 +20,36 @@ public class GeneratorC extends ModExpTestFormater { public void format(TestVector testVector) { String testname = ("autogenerated_" + testVector.generator + "_" + testVector.seed) .replace("-", "M"); - footer.append(" ").append(testname).append("();").append(LF); - - StringBuilder sb = new StringBuilder(); - sb.append("void ").append(testname).append("(void) {").append(LF); - sb.append(" printf(\"=== ").append(testname).append(" ===\\n\");") - .append(LF); - appendCArray(sb, "X", testVector.X); - appendCArray(sb, "E", testVector.E); - appendCArray(sb, "M", testVector.M); - appendCArray(sb, "expected", testVector.expected); + footer.append(" ").append(testname).append("();").append((char) 10); + + out("void %s(void) {", testname); + out(" printf(\"=== %s ===\\n\");", testname); + appendCArray("X", testVector.X); + appendCArray("E", testVector.E); + appendCArray("M", testVector.M); + appendCArray("expected", testVector.expected); int[] Z = new int[testVector.length]; - appendCArray(sb, "Z", Z); - sb.append(" mod_exp_array(").append(testVector.length) - .append(", X, E, M, Z);").append(LF); - sb.append(" assertArrayEquals(").append(testVector.length) - .append(", expected, Z);").append(LF); - sb.append("}").append(LF); - out(sb.toString()); + appendCArray("Z", Z); + out(" mod_exp_array(%s, X, E, M, Z);", testVector.length); + out(" assertArrayEquals(%d, expected, Z);", testVector.length); + out("}"); } - private void appendCArray(StringBuilder sb, String arrayName, int[] array) { + private void appendCArray(String arrayName, int[] array) { + StringBuilder sb = new StringBuilder(); sb.append(" uint32_t ").append(arrayName).append("[] = "); sb.append("{ "); for (int m : array) sb.append(String.format("0x%08x, ", m)); sb.replace(sb.length() - 2, sb.length(), " };"); - sb.append(LF); + out(sb.toString()); } @Override public void close() throws Exception { - out("void autogenerated_tests(void) {" + LF); + out("void autogenerated_tests(void) {"); out(footer.toString()); - out("}" + LF); + out("}"); super.close(); } diff --git a/src/testgenerator/src/org/crypttech/modexp/testgenerator/format/GeneratorVerilog.java b/src/testgenerator/src/org/crypttech/modexp/testgenerator/format/GeneratorVerilog.java new file mode 100644 index 0000000..18efaa8 --- /dev/null +++ b/src/testgenerator/src/org/crypttech/modexp/testgenerator/format/GeneratorVerilog.java @@ -0,0 +1,122 @@ +package org.crypttech.modexp.testgenerator.format; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.List; + +import org.crypttech.modexp.testgenerator.TestVector; + +public class GeneratorVerilog extends ModExpTestFormater { + private BufferedReader br; + private List taskCalls = new ArrayList(); + private boolean headerEmitted = false; + + public GeneratorVerilog(String templateFile, String destinationFile) + throws FileNotFoundException { + super(new PrintWriter(destinationFile), true); + this.br = new BufferedReader(new InputStreamReader(new FileInputStream( + templateFile))); + + } + + @Override + public void format(TestVector testVector) { + emitHeader(); + + 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()"); + + out("write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h%08x);", + testVector.length); + out("wait_ready();"); + + 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"); + } + out("end"); + out("endtask // " + testname); + + } + + @Override + public void close() throws Exception { + emitMiddle(); + for (String taskCall : taskCalls) + out(taskCall); + emitFinal(); + if (br != null) + br.close(); + super.close(); + } + + private void emitHeader() { + if (headerEmitted == true) + return; + headerEmitted = true; + String terminatingLine = "===TEMPLATE_HEADER_END==="; + emitTemplateSection(terminatingLine); + } + + private void emitMiddle() { + String terminatingLine = "===TEMPLATE_CALL_TASKS==="; + emitTemplateSection(terminatingLine); + } + + private void emitFinal() { + String terminatingLine = "Never gonna give you up, never gonna let you down"; + emitTemplateSection(terminatingLine); + } + + private void emitTemplateSection(String terminatingLine) { + String line; + try { + while ((line = br.readLine()) != null) { + if (line.contains(terminatingLine)) + return; + out(line); + } + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + } + } + +} 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 c15ca88..7f9bbb3 100644 --- a/src/testgenerator/src/org/crypttech/modexp/testgenerator/format/ModExpTestFormater.java +++ b/src/testgenerator/src/org/crypttech/modexp/testgenerator/format/ModExpTestFormater.java @@ -5,22 +5,33 @@ import java.io.PrintWriter; import org.crypttech.modexp.testgenerator.TestVector; public abstract class ModExpTestFormater implements AutoCloseable { - private PrintWriter pw; - - public ModExpTestFormater(PrintWriter pw) { + private static final char LF = (char) 10; + private final boolean alwaysLF; + private final PrintWriter pw; + + public ModExpTestFormater(PrintWriter pw, boolean alwaysLF) { this.pw = pw; + this.alwaysLF = alwaysLF; + } + + public ModExpTestFormater(PrintWriter pw) { + this(pw, false); } - + public abstract void format(TestVector testVector); protected final void out(String s) { pw.print(s); + if (alwaysLF) + pw.print(LF); + } + + protected final void out(String frmt, Object... args) { + out(String.format(frmt, args)); } - + @Override public void close() throws Exception { pw.close(); } - - } -- cgit v1.2.3