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

Subversion Repositories xulalx25soc

[/] [xulalx25soc/] [trunk/] [rtl/] [rxuart.v] - Diff between revs 58 and 99

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 58 Rev 99
Line 4... Line 4...
//
//
// Project:     XuLA2 board
// Project:     XuLA2 board
//
//
// Purpose:     Receive and decode inputs from a single UART line.
// Purpose:     Receive and decode inputs from a single UART line.
//
//
 
//
//      To interface with this module, connect it to your system clock,
//      To interface with this module, connect it to your system clock,
//      pass it the 32 bit setup register (defined below) and the UART
//      pass it the 32 bit setup register (defined below) and the UART
//      input.  When data becomes available, the o_wr line will be asserted
//      input.  When data becomes available, the o_wr line will be asserted
//      for one clock cycle.  On parity or frame errors, the o_parity_err
//      for one clock cycle.  On parity or frame errors, the o_parity_err
//      or o_frame_err lines will be asserted.  Likewise, on a break 
//      or o_frame_err lines will be asserted.  Likewise, on a break 
Line 58... Line 59...
// Creator:     Dan Gisselquist, Ph.D.
// Creator:     Dan Gisselquist, Ph.D.
//              Gisselquist Technology, LLC
//              Gisselquist Technology, LLC
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// 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
// 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
// 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
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
// your option) any later version.
Line 70... Line 71...
// This program is distributed in the hope that it will be useful, but WITHOUT
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
// 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,
// License:     GPL, v3, as defined and found on www.gnu.org,
//              http://www.gnu.org/licenses/gpl.html
//              http://www.gnu.org/licenses/gpl.html
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
 
 
// States: (@ baud counter == 0)
// States: (@ baud counter == 0)
//      0        First bit arrives
//      0        First bit arrives
//      ..7     Bits arrive
//      ..7     Bits arrive
//      8       Stop bit (x1)
//      8       Stop bit (x1)
//      9       Stop bit (x2)
//      9       Stop bit (x2)
Line 142... Line 147...
        begin
        begin
                q_uart <= i_uart;
                q_uart <= i_uart;
                qq_uart <= q_uart;
                qq_uart <= q_uart;
                ck_uart <= qq_uart;
                ck_uart <= qq_uart;
        end
        end
        // assign       o_ck_uart = ck_uart;
 
 
 
        reg     [27:0]   chg_counter;
        reg     [27:0]   chg_counter;
        initial chg_counter = 28'h00;
        initial chg_counter = 28'h00;
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (i_reset)
                if (i_reset)
Line 154... Line 158...
                else if (qq_uart != ck_uart)
                else if (qq_uart != ck_uart)
                        chg_counter <= 28'h00;
                        chg_counter <= 28'h00;
                else if (chg_counter < break_condition)
                else if (chg_counter < break_condition)
                        chg_counter <= chg_counter + 1;
                        chg_counter <= chg_counter + 1;
 
 
 
        reg     line_synch;
 
        initial line_synch = 1'b0;
 
        initial o_break    = 1'b0;
        always @(posedge i_clk)
        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     [3:0]    state;
        reg     [27:0]   baud_counter;
        reg     [27:0]   baud_counter;
        reg     [7:0]    data_reg;
        reg     [7:0]    data_reg;
        reg             calc_parity;
        reg             calc_parity, zero_baud_counter, half_baud_time;
        initial o_wr = 1'b0;
        initial o_wr = 1'b0;
        initial state = `RXU_RESET_IDLE;
        initial state = `RXU_RESET_IDLE;
        initial o_parity_err = 1'b0;
        initial o_parity_err = 1'b0;
        initial o_frame_err  = 1'b0;
        initial o_frame_err  = 1'b0;
        // initial      baud_counter = clocks_per_baud;
        // initial      baud_counter = clocks_per_baud;
Line 173... Line 182...
                if (i_reset)
                if (i_reset)
                begin
                begin
                        o_wr <= 1'b0;
                        o_wr <= 1'b0;
                        o_data <= 8'h00;
                        o_data <= 8'h00;
                        state <= `RXU_RESET_IDLE;
                        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;
                        data_reg <= 8'h00;
                        calc_parity <= 1'b0;
                        calc_parity <= 1'b0;
                        o_parity_err <= 1'b0;
                        o_parity_err <= 1'b0;
                        o_frame_err <= 1'b0;
                        o_frame_err <= 1'b0;
                end else if (state == `RXU_RESET_IDLE)
                end else if (state == `RXU_RESET_IDLE)
                begin
                begin
                        r_setup <= i_setup;
                        r_setup <= i_setup;
                        data_reg <= 8'h00; o_data <= 8'h00; o_wr <= 1'b0;
                        data_reg <= 8'h00; o_data <= 8'h00; o_wr <= 1'b0;
                        baud_counter <= clocks_per_baud-28'h01;// Set, not reset
                        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
                                // Goto idle state from a reset
                                state <= `RXU_IDLE;
                                state <= `RXU_IDLE;
                        else // Otherwise, stay in this condition 'til reset
                        else // Otherwise, stay in this condition 'til reset
                                state <= `RXU_RESET_IDLE;
                                state <= `RXU_RESET_IDLE;
                        calc_parity <= 1'b0;
                        calc_parity <= 1'b0;
                        o_parity_err <= 1'b0;
                        o_parity_err <= 1'b0;
                        o_frame_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
                begin // We are in a break condition
                        state <= `RXU_BREAK;
                        state <= `RXU_BREAK;
                        o_wr <= 1'b0;
                        o_wr <= 1'b0;
                        o_data <= 8'h00;
                        o_data <= 8'h00;
                        baud_counter <= clocks_per_baud-28'h01;// Set, not reset
                        baud_counter <= clocks_per_baud-28'h01;// Set, not reset
Line 219... Line 228...
                end else if (state == `RXU_IDLE)
                end else if (state == `RXU_IDLE)
                begin // Idle state, independent of baud counter
                begin // Idle state, independent of baud counter
                        r_setup <= i_setup;
                        r_setup <= i_setup;
                        data_reg <= 8'h00; o_data <= 8'h00; o_wr <= 1'b0;
                        data_reg <= 8'h00; o_data <= 8'h00; o_wr <= 1'b0;
                        baud_counter <= clocks_per_baud - 28'h01;
                        baud_counter <= clocks_per_baud - 28'h01;
                        if ((ck_uart == 1'b0)&&(chg_counter > half_baud))
                        if ((~ck_uart)&&(half_baud_time))
                        begin
                        begin
                                // We are in the center of a valid start bit
                                // We are in the center of a valid start bit
                                case (data_bits)
                                case (data_bits)
                                2'b00: state <= `RXU_BIT_ZERO;
                                2'b00: state <= `RXU_BIT_ZERO;
                                2'b01: state <= `RXU_BIT_ONE;
                                2'b01: state <= `RXU_BIT_ONE;
Line 233... Line 242...
                        end else // Otherwise, just stay here in idle
                        end else // Otherwise, just stay here in idle
                                state <= `RXU_IDLE;
                                state <= `RXU_IDLE;
                        calc_parity <= 1'b0;
                        calc_parity <= 1'b0;
                        o_parity_err <= 1'b0;
                        o_parity_err <= 1'b0;
                        o_frame_err <= 1'b0;
                        o_frame_err <= 1'b0;
                end else if (baud_counter == 0)
                end else if (zero_baud_counter)
                begin
                begin
                        baud_counter <= clocks_per_baud-28'h1;
                        baud_counter <= clocks_per_baud-28'h1;
                        if (state < `RXU_BIT_SEVEN)
                        if (state < `RXU_BIT_SEVEN)
                        begin
                        begin
                                // Data arrives least significant bit first.
                                // Data arrives least significant bit first.
Line 303... Line 312...
                        o_parity_err <= 1'b0;
                        o_parity_err <= 1'b0;
                        o_frame_err  <= 1'b0;
                        o_frame_err  <= 1'b0;
                end
                end
        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
endmodule
 
 
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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