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

Subversion Repositories rtfsimpleuart

[/] [rtfsimpleuart/] [trunk/] [rtl/] [verilog/] [rtfSimpleUartRx.v] - Diff between revs 14 and 15

Only display areas with differences | Details | Blame | View Log

Rev 14 Rev 15
// ============================================================================
// ============================================================================
//      (C) 2011,2013  Robert Finch
//      (C) 2011,2013,2015  Robert Finch
//  All rights reserved.
//  All rights reserved.
//      robfinch@<remove>finitron.ca
//      robfinch@<remove>finitron.ca
//
//
//      rtfSimpleUartRx.v
//      rtfSimpleUartRx.v
//
//
// Redistribution and use in source and binary forms, with or without
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// modification, are permitted provided that the following conditions are met:
//     * Redistributions of source code must retain the above copyright
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of the <organization> nor the
//     * Neither the name of the <organization> nor the
//       names of its contributors may be used to endorse or promote products
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//       derived from this software without specific prior written permission.
//
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
// DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//
//      Simple UART receiver core
//      Simple UART receiver core
//              Features:
//              Features:
//                      false start bit detection
//                      false start bit detection
//                      framing error detection
//                      framing error detection
//                      overrun state detection
//                      overrun state detection
//                      resynchronization on every character
//                      resynchronization on every character
//                      fixed format 1 start - 8 data - 1 stop bits
//                      fixed format 1 start - 8 data - 1 stop bits
//                      uses 16x clock rate
//                      uses 16x clock rate
//                      
//                      
//              This core may be used as a standalone peripheral
//              This core may be used as a standalone peripheral
//      on a SoC bus if all that is desired is recieve
//      on a SoC bus if all that is desired is recieve
//      capability. It requires a 16x baud rate clock.
//      capability. It requires a 16x baud rate clock.
//      
//      
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//      |WISHBONE Datasheet
//      |WISHBONE Datasheet
//      |WISHBONE SoC Architecture Specification, Revision B.3
//      |WISHBONE SoC Architecture Specification, Revision B.3
//      |
//      |
//      |Description:                                           Specifications:
//      |Description:                                           Specifications:
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//      |General Description:                           simple serial UART receiver
//      |General Description:                           simple serial UART receiver
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//      |Supported Cycles:                                      SLAVE,READ
//      |Supported Cycles:                                      SLAVE,READ
//      |                                                                       SLAVE,BLOCK READ
//      |                                                                       SLAVE,BLOCK READ
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//      |Data port, size:                                       8 bit
//      |Data port, size:                                       8 bit
//      |Data port, granularity:                        8 bit
//      |Data port, granularity:                        8 bit
//      |Data port, maximum operand size:       8 bit
//      |Data port, maximum operand size:       8 bit
//      |Data transfer ordering:                        Undefined
//      |Data transfer ordering:                        Undefined
//      |Data transfer sequencing:                      Undefined
//      |Data transfer sequencing:                      Undefined
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//      |Clock frequency constraints:           none
//      |Clock frequency constraints:           none
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//      |Supported signal list and                      Signal Name             WISHBONE equiv.
//      |Supported signal list and                      Signal Name             WISHBONE equiv.
//      |cross reference to equivalent          ack_o                   ACK_O
//      |cross reference to equivalent          ack_o                   ACK_O
//      |WISHBONE signals                                       
//      |WISHBONE signals                                       
//      |                                                                       clk_i                   CLK_I
//      |                                                                       clk_i                   CLK_I
//      |                                   rst_i           RST_I
//      |                                   rst_i           RST_I
//      |                                                                       dat_o(7:0)              DAT_O()
//      |                                                                       dat_o(7:0)              DAT_O()
//      |                                                                       cyc_i                   CYC_I
//      |                                                                       cyc_i                   CYC_I
//      |                                                                       stb_i                   STB_I
//      |                                                                       stb_i                   STB_I
//      |                                                                       we_i                    WE_I
//      |                                                                       we_i                    WE_I
//      |
//      |
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//      |Special requirements:
//      |Special requirements:
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
//
//      Ref: Spartan3 -4
//      Ref: Spartan3 -4
//      27 LUTs / 24 slices / 170 MHz
//      27 LUTs / 24 slices / 170 MHz
//==============================================================================
//==============================================================================
 
 
`define IDLE    0
`define IDLE    0
`define CNT             1
`define CNT             1
 
 
module rtfSimpleUartRx(
module rtfSimpleUartRx(
        // WISHBONE SoC bus interface
        // WISHBONE SoC bus interface
        input rst_i,                    // reset
        input rst_i,                    // reset
        input clk_i,                    // clock
        input clk_i,                    // clock
        input cyc_i,                    // cycle is valid
        input cyc_i,                    // cycle is valid
        input stb_i,                    // strobe
        input stb_i,                    // strobe
        output ack_o,                   // data is ready
        output ack_o,                   // data is ready
        input we_i,                             // write (this signal is used to qualify reads)
        input we_i,                             // write (this signal is used to qualify reads)
        output [7:0] dat_o,              // data out
        output [7:0] dat_o,              // data out
        //------------------------
        //------------------------
        input cs_i,                             // chip select
        input cs_i,                             // chip select
        input baud16x_ce,               // baud rate clock enable
        input baud16x_ce,               // baud rate clock enable
    input tri0 baud8x,       // switches to mode baudX8
    input tri0 baud8x,       // switches to mode baudX8
        input clear,                    // clear reciever
        input clear,                    // clear reciever
        input rxd,                              // external serial input
        input rxd,                              // external serial input
        output reg data_present,        // data present in fifo
        output reg data_present,        // data present in fifo
        output reg frame_err,           // framing error
        output reg frame_err,           // framing error
        output reg overrun                      // receiver overrun
        output reg overrun                      // receiver overrun
);
);
 
 
//0 - simple sampling at middle of symbol period
//0 - simple sampling at middle of symbol period
//>0 - sampling of 3 middle ticks of sumbol perion and results as majority
//>0 - sampling of 3 middle ticks of sumbol perion and results as majority
parameter SamplerStyle = 0;
parameter SamplerStyle = 0;
 
 
// variables
// variables
reg [7:0] cnt;                   // sample bit rate counter
reg [7:0] cnt;                   // sample bit rate counter
reg [9:0] rx_data;               // working receive data register
reg [9:0] rx_data;               // working receive data register
reg state;                              // state machine
reg state;                              // state machine
reg wf;                                 // buffer write
reg wf;                                 // buffer write
reg [7:0] dat;
reg [7:0] dat;
 
 
wire isX8;
wire isX8;
buf(isX8, baud8x);
buf(isX8, baud8x);
reg modeX8;
reg modeX8;
 
 
assign ack_o = cyc_i & stb_i & cs_i;
assign ack_o = cyc_i & stb_i & cs_i;
assign dat_o = ack_o ? dat : 8'b0;
assign dat_o = ack_o ? dat : 8'b0;
 
 
// update data register
// update data register
always @(posedge clk_i)
always @(posedge clk_i)
        if (wf) dat <= rx_data[8:1];
        if (wf) dat <= rx_data[8:1];
 
 
// on a read clear the data present status
// on a read clear the data present status
// but set the status when the data register
// but set the status when the data register
// is updated by the receiver           
// is updated by the receiver           
always @(posedge clk_i)
always @(posedge clk_i)
    if (rst_i)
    if (rst_i)
        data_present <= 0;
        data_present <= 0;
    else if (wf)
    else if (wf)
        data_present <= 1;
        data_present <= 1;
        else if (ack_o & ~we_i) data_present <= 0;
        else if (ack_o & ~we_i) data_present <= 0;
 
 
 
 
// Three stage synchronizer to synchronize incoming data to
// Three stage synchronizer to synchronize incoming data to
// the local clock (avoids metastability).
// the local clock (avoids metastability).
reg [5:0] rxdd          /* synthesis ramstyle = "logic" */; // synchronizer flops
reg [5:0] rxdd          /* synthesis ramstyle = "logic" */; // synchronizer flops
reg rxdsmp;             // majority samples
reg rxdsmp;             // majority samples
reg rdxstart;           // for majority style sample solid 3tik-wide sample
reg rdxstart;           // for majority style sample solid 3tik-wide sample
reg [1:0] rxdsum;
reg [1:0] rxdsum;
always @(posedge clk_i)
always @(posedge clk_i)
if (baud16x_ce) begin
if (baud16x_ce) begin
        rxdd <= {rxdd[4:0],rxd};
        rxdd <= {rxdd[4:0],rxd};
    if (SamplerStyle == 0) begin
    if (SamplerStyle == 0) begin
        rxdsmp <= rxdd[3];
        rxdsmp <= rxdd[3];
        rdxstart <= rxdd[4]&~rxdd[3];
        rdxstart <= rxdd[4]&~rxdd[3];
    end
    end
    else begin
    else begin
        rxdsum[1] <= rxdsum[0];
        rxdsum[1] <= rxdsum[0];
        rxdsum[0] <= {1'b0,rxdd[3]} + {1'b0,rxdd[4]} + {1'b0,rxdd[5]};
        rxdsum[0] <= {1'b0,rxdd[3]} + {1'b0,rxdd[4]} + {1'b0,rxdd[5]};
        rxdsmp <= rxdsum[1];
        rxdsmp <= rxdsum[1];
        rdxstart <= (rxdsum[0] == 2'b00) & ((rxdsum[1] == 2'b11));
        rdxstart <= (rxdsum[0] == 2'b00) & ((rxdsum[1] == 2'b11));
    end
    end
end
end
 
 
 
 
`define CNT_FRAME  (8'h97)
`define CNT_FRAME  (8'h97)
`define CNT_FINISH (8'h9D)
`define CNT_FINISH (8'h9D)
 
 
always @(posedge clk_i) begin
always @(posedge clk_i) begin
        if (rst_i) begin
        if (rst_i) begin
                state <= `IDLE;
                state <= `IDLE;
                wf <= 1'b0;
                wf <= 1'b0;
                overrun <= 1'b0;
                overrun <= 1'b0;
        frame_err <= 1'b0;
        frame_err <= 1'b0;
        end
        end
        else begin
        else begin
 
 
                // Clear write flag
                // Clear write flag
                wf <= 1'b0;
                wf <= 1'b0;
 
 
                if (clear) begin
                if (clear) begin
                        wf <= 1'b0;
                        wf <= 1'b0;
                        state <= `IDLE;
                        state <= `IDLE;
                        overrun <= 1'b0;
                        overrun <= 1'b0;
            frame_err <= 1'b0;
            frame_err <= 1'b0;
                end
                end
 
 
                else if (baud16x_ce) begin
                else if (baud16x_ce) begin
 
 
                        case (state)
                        case (state)
 
 
                        // Sit in the idle state until a start bit is
                        // Sit in the idle state until a start bit is
                        // detected.
                        // detected.
                        `IDLE:
                        `IDLE:
                                // look for start bit
                                // look for start bit
                                if (rdxstart)
                                if (rdxstart)
                                        state <= `CNT;
                                        state <= `CNT;
 
 
                        `CNT:
                        `CNT:
                                begin
                                begin
                                        // End of the frame ?
                                        // End of the frame ?
                                        // - check for framing error
                                        // - check for framing error
                                        // - write data to read buffer
                                        // - write data to read buffer
                                        if (cnt==`CNT_FRAME)
                                        if (cnt==`CNT_FRAME)
                                                begin
                                                begin
                                                        frame_err <= ~rxdsmp;
                                                        frame_err <= ~rxdsmp;
                            overrun <= data_present;
                            overrun <= data_present;
                                                        if (!data_present)
                                                        if (!data_present)
                                                                wf <= 1'b1;
                                                                wf <= 1'b1;
                            state <= `IDLE;
                            state <= `IDLE;
                                                end
                                                end
                                        // Switch back to the idle state a little
                                        // Switch back to the idle state a little
                                        // bit too soon.
                                        // bit too soon.
                                        //if (cnt==`CNT_FINISH) begin
                                        //if (cnt==`CNT_FINISH) begin
                                        //      state <= `IDLE;
                                        //      state <= `IDLE;
                    //end
                    //end
 
 
                                        // On start bit check make sure the start
                                        // On start bit check make sure the start
                                        // bit is low, otherwise go back to the
                                        // bit is low, otherwise go back to the
                                        // idle state because it's a false start.
                                        // idle state because it's a false start.
                                        if (cnt==8'h07 && rxdsmp)
                                        if (cnt==8'h07 && rxdsmp)
                                                state <= `IDLE;
                                                state <= `IDLE;
 
 
                                        if (cnt[3:0]==4'h7)
                                        if (cnt[3:0]==4'h7)
                                                rx_data <= {rxdsmp,rx_data[9:1]};
                                                rx_data <= {rxdsmp,rx_data[9:1]};
                                end
                                end
 
 
                        endcase
                        endcase
                end
                end
        end
        end
end
end
 
 
 
 
// bit rate counter
// bit rate counter
always @(posedge clk_i)
always @(posedge clk_i)
        if (baud16x_ce) begin
        if (baud16x_ce) begin
                if (state == `IDLE) begin
                if (state == `IDLE) begin
                        cnt <= modeX8;
                        cnt <= modeX8;
            modeX8 <= isX8;
            modeX8 <= isX8;
        end
        end
        else begin
        else begin
            cnt[7:1] <= cnt[7:1] + cnt[0];
            cnt[7:1] <= cnt[7:1] + cnt[0];
            cnt[0] <= ~cnt[0] | (modeX8);
            cnt[0] <= ~cnt[0] | (modeX8);
        end
        end
        end
        end
 
 
endmodule
endmodule
 
 
 
 

powered by: WebSVN 2.1.0

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