OpenCores
URL https://opencores.org/ocsvn/wbuart32/wbuart32/trunk

Subversion Repositories wbuart32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /wbuart32/trunk/rtl
    from Rev 14 to Rev 15
    Reverse comparison

Rev 14 → Rev 15

/Makefile
49,15 → 49,25
test: $(VDIRFB)/Vtxuart__ALL.a
test: $(VDIRFB)/Vrxuart__ALL.a
test: $(VDIRFB)/Vwbuart__ALL.a
test: $(VDIRFB)/Vtxuartlite__ALL.a
test: $(VDIRFB)/Vrxuartlite__ALL.a
 
$(VDIRFB)/Vrxuart__ALL.a: $(VDIRFB)/Vrxuart.h $(VDIRFB)/Vrxuart.cpp
$(VDIRFB)/Vrxuart__ALL.a: $(VDIRFB)/Vrxuart.mk
$(VDIRFB)/Vrxuart.h $(VDIRFB)/Vrxuart.cpp $(VDIRFB)/Vrxuart.mk: rxuart.v
 
$(VDIRFB)/Vrxuartlite__ALL.a: $(VDIRFB)/Vrxuartlite.h $(VDIRFB)/Vrxuartlite.cpp
$(VDIRFB)/Vrxuartlite__ALL.a: $(VDIRFB)/Vrxuartlite.mk
$(VDIRFB)/Vrxuartlite.h $(VDIRFB)/Vrxuartlite.cpp $(VDIRFB)/Vrxuartlite.mk: rxuartlite.v
 
$(VDIRFB)/Vtxuart__ALL.a: $(VDIRFB)/Vtxuart.h $(VDIRFB)/Vtxuart.cpp
$(VDIRFB)/Vtxuart__ALL.a: $(VDIRFB)/Vtxuart.mk
$(VDIRFB)/Vtxuart.h $(VDIRFB)/Vtxuart.cpp $(VDIRFB)/Vtxuart.mk: txuart.v
 
$(VDIRFB)/Vtxuartlite__ALL.a: $(VDIRFB)/Vtxuartlite.h $(VDIRFB)/Vtxuartlite.cpp
$(VDIRFB)/Vtxuartlite__ALL.a: $(VDIRFB)/Vtxuartlite.mk
$(VDIRFB)/Vtxuartlite.h $(VDIRFB)/Vtxuartlite.cpp $(VDIRFB)/Vtxuartlite.mk: txuartlite.v
 
$(VDIRFB)/Vwbuart__ALL.a: $(VDIRFB)/Vwbuart.h $(VDIRFB)/Vwbuart.cpp
$(VDIRFB)/Vwbuart__ALL.a: $(VDIRFB)/Vwbuart.mk
$(VDIRFB)/Vwbuart.h $(VDIRFB)/Vwbuart.cpp $(VDIRFB)/Vwbuart.mk: wbuart.v ufifo.v txuart.v rxuart.v
/rxuartlite.v
0,0 → 1,197
////////////////////////////////////////////////////////////////////////////////
//
// Filename: rxuartlite.v
//
// Project: wbuart32, a full featured UART with simulator
//
// Purpose: Receive and decode inputs from a single UART line.
//
//
// To interface with this module, connect it to your system clock,
// and a UART input. Set the parameter to the number of clocks per
// baud. When data becomes available, the o_wr line will be asserted
// for one clock cycle.
//
// This interface only handles 8N1 serial port communications. It does
// not handle the break, parity, or frame error conditions.
//
//
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
//
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015-2017, Gisselquist Technology, LLC
//
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program. (It's in the $(ROOT)/doc directory. Run make with no
// target there if the PDF file isn't present.) If not, see
// <http://www.gnu.org/licenses/> for a copy.
//
// License: GPL, v3, as defined and found on www.gnu.org,
// http://www.gnu.org/licenses/gpl.html
//
//
////////////////////////////////////////////////////////////////////////////////
//
//
`define RXU_BIT_ZERO 4'h0
`define RXU_BIT_ONE 4'h1
`define RXU_BIT_TWO 4'h2
`define RXU_BIT_THREE 4'h3
`define RXU_BIT_FOUR 4'h4
`define RXU_BIT_FIVE 4'h5
`define RXU_BIT_SIX 4'h6
`define RXU_BIT_SEVEN 4'h7
// `define RXU_PARITY 4'h8 // Unused in RXUARTLITE
`define RXU_STOP 4'h8
// `define RXU_SECOND_STOP 4'ha // Unused in RXUARTLITE
// Unused 4'hb
// Unused 4'hc
// `define RXU_BREAK 4'hd // Unused in RXUARTLITE
// `define RXU_RESET_IDLE 4'he // Unused in RXUARTLITE
`define RXU_IDLE 4'hf
 
module rxuartlite(i_clk, i_uart_rx, o_wr, o_data);
parameter [23:0] CLOCKS_PER_BAUD = 24'd868;
input i_clk;
input i_uart_rx;
output reg o_wr;
output reg [7:0] o_data;
 
 
wire [23:0] clocks_per_baud, half_baud;
reg [3:0] state;
 
assign half_baud = { 1'b0, CLOCKS_PER_BAUD[23:1] } - 24'h1;
reg [23:0] baud_counter;
reg zero_baud_counter;
 
 
// Since this is an asynchronous receiver, we need to register our
// input a couple of clocks over to avoid any problems with
// metastability. We do that here, and then ignore all but the
// ck_uart wire.
reg q_uart, qq_uart, ck_uart;
initial q_uart = 1'b0;
initial qq_uart = 1'b0;
initial ck_uart = 1'b0;
always @(posedge i_clk)
begin
q_uart <= i_uart_rx;
qq_uart <= q_uart;
ck_uart <= qq_uart;
end
 
// Keep track of the number of clocks since the last change.
//
// This is used to determine if we are in either a break or an idle
// condition, as discussed further below.
reg [23:0] chg_counter;
initial chg_counter = 24'h00;
always @(posedge i_clk)
if (qq_uart != ck_uart)
chg_counter <= 24'h00;
else
chg_counter <= chg_counter + 1;
 
// Are we in the middle of a baud iterval? Specifically, are we
// in the middle of a start bit? Set this to high if so. We'll use
// this within our state machine to transition out of the IDLE
// state.
reg half_baud_time;
initial half_baud_time = 0;
always @(posedge i_clk)
half_baud_time <= (~ck_uart)&&(chg_counter >= half_baud);
 
 
initial state = `RXU_IDLE;
always @(posedge i_clk)
begin
if (state == `RXU_IDLE)
begin // Idle state, independent of baud counter
// By default, just stay in the IDLE state
state <= `RXU_IDLE;
if ((~ck_uart)&&(half_baud_time))
// UNLESS: We are in the center of a valid
// start bit
state <= `RXU_BIT_ZERO;
end else if (zero_baud_counter)
begin
if (state < `RXU_STOP)
// Data arrives least significant bit first.
// By the time this is clocked in, it's what
// you'll have.
state <= state + 1;
else // Wait for the next character
state <= `RXU_IDLE;
end
end
 
// Data bit capture logic.
//
// This is drastically simplified from the state machine above, based
// upon: 1) it doesn't matter what it is until the end of a captured
// byte, and 2) the data register will flush itself of any invalid
// data in all other cases. Hence, let's keep it real simple.
reg [7:0] data_reg;
always @(posedge i_clk)
if (zero_baud_counter)
data_reg <= { ck_uart, data_reg[7:1] };
 
// Our data bit logic doesn't need nearly the complexity of all that
// work above. Indeed, we only need to know if we are at the end of
// a stop bit, in which case we copy the data_reg into our output
// data register, o_data, and tell others (for one clock) that data is
// available.
//
initial o_data = 8'h00;
reg pre_wr;
initial pre_wr = 1'b0;
always @(posedge i_clk)
if ((zero_baud_counter)&&(state == `RXU_STOP))
begin
o_wr <= 1'b1;
o_data <= data_reg;
end else
o_wr <= 1'b0;
 
// The baud counter
//
// This is used as a "clock divider" if you will, but the clock needs
// to be reset before any byte can be decoded. In all other respects,
// we set ourselves up for clocks_per_baud counts between baud
// intervals.
always @(posedge i_clk)
if ((zero_baud_counter)|||(state == `RXU_IDLE))
baud_counter <= CLOCKS_PER_BAUD-1'b1;
else
baud_counter <= baud_counter-1'b1;
 
// zero_baud_counter
//
// Rather than testing whether or not (baud_counter == 0) within our
// (already too complicated) state transition tables, we use
// zero_baud_counter to pre-charge that test on the clock
// before--cleaning up some otherwise difficult timing dependencies.
initial zero_baud_counter = 1'b0;
always @(posedge i_clk)
if (state == `RXU_IDLE)
zero_baud_counter <= 1'b0;
else
zero_baud_counter <= (baud_counter == 24'h01);
 
 
endmodule
 
 
/txuart.v
112,7 → 112,7
//
//
module txuart(i_clk, i_reset, i_setup, i_break, i_wr, i_data,
i_rts, o_uart_tx, o_busy);
i_cts_n, o_uart_tx, o_busy);
parameter [30:0] INITIAL_SETUP = 31'd868;
input i_clk, i_reset;
input [30:0] i_setup;
122,7 → 122,7
// Hardware flow control Ready-To-Send bit. Set this to one to use
// the core without flow control. (A more appropriate name would be
// the Ready-To-Receive bit ...)
input i_rts;
input i_cts_n;
// And the UART input line itself
output reg o_uart_tx;
// A line to tell others when we are ready to accept data. If
156,22 → 156,22
// Clock in the flow control data, two clocks to avoid metastability
// Default to using hardware flow control (uart_setup[30]==0 to use it).
// Set this high order bit off if you do not wish to use it.
reg q_rts, qq_rts, ck_rts;
// While we might wish to give initial values to q_rts and ck_rts,
reg q_cts_n, qq_cts_n, ck_cts;
// While we might wish to give initial values to q_rts and ck_cts,
// 1) it's not required since the transmitter starts in a long wait
// state, and 2) doing so will prevent the synthesizer from optimizing
// this pin in the case it is hard set to 1'b1 external to this
// peripheral.
//
// initial q_rts = 1'b0;
// initial qq_rts = 1'b0;
// initial ck_rts = 1'b0;
// initial q_cts_n = 1'b1;
// initial qq_cts_n = 1'b1;
// initial ck_cts = 1'b0;
always @(posedge i_clk)
q_rts <= i_rts;
q_cts_n <= i_cts_n;
always @(posedge i_clk)
qq_rts <= q_rts;
qq_cts_n <= q_cts_n;
always @(posedge i_clk)
ck_rts <= (qq_rts)||(!hw_flow_control);
ck_cts <= (!qq_cts_n)||(!hw_flow_control);
 
initial o_uart_tx = 1'b1;
initial r_busy = 1'b1;
208,7 → 208,7
2'b11: state <= `TXU_BIT_THREE;
endcase
end else begin // Stay in idle
r_busy <= !ck_rts;
r_busy <= !ck_cts;
end
end else begin
// One clock tick in each of these states ...
/txuartlite.v
0,0 → 1,206
////////////////////////////////////////////////////////////////////////////////
//
// Filename: txuartlite.v
//
// Project: wbuart32, a full featured UART with simulator
//
// Purpose: Transmit outputs over a single UART line. This particular UART
// implementation has been extremely simplified: it does not handle
// generating break conditions, nor does it handle anything other than the
// 8N1 (8 data bits, no parity, 1 stop bit) UART sub-protocol.
//
// To interface with this module, connect it to your system clock, and
// pass it the byte of data you wish to transmit. Strobe the i_wr line
// high for one cycle, and your data will be off. Wait until the 'o_busy'
// line is low before strobing the i_wr line again--this implementation
// has NO BUFFER, so strobing i_wr while the core is busy will just
// get ignored. The output will be placed on the o_txuart output line.
//
// (I often set both data and strobe on the same clock, and then just leave
// them set until the busy line is low. Then I move on to the next piece
// of data.)
//
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
//
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015-2017, Gisselquist Technology, LLC
//
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program. (It's in the $(ROOT)/doc directory. Run make with no
// target there if the PDF file isn't present.) If not, see
// <http://www.gnu.org/licenses/> for a copy.
//
// License: GPL, v3, as defined and found on www.gnu.org,
// http://www.gnu.org/licenses/gpl.html
//
//
////////////////////////////////////////////////////////////////////////////////
//
//
`define TXU_BIT_ZERO 4'h0
`define TXU_BIT_ONE 4'h1
`define TXU_BIT_TWO 4'h2
`define TXU_BIT_THREE 4'h3
`define TXU_BIT_FOUR 4'h4
`define TXU_BIT_FIVE 4'h5
`define TXU_BIT_SIX 4'h6
`define TXU_BIT_SEVEN 4'h7
`define TXU_STOP 4'h8
`define TXU_IDLE 4'hf
//
//
module txuartlite(i_clk, i_wr, i_data, o_uart_tx, o_busy);
parameter [23:0] CLOCKS_PER_BAUD = 24'd868;
input i_clk;
input i_wr;
input [7:0] i_data;
// And the UART input line itself
output reg o_uart_tx;
// A line to tell others when we are ready to accept data. If
// (i_wr)&&(!o_busy) is ever true, then the core has accepted a byte
// for transmission.
output wire o_busy;
 
reg [23:0] baud_counter;
reg [3:0] state;
reg [7:0] lcl_data;
reg r_busy, zero_baud_counter;
 
initial r_busy = 1'b1;
initial state = `TXU_IDLE;
initial lcl_data= 8'h0;
always @(posedge i_clk)
begin
if (!zero_baud_counter)
// r_busy needs to be set coming into here
r_busy <= 1'b1;
else if (state == `TXU_IDLE) // STATE_IDLE
begin
r_busy <= 1'b0;
if ((i_wr)&&(!r_busy))
begin // Immediately start us off with a start bit
r_busy <= 1'b1;
state <= `TXU_BIT_ZERO;
end
end else begin
// One clock tick in each of these states ...
r_busy <= 1'b1;
if (state <=`TXU_STOP) // start bit, 8-d bits, stop-b
state <= state + 1;
else
state <= `TXU_IDLE;
end
end
 
// o_busy
//
// This is a wire, designed to be true is we are ever busy above.
// originally, this was going to be true if we were ever not in the
// idle state. The logic has since become more complex, hence we have
// a register dedicated to this and just copy out that registers value.
assign o_busy = (r_busy);
 
 
// lcl_data
//
// This is our working copy of the i_data register which we use
// when transmitting. It is only of interest during transmit, and is
// allowed to be whatever at any other time. Hence, if r_busy isn't
// true, we can always set it. On the one clock where r_busy isn't
// true and i_wr is, we set it and r_busy is true thereafter.
// Then, on any zero_baud_counter (i.e. change between baud intervals)
// we simple logically shift the register right to grab the next bit.
initial lcl_data = 8'hff;
always @(posedge i_clk)
if ((i_wr)&&(!r_busy))
lcl_data <= i_data;
else if (zero_baud_counter)
lcl_data <= { 1'b1, lcl_data[7:1] };
 
// o_uart_tx
//
// This is the final result/output desired of this core. It's all
// centered about o_uart_tx. This is what finally needs to follow
// the UART protocol.
//
initial o_uart_tx = 1'b1;
always @(posedge i_clk)
if ((i_wr)&&(!r_busy))
o_uart_tx <= 1'b0; // Set the start bit on writes
else if (zero_baud_counter) // Set the data bit.
o_uart_tx <= lcl_data[0];
 
 
// All of the above logic is driven by the baud counter. Bits must last
// CLOCKS_PER_BAUD in length, and this baud counter is what we use to
// make certain of that.
//
// The basic logic is this: at the beginning of a bit interval, start
// the baud counter and set it to count CLOCKS_PER_BAUD. When it gets
// to zero, restart it.
//
// However, comparing a 28'bit number to zero can be rather complex--
// especially if we wish to do anything else on that same clock. For
// that reason, we create "zero_baud_counter". zero_baud_counter is
// nothing more than a flag that is true anytime baud_counter is zero.
// It's true when the logic (above) needs to step to the next bit.
// Simple enough?
//
// I wish we could stop there, but there are some other (ugly)
// conditions to deal with that offer exceptions to this basic logic.
//
// 1. When the user has commanded a BREAK across the line, we need to
// wait several baud intervals following the break before we start
// transmitting, to give any receiver a chance to recognize that we are
// out of the break condition, and to know that the next bit will be
// a stop bit.
//
// 2. A reset is similar to a break condition--on both we wait several
// baud intervals before allowing a start bit.
//
// 3. In the idle state, we stop our counter--so that upon a request
// to transmit when idle we can start transmitting immediately, rather
// than waiting for the end of the next (fictitious and arbitrary) baud
// interval.
//
// When (i_wr)&&(!r_busy)&&(state == `TXU_IDLE) then we're not only in
// the idle state, but we also just accepted a command to start writing
// the next word. At this point, the baud counter needs to be reset
// to the number of CLOCKS_PER_BAUD, and zero_baud_counter set to zero.
//
// The logic is a bit twisted here, in that it will only check for the
// above condition when zero_baud_counter is false--so as to make
// certain the STOP bit is complete.
initial zero_baud_counter = 1'b0;
initial baud_counter = 24'h05;
always @(posedge i_clk)
begin
zero_baud_counter <= (baud_counter == 24'h01);
if (state == `TXU_IDLE)
begin
baud_counter <= 24'h0;
zero_baud_counter <= 1'b1;
if ((i_wr)&&(!r_busy))
begin
baud_counter <= CLOCKS_PER_BAUD - 24'h01;
zero_baud_counter <= 1'b0;
end
end else if (!zero_baud_counter)
baud_counter <= baud_counter - 24'h01;
else
baud_counter <= CLOCKS_PER_BAUD - 24'h01;
end
endmodule
 
/wbuart-insert.v
86,16 → 86,16
if(((i_wb_stb)&&(!i_wb_we)&&(i_wb_addr == `UART_RX_ADDR))
||(rx_stb))
r_rx_data[8] <= !rx_stb;
assign o_cts = !r_rx_data[8];
assign o_rts_n = r_rx_data[8];
assign rx_data = { 20'h00, r_rx_data };
assign rx_int = !r_rx_data[8];
 
// Transmit hardware flow control, the rts line
wire rts;
// Set this rts value to one if you aren't ever going to use H/W flow
// Transmit hardware flow control, the cts line
wire cts_n;
// Set this cts value to zero if you aren't ever going to use H/W flow
// control, otherwise set it to the value coming in from the external
// i_rts pin.
assign rts = i_rts;
// i_cts_n pin.
assign cts_n = i_cts_n;
 
//
// Then the UART transmitter
109,7 → 109,7
wire [31:0] tx_data;
txuart #(UART_SETUP) tx(i_clk, 1'b0, uart_setup,
r_tx_break, r_tx_stb, r_tx_data,
rts, o_tx, tx_busy);
cts_n, o_tx, tx_busy);
always @(posedge i_clk)
if ((i_wb_stb)&&(i_wb_addr == 5'h0f))
begin
121,7 → 121,7
r_tx_stb <= 1'b0;
r_tx_data <= 8'h0;
end
assign tx_data = { 16'h00, rts, 3'h0,
assign tx_data = { 16'h00, cts_n, 3'h0,
ck_uart, o_tx, r_tx_break, tx_busy,
r_tx_data };
assign tx_int = ~tx_busy;
/wbuart.v
47,8 → 47,7
i_wb_cyc, i_wb_stb, i_wb_we, i_wb_addr, i_wb_data,
o_wb_ack, o_wb_stall, o_wb_data,
//
i_uart_rx, o_uart_tx, i_rts, o_cts,
// i_uart_rts, o_uart_cts, i_uart_dtr, o_uart_dts
i_uart_rx, o_uart_tx, i_cts_n, o_rts_n,
//
o_uart_rx_int, o_uart_tx_int,
o_uart_rxfifo_int, o_uart_txfifo_int);
77,13 → 76,13
// whether or not the receiving hardware is ready to accept another
// byte. If low, the transmitter will pause.
//
// If you don't wish to use hardware flow control, just set i_rts to
// 1'b1 and let the optimizer simply remove this logic.
input i_rts;
// If you don't wish to use hardware flow control, just set i_cts_n to
// 1'b0 and let the optimizer simply remove this logic.
input i_cts_n;
// CTS is the "Clear-to-send" signal. We set it anytime our FIFO
// isn't full. Feel free to ignore this output if you do not wish to
// use flow control.
output reg o_cts;
output reg o_rts_n;
output wire o_uart_rx_int, o_uart_tx_int,
o_uart_rxfifo_int, o_uart_txfifo_int;
 
120,15 → 119,25
 
// Here's our UART receiver. Basically, it accepts our setup wires,
// the UART input, a clock, and a reset line, and produces outputs:
// a stb (true when new data is ready), an 8-bit data out value
// valid when stb is high, a break value (true during a break cond.),
// and parity/framing error flags--also valid when stb is true.
// a stb (true when new data is ready), and an 8-bit data out value
// valid when stb is high.
`ifdef USE_LITE_UART
rxuartlite #(INITIAL_SETUP[23:0])
rx(i_clk, (i_rst), i_uart_rx, rx_stb, rx_uart_data);
assign rx_break = 1'b0;
assign rx_perr = 1'b0;
assign rx_ferr = 1'b0;
assign ck_uart = 1'b0;
`else
// The full receiver also produces a break value (true during a break
// cond.), and parity/framing error flags--also valid when stb is true.
rxuart #(INITIAL_SETUP) rx(i_clk, (i_rst)||(rx_uart_reset),
uart_setup, i_uart_rx,
rx_stb, rx_uart_data, rx_break,
rx_perr, rx_ferr, ck_uart);
// The real trick is ... now that we have this data, what do we do
// The real trick is ... now that we have this extra data, what do we do
// with it?
`endif
 
 
// We place it into a receiver FIFO.
170,12 → 179,10
// that if the transmit end starts sending we won't have a location to
// receive it. (Transmit might've started on the next character by the
// time we set this--need to set it to one character before necessary
// thus.)
wire [(LCLLGFLEN-1):0] check_cutoff;
assign check_cutoff = -3;
always @(posedge i_clk)
o_cts = (!HARDWARE_FLOW_CONTROL_PRESENT)
||(rxf_status[(LCLLGFLEN+1):2] > check_cutoff);
o_rts_n = ((HARDWARE_FLOW_CONTROL_PRESENT)
&&(!uart_setup[30])
&&(rxf_status[(LCLLGFLEN+1):4]=={(LCLLGFLEN-2){1'b1}}));
 
// If the bus requests that we read from the receive FIFO, we need to
// tell this to the receive FIFO. Note that because we are using a
250,10 → 257,10
//
//
/////////////////////////////////////////
wire tx_empty_n, txf_err;
wire tx_empty_n, txf_err, tx_break;
wire [7:0] tx_data;
wire [15:0] txf_status;
reg r_tx_break, txf_wb_write, tx_uart_reset;
reg txf_wb_write, tx_uart_reset;
reg [7:0] txf_wb_data;
 
// Unlike the receiver which goes from RXUART -> UFIFO -> WB, the
282,7 → 289,7
// and ... we just set the values (above) for controlling writing into
// this.
ufifo #(.LGFLEN(LGFLEN), .RXFIFO(0))
txfifo(i_clk, (r_tx_break)||(tx_uart_reset),
txfifo(i_clk, (tx_break)||(tx_uart_reset),
txf_wb_write, txf_wb_data,
tx_empty_n,
(!tx_busy)&&(tx_empty_n), tx_data,
296,6 → 303,7
// charged.
assign o_uart_txfifo_int = txf_status[1];
 
`ifndef USE_LITE_UART
// Break logic
//
// A break in a UART controller is any time the UART holds the line
304,6 → 312,7
// write unsigned characters to the interface, this will never be true
// unless you wish it to be true. Be aware, though, writing a valid
// value to the interface will bring it out of the break condition.
reg r_tx_break;
initial r_tx_break = 1'b0;
always @(posedge i_clk)
if (i_rst)
310,6 → 319,10
r_tx_break <= 1'b0;
else if ((i_wb_stb)&&(i_wb_addr[1:0]==`UART_TXREG)&&(i_wb_we))
r_tx_break <= i_wb_data[9];
assign tx_break = r_tx_break;
`else
assign tx_break = 1'b0;
`endif
 
// TX-Reset logic
//
326,8 → 339,12
else
tx_uart_reset <= 1'b0;
 
wire rts;
assign rts = (!HARDWARE_FLOW_CONTROL_PRESENT)||(i_rts);
`ifdef USE_LITE_UART
txuart #(INITIAL_SETUP[23:0]) tx(i_clk, (tx_empty_n), tx_data,
o_uart_tx, tx_busy);
`else
wire cts_n;
assign cts_n = (HARDWARE_FLOW_CONTROL_PRESENT)&&(i_cts_n);
// Finally, the UART transmitter module itself. Note that we haven't
// connected the reset wire. Transmitting is as simple as setting
// the stb value (here set to tx_empty_n) and the data. When these
339,7 → 356,8
// starting to transmit a new byte.)
txuart #(INITIAL_SETUP) tx(i_clk, 1'b0, uart_setup,
r_tx_break, (tx_empty_n), tx_data,
i_rts, o_uart_tx, tx_busy);
cts_n, o_uart_tx, tx_busy);
`endif
 
// Now that we are done with the chain, pick some wires for the user
// to read on any read of the transmit port.
355,8 → 373,8
// whether or not we are actively transmitting.
wire [31:0] wb_tx_data;
assign wb_tx_data = { 16'h00,
i_rts, txf_status[1:0], txf_err,
ck_uart, o_uart_tx, r_tx_break, (tx_busy|txf_status[0]),
i_cts_n, txf_status[1:0], txf_err,
ck_uart, o_uart_tx, tx_break, (tx_busy|txf_status[0]),
(tx_busy|txf_status[0])?txf_wb_data:8'b00};
 
// Each of the FIFO's returns a 16 bit status value. This value tells
/.
. Property changes : Added: svn:ignore ## -0,0 +1 ## +obj_dir

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.