Line 102... |
Line 102... |
// `define TXU_START 4'hd // An unused state
|
// `define TXU_START 4'hd // An unused state
|
`define TXU_BREAK 4'he
|
`define TXU_BREAK 4'he
|
`define TXU_IDLE 4'hf
|
`define TXU_IDLE 4'hf
|
//
|
//
|
//
|
//
|
module txuart(i_clk, i_reset, i_setup, i_break, i_wr, i_data, o_uart, o_busy);
|
module txuart(i_clk, i_reset, i_setup, i_break, i_wr, i_data,o_uart_tx, o_busy);
|
|
parameter INITIAL_SETUP = 30'd868;
|
input i_clk, i_reset;
|
input i_clk, i_reset;
|
input [29:0] i_setup;
|
input [29:0] i_setup;
|
input i_break;
|
input i_break;
|
input i_wr;
|
input i_wr;
|
input [7:0] i_data;
|
input [7:0] i_data;
|
output reg o_uart;
|
output reg o_uart_tx;
|
output wire o_busy;
|
output wire o_busy;
|
|
|
wire [27:0] clocks_per_baud, break_condition;
|
wire [27:0] clocks_per_baud, break_condition;
|
wire [1:0] data_bits;
|
wire [1:0] data_bits;
|
wire use_parity, parity_even, dblstop, fixd_parity;
|
wire use_parity, parity_even, dblstop, fixd_parity;
|
Line 128... |
Line 129... |
reg [27:0] baud_counter;
|
reg [27:0] baud_counter;
|
reg [3:0] state;
|
reg [3:0] state;
|
reg [7:0] lcl_data;
|
reg [7:0] lcl_data;
|
reg calc_parity, r_busy, zero_baud_counter;
|
reg calc_parity, r_busy, zero_baud_counter;
|
|
|
initial o_uart = 1'b1;
|
initial r_setup = INITIAL_SETUP;
|
|
initial o_uart_tx = 1'b1;
|
initial r_busy = 1'b1;
|
initial r_busy = 1'b1;
|
initial state = `TXU_IDLE;
|
initial state = `TXU_IDLE;
|
initial lcl_data= 8'h0;
|
initial lcl_data= 8'h0;
|
initial calc_parity = 1'b0;
|
initial calc_parity = 1'b0;
|
// initial baud_counter = clocks_per_baud;//ILLEGAL--not constant
|
// initial baud_counter = clocks_per_baud;//ILLEGAL--not constant
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
begin
|
begin
|
if (i_reset)
|
if (i_reset)
|
begin
|
begin
|
o_uart <= 1'b1;
|
o_uart_tx <= 1'b1;
|
r_busy <= 1'b1;
|
r_busy <= 1'b1;
|
state <= `TXU_IDLE;
|
state <= `TXU_IDLE;
|
lcl_data <= 8'h0;
|
lcl_data <= 8'h0;
|
calc_parity <= 1'b0;
|
calc_parity <= 1'b0;
|
end else if (i_break)
|
end else if (i_break)
|
begin
|
begin
|
o_uart <= 1'b0;
|
o_uart_tx <= 1'b0;
|
state <= `TXU_BREAK;
|
state <= `TXU_BREAK;
|
calc_parity <= 1'b0;
|
calc_parity <= 1'b0;
|
r_busy <= 1'b1;
|
r_busy <= 1'b1;
|
end else if (~zero_baud_counter)
|
end else if (~zero_baud_counter)
|
begin // r_busy needs to be set coming into here
|
begin // r_busy needs to be set coming into here
|
r_busy <= 1'b1;
|
r_busy <= 1'b1;
|
end else if (state == `TXU_BREAK)
|
end else if (state == `TXU_BREAK)
|
begin
|
begin
|
state <= `TXU_IDLE;
|
state <= `TXU_IDLE;
|
r_busy <= 1'b1;
|
r_busy <= 1'b1;
|
o_uart <= 1'b1;
|
o_uart_tx <= 1'b1;
|
calc_parity <= 1'b0;
|
calc_parity <= 1'b0;
|
end else if (state == `TXU_IDLE) // STATE_IDLE
|
end else if (state == `TXU_IDLE) // STATE_IDLE
|
begin
|
begin
|
// baud_counter <= 0;
|
// baud_counter <= 0;
|
r_setup <= i_setup;
|
r_setup <= i_setup;
|
calc_parity <= 1'b0;
|
calc_parity <= 1'b0;
|
if ((i_wr)&&(~r_busy))
|
if ((i_wr)&&(~r_busy))
|
begin // Immediately start us off with a start bit
|
begin // Immediately start us off with a start bit
|
o_uart <= 1'b0;
|
o_uart_tx <= 1'b0;
|
r_busy <= 1'b1;
|
r_busy <= 1'b1;
|
case(data_bits)
|
case(data_bits)
|
2'b00: state <= `TXU_BIT_ZERO;
|
2'b00: state <= `TXU_BIT_ZERO;
|
2'b01: state <= `TXU_BIT_ONE;
|
2'b01: state <= `TXU_BIT_ONE;
|
2'b10: state <= `TXU_BIT_TWO;
|
2'b10: state <= `TXU_BIT_TWO;
|
2'b11: state <= `TXU_BIT_THREE;
|
2'b11: state <= `TXU_BIT_THREE;
|
endcase
|
endcase
|
lcl_data <= i_data;
|
lcl_data <= i_data;
|
// baud_counter <= clocks_per_baud-28'h01;
|
// baud_counter <= clocks_per_baud-28'h01;
|
end else begin // Stay in idle
|
end else begin // Stay in idle
|
o_uart <= 1'b1;
|
o_uart_tx <= 1'b1;
|
r_busy <= 0;
|
r_busy <= 0;
|
// lcl_data is irrelevant
|
// lcl_data is irrelevant
|
// state <= state;
|
// state <= state;
|
end
|
end
|
end else begin
|
end else begin
|
// One clock tick in each of these states ...
|
// One clock tick in each of these states ...
|
// baud_counter <= clocks_per_baud - 28'h01;
|
// baud_counter <= clocks_per_baud - 28'h01;
|
r_busy <= 1'b1;
|
r_busy <= 1'b1;
|
if (state[3] == 0) // First 8 bits
|
if (state[3] == 0) // First 8 bits
|
begin
|
begin
|
o_uart <= lcl_data[0];
|
o_uart_tx <= lcl_data[0];
|
calc_parity <= calc_parity ^ lcl_data[0];
|
calc_parity <= calc_parity ^ lcl_data[0];
|
if (state == `TXU_BIT_SEVEN)
|
if (state == `TXU_BIT_SEVEN)
|
state <= (use_parity)?`TXU_PARITY:`TXU_STOP;
|
state <= (use_parity)?`TXU_PARITY:`TXU_STOP;
|
else
|
else
|
state <= state + 1;
|
state <= state + 1;
|
lcl_data <= { 1'b0, lcl_data[7:1] };
|
lcl_data <= { 1'b0, lcl_data[7:1] };
|
end else if (state == `TXU_PARITY)
|
end else if (state == `TXU_PARITY)
|
begin
|
begin
|
state <= `TXU_STOP;
|
state <= `TXU_STOP;
|
if (fixd_parity)
|
if (fixd_parity)
|
o_uart <= parity_even;
|
o_uart_tx <= parity_even;
|
else
|
else
|
o_uart <= calc_parity^((parity_even)? 1'b1:1'b0);
|
o_uart_tx <= calc_parity^((parity_even)? 1'b1:1'b0);
|
end else if (state == `TXU_STOP)
|
end else if (state == `TXU_STOP)
|
begin // two stop bit(s)
|
begin // two stop bit(s)
|
o_uart <= 1'b1;
|
o_uart_tx <= 1'b1;
|
if (dblstop)
|
if (dblstop)
|
state <= `TXU_SECOND_STOP;
|
state <= `TXU_SECOND_STOP;
|
else
|
else
|
state <= `TXU_IDLE;
|
state <= `TXU_IDLE;
|
calc_parity <= 1'b0;
|
calc_parity <= 1'b0;
|
end else // `TXU_SECOND_STOP and default:
|
end else // `TXU_SECOND_STOP and default:
|
begin
|
begin
|
state <= `TXU_IDLE; // Go back to idle
|
state <= `TXU_IDLE; // Go back to idle
|
o_uart <= 1'b1;
|
o_uart_tx <= 1'b1;
|
// Still r_busy, since we need to wait
|
// Still r_busy, since we need to wait
|
// for the baud clock to finish counting
|
// for the baud clock to finish counting
|
// out this last bit.
|
// out this last bit.
|
end
|
end
|
end
|
end
|
Line 229... |
Line 231... |
initial baud_counter = 28'h05;
|
initial baud_counter = 28'h05;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
begin
|
begin
|
zero_baud_counter <= (baud_counter == 28'h01);
|
zero_baud_counter <= (baud_counter == 28'h01);
|
if ((i_reset)||(i_break))
|
if ((i_reset)||(i_break))
|
|
begin
|
// Give ourselves 16 bauds before being ready
|
// Give ourselves 16 bauds before being ready
|
baud_counter <= break_condition;
|
baud_counter <= break_condition;
|
else if (~zero_baud_counter)
|
zero_baud_counter <= 1'b0;
|
|
end else if (~zero_baud_counter)
|
baud_counter <= baud_counter - 28'h01;
|
baud_counter <= baud_counter - 28'h01;
|
else if (state == `TXU_BREAK)
|
else if (state == `TXU_BREAK)
|
// Give us two stop bits before becoming available
|
// Give us two stop bits before becoming available
|
baud_counter <= clocks_per_baud<<2;
|
baud_counter <= clocks_per_baud<<2;
|
else if (state == `TXU_IDLE)
|
else if (state == `TXU_IDLE)
|