• 0
Alex

Help on first RS232 Verilog project on Basys 3

Question

Hi, I tried to learn RS232 and created a project on Basys 3 with Pmod R232. The plan I would like to do is that whenever I set binary number at 8 switches on Basys 3, the data will be passed to the PC and I can see the character in the hyperterminal. At the same time, the LEDs for the "ON" switches with be turned on. I have successfully generated the bitstream file but it doesn't seems function. Include the Verilog code for transmitter, receiver and top modules. It will be great if someone can give hints to let me finish this project.  

P.S. I have used the logic from http://www.ece301.com/

Transmitter

module transmitter(
input clk, //clock
input reset, // reset 
input transmit, //input to say transmission is ready, can be push button or switch
input [7:0] data, // data transmitted
output reg TxD // transmit data line 
    );
reg TxDready; //register variable to tell when transmission is ready 
reg [3:0] bitcounter; //vector 4 bits counter to count up to 9
reg [13:0] counter; //vector 14 bits counter to count the baud rate, counter = clock / baud rate
reg state, nextstate; // register state variable
reg [9:0] rightshiftreg; // vector data needed to be transmitted 1 start, 8 data & 1 stop bit
reg shift, load, clear; //register variable for shifting, loading the bits and clear the counter

//counter logic
always @ (posedge clk) //positive edge
begin 
    if (reset) begin // reset is asserted (reset = 1)
        state <=0; // state is idle (state = 0)
        counter <=0; // counter for baud rate is reset to 0 
        bitcounter <=0; //counter for bit transmission is reset to 0
    end
    else begin
         counter <= counter + 1; //start counting 
         if (counter >= 10415) //if count to 5207 because we start the conunt from 0, so not 5208
            begin 
            state <= nextstate; //state change to next state
            counter <=0; // reset counter to 0
            if (load) rightshiftreg <= {1'b1,data,1'b0}; //load the data if load is asserted
            if (clear) bitcounter <=0; // reset the bitcounter if clear is asserted
            if (shift) 
                begin // if shift is asserted
                rightshiftreg <= rightshiftreg >> 1; //right shift the data as we transmit the data from lsb
                bitcounter <= bitcounter + 1; //count the bitcounter
                end
            end
          end
end 

//state machine

always @ (state, bitcounter, transmit,rightshiftreg) //trigger by change of state, bitcounter or transmit
begin 
    load <=0; // set load equal to 0 at the beginning
    shift <=0; // set shift equal to 0 at the beginning
    clear <=0; // set clear equal to 0 at the beginning
    TxDready <=1; // set TxDReady equal to 1 so no transmission. When TxD is zero, the receiver knows it is transmitting
    TxD <=0; // set TxD equals to 0 at the beginning to avoid latch
    case (state)
        0: begin // idle state
             if (transmit) begin // assert transmit input
             nextstate <=1; // set nextstate register variable to 1 to transmit state
             load <=1; // set load to 1 to prepare to load the data
             shift <=0; // set shift to 0 so no shift ready yet
             clear <=0; // set clear to 0 to avoid clear any counter
             end else begin // if transmit not asserted
             nextstate <=0; // next state is 0 back to idle
             TxDready <=1; // set TxD to 1 to avoid any transmission
             end
           end
        1: begin  // transmit state
             if (bitcounter >=9) begin // check if transmission is complete or not. If complete
             nextstate <= 0; // set nextstate back to 0 to idle state
             clear <=1; // set clear to 1 to clear all counters
             end else begin // if transmisssion is not complete 
             nextstate <= 1; // set nextstate to 1 to stay in transmit state
             shift <=1; // set shift to 1 to continue shifting the data
             TxD <= rightshiftreg[0]; // shift the bit to output TxD
             end
           end
         default: begin // idle state
                     if (transmit) begin // assert transmit input
                     nextstate <=1; // set nextstate register variable to 1 to transmit state
                     load <=1; // set load to 1 to prepare to load the data
                     shift <=0; // set shift to 0 so no shift ready yet
                     clear <=0; // set clear to 0 to avoid clear any counter
                     end else begin // if transmit not asserted
                     nextstate <=0; // next state is 0 back to idle
                     TxDready <=1; // set TxD to 1 to avoid any transmission
                     end
                  end           
    endcase
end
endmodule

Receiver

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 [7:0]LED // output 8 LEDs
    );
reg shift; // register variable shift to trigger shifting data
reg state, nextstate; // register state variable
reg [3:0] bitcounter; // register vector 4 bits counter to count up to 9
reg [3:0] samplecounter; // register vector 4 bits sample counter to count up to 9
reg [13:0] counter; // register vector 14 bits counter to count the baud rate
reg [9:0] rxshiftreg; //register vector for bit shifting
reg clear_bitcounter,inc_bitcounter,inc_samplecounter,clear_samplecounter; //register variable to clear or increment the counter

assign RxData = rxshiftreg [8:1]; // assign the RxData 
// assign LED = RxData; // assign the LED output 

//counter logic
always @ (posedge clk)
    begin 
        if (reset)begin // if reset is asserted
            state <=0; // 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 >= 3472) 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 @ (state or RxD or bitcounter or samplecounter or rxshiftreg) // triggered by change of state, Rxd and bit counter
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 <=0; // set nextstate equals to 0 at the beginning to avoid any latch
    case (state)
        0: begin // idle state
            if (RxD) // if input RxD data line asserted
                nextstate <=0; // back to idle state because RxD needs to be low to start transmission
            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
            if (samplecounter==1) shift <=1; // if sample counter is 1, trigger shift 
            if (samplecounter==3) begin // if sample counter is 3 as the sample rate used is 3
                if (bitcounter ==9) 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: begin // idle state
                    if (RxD) // if input RxD data line asserted
                        nextstate <=0; // back to idle state because RxD needs to be low to start transmission
                    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
     endcase
end         
endmodule

Top

module top(
input btn0,
input [8:0] sw, // input 8 switches , one for transmit 
input clk,
input RxD,
output TxD,
output [7:0]LED // output 8 LEDs
); 

wire [7:0] data;
assign data = sw;

receiver R1 (.clk(clk), .reset(btn0), .RxD(RxD), .RxData(LED));
transmitter T1 (.clk(clk),.transmit(sw[8]), .reset(btn0),.data(sw[7:0]), .TxD(TxD));


endmodule

 

Share this post


Link to post
Share on other sites

13 answers to this question

Recommended Posts

  • 0

Hi Alex - you might want to have a look at a similar thread ( https://forum.digilentinc.com/topic/766-vhdl-uart-rx-for-nexys4-ddr/ ) but in a different language.

Some hints: 

- If you can,run the design in a simulator - it can show all sorts of helpful info.

- Look at all the output reports, and see if anything is amiss. Check that the signals are assigned to the correct pins, that all warnings are explainable (and FPGA designs  usually have some warnings).

- RS232 always has confusion over TX/RX lines - they are easy to get mixed up. Am I listening for data being transmitted on the TX line? or should I be sending on the TX line?

- Start simple, giving you the minimal things that can go wrong (and verifying that a few things are working right)

In the idea of start simple, if you load a 20 bit shift register with "11111111111010110100", and then send out a right-most bit every baud tick before you roll the shift register to the right. You should get ASCII 5A - a capital Z - on the output pin.

Once you get that working (it shouldn't take that much code) you will know a lot of things and have removed a lot of uncertainty. 

- The system clock is connected to the pin that you think it is

- The system clock is at the expected frequency

- You are using have the correct baud divisor

- You have the correct TX pin, so finding the RX pin should be easy!

Although it might distract you for a short while from your main design, but should get you well on your way.If it doesn't work then there is a lot less to debug...

 

Share this post


Link to post
Share on other sites
  • 0

Hi Hamster, thanks for the useful information. I think I am too greedy to do both TX and RX in the first project. So, I left the the RX alone and just focus on the TX module. Instead of using the Pmod RS232, I used the on board UART (I think that is making more sense).

I revised the transmitter module a bit based on the Basys 3 reference project and successfully compiled bitstream without any warning or error. However, the implementation doesn't work. When I set a switch "01101011" and press the push button to initiate the transmission. However, either there is a character in the TeraTerm or the TX status LED is on. So, I run a behavioral simulation. All the inputs are high impedance. I checked that my code should be ok. 

Here is my design. I wonder if it is about the clock or what. 

Input - system clk: 100MHz, 8 switches for 8 bit data, reset button, transmit push button (a button that initiate the transmission

Output - TxD - the TxD is the Tx Line

Variable - 

1. bitcounter - 4 bit counter check if we send all 9 bits including 1 start bit, 8 data bits and 1 stop bit 

2. counter - 14 bit counte to make sure we have the desired baud rate

3. state & nextstate - state variable for the state machine

4. rightshiftreg - 9 bit vector to store start, data and stop bits for shifting

5. shift, load and clear - control signal to do loading and shift the data and clearing counters

Counter logic - 

1. Reset - state, clear, bitcounter zero

2. Once the counter reach 10,416 (100MHz /9600)

           a. if load is asserted - load the data in the rightshiftreg

           b. if clear is asserted - clear the bitcounter

           c. if shift is asserted - shift the data in rightshiftreg to the right and then count up bitcounter

State Machine

State 0 (idle):

1. if transmit is asserted (i.e. button pushed)

        a. Go to next state

        b. assert load

        c.set shift and clear to 0

2. if transmit is not asserted (i.e. no button pushed)

       a. Make TxDready to 1

       b. stay in idle state 0

State 1 (transmit state)

1. if bitcounter >=9 , go back to idle state, assert clear

2. if bitcounter <9, stay in the transmit state, assert shift, set TxDready to 0, assign the LSB of the rightshift to TxD  

Verilog Code

module transmitter(
input clk, //clock
input reset, // reset 
input transmit, //input to say transmission is ready, can be push button or switch
input [7:0] data, // data transmitted
output reg TxD, // transmit data line 
output reg TxDready //register variable to tell when transmission is on
    );


reg [3:0] bitcounter; //vector 4 bits counter to count up to 9
reg [13:0] counter; //vector 14 bits counter to count the baud rate, counter = clock / baud rate
reg state, nextstate; // register state variable
reg [9:0] rightshiftreg; // vector data needed to be transmitted 1 start, 8 data & 1 stop bit
reg shift, load, clear; //register variable for shifting, loading the bits and clear the counter

//counter logic
always @ (posedge clk or posedge reset) //positive edge
begin 
    if (reset) begin // reset is asserted (reset = 1)
        state <=0; // state is idle (state = 0)
        counter <=0; // counter for baud rate is reset to 0 
        bitcounter <=0; //counter for bit transmission is reset to 0
    end
    else begin
         counter <= counter + 1; //start counting 
         if (counter >= 10416) //if count to 10416 because we start from 0 not 1. Supposed 10417 after rounding up
            begin 
            state <= nextstate; //state change to next state
            counter <=0; // reset counter to 0
            if (load) rightshiftreg <= {1'b1,data,1'b0}; //load the data if load is asserted
            if (clear) bitcounter <=0; // reset the bitcounter if clear is asserted
            if (shift) 
                begin // if shift is asserted
                rightshiftreg <= rightshiftreg >> 1; //right shift the data as we transmit the data from lsb
                bitcounter <= bitcounter + 1; //count the bitcounter
                end
            end
          end
end 

//state machine

always @ (clk or state or bitcounter or transmit or rightshiftreg) //trigger by clk, change of state, bitcounter or transmit
begin 
    load <=0; // set load equal to 0 at the beginning
    shift <=0; // set shift equal to 0 at the beginning
    clear <=0; // set clear equal to 0 at the beginning
    TxDready <=1; // set TxDReady equal to 1 so no transmission. When TxD is zero, the receiver knows it is transmitting
    TxD <=0; // set TxD equals to 0 at the beginning to avoid latch
    case (state)
        0: begin // idle state
             if (transmit) begin // assert transmit input
             nextstate <=1; // set nextstate register variable to 1 to transmit state
             load <=1; // set load to 1 to prepare to load the data
             shift <=0; // set shift to 0 so no shift ready yet
             clear <=0; // set clear to 0 to avoid clear any counter
             end else begin // if transmit not asserted
             nextstate <=0; // next state is 0 back to idle
             TxDready <=1; // set TxDready to 1 to state no transmission
             end
           end
        1: begin  // transmit state
             if (bitcounter >=9) begin // check if transmission is complete or not. If complete
             nextstate <= 0; // set nextstate back to 0 to idle state
             clear <=1; // set clear to 1 to clear all counters
             end else begin // if transmisssion is not complete 
             nextstate <= 1; // set nextstate to 1 to stay in transmit state
             shift <=1; // set shift to 1 to continue shifting the data
             TxDready <=0; // set TxDready to 0 to keep it low during transmission
             TxD <= rightshiftreg[0]; // shift the bit to output TxD
             end
           end
         default: nextstate <=0;
                             
    endcase
end
endmodule

 

 

Share this post


Link to post
Share on other sites
  • 0

Hi, 

I quickly run this in a simulation - if you get the chance, try setting one up.

First things - if 'load' is asserted for one clock cycle, there is a one in 10,416 chance that data will actually be loaded, as the FSM's state can only change that fast. So I moved things around in the clocked process.

Also, the TX line was at '0' when the not transmitting anything, it should be '1';

Try this - it still buggy, but should give you something!

module transmitter(
input clk,          // clock
input reset,        // reset 
input transmit,     // input to say transmission is ready, can be push button or switch
input [7:0] data,   // data transmitted
output reg TxD,     // transmit data line 
output reg TxDready //register variable to tell when transmission is on
    );

reg [3:0] bitcounter;    //vector 4 bits counter to count up to 9
reg [13:0] counter;      //vector 14 bits counter to count the baud rate, counter = clock / baud rate
reg state, nextstate;    // register state variable
reg [9:0] rightshiftreg; // vector data needed to be transmitted 1 start, 8 data & 1 stop bit
reg load, clear;  //register variable for shifting, loading the bits and clear the counter
//counter logic
always @ (posedge clk or posedge reset) //positive edge
begin 
    if (reset) begin // reset is asserted (reset = 1)
        state <=0; // state is idle (state = 0)
        counter <=0; // counter for baud rate is reset to 0 
        bitcounter <=0; //counter for bit transmission is reset to 0
    end
    else begin
         // MAF First fix use test for equality - faster!
         if (counter != 10415) // count to 10416 
            counter <= counter + 1; //start counting 
         else begin;
            counter <= 0; // reset counter to 0
            // Shift out the next bit.               
            TxD              <= rightshiftreg[0]; // shift the bit to output TxD
            rightshiftreg    <= rightshiftreg >> 1; //right shift the data as we transmit the data from lsb
            rightshiftreg[9] <= 1'b1;  // MAF - Set the idle bit to be '1'
            bitcounter <= bitcounter + 1; //count the bitcounter
         end
         
         // Moved this outside of the one in 10,416 cycles block
         state   <= nextstate; //state change to next state
         if (load) rightshiftreg <= {1'b1,data,1'b0}; //load the data if load is asserted
    end
end 
//state machine

always @ (state or bitcounter or transmit or rightshiftreg) //trigger by change of state, bitcounter or transmit
begin 
    load     <= 0; // set load equal to 0 at the beginning
    TxDready <= 1; // set TxDReady equal to 1 so no transmission. When TxD is zero, the receiver knows it is transmitting
    case (state)
        0: begin // idle state
             if (transmit) begin // assert transmit input
                nextstate <= 1; // set nextstate register variable to 1 to transmit state
                load      <= 1; // set load to 1 to prepare to load the data
             end else begin // if transmit not asserted
                nextstate <= 0; // next state is 0 back to idle
                TxDready  <= 1; // set TxDready to 1 to state no transmission
             end
           end
 
        1: begin  // transmit state
             // MAF - Chage to test for equality
             if (bitcounter == 9) begin // check if transmission is complete or not. If complete
               nextstate  <= 0; // set nextstate back to 0 to idle state
             end else begin     // if transmisssion is not complete 
               nextstate  <= 1; // set nextstate to 1 to stay in transmit state
               TxDready   <=0;  // set TxDready to 0 to keep it low during transmission
             end
           end
           
        default: nextstate <=0;
    endcase
end
endmodule

Share this post


Link to post
Share on other sites
  • 0

Hi Hamster, thanks for the useful tips. Actually, I have tried to revise the module based on your suggestion. 

It looks like Vivado optimize out counter, bitcounter and state. However, those variables are used in the program. 

  • [Synth 8-3332] Sequential element (\counter_reg[0] ) is unused and will be removed from module transmitter.
  • [Synth 8-3332] Sequential element (\counter_reg[1] ) is unused and will be removed from module transmitter.
  • [Synth 8-3332] Sequential element (\counter_reg[2] ) is unused and will be removed from module transmitter.
  • [Synth 8-3332] Sequential element (\counter_reg[3] ) is unused and will be removed from module transmitter.
  • [Synth 8-3332] Sequential element (\counter_reg[4] ) is unused and will be removed from module transmitter.
  • [Synth 8-3332] Sequential element (\counter_reg[5] ) is unused and will be removed from module transmitter.
  • [Synth 8-3332] Sequential element (\counter_reg[6] ) is unused and will be removed from module transmitter.
  • [Synth 8-3332] Sequential element (\counter_reg[7] ) is unused and will be removed from module transmitter.
  • [Synth 8-3332] Sequential element (\counter_reg[8] ) is unused and will be removed from module transmitter.
  • [Synth 8-3332] Sequential element (\counter_reg[9] ) is unused and will be removed from module transmitter.
  • [Synth 8-3332] Sequential element (\counter_reg[10] ) is unused and will be removed from module transmitter.
  • [Synth 8-3332] Sequential element (\counter_reg[11] ) is unused and will be removed from module transmitter.
  • [Synth 8-3332] Sequential element (\counter_reg[12] ) is unused and will be removed from module transmitter.
  • [Synth 8-3332] Sequential element (\counter_reg[13] ) is unused and will be removed from module transmitter.
  • [Synth 8-3332] Sequential element (\bitcounter_reg[3] ) is unused and will be removed from module transmitter.
  • [Synth 8-3332] Sequential element (\bitcounter_reg[2] ) is unused and will be removed from module transmitter.
  • [Synth 8-3332] Sequential element (\bitcounter_reg[1] ) is unused and will be removed from module transmitter.
  • [Synth 8-3332] Sequential element (\bitcounter_reg[0] ) is unused and will be removed from module transmitter.
  • [Synth 8-3332] Sequential element (state_reg) is unused and will be removed from module transmitter.  

 

Share this post


Link to post
Share on other sites
  • 0

Humm,,, something must be wrong - can't say what.

I've tested on the board with this source - the original source didn't send the stop bit if the transmit button was held down. I'm no good at Verilog, so it might be full errors :)

module transmitter(
    input clk,          // clock
    input reset,        // reset 
    input transmit,     // input to say transmission is ready, can be push button or switch
    input [7:0] data,   // data transmitted
    output reg TxD,     // transmit data line 
    output reg TxDready //register variable to tell when transmission is on
);

reg [3:0] bitcounter;     //vector 4 bits counter to count up to 10
reg [13:0] counter;       //vector 14 bits counter to count the baud rate, counter = clock / baud rate
reg state, nextstate;     // register state variable
reg [9:0]  rightshiftreg; // vector data needed to be transmitted 1 start, 8 data & 1 stop bit
reg load;                 //register variable for shifting, loading the bits and clear the counter
//counter logic
always @ (posedge clk or posedge reset) //positive edge
begin 
    if (reset) begin // reset is asserted (reset = 1)
        state      <=0; // state is idle (state = 0)
        counter    <=0; // counter for baud rate is reset to 0 
        bitcounter <=0; // counter for bit transmission is reset to 0
    end else begin
        if (counter == 10415) // count to 10416
        begin 
            counter <= 0; // reset counter to 0
            // Shift out the next bit.               
            TxD              <= rightshiftreg[0]; // shift the bit to output TxD
            rightshiftreg    <= rightshiftreg >> 1; //right shift the data as we transmit the data from lsb
            rightshiftreg[9] <= 1'b1;  // Set the idle bit to be '1'
            bitcounter <= bitcounter + 1; //count the bitcounter
        end else begin
            counter <= counter + 1; 
        end
         
        // Moved this outside of the one in 10,416 cycles block
        state   <= nextstate; //state change to next state
        if (load) begin
            rightshiftreg <= {1'b1,data,1'b0}; //load the data if load is asserted
            bitcounter    <= 0;
        end
    end
end 
//state machine

always @ (state or bitcounter or transmit) //trigger by change of state, bitcounter or transmit
begin 
    load     <= 0; // set load equal to 0 at the beginning
    TxDready <= 1; // set TxDReady equal to 1 so no transmission. When TxD is zero, the receiver knows it is transmitting
    case (state)
        0: begin // idle state
             if (transmit) begin // assert transmit input
                nextstate <= 1; // set nextstate register variable to 1 to transmit state
                load      <= 1; // set load to 1 to prepare to load the data
             end else begin // if transmit not asserted
                nextstate <= 0; // next state is 0 back to idle
                TxDready  <= 1; // set TxDready to 1 to state no transmission
             end
           end
 
        1: begin  // transmit state
             if (bitcounter == 10) begin // check if we have transmitted 10 bits - start, 8x data, start
               nextstate  <= 0; // set nextstate back to 0 to idle state
             end else begin     // if transmisssion is not complete 
               nextstate  <= 1; // set nextstate to 1 to stay in transmit state
               TxDready   <=0;  // set TxDready to 0 to keep it low during transmission
             end
           end
           
        default: nextstate <=0;
    endcase
end
endmodule
and these constraints:
## Clock signal
set_property PACKAGE_PIN W5 [get_ports clk]                            
    set_property IOSTANDARD LVCMOS33 [get_ports clk]
    create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports clk]
 
##USB-RS232 Interface
#set_property PACKAGE_PIN B18 [get_ports RxD]                        
    #set_property IOSTANDARD LVCMOS33 [get_ports RxD]
set_property PACKAGE_PIN A18 [get_ports TxD]                        
    set_property IOSTANDARD LVCMOS33 [get_ports TxD]
##Buttons
# Center
set_property PACKAGE_PIN U18 [get_ports transmit]                    
    set_property IOSTANDARD LVCMOS33 [get_ports transmit]
# Up
set_property PACKAGE_PIN T18 [get_ports reset]                        
    set_property IOSTANDARD LVCMOS33 [get_ports reset]
#set_property PACKAGE_PIN W19 [get_ports btnL]                        
    #set_property IOSTANDARD LVCMOS33 [get_ports btnL]
#set_property PACKAGE_PIN T17 [get_ports btnR]                        
    #set_property IOSTANDARD LVCMOS33 [get_ports btnR]
#set_property PACKAGE_PIN U17 [get_ports btnD]                        
    #set_property IOSTANDARD LVCMOS33 [get_ports btnD]
        
## LEDs
set_property PACKAGE_PIN U16 [get_ports {TxDready}]                    
    set_property IOSTANDARD LVCMOS33 [get_ports {TxDready}]
#set_property PACKAGE_PIN E19 [get_ports {led[1]}]                    
#    set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]
#set_property PACKAGE_PIN U19 [get_ports {led[2]}]                    
#    set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]
#set_property PACKAGE_PIN V19 [get_ports {led[3]}]                    
#    set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]
#set_property PACKAGE_PIN W18 [get_ports {led[4]}]                    
#    set_property IOSTANDARD LVCMOS33 [get_ports {led[4]}]
#set_property PACKAGE_PIN U15 [get_ports {led[5]}]                    
#    set_property IOSTANDARD LVCMOS33 [get_ports {led[5]}]
#set_property PACKAGE_PIN U14 [get_ports {led[6]}]                    
#    set_property IOSTANDARD LVCMOS33 [get_ports {led[6]}]
#set_property PACKAGE_PIN V14 [get_ports {led[7]}]                    
#    set_property IOSTANDARD LVCMOS33 [get_ports {led[7]}]
#set_property PACKAGE_PIN V13 [get_ports {led[8]}]                    
#    set_property IOSTANDARD LVCMOS33 [get_ports {led[8]}]
#set_property PACKAGE_PIN V3 [get_ports {led[9]}]                    
#    set_property IOSTANDARD LVCMOS33 [get_ports {led[9]}]
#set_property PACKAGE_PIN W3 [get_ports {led[10]}]                    
#    set_property IOSTANDARD LVCMOS33 [get_ports {led[10]}]
#set_property PACKAGE_PIN U3 [get_ports {led[11]}]                    
#    set_property IOSTANDARD LVCMOS33 [get_ports {led[11]}]
#set_property PACKAGE_PIN P3 [get_ports {led[12]}]                    
#    set_property IOSTANDARD LVCMOS33 [get_ports {led[12]}]
#set_property PACKAGE_PIN N3 [get_ports {led[13]}]                    
#    set_property IOSTANDARD LVCMOS33 [get_ports {led[13]}]
#set_property PACKAGE_PIN P1 [get_ports {led[14]}]                    
#    set_property IOSTANDARD LVCMOS33 [get_ports {led[14]}]
#set_property PACKAGE_PIN L1 [get_ports {led[15]}]                    
#    set_property IOSTANDARD LVCMOS33 [get_ports {led[15]}]
    
## Switches
set_property PACKAGE_PIN V17 [get_ports {data[0]}]                    
    set_property IOSTANDARD LVCMOS33 [get_ports {data[0]}]
set_property PACKAGE_PIN V16 [get_ports {data[1]}]                    
    set_property IOSTANDARD LVCMOS33 [get_ports {data[1]}]
set_property PACKAGE_PIN W16 [get_ports {data[2]}]                    
    set_property IOSTANDARD LVCMOS33 [get_ports {data[2]}]
set_property PACKAGE_PIN W17 [get_ports {data[3]}]                    
    set_property IOSTANDARD LVCMOS33 [get_ports {data[3]}]
set_property PACKAGE_PIN W15 [get_ports {data[4]}]                    
    set_property IOSTANDARD LVCMOS33 [get_ports {data[4]}]
set_property PACKAGE_PIN V15 [get_ports {data[5]}]                    
    set_property IOSTANDARD LVCMOS33 [get_ports {data[5]}]
set_property PACKAGE_PIN W14 [get_ports {data[6]}]                    
    set_property IOSTANDARD LVCMOS33 [get_ports {data[6]}]
set_property PACKAGE_PIN W13 [get_ports {data[7]}]                    
    set_property IOSTANDARD LVCMOS33 [get_ports {data[7]}]
.

Seems to work.

Share this post


Link to post
Share on other sites
  • 0

@hamster Finally, I have finished this project and put everything at instructables. I separate TX and RX into two parts

Part I: http://www.instructables.com/id/UART-Communication-on-Basys-3-FPGA-Dev-Board-Power/

Part II: http://www.instructables.com/id/UART-Communication-on-Basys-3-FPGA-Dev-Board-Power-1/

Note: Somehow, even though I used the debounced button module in the Part I, it still has debouncing issue. I found out the potential root cause is due to the prolong "transmit" signal. No matter how I modify the debounce module, I still can't change the period of transmit signal. Anyway, I hope to move on to another project. Feel free to give some inputs.

Thanks for the help.

Share this post


Link to post
Share on other sites
  • 0

@Alex,

I really hope you haven't been struggling on this every day for the last year and a half, but ... even if so ... I admire your willingness to stick to this project.

Well done, and thanks for posting!

Dan

Share this post


Link to post
Share on other sites
  • 0

@D@n, I just pick this up in the Christmas break after a year and half. Somehow, I want to complete this before I move on. 

Share this post


Link to post
Share on other sites
  • 0

@Alex,

If it's of any use to you, I'm in the process of posting/updating a UART module on GitHub.  I hope to have the updates posted to GitHub later today, to include a post in the ProjectVault about it.  The module is designed to be very generic, and has a bunch of very wonderful features.  Among them is a simulated UART decoder that can be used from within Verilator .  Should you wish to use it, you should be able to test your UART code (above) in a context that won't be struggling from bounce issues.  You might struggle to test the button press in that same simulated environment ... but that's a separate issue.  :P

Dan

Share this post


Link to post
Share on other sites
  • 0
On 1/2/2017 at 10:42 PM, Alex said:

@hamster Finally, I have finished this project and put everything at instructables. I separate TX and RX into two parts

Part I: http://www.instructables.com/id/UART-Communication-on-Basys-3-FPGA-Dev-Board-Power/

Part II: http://www.instructables.com/id/UART-Communication-on-Basys-3-FPGA-Dev-Board-Power-1/

Note: Somehow, even though I used the debounced button module in the Part I, it still has debouncing issue. I found out the potential root cause is due to the prolong "transmit" signal. No matter how I modify the debounce module, I still can't change the period of transmit signal. Anyway, I hope to move on to another project. Feel free to give some inputs.

Thanks for the help.

I don't know if you are aware of this, but your Tx and Rx clocks need to be 16 times the baud rate. The receiver uses the baud rate clock to sync on the start bit of the received character. For 9600 baud and a 100Mhz clock, you baud rate divisor should be 651. I don't know if this matters since you are using the USB UART.

Share this post


Link to post
Share on other sites
  • 0

@Alex,

That's a good discussion you linked to, thank you for it.

Judging by the explanation on stackexchange, one only needs the rate divisor to be larger than 16, hence the fastest baud rate one might use would be 100MHz/16 or 6.25MHz.  I know I've been quite successful with my Basys3 at 4 MBaud and a clock divisor of 25, so ... we're still well within reasonable here.  I'm not sure if the FTDI provided UART will go much faster ... as I recall, 4MBaud was the fastest my Linux distro supported without hardware specific rate adjustments.

Dan

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