n
`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