n Audio top.v
`timescale 1ns / 1ps

module top(
    input clock,            // system clock
    input reset,            // BTNR
    input version,          // BTNU
    input adc_n, adc_p,     // VCAUX 6, P and N
    input [15:0] sw,        // slide switches
    output [15:0] led,      // 16  onboard LEDs above the switches
    output [6:0] segment,   // 4 digit LED display
    output dp,              // "." next to each LED digit
    output [3:0] digit,     // which of 4 7-segment digits
    output reg [7:0] JB,    // debugging
    output reg [7:0] JA,        // debugging
    input rx,               // UART receive
    output tx               // UART transmit
    );
    parameter VERSION = 'h3001;
    //
    //  a 25MHz clock for the uart rx and tx, and the state machines that control them
    //
    wire locked, clock25;
    clock25 MYCLOCK25 (
        .reset(reset),
        .clk_in1(clock),
        .locked(locked),
        .clk_out1(clock25)
    );
    //
    //  we want the XADC to deliver an audio signal at 44.1kHz.   The minimum output
    //  clock is 8MHz, so we need the lowest multiple of 44.1kHz in powers of 2 that
    //  generates a clock with f>8MHz, which is 256x0.0441=11.2896MHz
    //
    //  for the FIFO clock, we want 44.1kHz so if we generate a 11.2896 MHz clock
    //  and divide it down by 256 using an 8 bit counter using the MSB, we will get
    //  the 44.1kHz FIFO write clock
    //
    wire locked2, clock256;         // will be 256 times the FIFO clock
    adc_fifo_clock ADC_CLOCK (
        .reset(reset),
        .clk_in1(clock),
        .locked(locked2),
        .clk_out1(clock256)
    );
    wire fifo_clock;            // will be 44.1kHz
    reg [7:0] count1;
    always @ (posedge clock256) 
        if (reset) count1 <= 0;
        else count1 <= count1 + 1;
    BUFG fifoclock (.I(count1[7]), .O(fifo_clock));
    //
    //  for the XADC DCLK clock, we want a clock that is an even multiple of 2 times
    //  the 44.1kHz samping rate times 26, since there are 26 clocks per sample.
    //  so 44.1kHz x 26 = 1146.6kHz.  The XADC minimum is 8000kHz, so if we use
    //  8 x 1146.6 = 9.1728Mhz, we will get a 44.1kHz sampling.
    //
    //  turns out that we first have to generate a 101MHz clock, then use that to
    //  generate the 9.1728MHz clock
    //
    wire locked101, clock101;
    clock101 CLOCK101 (
        .reset(reset),
        .clk_in1(clock),
        .locked(locked101),
        .clk_out1(clock101)
    );
    wire locked3, xadc_clock;
    clock_xadc XADC_CLOCK (
        .reset(reset),
        .clk_in1(clock101),
        .locked(locked3),
        .clk_out1(xadc_clock)
    );
    //
    //  next drive the 4 7-segment displays
    //
    wire [15:0] display_this;
    display4 DISPLAY (
        .clk100(clock),
        .number(display_this),
        .digit(digit),
        .segments(segment),
        .period(dp)
        );
    //
    //  here is the XADC block
    //
    wire [6:0] daddr_in = 7'h16;
    wire adc_ready, isbusy, adc_data_ready, eos_out, alarm;
    wire [15:0] adc_data;
    wire [4:0] channel_out;
    myxadc XADC_INST (
        .daddr_in(7'h16),   // specifies vcaux6 pints to digitize
        .dclk_in(xadc_clock),    // 9.1728MHz clock
        .den_in(adc_ready), // tied to adc_ready, tells adc to convert, tieing causes continuous conversions
        .di_in(16'h0),      // to set the data to something, not used here
        .dwe_in(1'b0),      //  set to enable writing to di_in, which we don't want to do
        .vauxp6(adc_p),     //  positive input to digitize
        .vauxn6(adc_n),     //  negative input to digitize
        .busy_out(isbusy),  // tells you the adc is busy converting
        .channel_out(channel_out[4:0]), // for using more than 1 channel, tells you which one.  not used here
        .do_out(adc_data),      // adc value from conversion
        .drdy_out(adc_data_ready),  //tells you valid data is ready to be latched
        .eoc_out(adc_ready),   //  specifies that the ADC is ready (conversion complete)
        .eos_out(eos_out),     //  specifies that conversion sequence is complete
        .alarm_out(alarm),      // OR's output of all internal alarms, not used here
        .vp_in(1'b0),           // dedicated analog input pair for differential, tied to 0 if not used
        .vn_in(1'b0)
    );
    //
    // wait for XADC to tell you something is ready to latch. note this means continuous latching
    //
    reg [15:0] r_adc_data;
    always @ (negedge isbusy) 
        if (reset) r_adc_data <= 16'h0;
        else r_adc_data <= adc_data;
    //
    //  make a ~1Hz clock so we can run the LED display slower
    //
    reg [27:0] counter;
    reg [15:0] s_adc_data;
    always @ (posedge clock) begin
        if (reset) counter <= 0;
        else counter <= counter + 1;
        end
    wire clock_1hz = counter[27];
    always @ (posedge clock_1hz) s_adc_data <= r_adc_data;
    assign display_this = version ? VERSION : s_adc_data;
    //
    //  now instantiate the ADC FIFO.  the write clock will be the fifo_clock (44.1kHz) but the
    //  read clock will be 25MHz because we want to blast data out as soon as the fifo is full
    //  and we get a request from the RPi
    //
    wire [17:0] din = {2'b00,r_adc_data};   // feed this directly into the FIFO data input
    wire [17:0] dout;
    wire [11:0] fifo_adc_out = dout[15:4];  // only keep the 12 bits of ADC data
    wire wr_en;
    wire rd_en, fifo_full, fifo_empty, wr_rst_busy, rd_rst_busy;
    wire [15:0] fifo_data_count;
    fifo_adc DATA_FIFO (
        .rst(reset),
        .wr_clk(fifo_clock),
        .rd_clk(clock25),
        .din(din),
        .wr_en(wr_en),
        .rd_en(rd_en),
        .dout(dout),
        .full(fifo_full),
        .empty(fifo_empty),
        .rd_data_count(fifo_data_count),
        .wr_rst_busy(wr_rst_busy),
        .rd_rst_busy(rd_rst_busy)
    );
    //
    //  instantiate the UART receiver.  run with the 25MHz clock so that
    //  we can stay in phase with the state machines that control things
    //
    wire dv;
    wire [7:0] rx_data;
    uart_rx RECEIVER (
        .i_Clocks_per_Bit('d25),
        .i_Clock(clock25),
        .i_Reset(reset),
        .i_Rx_Serial(rx),       // tied to FPGA rx output
        .o_Rx_DV(dv),
        .o_Rx_Byte(rx_data)
        );
    //
    //  instantiate a fifo for the UART receiving from the RPi
    //  tie rx_wr_en to dv so that we can have the fifo write clock
    //  always going.  use the same for the read clock
    //
    wire rx_wr_en = dv;
    wire rx_full, rx_empty;
    wire rx_rd_en;
    wire [7:0] rx_dout;
    rxfifo FIFO_RX  (           // this fifo is 9 bits wide
        .rst(reset),
        .wr_clk(clock25),
        .rd_clk(clock25),
        .din(rx_data),   
        .wr_en(rx_wr_en),
        .rd_en(rx_rd_en),
        .dout(rx_dout),         // and 9 bits out
        .full(rx_full),
        .empty(rx_empty)
    );
    //
    //  instantiate the UART transmitter
    //
    wire tx_active, tx_done;
    wire do_transmit;
    wire [7:0] transmit_byte;
    uart_tx TRANSMITTER (
        .i_Clocks_per_Bit('d25),
        .i_Clock(clock25),
        .i_Reset(reset),
        .i_Tx_DV(do_transmit),
        .i_Tx_Byte(transmit_byte), 
        .o_Tx_Active(tx_active),
        .o_Tx_Serial(tx),       // tied to FPGA tx output
        .o_Tx_Done(tx_done)
        );
    //
    //  now make a state machine to deal with transmitting 2 bytes at a
    //  time, including the FIFO value that is present.
    //
    reg [2:0] tx_state;     // 8 states so 3 bits will do
    localparam [2:0] TX_IDLE=0, TX_BYTE1=1, TX_DO1=2, TX_WAIT1=3, TX_BYTE2=4,
                    TX_DO2=5, TX_WAIT2=6, TX_DONE=7;
    reg doit;
    wire [15:0] transmit_word;
    wire begin_transfer;
    reg [7:0] tx_data;
    always @ (posedge clock25) begin
        if (reset) begin
            tx_state <= TX_IDLE;
            doit <= 0;
            tx_data <= 0;
        end
        else 
            case (tx_state)
                TX_IDLE: begin
                    //
                    //  wait for begin_transfer to start
                    //
                    if (begin_transfer) tx_state <= TX_BYTE1;
                    else tx_state <= TX_IDLE;
                    doit <= 0;
                    tx_data <= 0;
                end
                TX_BYTE1: begin
                    //
                    //  latch the first byte of the transmit_word
                    //
                    tx_data <= transmit_word[7:0];
                    tx_state <= TX_DO1;
                end
                TX_DO1: begin
                    //
                    //  turn on uart_tx
                    //
                    doit <= 1;
                    tx_state <= TX_WAIT1;
                end
                TX_WAIT1: begin
                    //
                    //  turn off doit and wait for uart_tx to finish
                    //
                    doit <= 0;
                    if (tx_done) tx_state <= TX_BYTE2;
                    else tx_state <= TX_WAIT1;
                end
                TX_BYTE2: begin
                    //
                    //  latch the 2nd byte to transfer
                    //
                    tx_data <= transmit_word[15:8];
                    tx_state <= TX_DO2;
                end
                TX_DO2: begin
                    //
                    //  turn on uart_tx
                    //
                    doit <= 1;
                    tx_state <= TX_WAIT2;
                end
                TX_WAIT2: begin
                    //
                    //  wait for the 2nd byte to finish begin sent
                    //
                    doit <= 0;
                    if (tx_done) tx_state <= TX_DONE;
                    else tx_state <= TX_WAIT2;
                end
                TX_DONE: begin
                    //
                    //  wait for begin_transfer to go away
                    //
                    if (do_transmit) tx_state <= TX_DONE;
                    else tx_state <= TX_IDLE;
                end
                default: begin
                    tx_state <= TX_IDLE;
                end
            endcase
    end
    assign do_transmit = doit;
    assign transmit_byte = tx_data;
    //
    //  now instantiate the controller
    //
    wire global_state;
    wire [50:0] cdebug;
    controller CONTROL (
        .clock25(clock25),
        .fifo_clock(fifo_clock),
        .reset(reset),
        .global_start(global_start),
        .rx_fifo_empty(rx_empty),
        .rx_fifo_data(rx_dout),
        .rx_fifo_rd_en(rx_rd_en),
        .tx_transmit_out(transmit_word),
        .tx_transmit(begin_transfer),
        .tx_done(tx_done),
        .version(VERSION),
        .test(sw),
        .adc_data(r_adc_data),
        .adc_fifo_empty(fifo_empty),
        .adc_fifo_full(fifo_full),
        .adc_fifo_rd(rd_en),
        .adc_fifo_wr(wr_en),
        .adc_fifo_data_count(fifo_data_count),
        .adc_fifo_data(dout[15:0]),
        .debug(cdebug)
    );
    assign led[0] = rx_empty;
    assign led[1] = rx_full;
    assign led[2] = fifo_data_count == 12'h1;
    assign led[3] = fifo_empty;
    assign led[4] = fifo_full;
    assign led[5] = global_start;
    assign led[15] = clock_1hz;             // make a heartbeat
    //
    //  for debugging:
    //
        //  50      digitized
        //  49      adc_fifo_empty
        //  48      count_done
        //  47:32   tx_transmit_out[15:0]
        //  31      do_outgoing
        //  30       transmit_out
        //  29       blast_transmit
        //  28       blast_done
        //  27       do_blast,
        //  26:23     blast_state[3:0]
        //  22      tx_done
        //  21      tx_transmit
        //  20      out_done
        //  19:17   out_state[2:0]
        //  16      in_done
        //  15      in_read_fifo
        //  14:12   in_state[2:0]
        //  11      do_incoming
        //  10      do_blast
        //  9       incoming
        //  8       rx_instructions[7]
        //  7:5     rx_instructions[3:1]
        //  4:1     rx_state
        //  0       clock25
        
    always @*
        case (sw[11])
            0: JA = {rx_rd_en,rx_empty,rd_en,tx_done,tx,dv,rx,clock25};
            1: JA = {cdebug[10],rd_en,wr_en,fifo_empty,tx,fifo_full,rx,clock25};
        endcase
    always @*
        case (sw[15:12])
            4'b0000: JB = dout[15:8];
            4'b0001: JB = dout[7:0];
            4'b0010: JB = dout[11:4];
            4'b0011: JB = {tx_done,cdebug[28],cdebug[49],cdebug[48],cdebug[26:23]};
            4'b0100: JB = cdebug[39:32];
            4'b1000: JB = {cdebug[50],cdebug[14:12],cdebug[19:17],fifo_clock};
            4'b0101: JB = cdebug[47:40];
            4'b0110: JB = {cdebug[31],cdebug[19:17],cdebug[35:32]};
            4'b0111: JB = cdebug[7:0];
            default: JB = 'hdead;
        endcase

endmodule