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.

Transfer the ASCII Value to Digilent Basys 3 FPGA board

Status
Not open for further replies.

Alexwonglik

Newbie level 5
Joined
Feb 15, 2015
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
59
Hi, I want to learn how to use communicate the FPGA with RS232, so I tried to create a project - whenever I hit the keystroke, the 8 bits LED will show the ASCII value. The hardware I used are Basys 3 and Pmod RS232. I can successfully generate the bit file and load that to Digilent Basys 3. However, it isn't implemented correct. Here are verilog codes and constraint file. It will be great if you can provide some hints. Or, let me know what mistake I have.

Transmitter
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 
    );
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 TxD 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
             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
Code:
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
    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 instantiation
Code:
module top(
input [1:0] btn,
input clk,
input RxD,
output TxD,
output [7:0]LED // output 8 LEDs

    );
reg [7:0] data;
receiver R1 (.clk(clk), .reset(btn[0]), .RxD(RxD), .RxData(LED));
transmitter T1 (.clk(clk),.transmit(btn[1]), .reset(btn[0]),.data(data), .TxD(TxD));

endmodule

Constraint
Code:
set_property PACKAGE_PIN W5 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
create_clock -period 10.000 -name sys_clk_pin -waveform {0.000 5.000} -add [get_ports clk]set_property PACKAGE_PIN U16 [get_ports {LED[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[0]}]
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 U18 [get_ports {btn[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {btn[1]}]
set_property PACKAGE_PIN T18 [get_ports {btn[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {btn[0]}]
set_property PACKAGE_PIN J2 [get_ports TxD]
set_property IOSTANDARD LVCMOS33 [get_ports TxD]
set_property PACKAGE_PIN G2 [get_ports RxD]
set_property IOSTANDARD LVCMOS33 [get_ports RxD]
 

You shouldn't be using a button to control an input to the reset logic of your code. A button will "bounce" and you won't have a clean reset. You need to debounce the reset lines (button inputs) and then synchronize the release of the reset to the clock.

Have you checked the reports to make sure that something isn't getting removed? Also have you verified the pinouts match the board?
 

Hi, thanks for the reminder. Actually, I got the following warnings in the synthesis at the top module. It is about the transmitter module instantiation. I wonder what port I should connect to "data" input in the transmitter. Physically, I want the ASCII value of the keystrobe can be shown in LEDs of the board. Any suggestion?
[Synth 8-3848] Net data in module/entity top does not have driver. ["C:/PmodRS232_Basys3/PmodRS232_Basys3.srcs/sources_1/new/top.v":31]

[Synth 8-3295] tying undriven pin T1:data[7] to constant 0 ["C:/PmodRS232_Basys3/PmodRS232_Basys3.srcs/sources_1/new/top.v":33]

[Synth 8-3295] tying undriven pin T1:data[6] to constant 0 ["C:/PmodRS232_Basys3/PmodRS232_Basys3.srcs/sources_1/new/top.v":33]

[Synth 8-3295] tying undriven pin T1:data[5] to constant 0 ["C:/PmodRS232_Basys3/PmodRS232_Basys3.srcs/sources_1/new/top.v":33]

[Synth 8-3295] tying undriven pin T1:data[4] to constant 0 ["C:/PmodRS232_Basys3/PmodRS232_Basys3.srcs/sources_1/new/top.v":33]

[Synth 8-3295] tying undriven pin T1:data[3] to constant 0 ["C:/PmodRS232_Basys3/PmodRS232_Basys3.srcs/sources_1/new/top.v":33]

[Synth 8-3295] tying undriven pin T1:data[2] to constant 0 ["C:/PmodRS232_Basys3/PmodRS232_Basys3.srcs/sources_1/new/top.v":33]

[Synth 8-3295] tying undriven pin T1:data[1] to constant 0 ["C:/PmodRS232_Basys3/PmodRS232_Basys3.srcs/sources_1/new/top.v":33]

[Synth 8-3295] tying undriven pin T1:data[0] to constant 0 ["C:/PmodRS232_Basys3/PmodRS232_Basys3.srcs/sources_1/new/top.v":33]

[Synth 8-327] inferring latch for variable 'nextstate_reg' ["C:/PmodRS232_Basys3/PmodRS232_Basys3.srcs/sources_1/new/receiver.v":75]

[Synth 8-327] inferring latch for variable 'TxD_reg' ["C:/PmodRS232_Basys3/PmodRS232_Basys3.srcs/sources_1/new/transmitter.v":89]

[Synth 8-3332] Sequential element (\R1/rxshiftreg_reg[0] ) is unused and will be removed from module top.

[Synth 8-3332] Sequential element (\R1/samplecounter_reg[3] ) is unused and will be removed from module top.

[Synth 8-3332] Sequential element (\R1/samplecounter_reg[2] ) is unused and will be removed from module top.
 
Last edited by a moderator:

It is about the transmitter module instantiation. I wonder what port I should connect to "data" input in the transmitter. Physically, I want the ASCII value of the keystrobe can be shown in LEDs of the board. Any suggestion?
This statement seems to mean you don't transmit anything back to the PC? You might want to use it to "echo" the RX back to the PC.

[Synth 8-3848] Net data in module/entity top does not have driver. ["C:/PmodRS232_Basys3/PmodRS232_Basys3.srcs/sources_1/new/top.v":31]
[Synth 8-3295] tying undriven pin T1:data[7] to constant 0 ["C:/PmodRS232_Basys3/PmodRS232_Basys3.srcs/sources_1/new/top.v":33]
[Synth 8-3295] tying undriven pin T1:data[6] to constant 0 ["C:/PmodRS232_Basys3/PmodRS232_Basys3.srcs/sources_1/new/top.v":33]
[Synth 8-3295] tying undriven pin T1:data[5] to constant 0 ["C:/PmodRS232_Basys3/PmodRS232_Basys3.srcs/sources_1/new/top.v":33]
[Synth 8-3295] tying undriven pin T1:data[4] to constant 0 ["C:/PmodRS232_Basys3/PmodRS232_Basys3.srcs/sources_1/new/top.v":33]
[Synth 8-3295] tying undriven pin T1:data[3] to constant 0 ["C:/PmodRS232_Basys3/PmodRS232_Basys3.srcs/sources_1/new/top.v":33]
[Synth 8-3295] tying undriven pin T1:data[2] to constant 0 ["C:/PmodRS232_Basys3/PmodRS232_Basys3.srcs/sources_1/new/top.v":33]
[Synth 8-3295] tying undriven pin T1:data[1] to constant 0 ["C:/PmodRS232_Basys3/PmodRS232_Basys3.srcs/sources_1/new/top.v":33]
[Synth 8-3295] tying undriven pin T1:data[0] to constant 0 ["C:/PmodRS232_Basys3/PmodRS232_Basys3.srcs/sources_1/new/top.v":33]
These are expected and synthesis or PaR probably removed all the logic for the transmit side.

[Synth 8-327] inferring latch for variable 'nextstate_reg' ["C:/PmodRS232_Basys3/PmodRS232_Basys3.srcs/sources_1/new/receiver.v":75]
[Synth 8-327] inferring latch for variable 'TxD_reg' ["C:/PmodRS232_Basys3/PmodRS232_Basys3.srcs/sources_1/new/transmitter.v":89]
Bad, bad, bad, bad design. You never want latches in an FPGA. This is the big flaw with separating your FSM into clocked and combinational logic. It's better to have the entire FSM in a single clocked block.
In this case you are missing assignments in all the branches of your code. It's really hard to see that due to your coding style. The transmit would have had the same issue if it wasn't for the fact it likely got removed due the constant 0 applied to data.
 

Thanks for the guide. I have revised the design.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top