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

Subversion Repositories mmuart

[/] [mmuart/] [trunk/] [mmuart.tar] - Diff between revs 2 and 3

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

Rev 2 Rev 3
uart/0000755000175000017500000000000011411201677012215 5ustar  lekernellekerneluart/rtl/0000755000175000017500000000000011411201677013016 5ustar  lekernellekerneluart/rtl/uart_transceiver.v0000644000175000017500000000733611411201677016576 0ustar  lekernellekernel/*
uart/0000755000175000017500000000000011411201677012215 5ustar  lekernellekerneluart/rtl/0000755000175000017500000000000011411201677013016 5ustar  lekernellekerneluart/rtl/uart_transceiver.v0000644000175000017500000000731011434747236016601 0ustar  lekernellekernel/*
 * Milkymist VJ SoC
 * Milkymist VJ SoC
 * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
 * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
 * Copyright (C) 2007 Das Labor
 * Copyright (C) 2007 Das Labor
 *
 *
 * This program is free software: you can redistribute it and/or modify
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3 of the License.
 * the Free Software Foundation, version 3 of the License.
 *
 *
 * This program is distributed in the hope that it will be useful,
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * GNU General Public License for more details.
 *
 *
 * You should have received a copy of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 * along with this program.  If not, see .
 */
 */
module uart_transceiver(
module uart_transceiver(
        input sys_rst,
        input sys_rst,
        input sys_clk,
        input sys_clk,
        input uart_rxd,
        input uart_rx,
        output reg uart_txd,
        output reg uart_tx,
        input [15:0] divisor,
        input [15:0] divisor,
        output reg [7:0] rx_data,
        output reg [7:0] rx_data,
        output reg rx_done,
        output reg rx_done,
        input [7:0] tx_data,
        input [7:0] tx_data,
        input tx_wr,
        input tx_wr,
        output reg tx_done
        output reg tx_done
);
);
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// enable16 generator
// enable16 generator
//-----------------------------------------------------------------
//-----------------------------------------------------------------
reg [15:0] enable16_counter;
reg [15:0] enable16_counter;
wire enable16;
wire enable16;
assign enable16 = (enable16_counter == 16'd0);
assign enable16 = (enable16_counter == 16'd0);
always @(posedge sys_clk) begin
always @(posedge sys_clk) begin
        if(sys_rst)
        if(sys_rst)
                enable16_counter <= divisor - 16'b1;
                enable16_counter <= divisor - 16'b1;
        else begin
        else begin
                enable16_counter <= enable16_counter - 16'd1;
                enable16_counter <= enable16_counter - 16'd1;
                if(enable16)
                if(enable16)
                        enable16_counter <= divisor - 16'b1;
                        enable16_counter <= divisor - 16'b1;
        end
        end
end
end
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// Synchronize uart_rxd
// Synchronize uart_rx
//-----------------------------------------------------------------
//-----------------------------------------------------------------
reg uart_rxd1;
reg uart_rx1;
reg uart_rxd2;
reg uart_rx2;
always @(posedge sys_clk) begin
always @(posedge sys_clk) begin
        uart_rxd1 <= uart_rxd;
        uart_rx1 <= uart_rx;
        uart_rxd2 <= uart_rxd1;
        uart_rx2 <= uart_rx1;
end
end
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// UART RX Logic
// UART RX Logic
//-----------------------------------------------------------------
//-----------------------------------------------------------------
reg rx_busy;
reg rx_busy;
reg [3:0] rx_count16;
reg [3:0] rx_count16;
reg [3:0] rx_bitcount;
reg [3:0] rx_bitcount;
reg [7:0] rxd_reg;
reg [7:0] rx_reg;
always @(posedge sys_clk) begin
always @(posedge sys_clk) begin
        if(sys_rst) begin
        if(sys_rst) begin
                rx_done <= 1'b0;
                rx_done <= 1'b0;
                rx_busy <= 1'b0;
                rx_busy <= 1'b0;
                rx_count16  <= 4'd0;
                rx_count16  <= 4'd0;
                rx_bitcount <= 4'd0;
                rx_bitcount <= 4'd0;
        end else begin
        end else begin
                rx_done <= 1'b0;
                rx_done <= 1'b0;
                if(enable16) begin
                if(enable16) begin
                        if(~rx_busy) begin // look for start bit
                        if(~rx_busy) begin // look for start bit
                                if(~uart_rxd2) begin // start bit found
                                if(~uart_rx2) begin // start bit found
                                        rx_busy <= 1'b1;
                                        rx_busy <= 1'b1;
                                        rx_count16 <= 4'd7;
                                        rx_count16 <= 4'd7;
                                        rx_bitcount <= 4'd0;
                                        rx_bitcount <= 4'd0;
                                end
                                end
                        end else begin
                        end else begin
                                rx_count16 <= rx_count16 + 4'd1;
                                rx_count16 <= rx_count16 + 4'd1;
                                if(rx_count16 == 4'd0) begin // sample
                                if(rx_count16 == 4'd0) begin // sample
                                        rx_bitcount <= rx_bitcount + 4'd1;
                                        rx_bitcount <= rx_bitcount + 4'd1;
                                        if(rx_bitcount == 4'd0) begin // verify startbit
                                        if(rx_bitcount == 4'd0) begin // verify startbit
                                                if(uart_rxd2)
                                                if(uart_rx2)
                                                        rx_busy <= 1'b0;
                                                        rx_busy <= 1'b0;
                                        end else if(rx_bitcount == 4'd9) begin
                                        end else if(rx_bitcount == 4'd9) begin
                                                rx_busy <= 1'b0;
                                                rx_busy <= 1'b0;
                                                if(uart_rxd2) begin // stop bit ok
                                                if(uart_rx2) begin // stop bit ok
                                                        rx_data <= rxd_reg;
                                                        rx_data <= rx_reg;
                                                        rx_done <= 1'b1;
                                                        rx_done <= 1'b1;
                                                end // ignore RX error
                                                end // ignore RX error
                                        end else
                                        end else
                                                rxd_reg <= {uart_rxd2, rxd_reg[7:1]};
                                                rx_reg <= {uart_rx2, rx_reg[7:1]};
                                end
                                end
                        end
                        end
                end
                end
        end
        end
end
end
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// UART TX Logic
// UART TX Logic
//-----------------------------------------------------------------
//-----------------------------------------------------------------
reg tx_busy;
reg tx_busy;
reg [3:0] tx_bitcount;
reg [3:0] tx_bitcount;
reg [3:0] tx_count16;
reg [3:0] tx_count16;
reg [7:0] txd_reg;
reg [7:0] tx_reg;
always @(posedge sys_clk) begin
always @(posedge sys_clk) begin
        if(sys_rst) begin
        if(sys_rst) begin
                tx_done <= 1'b0;
                tx_done <= 1'b0;
                tx_busy <= 1'b0;
                tx_busy <= 1'b0;
                uart_txd <= 1'b1;
                uart_tx <= 1'b1;
        end else begin
        end else begin
                tx_done <= 1'b0;
                tx_done <= 1'b0;
                if(tx_wr) begin
                if(tx_wr) begin
                        txd_reg <= tx_data;
                        tx_reg <= tx_data;
                        tx_bitcount <= 4'd0;
                        tx_bitcount <= 4'd0;
                        tx_count16 <= 4'd1;
                        tx_count16 <= 4'd1;
                        tx_busy <= 1'b1;
                        tx_busy <= 1'b1;
                        uart_txd <= 1'b0;
                        uart_tx <= 1'b0;
`ifdef SIMULATION
`ifdef SIMULATION
                        $display("UART: %c", tx_data);
                        $display("UART: %c", tx_data);
`endif
`endif
                end else if(enable16 && tx_busy) begin
                end else if(enable16 && tx_busy) begin
                        tx_count16  <= tx_count16 + 4'd1;
                        tx_count16  <= tx_count16 + 4'd1;
                        if(tx_count16 == 4'd0) begin
                        if(tx_count16 == 4'd0) begin
                                tx_bitcount <= tx_bitcount + 4'd1;
                                tx_bitcount <= tx_bitcount + 4'd1;
                                if(tx_bitcount == 4'd8) begin
                                if(tx_bitcount == 4'd8) begin
                                        uart_txd <= 1'b1;
                                        uart_tx <= 1'b1;
                                end else if(tx_bitcount == 4'd9) begin
                                end else if(tx_bitcount == 4'd9) begin
                                        uart_txd <= 1'b1;
                                        uart_tx <= 1'b1;
                                        tx_busy <= 1'b0;
                                        tx_busy <= 1'b0;
                                        tx_done <= 1'b1;
                                        tx_done <= 1'b1;
                                end else begin
                                end else begin
                                        uart_txd <= txd_reg[0];
                                        uart_tx <= tx_reg[0];
                                        txd_reg  <= {1'b0, txd_reg[7:1]};
                                        tx_reg <= {1'b0, tx_reg[7:1]};
                                end
                                end
                        end
                        end
                end
                end
        end
        end
end
end
endmodule
endmodule
uart/rtl/uart.v0000644000175000017500000000347011411201677014164 0ustar  lekernellekernel/*
uart/rtl/uart.v0000644000175000017500000000403311434747242014170 0ustar  lekernellekernel/*
 * Milkymist VJ SoC
 * Milkymist VJ SoC
 * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
 * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
 *
 *
 * This program is free software: you can redistribute it and/or modify
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3 of the License.
 * the Free Software Foundation, version 3 of the License.
 *
 *
 * This program is distributed in the hope that it will be useful,
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * GNU General Public License for more details.
 *
 *
 * You should have received a copy of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 * along with this program.  If not, see .
 */
 */
module uart #(
module uart #(
        parameter csr_addr = 4'h0,
        parameter csr_addr = 4'h0,
        parameter clk_freq = 100000000,
        parameter clk_freq = 100000000,
        parameter baud = 115200
        parameter baud = 115200
) (
) (
        input sys_clk,
        input sys_clk,
        input sys_rst,
        input sys_rst,
        input [13:0] csr_a,
        input [13:0] csr_a,
        input csr_we,
        input csr_we,
        input [31:0] csr_di,
        input [31:0] csr_di,
        output reg [31:0] csr_do,
        output reg [31:0] csr_do,
        output rx_irq,
        output rx_irq,
        output tx_irq,
        output tx_irq,
        input uart_rxd,
        input uart_rx,
        output uart_txd
        output uart_tx
);
);
reg [15:0] divisor;
reg [15:0] divisor;
wire [7:0] rx_data;
wire [7:0] rx_data;
wire [7:0] tx_data;
wire [7:0] tx_data;
wire tx_wr;
wire tx_wr;
uart_transceiver transceiver(
reg thru;
        .sys_clk(sys_clk),
wire uart_tx_transceiver;
        .sys_rst(sys_rst),
uart_transceiver transceiver(
        .uart_rxd(uart_rxd),
        .sys_clk(sys_clk),
        .uart_txd(uart_txd),
        .sys_rst(sys_rst),
        .divisor(divisor),
        .uart_rx(uart_rx),
        .uart_tx(uart_tx_transceiver),
        .rx_data(rx_data),
        .rx_done(rx_irq),
        .divisor(divisor),
        .tx_data(tx_data),
        .rx_data(rx_data),
        .tx_wr(tx_wr),
        .rx_done(rx_irq),
        .tx_done(tx_irq)
);
        .tx_data(tx_data),
        .tx_wr(tx_wr),
/* CSR interface */
        .tx_done(tx_irq)
wire csr_selected = csr_a[13:10] == csr_addr;
);
assign tx_data = csr_di[7:0];
assign uart_tx = thru ? uart_rx : uart_tx_transceiver;
assign tx_wr = csr_selected & csr_we & (csr_a[0] == 1'b0);
/* CSR interface */
parameter default_divisor = clk_freq/baud/16;
wire csr_selected = csr_a[13:10] == csr_addr;
always @(posedge sys_clk) begin
assign tx_data = csr_di[7:0];
        if(sys_rst) begin
assign tx_wr = csr_selected & csr_we & (csr_a[1:0] == 2'b00);
                divisor <= default_divisor;
                csr_do <= 32'd0;
parameter default_divisor = clk_freq/baud/16;
        end else begin
                csr_do <= 32'd0;
always @(posedge sys_clk) begin
                if(csr_selected) begin
        if(sys_rst) begin
                        case(csr_a[0])
                divisor <= default_divisor;
                                1'b0: csr_do <= rx_data;
                csr_do <= 32'd0;
                                1'b1: csr_do <= divisor;
        end else begin
                        endcase
                csr_do <= 32'd0;
                        if(csr_we) begin
                if(csr_selected) begin
                                if(csr_a[0] == 1'b1)
                        case(csr_a[1:0])
                                        divisor <= csr_di[15:0];
                                2'b00: csr_do <= rx_data;
                        end
                                2'b01: csr_do <= divisor;
                end
                                2'b10: csr_do <= thru;
        end
                        endcase
end
                        if(csr_we) begin
                                case(csr_a[1:0])
endmodule
                                        2'b00:; /* handled by transceiver */
uart/doc/0000755000175000017500000000000011422324710012756 5ustar  lekernellekerneluart/doc/uart.tex0000644000175000017500000000501511411201677014460 0ustar  lekernellekernel\documentclass[a4paper,11pt]{article}
                                        2'b01: divisor <= csr_di[15:0];
\usepackage{fullpage}
                                        2'b10: thru <= csr_di[0];
\usepackage[latin1]{inputenc}
                                endcase
\usepackage[T1]{fontenc}
                        end
\usepackage[normalem]{ulem}
                end
\usepackage[english]{babel}
        end
\usepackage{listings,babel}
end
\lstset{breaklines=true,basicstyle=\ttfamily}
\usepackage{graphicx}
endmodule
\usepackage{moreverb}
uart/doc/0000755000175000017500000000000011431543453012765 5ustar  lekernellekerneluart/doc/uart.tex0000644000175000017500000000501111434746217014465 0ustar  lekernellekernel\documentclass[a4paper,11pt]{article}
\usepackage{amsmath}
\usepackage{fullpage}
\usepackage{url}
\usepackage[latin1]{inputenc}
\usepackage{tabularx}
\usepackage[T1]{fontenc}
\usepackage[normalem]{ulem}
\title{Simple UART}
\usepackage[english]{babel}
\author{S\'ebastien Bourdeauducq}
\usepackage{listings,babel}
\date{December 2009}
\lstset{breaklines=true,basicstyle=\ttfamily}
\begin{document}
\usepackage{graphicx}
\setlength{\parindent}{0pt}
\usepackage{moreverb}
\setlength{\parskip}{5pt}
\usepackage{amsmath}
\maketitle{}
\usepackage{url}
\section{Specifications}
\usepackage{tabularx}
The UART is based on a very simple design from Das Labor. Its purpose is basically to provide a debug console.
\title{Simple UART}
The UART operates with 8 bits per character, no parity, and 1 stop bit. The default baudrate is configured during synthesis and can be modified at runtime using the divisor register.
\author{S\'ebastien Bourdeauducq}
\date{August 2010}
The divisor is computed as follows :
\begin{document}
\begin{equation*}
\setlength{\parindent}{0pt}
\text{divisor} = \frac{\text{Clock frequency (Hz)}}{16 \cdot \text{Bitrate (bps)}}
\setlength{\parskip}{5pt}
\end{equation*}
\maketitle{}
\section{Specifications}
\section{Registers}
The UART is based on a very simple design from Das Labor. Its purpose is basically to provide a debug console.
\begin{tabularx}{\textwidth}{|l|l|l|X|}
\hline
The UART operates with 8 bits per character, no parity, and 1 stop bit. The default baudrate is configured during synthesis and can be modified at runtime using the divisor register.
\bf{Offset} & \bf{Read/Write} & \bf{Default} & \bf{Description} \\
\hline
The divisor is computed as follows :
0x0 & RW & 0x00 & Data register. Received bytes and bytes to transmit are read/written from/to this register. \\
\begin{equation*}
\hline
\text{divisor} = \frac{\text{Clock frequency (Hz)}}{16 \cdot \text{Bitrate (bps)}}
0x4 & RW & for default bitrate & Divisor register (for bitrate selection). \\
\end{equation*}
\hline
\end{tabularx}\\
\section{Registers}
\begin{tabularx}{\textwidth}{|l|l|l|X|}
\section{Interrupts}
\hline
The core has two active-high edge-sensitive interrupts outputs.
\bf{Offset} & \bf{Read/Write} & \bf{Default} & \bf{Description} \\
\hline
The ``RX'' interrupt is sent whenever a new character is received. The CPU should then read the data register immediately. If a new character is sent before the CPU has had time to read it, the first character will be lost.
0x0 & RW & 0x00 & Data register. Received bytes and bytes to transmit are read/written from/to this register. \\
\hline
The ``TX'' interrupt is sent as soon as the UART finished transmitting a character. When the CPU has written to the data register, it must wait for the interrupt before writing again.
0x4 & RW & for default bitrate & Divisor register (for bitrate selection). \\
\hline
\section{Using the core}
\end{tabularx}\\
Connect the CSR signals and the interrupts to the system bus and the interrupt controller. The \verb!uart_txd! and \verb!uart_rxd! signals should go to the FPGA pads. You must also provide the desired default baudrate and the system clock frequency in Hz using the parameters.
\section{Interrupts}
\section*{Copyright notice}
The core has two active-high edge-sensitive interrupts outputs.
Copyright \copyright 2007-2009 S\'ebastien Bourdeauducq. \\
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the LICENSE.FDL file at the root of the Milkymist source distribution.
The ``RX'' interrupt is sent whenever a new character is received. The CPU should then read the data register immediately. If a new character is sent before the CPU has had time to read it, the first character will be lost.
\end{document}
The ``TX'' interrupt is sent as soon as the UART finished transmitting a character. When the CPU has written to the data register, it must wait for the interrupt before writing again.
uart/doc/Makefile0000644000175000017500000000041111411201677014416 0ustar  lekernellekernelTEX=uart.tex
\section{Using the core}
DVI=$(TEX:.tex=.dvi)
Connect the CSR signals and the interrupts to the system bus and the interrupt controller. The \verb!uart_tx! and \verb!uart_rx! signals should go to the FPGA pads. You must also provide the desired default baudrate and the system clock frequency in Hz using the parameters.
PS=$(TEX:.tex=.ps)
PDF=$(TEX:.tex=.pdf)
\section*{Copyright notice}
AUX=$(TEX:.tex=.aux)
Copyright \copyright 2007-2010 S\'ebastien Bourdeauducq. \\
LOG=$(TEX:.tex=.log)
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the LICENSE.FDL file at the root of the Milkymist source distribution.
all: $(PDF)
\end{document}
uart/doc/Makefile0000644000175000017500000000041111411201677014416 0ustar  lekernellekernelTEX=uart.tex
%.dvi: %.tex
        latex $<
DVI=$(TEX:.tex=.dvi)
PS=$(TEX:.tex=.ps)
%.ps: %.dvi
PDF=$(TEX:.tex=.pdf)
        dvips $<
AUX=$(TEX:.tex=.aux)
LOG=$(TEX:.tex=.log)
%.pdf: %.ps
        ps2pdf $<
all: $(PDF)
clean:
%.dvi: %.tex
        rm -f $(DVI) $(PS) $(PDF) $(AUX) $(LOG)
        latex $<
.PHONY: clean
%.ps: %.dvi
 
        dvips $<
 
 
%.pdf: %.ps
 
        ps2pdf $<
 
 
clean:
 
        rm -f $(DVI) $(PS) $(PDF) $(AUX) $(LOG)
 
 
.PHONY: clean
 
 

powered by: WebSVN 2.1.0

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