testbench.cpp (2625B)
1 /* Copyright 2014 Brian Swetland <swetland@frotz.net> 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 /* reusable verilator testbench driver 17 * - expects the top module to be testbench(clk); 18 * - provides clk to module 19 * - handles vcd tracing if compiled with TRACE 20 * - allows tracefilename to be specified via -o 21 */ 22 23 #include <sys/types.h> 24 #include <unistd.h> 25 #include <fcntl.h> 26 27 #include "Vtestbench.h" 28 #include "verilated.h" 29 #include <verilated_vcd_c.h> 30 31 static unsigned memory[4096]; 32 33 void dpi_mem_write(int addr, int data) { 34 memory[addr & 0xFFF] = data; 35 } 36 37 void dpi_mem_read(int addr, int *data) { 38 *data = (int) memory[addr & 0xFFF]; 39 } 40 41 #ifdef TRACE 42 static vluint64_t now = 0; 43 44 double sc_time_stamp() { 45 return now; 46 } 47 #endif 48 49 int main(int argc, char **argv) { 50 const char *vcdname = "trace.vcd"; 51 const char *memname = NULL; 52 int fd; 53 54 while (argc > 1) { 55 if (!strcmp(argv[1], "-o")) { 56 #ifdef TRACE 57 if (argc < 3) { 58 fprintf(stderr,"error: -o requires argument\n"); 59 return -1; 60 } 61 vcdname = argv[2]; 62 argv += 2; 63 argc -= 2; 64 continue; 65 #else 66 fprintf(stderr,"error: no trace support\n"); 67 return -1; 68 #endif 69 } else if (!strcmp(argv[1], "-om")) { 70 if (argc < 3) { 71 fprintf(stderr, "error: -om requires argument\n"); 72 return -1; 73 } 74 memname = argv[2]; 75 argv += 2; 76 argc -= 3; 77 } else { 78 break; 79 } 80 } 81 82 Verilated::commandArgs(argc, argv); 83 Verilated::debug(0); 84 Verilated::randReset(2); 85 86 Vtestbench *testbench = new Vtestbench; 87 testbench->clk = 0; 88 89 #ifdef TRACE 90 Verilated::traceEverOn(true); 91 VerilatedVcdC* tfp = new VerilatedVcdC; 92 testbench->trace(tfp, 99); 93 tfp->open(vcdname); 94 #endif 95 96 while (!Verilated::gotFinish()) { 97 testbench->clk = !testbench->clk; 98 testbench->eval(); 99 #ifdef TRACE 100 tfp->dump(now); 101 now += 5; 102 #endif 103 } 104 #ifdef TRACE 105 tfp->close(); 106 #endif 107 testbench->final(); 108 delete testbench; 109 110 if (memname != NULL) { 111 fd = open(memname, O_WRONLY | O_CREAT | O_TRUNC, 0640); 112 if (fd < 0) { 113 fprintf(stderr, "cannot open '%s' for writing\n", memname); 114 return -1; 115 } 116 write(fd, memory, sizeof(memory)); 117 close(fd); 118 } 119 return 0; 120 } 121