OpenCores
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
 
 

powered by: WebSVN 2.1.0

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