uart/ 0000755 0001750 0001750 00000000000 11411201677 012215 5 ustar lekernel lekernel uart/rtl/ 0000755 0001750 0001750 00000000000 11411201677 013016 5 ustar lekernel lekernel uart/rtl/uart_transceiver.v 0000644 0001750 0001750 00000007336 11411201677 016576 0 ustar lekernel lekernel /*
|
uart/ 0000755 0001750 0001750 00000000000 11411201677 012215 5 ustar lekernel lekernel uart/rtl/ 0000755 0001750 0001750 00000000000 11411201677 013016 5 ustar lekernel lekernel uart/rtl/uart_transceiver.v 0000644 0001750 0001750 00000007310 11434747236 016601 0 ustar lekernel lekernel /*
|
* Milkymist VJ SoC
|
* Milkymist VJ SoC
|
* Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
|
* Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
|
* Copyright (C) 2007 Das Labor
|
* Copyright (C) 2007 Das Labor
|
*
|
*
|
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
* the Free Software Foundation, version 3 of the License.
|
* the Free Software Foundation, version 3 of the License.
|
*
|
*
|
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
*
|
*
|
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
* along with this program. If not, see .
|
* along with this program. If not, see .
|
*/
|
*/
|
|
|
module uart_transceiver(
|
module uart_transceiver(
|
input sys_rst,
|
input sys_rst,
|
input sys_clk,
|
input sys_clk,
|
|
|
input uart_rxd,
|
input uart_rx,
|
output reg uart_txd,
|
output reg uart_tx,
|
|
|
input [15:0] divisor,
|
input [15:0] divisor,
|
|
|
output reg [7:0] rx_data,
|
output reg [7:0] rx_data,
|
output reg rx_done,
|
output reg rx_done,
|
|
|
input [7:0] tx_data,
|
input [7:0] tx_data,
|
input tx_wr,
|
input tx_wr,
|
output reg tx_done
|
output reg tx_done
|
);
|
);
|
|
|
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
// enable16 generator
|
// enable16 generator
|
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
reg [15:0] enable16_counter;
|
reg [15:0] enable16_counter;
|
|
|
wire enable16;
|
wire enable16;
|
assign enable16 = (enable16_counter == 16'd0);
|
assign enable16 = (enable16_counter == 16'd0);
|
|
|
always @(posedge sys_clk) begin
|
always @(posedge sys_clk) begin
|
if(sys_rst)
|
if(sys_rst)
|
enable16_counter <= divisor - 16'b1;
|
enable16_counter <= divisor - 16'b1;
|
else begin
|
else begin
|
enable16_counter <= enable16_counter - 16'd1;
|
enable16_counter <= enable16_counter - 16'd1;
|
if(enable16)
|
if(enable16)
|
enable16_counter <= divisor - 16'b1;
|
enable16_counter <= divisor - 16'b1;
|
end
|
end
|
end
|
end
|
|
|
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
// Synchronize uart_rxd
|
// Synchronize uart_rx
|
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
reg uart_rxd1;
|
reg uart_rx1;
|
reg uart_rxd2;
|
reg uart_rx2;
|
|
|
always @(posedge sys_clk) begin
|
always @(posedge sys_clk) begin
|
uart_rxd1 <= uart_rxd;
|
uart_rx1 <= uart_rx;
|
uart_rxd2 <= uart_rxd1;
|
uart_rx2 <= uart_rx1;
|
end
|
end
|
|
|
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
// UART RX Logic
|
// UART RX Logic
|
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
reg rx_busy;
|
reg rx_busy;
|
reg [3:0] rx_count16;
|
reg [3:0] rx_count16;
|
reg [3:0] rx_bitcount;
|
reg [3:0] rx_bitcount;
|
reg [7:0] rxd_reg;
|
reg [7:0] rx_reg;
|
|
|
always @(posedge sys_clk) begin
|
always @(posedge sys_clk) begin
|
if(sys_rst) begin
|
if(sys_rst) begin
|
rx_done <= 1'b0;
|
rx_done <= 1'b0;
|
rx_busy <= 1'b0;
|
rx_busy <= 1'b0;
|
rx_count16 <= 4'd0;
|
rx_count16 <= 4'd0;
|
rx_bitcount <= 4'd0;
|
rx_bitcount <= 4'd0;
|
end else begin
|
end else begin
|
rx_done <= 1'b0;
|
rx_done <= 1'b0;
|
|
|
if(enable16) begin
|
if(enable16) begin
|
if(~rx_busy) begin // look for start bit
|
if(~rx_busy) begin // look for start bit
|
if(~uart_rxd2) begin // start bit found
|
if(~uart_rx2) begin // start bit found
|
rx_busy <= 1'b1;
|
rx_busy <= 1'b1;
|
rx_count16 <= 4'd7;
|
rx_count16 <= 4'd7;
|
rx_bitcount <= 4'd0;
|
rx_bitcount <= 4'd0;
|
end
|
end
|
end else begin
|
end else begin
|
rx_count16 <= rx_count16 + 4'd1;
|
rx_count16 <= rx_count16 + 4'd1;
|
|
|
if(rx_count16 == 4'd0) begin // sample
|
if(rx_count16 == 4'd0) begin // sample
|
rx_bitcount <= rx_bitcount + 4'd1;
|
rx_bitcount <= rx_bitcount + 4'd1;
|
|
|
if(rx_bitcount == 4'd0) begin // verify startbit
|
if(rx_bitcount == 4'd0) begin // verify startbit
|
if(uart_rxd2)
|
if(uart_rx2)
|
rx_busy <= 1'b0;
|
rx_busy <= 1'b0;
|
end else if(rx_bitcount == 4'd9) begin
|
end else if(rx_bitcount == 4'd9) begin
|
rx_busy <= 1'b0;
|
rx_busy <= 1'b0;
|
if(uart_rxd2) begin // stop bit ok
|
if(uart_rx2) begin // stop bit ok
|
rx_data <= rxd_reg;
|
rx_data <= rx_reg;
|
rx_done <= 1'b1;
|
rx_done <= 1'b1;
|
end // ignore RX error
|
end // ignore RX error
|
end else
|
end else
|
rxd_reg <= {uart_rxd2, rxd_reg[7:1]};
|
rx_reg <= {uart_rx2, rx_reg[7:1]};
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
|
|
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
// UART TX Logic
|
// UART TX Logic
|
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
reg tx_busy;
|
reg tx_busy;
|
reg [3:0] tx_bitcount;
|
reg [3:0] tx_bitcount;
|
reg [3:0] tx_count16;
|
reg [3:0] tx_count16;
|
reg [7:0] txd_reg;
|
reg [7:0] tx_reg;
|
|
|
always @(posedge sys_clk) begin
|
always @(posedge sys_clk) begin
|
if(sys_rst) begin
|
if(sys_rst) begin
|
tx_done <= 1'b0;
|
tx_done <= 1'b0;
|
tx_busy <= 1'b0;
|
tx_busy <= 1'b0;
|
uart_txd <= 1'b1;
|
uart_tx <= 1'b1;
|
end else begin
|
end else begin
|
tx_done <= 1'b0;
|
tx_done <= 1'b0;
|
if(tx_wr) begin
|
if(tx_wr) begin
|
txd_reg <= tx_data;
|
tx_reg <= tx_data;
|
tx_bitcount <= 4'd0;
|
tx_bitcount <= 4'd0;
|
tx_count16 <= 4'd1;
|
tx_count16 <= 4'd1;
|
tx_busy <= 1'b1;
|
tx_busy <= 1'b1;
|
uart_txd <= 1'b0;
|
uart_tx <= 1'b0;
|
`ifdef SIMULATION
|
`ifdef SIMULATION
|
$display("UART: %c", tx_data);
|
$display("UART: %c", tx_data);
|
`endif
|
`endif
|
end else if(enable16 && tx_busy) begin
|
end else if(enable16 && tx_busy) begin
|
tx_count16 <= tx_count16 + 4'd1;
|
tx_count16 <= tx_count16 + 4'd1;
|
|
|
if(tx_count16 == 4'd0) begin
|
if(tx_count16 == 4'd0) begin
|
tx_bitcount <= tx_bitcount + 4'd1;
|
tx_bitcount <= tx_bitcount + 4'd1;
|
|
|
if(tx_bitcount == 4'd8) begin
|
if(tx_bitcount == 4'd8) begin
|
uart_txd <= 1'b1;
|
uart_tx <= 1'b1;
|
end else if(tx_bitcount == 4'd9) begin
|
end else if(tx_bitcount == 4'd9) begin
|
uart_txd <= 1'b1;
|
uart_tx <= 1'b1;
|
tx_busy <= 1'b0;
|
tx_busy <= 1'b0;
|
tx_done <= 1'b1;
|
tx_done <= 1'b1;
|
end else begin
|
end else begin
|
uart_txd <= txd_reg[0];
|
uart_tx <= tx_reg[0];
|
txd_reg <= {1'b0, txd_reg[7:1]};
|
tx_reg <= {1'b0, tx_reg[7:1]};
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
|
|
endmodule
|
endmodule
|
|