From 07193819972aed16e8474913dbbbee5e01570e58 Mon Sep 17 00:00:00 2001 From: Olof Kindgren Date: Sat, 1 Jan 2022 17:15:00 +0100 Subject: [PATCH] Add ViDBo support --- bench/servant_tb_vidbo.cpp | 163 +++++++++++++++++++++++++++++++++++++ servant.core | 4 +- 2 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 bench/servant_tb_vidbo.cpp diff --git a/bench/servant_tb_vidbo.cpp b/bench/servant_tb_vidbo.cpp new file mode 100644 index 0000000..d0a8322 --- /dev/null +++ b/bench/servant_tb_vidbo.cpp @@ -0,0 +1,163 @@ +#include +#include + +#include "verilated_vcd_c.h" +#include "Vservant_sim.h" + +#include "vidbo.h" + +using namespace std; + +static bool done; + +vluint64_t main_time = 0; // Current simulation time +// This is a 64-bit integer to reduce wrap over issues and +// allow modulus. You can also use a double, if you wish. + +double sc_time_stamp () { // Called by $time in Verilog + return main_time; // converts to double, to match + // what SystemC does +} + +void INThandler(int signal) +{ + printf("\nCaught ctrl-c\n"); + done = true; +} + +typedef struct { + bool last_value; +} gpio_context_t; + +void do_gpio(gpio_context_t *context, bool gpio) { + if (context->last_value != gpio) { + context->last_value = gpio; + printf("%lu output q is %s\n", main_time, gpio ? "ON" : "OFF"); + } +} + +typedef struct { + uint8_t state; + char ch; + uint32_t baud_t; + vluint64_t last_update; +} uart_context_t; + +void uart_init(uart_context_t *context, uint32_t baud_rate) { + context->baud_t = 1000*1000*1000/baud_rate; + context->state = 0; +} + +bool do_uart(uart_context_t *context, bool rx) { + if (context->state == 0) { + if (rx) + context->state++; + } + else if (context->state == 1) { + if (!rx) { + context->last_update = main_time + context->baud_t/2; + context->state++; + } + } + else if(context->state == 2) { + if (main_time > context->last_update) { + context->last_update += context->baud_t; + context->ch = 0; + context->state++; + } + } + else if (context->state < 11) { + if (main_time > context->last_update) { + context->last_update += context->baud_t; + context->ch |= rx << (context->state-3); + context->state++; + } + } + else { + if (main_time > context->last_update) { + context->last_update += context->baud_t; + context->state=1; + return true; + } + } + return false; +} + +int main(int argc, char **argv, char **env) +{ + int baud_rate = 0; + + gpio_context_t gpio_context; + uart_context_t uart_context; + + vidbo_context_t vidbo_context; + vidbo_init(&vidbo_context, 8081); + int poll_vidbo = 0; + + Verilated::commandArgs(argc, argv); + + Vservant_sim* top = new Vservant_sim; + + const char *arg = Verilated::commandArgsPlusMatch("uart_baudrate="); + if (arg[0]) { + baud_rate = atoi(arg+15); + if (baud_rate) { + uart_init(&uart_context, baud_rate); + } + } + + VerilatedVcdC * tfp = 0; + const char *vcd = Verilated::commandArgsPlusMatch("vcd="); + if (vcd[0]) { + Verilated::traceEverOn(true); + tfp = new VerilatedVcdC; + top->trace (tfp, 99); + tfp->open ("trace.vcd"); + } + + signal(SIGINT, INThandler); + + vluint64_t timeout = 0; + const char *arg_timeout = Verilated::commandArgsPlusMatch("timeout="); + if (arg_timeout[0]) + timeout = atoi(arg_timeout+9); + + vluint64_t vcd_start = 0; + const char *arg_vcd_start = Verilated::commandArgsPlusMatch("vcd_start="); + if (arg_vcd_start[0]) + vcd_start = atoi(arg_vcd_start+11); + + bool dump = false; + top->wb_clk = 1; + bool q = top->q; + while (!(done || Verilated::gotFinish())) { + if (tfp && !dump && (main_time > vcd_start)) { + dump = true; + } + top->wb_rst = main_time < 100; + top->eval(); + if (dump) + tfp->dump(main_time); + if (baud_rate) { + if (do_uart(&uart_context, top->q)) + vidbo_send(&vidbo_context, main_time, "serial", "uart", uart_context.ch); + } + if (top->q != gpio_context.last_value) { + vidbo_send(&vidbo_context, main_time, "gpio", "LD0", (top->q) & 0x1); + gpio_context.last_value = top->q; + } + if (timeout && (main_time >= timeout)) { + printf("Timeout: Exiting at time %lu\n", main_time); + done = true; + } + + if (!(poll_vidbo++ % 100000)) vidbo_recv(&vidbo_context, 0); + + top->wb_clk = !top->wb_clk; + main_time+=31.25; + + } + if (tfp) + tfp->close(); + exit(0); +} diff --git a/servant.core b/servant.core index 1884773..2df904e 100644 --- a/servant.core +++ b/servant.core @@ -25,8 +25,10 @@ filesets: verilator_tb: files: - bench/servant_sim.v - - bench/servant_tb.cpp : {file_type : cppSource} + - "vidbo? (bench/servant_tb_vidbo.cpp)" : {file_type : cppSource} + - "!vidbo? (bench/servant_tb.cpp)" : {file_type : cppSource} file_type : verilogSource + depend : ["vidbo? (vidbo)"] soc: files: