EECS151 / fpga_labs_fa20 / lab6 / sim / system_testbench.v
system_testbench.v
Raw
`timescale 1ns/100ps

`define SECOND 1000000000
`define MS 1000000
`define CLK_PERIOD 8
`define B_SAMPLE_COUNT_MAX 5
`define B_PULSE_COUNT_MAX 5

`define CLOCK_FREQ 125_000_000
`define BAUD_RATE 115_200

module system_testbench();
    reg clk = 0;
    wire audio_pwm;
    wire [5:0] leds;
    reg [2:0] buttons;
    reg [1:0] switches;
    reg reset;

    initial begin
        switches[1] = 1'b1;
    end

    wire FPGA_SERIAL_RX, FPGA_SERIAL_TX;

    // Generate system clock
    always #(`CLK_PERIOD/2) clk <= ~clk;

    z1top #(
        .B_SAMPLE_COUNT_MAX(`B_SAMPLE_COUNT_MAX),
        .B_PULSE_COUNT_MAX(`B_PULSE_COUNT_MAX),
        .CLOCK_FREQ(`CLOCK_FREQ),
        .BAUD_RATE(`BAUD_RATE)
    ) top (
        .CLK_125MHZ_FPGA(clk),
        .BUTTONS({buttons, reset}),
        .SWITCHES(switches),
        .LEDS(leds),
        .aud_pwm(audio_pwm),
        .FPGA_SERIAL_RX(FPGA_SERIAL_RX),
        .FPGA_SERIAL_TX(FPGA_SERIAL_TX)
    );


    // Instantiate an off-chip UART here that uses the RX and TX lines
    // You can refer to the echo_testbench from lab 4
    // The off-chip UART (on your desktop/workstation computer)
    
    reg  data_in_valid, data_out_ready;
    wire data_in_ready, data_out_valid;
    reg  [7:0] data_in;
    wire [7:0] data_out;
    uart # (
        .CLOCK_FREQ(`CLOCK_FREQ),
        .BAUD_RATE(`BAUD_RATE)
    ) off_chip_uart (
        .clk(clk),
        .reset(reset),
        .data_in(data_in),
        .data_in_valid(data_in_valid),
        .data_in_ready(data_in_ready),
        .data_out(data_out),
        .data_out_valid(data_out_valid),
        .data_out_ready(data_out_ready),
        .serial_in(FPGA_SERIAL_TX), // Note these serial connections are the opposite of the connections to z1top
        .serial_out(FPGA_SERIAL_RX)
    );


    initial begin
        `ifndef IVERILOG
            $vcdpluson;
        `endif
        `ifdef IVERILOG
            $dumpfile("system_testbench.vcd");
            $dumpvars(0,system_testbench);
        `endif
        // Simulate pushing the reset button and holding it for a while
        reset = 1'b0;
        repeat (50) @(posedge clk); #1;
        reset = 1'b1;
        repeat (50) @(posedge clk); #1;
        reset = 1'b0;

        data_in = 8'h77;
        data_in_valid = 1'b0;
        data_out_ready = 1'b1;
        repeat (2) @(posedge clk); #1;

        fork 
            begin
                while (!data_in_ready) @(posedge clk); #1;

                $display("About to send %d/%h", data_in, data_in);
                @(negedge clk); #1;
                data_in_valid = 1'b1;
                @(negedge clk); #1;
                data_in_valid = 1'b0;
               
                while (!top.on_chip_uart.data_out_valid) @(posedge clk); #1;
                $display("On chip UART forwarding %d/%h", top.on_chip_uart.data_out, top.on_chip_uart.data_out);

                @(negedge clk); #1;
                data_in = 8'h78;
                data_in_valid = 1'b1;
                @(negedge clk); #1;
                data_in_valid = 1'b0;

                while (!top.on_chip_uart.data_out_valid) @(posedge clk) #1;
                $display("On chip UART forwarding %d/%h", top.on_chip_uart.data_out, top.on_chip_uart.data_out);



            end
            begin
                repeat (15000000) @(posedge clk); #1; 
                $finish();
            end
        join        

        `ifndef IVERILOG
            $vcdplusoff;
        `endif
        $finish();
    end
endmodule