URL
https://opencores.org/ocsvn/xulalx25soc/xulalx25soc/trunk
Subversion Repositories xulalx25soc
Compare Revisions
- This comparison shows the changes necessary to convert path
/xulalx25soc
- from Rev 98 to Rev 99
- ↔ Reverse comparison
Rev 98 → Rev 99
/trunk/rtl/rxuart.v
6,6 → 6,7
// |
// Purpose: Receive and decode inputs from a single UART line. |
// |
// |
// To interface with this module, connect it to your system clock, |
// pass it the 32 bit setup register (defined below) and the UART |
// input. When data becomes available, the o_wr line will be asserted |
60,7 → 61,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015, Gisselquist Technology, LLC |
// Copyright (C) 2015-2016, 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 |
72,6 → 73,11
// 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 |
// |
79,7 → 85,6
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
|
// States: (@ baud counter == 0) |
// 0 First bit arrives |
// ..7 Bits arrive |
144,7 → 149,6
qq_uart <= q_uart; |
ck_uart <= qq_uart; |
end |
// assign o_ck_uart = ck_uart; |
|
reg [27:0] chg_counter; |
initial chg_counter = 28'h00; |
156,13 → 160,18
else if (chg_counter < break_condition) |
chg_counter <= chg_counter + 1; |
|
reg line_synch; |
initial line_synch = 1'b0; |
initial o_break = 1'b0; |
always @(posedge i_clk) |
o_break <=((chg_counter >= break_condition)&&(~ck_uart))? 1'b1:1'b0; |
o_break <= ((chg_counter >= break_condition)&&(~ck_uart))? 1'b1:1'b0; |
always @(posedge i_clk) |
line_synch <= ((chg_counter >= break_condition)&&(ck_uart)); |
|
reg [3:0] state; |
reg [27:0] baud_counter; |
reg [7:0] data_reg; |
reg calc_parity; |
reg calc_parity, zero_baud_counter, half_baud_time; |
initial o_wr = 1'b0; |
initial state = `RXU_RESET_IDLE; |
initial o_parity_err = 1'b0; |
175,7 → 184,7
o_wr <= 1'b0; |
o_data <= 8'h00; |
state <= `RXU_RESET_IDLE; |
baud_counter <= clocks_per_baud; // Set, not reset |
baud_counter <= clocks_per_baud-28'h01;// Set, not reset |
data_reg <= 8'h00; |
calc_parity <= 1'b0; |
o_parity_err <= 1'b0; |
185,7 → 194,7
r_setup <= i_setup; |
data_reg <= 8'h00; o_data <= 8'h00; o_wr <= 1'b0; |
baud_counter <= clocks_per_baud-28'h01;// Set, not reset |
if ((ck_uart)&&(chg_counter >= break_condition)) |
if (line_synch) |
// Goto idle state from a reset |
state <= `RXU_IDLE; |
else // Otherwise, stay in this condition 'til reset |
193,7 → 202,7
calc_parity <= 1'b0; |
o_parity_err <= 1'b0; |
o_frame_err <= 1'b0; |
end else if ((~ck_uart)&&(chg_counter >= break_condition)) |
end else if (o_break) |
begin // We are in a break condition |
state <= `RXU_BREAK; |
o_wr <= 1'b0; |
221,7 → 230,7
r_setup <= i_setup; |
data_reg <= 8'h00; o_data <= 8'h00; o_wr <= 1'b0; |
baud_counter <= clocks_per_baud - 28'h01; |
if ((ck_uart == 1'b0)&&(chg_counter > half_baud)) |
if ((~ck_uart)&&(half_baud_time)) |
begin |
// We are in the center of a valid start bit |
case (data_bits) |
235,7 → 244,7
calc_parity <= 1'b0; |
o_parity_err <= 1'b0; |
o_frame_err <= 1'b0; |
end else if (baud_counter == 0) |
end else if (zero_baud_counter) |
begin |
baud_counter <= clocks_per_baud-28'h1; |
if (state < `RXU_BIT_SEVEN) |
305,6 → 314,15
end |
end |
|
initial zero_baud_counter = 1'b0; |
always @(posedge i_clk) |
zero_baud_counter <= (baud_counter == 28'h01); |
|
initial half_baud_time = 0; |
always @(posedge i_clk) |
half_baud_time <= (~ck_uart)&&(chg_counter >= half_baud); |
|
|
endmodule |
|
|
/trunk/rtl/txuart.v
75,6 → 75,11
// 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 |
// |
99,7 → 104,8
// `define TXU_START 4'hd // An unused state |
`define TXU_BREAK 4'he |
`define TXU_IDLE 4'hf |
|
// |
// |
module txuart(i_clk, i_reset, i_setup, i_break, i_wr, i_data, o_uart, o_busy); |
input i_clk, i_reset; |
input [29:0] i_setup; |
106,7 → 112,8
input i_break; |
input i_wr; |
input [7:0] i_data; |
output reg o_uart, o_busy; |
output reg o_uart; |
output wire o_busy; |
|
wire [27:0] clocks_per_baud, break_condition; |
wire [1:0] data_bits; |
123,50 → 130,47
reg [27:0] baud_counter; |
reg [3:0] state; |
reg [7:0] lcl_data; |
reg calc_parity; |
reg calc_parity, r_busy, zero_baud_counter; |
|
initial o_uart = 1'b1; |
initial o_busy = 1'b1; |
initial r_busy = 1'b1; |
initial state = `TXU_IDLE; |
// initial baud_counter = clocks_per_baud; |
initial lcl_data= 8'h0; |
initial calc_parity = 1'b0; |
// initial baud_counter = clocks_per_baud;//ILLEGAL--not constant |
always @(posedge i_clk) |
begin |
if (i_reset) |
begin |
baud_counter <= clocks_per_baud; |
o_uart <= 1'b1; |
o_busy <= 1'b1; |
r_busy <= 1'b1; |
state <= `TXU_IDLE; |
lcl_data <= 8'h0; |
calc_parity <= 1'b0; |
end else if (i_break) |
begin |
baud_counter <= break_condition; |
o_uart <= 1'b0; |
state <= `TXU_BREAK; |
calc_parity <= 1'b0; |
o_busy <= 1'b1; |
end else if (baud_counter != 0) |
begin // o_busy needs to be set coming into here |
baud_counter <= baud_counter - 28'h01; |
o_busy <= 1'b1; |
r_busy <= 1'b1; |
end else if (~zero_baud_counter) |
begin // r_busy needs to be set coming into here |
r_busy <= 1'b1; |
end else if (state == `TXU_BREAK) |
begin |
state <= `TXU_IDLE; |
o_busy <= 1'b1; |
r_busy <= 1'b1; |
o_uart <= 1'b1; |
calc_parity <= 1'b0; |
// Give us two stop bits before becoming available |
baud_counter <= clocks_per_baud<<2; |
end else if (state == `TXU_IDLE) // STATE_IDLE |
begin |
// baud_counter <= 0; |
r_setup <= i_setup; |
calc_parity <= 1'b0; |
if ((i_wr)&&(~o_busy)) |
if ((i_wr)&&(~r_busy)) |
begin // Immediately start us off with a start bit |
o_uart <= 1'b0; |
o_busy <= 1'b1; |
r_busy <= 1'b1; |
case(data_bits) |
2'b00: state <= `TXU_BIT_ZERO; |
2'b01: state <= `TXU_BIT_ONE; |
174,17 → 178,17
2'b11: state <= `TXU_BIT_THREE; |
endcase |
lcl_data <= i_data; |
baud_counter <= clocks_per_baud-28'h01; |
// baud_counter <= clocks_per_baud-28'h01; |
end else begin // Stay in idle |
o_uart <= 1'b1; |
o_busy <= 0; |
r_busy <= 0; |
// lcl_data is irrelevant |
// state <= state; |
end |
end else begin |
// One clock tick in each of these states ... |
baud_counter <= clocks_per_baud - 28'h01; |
o_busy <= 1'b1; |
// baud_counter <= clocks_per_baud - 28'h01; |
r_busy <= 1'b1; |
if (state[3] == 0) // First 8 bits |
begin |
o_uart <= lcl_data[0]; |
213,7 → 217,7
begin |
state <= `TXU_IDLE; // Go back to idle |
o_uart <= 1'b1; |
// Still o_busy, since we need to wait |
// Still r_busy, since we need to wait |
// for the baud clock to finish counting |
// out this last bit. |
end |
220,8 → 224,29
end |
end |
|
endmodule |
assign o_busy = (r_busy); |
|
|
initial zero_baud_counter = 1'b0; |
always @(posedge i_clk) |
begin |
zero_baud_counter <= (baud_counter == 28'h01); |
if ((i_reset)||(i_break)) |
// Give ourselves 16 bauds before being ready |
baud_counter <= break_condition; |
else if (~zero_baud_counter) |
baud_counter <= baud_counter - 28'h01; |
else if (state == `TXU_BREAK) |
// Give us two stop bits before becoming available |
baud_counter <= clocks_per_baud<<2; |
else if (state == `TXU_IDLE) |
begin |
if((i_wr)&&(~r_busy)) |
baud_counter <= clocks_per_baud - 28'h01; |
else |
zero_baud_counter <= 1'b1; |
end else |
baud_counter <= clocks_per_baud - 28'h01; |
end |
endmodule |
|
|