Jump to content
  • 0

Arty-7-35T UART communication to PC problem


weilai

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

 

Link to comment
Share on other sites

3 answers to this question

Recommended Posts

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

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...