I am trying to use a Nexys A7 to capture an analog signal that I then want to transfer to my computer using a UART bridge. My problem is that the XADC/UART combination only works if I transfer the bits [15:8] of the XADC output data, for anything else, for example: [14:7], my UART transfer rate reduces and the entire thing starts behaving very strange
I used the XADC IP Source to set up the XADC(DRP, Continuous Mode, Single Channel, 100KSPS via VAUXP3/VAUXN3; I unchecked all the alarm and calibration things for now) and I am able to read analog data that I input via the respective pins: I can display it on the 16 LEDs and I can also transfer bits 15:8 to my computer and I see the correct signal.
I am running the serial transfer very fast (baud rate of 5e6) as I want to transfer a lot of data but things seem to be working both with CPP or Labview based serial communication. If I use the code below I get stable transfer for the simulated signal. I am using the data ready signal from the XADC "XADC_ready" to initiate the UART transfer so the code is linked to the somewhat "black-box" of the XADC IP source.
If I send the two 8 bit values below to the UART "w_RX_Byte" everything works fine and I am able to read a stable signal on the computer. If I substitute the simulated data for XADC_data[15:8], the 8 most significant bits from the XADC, the transfer works equally well and I don't have any problems. However, as soon as I use any other bits from XADC_data (for example [14:7] or [7:0]) the entire transfer breaks down. Unfortunately, I don't understand why/how. I try to read 4000 bytes with the computer which works well for [15:8] but for all other options the transfer fails to capture the correct number: sometimes I obtain 0 bytes, sometimes 2000 and rarely 4000. I am inputting a 100-200 mV sine-function and it looks like as if the transfer rate is coupled to the frequency of that function (not the case if I read 15:8 which allows me to nicely capture the sine-function but only the 8 most significant bits of it)..
I would be very grateful if someone had an idea 🙂
Sending the data: (works for: simulated or XADC_data[15:8]; does not work for XADC_data[x:x-7] for x !=15)
always @(posedge CLK100MHZ) //should have done this with a state machine!
begin
if (XADC_ready && wait_data == 0) //when XADC is ready and "idle" go ahead and send the first 8 bit
begin
w_RX_Byte <= 8'b11110001; //XADC_data[15:8];
w_RX_DV <= 1'b1;
wait_data <= wait_data +1;
end
else
begin
if (w_TX_DONE) //first UART tranfer complete
begin
if (wait_data == 1) //send the second 8 bit
begin
wait_data <= wait_data +1;
w_RX_Byte <= 8'b00110001; // works for: XADC_data[15:8] but I would like to send XADC_data[7:0];
w_RX_DV <= 1'b1;
end
else //go back to idle
wait_data <= 0;
end
else
w_RX_DV <= 1'b0;
end
end
UART_TX #(
.CLKS_PER_BIT(c_CLKS_PER_BIT) //ensure baud rate is set correctly
)
UART_TX(
.i_Clk(CLK100MHZ),
.i_TX_DV(w_RX_DV),
.i_TX_BYTE(w_RX_Byte),
.o_TX_SERIAL(w_TX_SERIAL),
.o_TX_ACTIVE(w_TX_ACTIVE),
.o_TX_DONE(w_TX_DONE)
);
assign o_UART_TX = w_TX_ACTIVE ? w_TX_SERIAL : 1'b1; //UART_TX "sends" information; if TRANSMITTER active, send the bit otherwise send 1
top.v declarations:
module top
#(
parameter xadc_address = 8'h13,
parameter c_CLKS_PER_BIT = 20 //I am running 5MS/s
)
(
input CLK100MHZ,
//XADC related
input vauxn3,
input vauxp3,
input vn_in,
input vp_in,
//UART related
input i_UART_RX,
output o_UART_TX
// output reg [15:0] LED
);
//This is for XADC
wire XADC_enable; //bounce back and forth with XADC to know when to read again
wire XADC_ready; //tells us when data is ready
wire [15:0] XADC_data; //holds 16 bit data from XADC
//This is for UART protcol
wire w_TX_SERIAL; //Serial Data connection from Transmitter
wire w_TX_ACTIVE; //Active information of Transmitter connection
wire w_TX_DONE;
integer wait_data = 0;
//This is for testing the fast UART
integer w_RX_DV = 0; //Receiver's Data Valid connection
reg [7:0] w_RX_Byte = 8'b00000000; //Receiver's Data Byte connection
UART transmitter code:
module UART_TX
#
(
parameter CLKS_PER_BIT = 20
)
(
input i_Clk,
input i_TX_DV, //Data Valid
input [7:0] i_TX_BYTE, //Parallel Data
output reg o_TX_SERIAL, //Serial Data
output o_TX_ACTIVE, //Information for TRANSMITTER being active
output o_TX_DONE //Information for Transmitting process being done
);
parameter [2:0] IDLE = 3'b000; //Default State
parameter [2:0] START_BIT = 3'b001; //Start bit's State
parameter [2:0] DATA_BITS = 3'b010; //Data's State
parameter [2:0] STOP_BIT = 3'b011; //Stop bit's State
parameter [2:0] CLEANUP = 3'b100; //This state is for returning to the Default State after 1 clock cycle
reg [2:0] r_STATE = 0; //State Variable
reg [9:0] r_Clock_Count = 0; //Counter for sampling data
reg [2:0] r_BIT_INDEX = 0; //Index counter variable for receiving data
reg [7:0] r_TX_BYTE = 0; //Variable which will be transmitted data as byte domain
reg r_TX_ACTIVE = 0; //Registered information for TRANSMITTER being active
reg r_TX_DONE = 0; //Registered information for Transmitting process being done
//Opposite algorithm of UART Receiver
always@(posedge i_Clk)
begin
case(r_STATE)
IDLE:
begin
r_Clock_Count <= 0;
r_BIT_INDEX <= 0;
r_TX_DONE <= 1'b0;
o_TX_SERIAL <= 1'b1;
if(i_TX_DV == 1'b1)
begin
r_TX_ACTIVE <= 1'b1;
r_TX_BYTE <= i_TX_BYTE;
r_STATE <= START_BIT;
end
else
r_STATE <= IDLE;
end
START_BIT:
begin
o_TX_SERIAL <= 1'b0;
if(r_Clock_Count < CLKS_PER_BIT -1)
begin
r_Clock_Count <= r_Clock_Count + 1;
r_STATE <= START_BIT;
end
else
begin
r_Clock_Count <= 0;
r_STATE <= DATA_BITS;
end
end
DATA_BITS:
begin
o_TX_SERIAL <= r_TX_BYTE[r_BIT_INDEX];
if(r_Clock_Count < CLKS_PER_BIT -1)
begin
r_Clock_Count <= r_Clock_Count + 1;
r_STATE <= DATA_BITS;
end
else
begin
r_Clock_Count <= 0;
if(r_BIT_INDEX < 7)
begin
r_BIT_INDEX <= r_BIT_INDEX + 1;
r_STATE <= DATA_BITS;
end
else
begin
r_BIT_INDEX <= 0;
r_STATE <= STOP_BIT;
end
end
end
STOP_BIT:
begin
o_TX_SERIAL <= 1'b1;
if(r_Clock_Count < CLKS_PER_BIT -1)
begin
r_Clock_Count <= r_Clock_Count + 1;
r_STATE <= STOP_BIT;
end
else
begin
r_Clock_Count <= 0;
r_STATE <= CLEANUP;
r_TX_DONE <= 1'b1;
r_TX_ACTIVE <= 1'b0;
end
end
CLEANUP:
begin
r_STATE <= IDLE;
r_TX_DONE <= 1'b1;
end
default:
r_STATE <= IDLE;
endcase
end
assign o_TX_ACTIVE = r_TX_ACTIVE;
assign o_TX_DONE = r_TX_DONE;
endmodule
Question
photoM
Hi,
I am trying to use a Nexys A7 to capture an analog signal that I then want to transfer to my computer using a UART bridge. My problem is that the XADC/UART combination only works if I transfer the bits [15:8] of the XADC output data, for anything else, for example: [14:7], my UART transfer rate reduces and the entire thing starts behaving very strange
I used the XADC IP Source to set up the XADC(DRP, Continuous Mode, Single Channel, 100KSPS via VAUXP3/VAUXN3; I unchecked all the alarm and calibration things for now) and I am able to read analog data that I input via the respective pins: I can display it on the 16 LEDs and I can also transfer bits 15:8 to my computer and I see the correct signal.
I am running the serial transfer very fast (baud rate of 5e6) as I want to transfer a lot of data but things seem to be working both with CPP or Labview based serial communication. If I use the code below I get stable transfer for the simulated signal. I am using the data ready signal from the XADC "XADC_ready" to initiate the UART transfer so the code is linked to the somewhat "black-box" of the XADC IP source.
If I send the two 8 bit values below to the UART "w_RX_Byte" everything works fine and I am able to read a stable signal on the computer. If I substitute the simulated data for XADC_data[15:8], the 8 most significant bits from the XADC, the transfer works equally well and I don't have any problems. However, as soon as I use any other bits from XADC_data (for example [14:7] or [7:0]) the entire transfer breaks down. Unfortunately, I don't understand why/how. I try to read 4000 bytes with the computer which works well for [15:8] but for all other options the transfer fails to capture the correct number: sometimes I obtain 0 bytes, sometimes 2000 and rarely 4000. I am inputting a 100-200 mV sine-function and it looks like as if the transfer rate is coupled to the frequency of that function (not the case if I read 15:8 which allows me to nicely capture the sine-function but only the 8 most significant bits of it)..
I would be very grateful if someone had an idea 🙂
Sending the data: (works for: simulated or XADC_data[15:8]; does not work for XADC_data[x:x-7] for x !=15)
XADC "black box code" in top.v:
UART transmitter in top.v:
top.v declarations:
UART transmitter code:
Link to comment
Share on other sites
1 answer to this question
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now