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