USB Communication (RS232)
The USB 2.0 capabilities are provided by the FT232RL, which is an USB to UART converter IC. So we just have to write some verilog to create an UART module to interface with the FT232RL for USB communication
.
The verilog consists of 3 modules: baud_generator, uartrx and uarttx.


The verilog consists of 3 modules: baud_generator, uartrx and uarttx.
Baud Rate Generator
The baud_generator module generats (as expected) the baud clock. It has a parameter for ClkFrequency input and the required baud rate.C: Baud rate generator
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| module baud_generator(clk, BaudTick); // Port declarations input clk; // Clock input output BaudTick; // Baud clock output // Parameters parameter ClkFrequency = 50000000; // 50MHz for Bluebird board parameter Baud = 115200; // Baudrate parameter BaudGeneratorInc = ((Baud<<12)+(ClkFrequency>>5))/(ClkFrequency>>4); // Internal Variables reg [16:0] BaudGeneratorAcc; // Accumulator always @(posedge clk) BaudGeneratorAcc <= BaudGeneratorAcc[15:0] + BaudGeneratorInc; // Clock generator wire BaudTick = BaudGeneratorAcc[16]; endmodule |
Transmitter
The transmitter transmits the data from tx_data on the tx pin. Once data is available on the tx_data port, you have to strobe the ld_tx_data for it to start sending the data. After strobing, the data on the tx_data port may be changed directly (it is buffered internally). The tx_empty pin will go high as soon as transmitting is completed. The code is only capable of sending 8 bits, no parity, and one stopbit.C: Transmitter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
| module uarttx (txclk,tx_data,ld_tx_data,tx_out,tx_empty); // Port declarations input txclk; // Baud Rate Clock input ld_tx_data; // Load data's data from tx_data input [7:0] tx_data; // Transmitting data output tx_out; // Output output tx_empty; // Busy flag // Internal Variables reg [7:0] tx_reg; reg tx_empty; reg [3:0] tx_cnt; reg tx_out; // Initial value's initial tx_empty = 1; // not busy initial tx_out = 1; // idle UART level is high // UART TX logic always @ (posedge txclk) begin if (!ld_tx_data) begin tx_reg <= tx_data; // Load data into transmitting register tx_empty <= 0; tx_cnt <= 8; end if (!tx_empty) begin tx_cnt <= tx_cnt - 1; // LSB first if (tx_cnt == 8) begin tx_out <= 0; end else if (tx_cnt < 8) begin tx_out <= tx_reg[7-tx_cnt]; // Output bit end else // Done transmitting byte begin tx_out <= 1; tx_empty <= 1; end end end endmodule |
Receiver
The receiver receives the UART data from pin rx. Once data is available the rx_empty pin will go low. Strobing the uld_rx_data pin will cause it to unload to the rx_data port, where it is buffered. The receiver is only capable of receiving 8 bits, no parity, and one stopbit.C: Receiver
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
| module uartrx (rxclk,uld_rx_data,rx_data,rx_in,rx_empty); // Port declarations input rxclk; // Baude Rate Clock input uld_rx_data; // Unloads data from rx_data output [7:0] rx_data; // Received data input rx_in; // Input output rx_empty; // Busy flag // Internal Variables reg [7:0] rx_reg; reg [7:0] rx_data; reg [3:0] rx_cnt; reg rx_empty; reg rx_d1; reg rx_d2; reg rx_busy; // Initial value's initial rx_empty = 1; initial rx_busy = 0; // UART RX logic always @ (posedge rxclk) begin rx_d1 <= rx_in; // Sync data from rx tot rxclk rx_d2 <= rx_d1; if (!uld_rx_data) begin // Unload data rx_data <= rx_reg; rx_empty <= 1; end if (!rx_busy && !rx_d2) begin // Find starting bit rx_busy <= 1; rx_cnt <= 0; end if (rx_busy) begin if (rx_cnt < 8) begin rx_reg[rx_cnt] <= rx_d2; // Receive byte rx_cnt <= rx_cnt + 1; end else begin // Done ^_^ rx_busy <= 0; rx_empty <= 0; end end end endmodule |
Conclusion
The following verilog may be used to glue the 3 modules together. When compiled for speed, the above (and below) verilog code will use 69 LE's.C: RS232 peripheral
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| module RS232(clk, uld, rx, ld, tx_data, tx, rx_empty, tx_empty, rx_data); input clk; // Clock input (50 MHz) input uld; // Unload RX data input rx; // RX data stream input input ld; // Load TX data input [7:0] tx_data; // TX data input output tx; // TX stream output output rx_empty; // RX buffer flag output tx_empty; // TX buffer flag output [7:0] rx_data; // RX data output uartrx(baud_tick, uld, rx_data, rx, rx_empty); uarttx(baud_tick, tx_data, ld, tx, tx_empty); baud_generator(clk, baud_tick); endmodule |
02-'10 PS/2 Keyboard Communication
02-'10 SRAM controller
Comments
hye there,
may i ask u, what is BaudGeneratorInc used for?
thank you
may i ask u, what is BaudGeneratorInc used for?
thank you
BaudGeneratorInc is the number with which BaudGeneratorAcc increments every clock cycle. This number is calculates so that the frequency of BaudGeneratorAcc[16] equals the desired baudratehye there,
may i ask u, what is BaudGeneratorInc used for?
thank you
Good Afternoon,
Respected sir,
can u plz explain in brief each statement u wrote on your baud_generator module.?
Thank You.
Respected sir,
can u plz explain in brief each statement u wrote on your baud_generator module.?
Thank You.
Similar code is explained in detail in fpga4fun website including the baud_generator.
Good luck!
-Susantha
Good luck!
-Susantha
Comments are closed