Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Problems in UART Communication using Nexys 3 board

Status
Not open for further replies.

BojackHorseman

Newbie level 6
Joined
Oct 7, 2022
Messages
13
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
91
I am trying to send a 1 byte of data from my Nexys 3 board to my PC using UART communication. But the problem is whenever I try to view the data on Real Term no matter my input(hard coded into the code or given via switches) the transmitted data always shows 0. I checked by simulating the entire thing but there, the code was working as expected.

Can someone help me in solving this bug.

Code:
Code:

`timescale 1ns / 1ps

module top( input sys_clk,
input sys_rst,
input [7:0] c,
output tx_done,
output uart_tx

    );
wire [7:0] w_c;
assign w_c = c;

reg [31:0] counter;
reg tx_wr1;
wire w_tx_wr;
assign w_tx_wr = tx_wr1;




uart_tx tx(
.sys_clk(sys_clk),
.sys_rst(sys_rst),
.tx_data(w_c),
.tx_wr(w_tx_wr),
.tx_done(tx_done),
.uart_tx(uart_tx)
);

always @(posedge sys_clk) begin
if(sys_rst == 0 ) begin
    counter <= 32'd0;
    tx_wr1<= 1'd0;
end
else begin

    counter <= counter + 32'd1;
        if (counter == 2) begin
        tx_wr1 <= 1'd1;
        end
        else tx_wr1 <= 1'd0;
end
end

endmodule

////////////////////////////////////////////////////////////////////////////////////


module uart_tx(
    input sys_rst,
    input sys_clk,


    output reg uart_tx,




    input [7:0] tx_data,
    input tx_wr,
    output reg tx_done
);

//-----------------------------------------------------------------
// enable16 generator
//-----------------------------------------------------------------
reg [15:0] enable16_counter;
reg [15:0] divisor;
parameter [15:0] BAUD = 16'd651;

wire enable16;
assign enable16 = (enable16_counter == 16'd0);

always @(posedge sys_clk)
begin
    if(sys_rst==0) begin
        enable16_counter <= divisor - 16'b1;
        divisor <= BAUD;
    end
    else begin
        enable16_counter <= enable16_counter - 16'd1;
        if(enable16)
            enable16_counter <= divisor - 16'b1;
         end
end


//-----------------------------------------------------------------
// UART TX Logic
//-----------------------------------------------------------------
reg tx_busy;
reg [3:0] tx_bitcount;
reg [3:0] tx_count16;
reg [7:0] tx_reg;

always @(posedge sys_clk) begin
    if(sys_rst==0) begin
        tx_done <= 1'b0;
        tx_busy <= 1'b0;
        uart_tx <= 1'b1;
    end else begin
        tx_done <= 1'b0;
        if(tx_wr) begin
            tx_reg <= tx_data;
            tx_bitcount <= 4'd0;
            tx_count16 <= 4'd1;
            tx_busy <= 1'b1;
            uart_tx <= 1'b0;
`ifdef SIMULATION
            $display("UART: %c", tx_data);
`endif
        end else if(enable16 && tx_busy) begin
            tx_count16  <= tx_count16 + 4'd1;

            if(tx_count16 == 4'd0) begin
                tx_bitcount <= tx_bitcount + 4'd1;
                
                if(tx_bitcount == 4'd8) begin
                    uart_tx <= 1'b1;
                end else if(tx_bitcount == 4'd9) begin
                    uart_tx <= 1'b1;
                    tx_busy <= 1'b0;
                    tx_done <= 1'b1;
                    $display("Transmission done");
                end else begin
                    uart_tx <= tx_reg[0];
                    tx_reg <= {1'b0, tx_reg[7:1]};
                end
            end
        end
    end
end

endmodule

////////////////////////TestBench///////////////////////////////////////////////////

`timescale 1ns / 1ps

////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date:   23:30:56 01/03/2023
// Design Name:   top
// Module Name:   D:/testb/simu.v
// Project Name:  testb
// Target Device: 
// Tool versions: 
// Description:
//
// Verilog Test Fixture created by ISE for module: top
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
////////////////////////////////////////////////////////////////////////////////

module simu;

    // Inputs
    reg sys_clk;
    reg sys_rst;
    reg [7:0] c;

    // Outputs
    wire tx_done;
    wire uart_tx;

    // Instantiate the Unit Under Test (UUT)
    top uut (
        .sys_clk(sys_clk),
        .sys_rst(sys_rst),
        .c(c),
        .tx_done(tx_done),
        .uart_tx(uart_tx)
    );

    initial begin
        // Initialize Inputs
        sys_clk = 0;
        sys_rst = 0;
        c = 0;
        // Wait 100 ns for global reset to finish
        #100 sys_rst = 1;
       c = 10 ;
        // Add stimulus here
 
    end
     always #5 sys_clk = ~sys_clk;
endmodule

Simulation Output:


1672772833369.png

tx_done indicates that the transmission of 1 byte has been done successfully

1672772856307.png

Output as shown on the RealTerm window. No matter the input, the transmitted value remains the same

Can someone help me as to why this is happening ?
 

The code is most certainly NOT working as expected in simulation, unless you're expecting no data.

All I see is your uart_tx is always high. I'd expect to see you receive NO data.
 

uart_tx is transmitting as expected and it was actually cutoff while taking the screenshot
Well, then, that’s a pretty useless post.

But, you mean to say that that tx_done doesn’t occur until (at least) 8 clocks after the data has actually been shifted out? That doesn’t sound like a very good design.
 

Well we are designing it for only sending 1 byte as of data now. Also the code for UART Tx-Rx was given to us directly by our prof who is also using the same code

Also is there a way to generate the tx_wr one pulse again once tx_done has gone high ?

uart_tx is working only in simulations. Not during actual implementation
 

Attachments

  • Attachment.txt
    6.7 KB · Views: 102

As stated, to convince us that the simulation is working, please show the transmission of a complete character frame between start to stop bit. You can also check for correct baud rate. If you don't manage this simple task, why should anybody start to look int the code?
 

@BojackHorseman

I see that the input sys_rst is always HIGH in the SS.

So if my assumption is true that your design has a active high reset, then it will not do anything. Or else as mentioned by others, show us the part of the screenshot where sys_rst is LOW and the UART bits are being transmitted.
 

Hi,

if the PC really receives 0 (0x00) then at least the start bit needs to be sent.
I can´t verify this.

Klaus
 

So, your system reset is active low. It would be a good idea to indicate that in the signal name, like sys_rst_n.

Why do you refuse to show us the whole story? We don't see what's happening prior to the start of transmission. From your post, it looks like the input data is 10 (hex? decimal?), but your output is 0x0A.

Again, maybe your baud rate is set incorrectly. Maybe you've got a broken wire. Maybe it's wired incorrectly. Have you looked at your transmitted data with an oscilloscope?
 

1. The data given is decimal value 10. So the output - at least in the simulations - corroborate the given input.
2. We checked the baud rate multiple times - the calculation done to get the value, baud rate selected on the RealTerm software - and we didn't find any discrepancies there.
3. The cables used for transferring are working fine because we cross checked the cables multiple times. Since we currently don't have an access to oscilloscope, we tried giving the uart_tx value to an onboard LED - after reducing the Baud rate to 1 so that we can see the changes in the LED - but the LED didn't blink at all.

Instead of using a separate counter to generate a pulse of tx_wr, as if(tx_busy == 0) tx_wr == 1 and if(tx_busy == 1) tx_wr == 0. For this too the simulation output obtained was as shown in the above simulation window screenshot. But when tried it on the hardware, the problem persisted.
 

Hi,

so basically you say there is everything correct.
But ask us for help.

I agree with Barry: Give us the whole story so we can validate the informations.
For example: do you have a properly working RS232 transmitter, with correct voltage levels? Scope-picture of it?


Klaus
 

What I mean to say is, everything is working in simulations but not when it is implemented on my Nexys 3 board. Nexys 3 board already has a microusb port on the board itself for UART communication. So all we have to do is connect the USB to microusb cable and assign assign that port as the output (J13). So where I need help is figuring out why the actual implementation is not working properly when all the simulations for the same are (is there something in the code due to which even though the simulations work, but while implementing it on the hardware problems arise ? ).
 

Hi,

again: give us informations we can validate.
Otherwise debugging is just guessing.

Klaus
 

As in what information ? All the information that I have are already mentioned in this thread and my question.
 

Hi,

I even gave an example.
Schematic, full timing simulation, more detailed simulation, scope pictures.....

Good luck. I leave.

Klaus
 

What I mean to say is, everything is working in simulations but not when it is implemented on my Nexys 3 board.
What is the best possible way to test your UART in simulation?

Let the test-bench inject 8 bits in to your design and let your rx side accumulate these 8 bits. Send out again the SAME 8 bits from your UART via the tx line to the test-bench. Verify in the test-bench if the same 8 bits are received.

If you can prove the above to me only then am I convinced that your design is working correctly.
 

I see that the simulation is basically working, transmission starts however immediately after reset and is repeated every 42 sec, both not useful.

Questions arise about design integration to Nexys3 board. I presume it uses 100 MHz clock, so 9600 baud are correctly generated. How is sysreset connected, how is transmission triggered, is TxD connected correctly?
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top