Alexwonglik
Newbie level 5

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
Receiver
Top module instantiation
Constraint
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]