• 0
weilai

Arty-7-35T UART communication to PC problem

Question

Hi,guys, I'm new and I have some problems in uart communication with PC(windows).

I  built UART RX (receiving) hardware. 8 LEDs will be used to show the binary value of the ASCII character. When the key strobe on the keyboard (from the computer) is pressed, the 8 bits will transmit from the keyboard to FPGA through USB-UART port on arty-7-35T board.

However, when I send something to board through TERATERM, all the LED is always off. when I connect one LED to RxD, the LED is always on. the following is my code.

`timescale 1ns / 1ps

module receiver(

input clk, //input clock
input reset, //input reset 
input RxD, //input receving data line
output [7:0]RxData, // output for 8 bits data
output LED01, // output 8 LEDs
output LED02
    );    
//internal variables
reg shift; // shift signal to trigger shifting data
reg state, nextstate; // initial state and next state variable
reg [3:0] bitcounter; // 4 bits counter to count up to 9 for UART receiving
reg [1:0] samplecounter; // 2 bits sample counter to count up to 4 for oversampling
reg [13:0] counter; // 14 bits counter to count the baud rate
reg [9:0] rxshiftreg; //bit shifting register
reg clear_bitcounter,inc_bitcounter,inc_samplecounter,clear_samplecounter; //clear or increment the counter
assign LED01=shift; 
assign LED02=nextstate;
// constants
parameter clk_freq = 100_000_000;  // system clock frequency
parameter baud_rate = 9_600; //baud rate
parameter div_sample = 4; //oversampling
parameter div_counter = clk_freq/(baud_rate*div_sample);  // this is the number we have to divide the system clock frequency to get a frequency (div_sample) time higher than (baud_rate)
parameter mid_sample = (div_sample/2);  // this is the middle point of a bit where you want to sample it
parameter div_bit = 10; // 1 start, 8 data, 1 stop


assign RxData = rxshiftreg [8:1]; // assign the RxData from the shiftregister

//UART receiver logic
always @ (posedge clk)
    begin 
        if (reset)begin // if reset is asserted
            state <=1; // set state to idle 
            bitcounter <=0; // reset the bit counter
            counter <=0; // reset the counter
            samplecounter <=0; // reset the sample counter
        end else begin // if reset is not asserted
            counter <= counter +1; // start count in the counter
            if (counter >= div_counter-1) begin // if counter reach the baud rate with sampling 
                counter <=0; //reset the counter
                state <= nextstate; // assign the state to nextstate
                if (shift)rxshiftreg <= {RxD,rxshiftreg[9:1]}; //if shift asserted, load the receiving data
                if (clear_samplecounter) samplecounter <=0; // if clear sampl counter asserted, reset sample counter
                if (inc_samplecounter) samplecounter <= samplecounter +1; //if increment counter asserted, start sample count
                if (clear_bitcounter) bitcounter <=0; // if clear bit counter asserted, reset bit counter
                if (inc_bitcounter)bitcounter <= bitcounter +1; // if increment bit counter asserted, start count bit counter
            end
        end
    end
   
//state machine

always @ (posedge clk) //trigger by clock
begin 
    shift <= 0; // set shift to 0 to avoid any shifting 
    clear_samplecounter <=0; // set clear sample counter to 0 to avoid reset
    inc_samplecounter <=0; // set increment sample counter to 0 to avoid any increment
    clear_bitcounter <=0; // set clear bit counter to 0 to avoid claring
    inc_bitcounter <=0; // set increment bit counter to avoid any count
    nextstate <=1; // set next state to be idle state
    case (state)
        0: begin // idle state
            if (RxD) // if input RxD data line asserted
              begin
              nextstate <=0; // back to idle state because RxD needs to be low to start transmission    
              end
            else begin // if input RxD data line is not asserted
                nextstate <=1; //jump to receiving state 
                clear_bitcounter <=1; // trigger to clear bit counter
                clear_samplecounter <=1; // trigger to clear sample counter
            end
        end
        1: begin // receiving state
            nextstate <= 1; // DEFAULT 
            if (samplecounter== mid_sample-1) shift <= 1; // if sample counter is 1, trigger shift 
                                                //LED<=1;
                if (samplecounter== div_sample - 1) begin // if sample counter is 3 as the sample rate used is 3
                    if (bitcounter == div_bit - 1) begin // check if bit counter if 9 or not
                nextstate <= 0; // back to idle state if bit counter is 9 as receving is complete
                end 
                inc_bitcounter <=1; // trigger the increment bit counter if bit counter is not 9
                clear_samplecounter <=1; //trigger the sample counter to reset the sample counter
            end else inc_samplecounter <=1; // if sample is not equal to 3, keep counting
        end
       default: nextstate <=0; //default idle state
     endcase
end         
endmodule

 

Share this post


Link to post
Share on other sites

3 answers to this question

Recommended Posts

  • 0

Welcome to the forums!

Please provide your XDC file, if possible. The behavior described sounds like it may be caused by one of two things:

1. The RxD port may be tied to the wrong pin. Pin A9, labeled uart_txd_in is the correct pin for receiving UART data.

2. The source that you are using for the reset port. The button labeled RESET (ck_rst, pin C2) is active low. If this is what the reset port is tied to, then the module would be held in a permanent reset state. This could be resolved by either modifying the core's reset condition/s, or by tying the reset to an active high button, BTN0-4 would work.

A quick simulation of the module shows that the module should be working properly, assuming that it is constrained properly. I've attached a quick and dirty testbench, as well as a screenshot.

Thanks,

Arthur

 

`timescale 10ns / 1ps

module tb;
    reg clk = 0;
    reg reset = 0;
    initial begin
        #1 clk = 1;
        forever #0.5 clk = ~clk;
    end
    initial begin
        #1 reset = 1;
        #1 reset = 0;
    end
    reg rxd = 0;
    wire [7:0] rxdata;
    wire led01;
    wire led02;
    receiver dut (
        clk,
        reset,
        rxd,
        rxdata,
        led01,
        led02
    );
endmodule

image.thumb.png.4755dfe32a86131be3d6bf032ce6766d.png

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now