URL
https://opencores.org/ocsvn/uart16550/uart16550/trunk
Subversion Repositories uart16550
Compare Revisions
- This comparison shows the changes necessary to convert path
/uart16550/tags/NewFormat/rtl
- from Rev 15 to Rev 106
- ↔ Reverse comparison
Rev 15 → Rev 106
/verilog/uart_regs.v
0,0 → 1,510
////////////////////////////////////////////////////////////////////// |
//// //// |
//// uart_regs.v //// |
//// //// |
//// //// |
//// This file is part of the "UART 16550 compatible" project //// |
//// http://www.opencores.org/cores/uart16550/ //// |
//// //// |
//// Documentation related to this project: //// |
//// - http://www.opencores.org/cores/uart16550/ //// |
//// //// |
//// Projects compatibility: //// |
//// - WISHBONE //// |
//// RS232 Protocol //// |
//// 16550D uart (mostly supported) //// |
//// //// |
//// Overview (main Features): //// |
//// Registers of the uart 16550 core //// |
//// //// |
//// Known problems (limits): //// |
//// Inserts 1 wait state in all WISHBONE transfers //// |
//// //// |
//// To Do: //// |
//// Nothing or verification. //// |
//// //// |
//// Author(s): //// |
//// - gorban@opencores.org //// |
//// - Jacob Gorban //// |
//// //// |
//// Created: 2001/05/12 //// |
//// Last Updated: (See log for the revision history //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Jacob Gorban, gorban@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.10 2001/06/23 11:21:48 gorban |
// DL made 16-bit long. Fixed transmission/reception bugs. |
// |
// Revision 1.9 2001/05/31 20:08:01 gorban |
// FIFO changes and other corrections. |
// |
// Revision 1.8 2001/05/29 20:05:04 gorban |
// Fixed some bugs and synthesis problems. |
// |
// Revision 1.7 2001/05/27 17:37:49 gorban |
// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file. |
// |
// Revision 1.6 2001/05/21 19:12:02 gorban |
// Corrected some Linter messages. |
// |
// Revision 1.5 2001/05/17 18:34:18 gorban |
// First 'stable' release. Should be sythesizable now. Also added new header. |
// |
// Revision 1.0 2001-05-17 21:27:11+02 jacob |
// Initial revision |
// |
// |
|
`include "timescale.v" |
//`include "uart_defines.v" |
|
`define UART_DL1 7:0 |
`define UART_DL2 15:8 |
|
module uart_regs (clk, |
wb_rst_i, wb_addr_i, wb_dat_i, wb_dat_o, wb_we_i, |
|
// additional signals |
modem_inputs, |
pad_stx_o, pad_srx_i, |
enable, |
rts_o, dtr_o, int_o |
); |
|
input clk; |
input wb_rst_i; |
input [`UART_ADDR_WIDTH-1:0] wb_addr_i; |
input [7:0] wb_dat_i; |
output [7:0] wb_dat_o; |
input wb_we_i; |
|
output pad_stx_o; |
input pad_srx_i; |
|
input [3:0] modem_inputs; |
output enable; |
output rts_o; |
output dtr_o; |
output int_o; |
|
wire [3:0] modem_inputs; |
reg enable; |
wire pad_stx_o; // received from transmitter module |
wire pad_srx_i; |
|
reg [7:0] wb_dat_o; |
|
wire [`UART_ADDR_WIDTH-1:0] wb_addr_i; |
wire [7:0] wb_dat_i; |
|
|
reg [3:0] ier; |
reg [3:0] iir; |
reg [1:0] fcr; /// bits 7 and 6 of fcr. Other bits are ignored |
reg [4:0] mcr; |
reg [7:0] lcr; |
reg [7:0] lsr; |
reg [7:0] msr; |
reg [15:0] dl; // 32-bit divisor latch |
reg start_dlc; // activate dlc on writing to UART_DL1 |
reg lsr_mask; |
reg msi_reset; // reset MSR 4 lower bits indicator |
reg threi_clear; // THRE interrupt clear flag |
reg [15:0] dlc; // 32-bit divisor latch counter |
reg int_o; |
|
reg [3:0] trigger_level; // trigger level of the receiver FIFO |
reg rx_reset; |
reg tx_reset; |
|
wire dlab; // divisor latch access bit |
wire cts_i, dsr_i, ri_i, dcd_i; // modem status bits |
wire loopback; // loopback bit (MCR bit 4) |
wire cts, dsr, ri, dcd; // effective signals (considering loopback) |
wire rts_o, dtr_o; // modem control outputs |
|
// |
// ASSINGS |
// |
assign {cts_i, dsr_i, ri_i, dcd_i} = modem_inputs; |
assign {cts, dsr, ri, dcd} = loopback ? {mcr[`UART_MC_RTS],mcr[`UART_MC_DTR],mcr[`UART_MC_OUT1],mcr[`UART_MC_OUT2]} |
: ~{cts_i,dsr_i,ri_i,dcd_i}; |
|
assign dlab = lcr[`UART_LC_DL]; |
assign loopback = mcr[4]; |
|
// assign modem outputs |
assign rts_o = mcr[`UART_MC_RTS]; |
assign dtr_o = mcr[`UART_MC_DTR]; |
|
// Interrupt signals |
reg rls_int; // receiver line status interrupt |
reg rda_int; // receiver data available interrupt |
reg ti_int; // timeout indicator interrupt |
reg thre_int; // transmitter holding register empty interrupt |
reg ms_int; // modem status interrupt |
|
// FIFO signals |
reg tf_push; |
reg rf_pop; |
wire [`UART_FIFO_REC_WIDTH-1:0] rf_data_out; |
wire rf_error_bit; // an error (parity or framing) is inside the fifo |
wire [`UART_FIFO_COUNTER_W-1:0] rf_count; |
wire [`UART_FIFO_COUNTER_W-1:0] tf_count; |
wire [2:0] state; |
wire [5:0] counter_t; |
wire [3:0] counter_b; |
|
// Transmitter Instance |
uart_transmitter transmitter(clk, wb_rst_i, lcr, tf_push, wb_dat_i, enable, pad_stx_o, state, tf_count, tx_reset); |
|
// Receiver Instance |
uart_receiver receiver(clk, wb_rst_i, lcr, rf_pop, pad_srx_i, enable, rda_int, |
counter_t, counter_b, rf_count, rf_data_out, rf_error_bit, rf_overrun, rx_reset); |
|
always @(posedge clk or posedge wb_rst_i) // synchrounous reading |
begin |
if (wb_rst_i) |
begin |
wb_dat_o <= #1 8'b0; |
end |
else |
if (!wb_we_i) //if (we're not writing) |
case (wb_addr_i) |
`UART_REG_RB : if (dlab) // Receiver FIFO or DL byte 1 |
wb_dat_o <= #1 dl[`UART_DL1]; |
else |
wb_dat_o <= #1 rf_data_out[9:2]; |
`UART_REG_IE : wb_dat_o <= #1 dlab ? dl[`UART_DL2] : ier; |
`UART_REG_II : wb_dat_o <= #1 {4'b1100,iir}; |
`UART_REG_LC : wb_dat_o <= #1 lcr; |
`UART_REG_LS : wb_dat_o <= #1 lsr; |
`UART_REG_MS : wb_dat_o <= #1 msr; |
default: wb_dat_o <= #1 8'b0; // ?? |
endcase |
else |
wb_dat_o <= #1 8'b0; |
end |
|
// rf_pop signal handling |
always @(posedge clk or posedge wb_rst_i) |
begin |
if (wb_rst_i) |
rf_pop <= #1 0; |
else |
if (rf_pop) // restore the signal to 0 after one clock cycle |
rf_pop <= #1 0; |
else |
if (!wb_we_i && wb_addr_i == `UART_REG_RB && !dlab) |
rf_pop <= #1 1; // advance read pointer |
end |
|
// lsr_mask signal handling |
always @(posedge clk or posedge wb_rst_i) |
begin |
if (wb_rst_i) |
lsr_mask <= #1 0; |
else |
if (lsr_mask) |
lsr_mask <= #1 0; |
else |
if (!wb_we_i && wb_addr_i == `UART_REG_LS && !dlab) |
lsr_mask <= #1 1; // reset bits in the Line Status Register |
end |
|
// msi_reset signal handling |
always @(posedge clk or posedge wb_rst_i) |
begin |
if (wb_rst_i) |
msi_reset <= #1 0; |
else |
if (msi_reset) |
msi_reset <= #1 0; |
else |
if (!wb_we_i && wb_addr_i == `UART_REG_MS) |
msi_reset <= #1 1; // reset bits in Modem Status Register |
end |
|
// threi_clear signal handling |
always @(posedge clk or posedge wb_rst_i) |
begin |
if (wb_rst_i) |
threi_clear <= #1 0; |
else |
if (threi_clear && !lsr[`UART_LS_TFE] && (tf_count==0)) // reset clear flag when tx fifo clears |
threi_clear <= #1 0; |
else |
if (!wb_we_i && wb_addr_i == `UART_REG_II) |
threi_clear <= #1 1; // reset bits in Modem Status Register |
end |
|
// |
// WRITES AND RESETS // |
// |
// Line Control Register |
always @(posedge clk or posedge wb_rst_i) |
if (wb_rst_i) |
lcr <= #1 8'b00000011; // 8n1 setting |
else |
if (wb_we_i && wb_addr_i==`UART_REG_LC) |
lcr <= #1 wb_dat_i; |
|
// Interrupt Enable Register or UART_DL2 |
always @(posedge clk or posedge wb_rst_i) |
if (wb_rst_i) |
begin |
ier <= #1 4'b0000; // no interrupts after reset |
dl[`UART_DL2] <= #1 8'b0; |
end |
else |
if (wb_we_i && wb_addr_i==`UART_REG_IE) |
if (dlab) |
begin |
dl[`UART_DL2] <= #1 wb_dat_i; |
end |
else |
ier <= #1 wb_dat_i[3:0]; // ier uses only 4 lsb |
|
|
// FIFO Control Register and rx_reset, tx_reset signals |
always @(posedge clk or posedge wb_rst_i) |
if (wb_rst_i) begin |
fcr <= #1 2'b11; |
rx_reset <= #1 0; |
tx_reset <= #1 0; |
end else |
if (wb_we_i && wb_addr_i==`UART_REG_FC) begin |
fcr <= #1 wb_dat_i[7:6]; |
rx_reset <= #1 wb_dat_i[1]; |
tx_reset <= #1 wb_dat_i[2]; |
end else begin // clear rx_reset, tx_reset signals when not written to |
rx_reset <= #1 0; |
tx_reset <= #1 0; |
end |
|
// Modem Control Register |
always @(posedge clk or posedge wb_rst_i) |
if (wb_rst_i) |
mcr <= #1 5'b0; |
else |
if (wb_we_i && wb_addr_i==`UART_REG_MC) |
mcr <= #1 wb_dat_i[4:0]; |
|
// TX_FIFO or UART_DL1 |
always @(posedge clk or posedge wb_rst_i) |
if (wb_rst_i) |
begin |
dl[`UART_DL1] <= #1 8'b0; |
tf_push <= #1 1'b0; |
start_dlc <= #1 1'b0; |
end |
else |
if (wb_we_i && wb_addr_i==`UART_REG_TR) |
if (dlab) |
begin |
dl[`UART_DL1] <= #1 wb_dat_i; |
start_dlc <= #1 1'b1; // enable DL counter |
tf_push <= #1 1'b0; |
end |
else |
begin |
tf_push <= #1 1'b1; |
start_dlc <= #1 1'b0; |
end |
else |
begin |
start_dlc <= #1 1'b0; |
tf_push <= #1 1'b0; |
end |
|
// Receiver FIFO trigger level selection logic (asynchronous mux) |
always @(fcr[`UART_FC_TL]) |
case (fcr[`UART_FC_TL]) |
2'b00 : trigger_level = 1; |
2'b01 : trigger_level = 4; |
2'b10 : trigger_level = 8; |
2'b11 : trigger_level = 14; |
endcase |
|
// |
// STATUS REGISTERS // |
// |
|
// Modem Status Register |
always @(posedge clk or posedge wb_rst_i) |
begin |
if (wb_rst_i) |
msr <= #1 0; |
else begin |
msr[`UART_MS_DDCD:`UART_MS_DCTS] <= #1 msi_reset ? 4'b0 : |
msr[`UART_MS_DDCD:`UART_MS_DCTS] | ({dcd, ri, dsr, cts} ^ msr[`UART_MS_CDCD:`UART_MS_CCTS]); |
msr[`UART_MS_CDCD:`UART_MS_CCTS] <= #1 {dcd, ri, dsr, cts}; |
end |
end |
|
// Line Status Register |
always @(posedge clk or posedge wb_rst_i) |
begin |
if (wb_rst_i) |
lsr <= #1 8'b01100000; |
else |
if (lsr_mask) |
lsr <= #1 lsr & 8'b00000001; |
else |
begin |
lsr[0] <= #1 (rf_count!=4'b0); // data in receiver fifo available |
lsr[1] <= #1 rf_overrun; // Receiver overrun error |
lsr[2] <= #1 rf_data_out[1]; // parity error bit |
lsr[3] <= #1 rf_data_out[0]; // framing error bit |
lsr[4] <= #1 (counter_b==4'b0); // break counter reached 0 |
lsr[5] <= #1 (tf_count==5'b0); // transmitter fifo is empty |
lsr[6] <= #1 (tf_count==5'b0 && (state == /*`S_IDLE */ 0)); // transmitter empty |
lsr[7] <= #1 rf_error_bit; |
end |
end |
|
// Enable signal generation logic |
always @(posedge clk or posedge wb_rst_i) |
begin |
if (wb_rst_i) |
begin |
dlc <= #1 0; |
enable <= #1 1'b0; |
end |
else |
begin |
if (start_dlc) |
begin |
enable <= #1 1'b0; |
dlc <= #1 dl; |
end |
else |
begin |
if (dl!=0) |
begin |
if ( (dlc-1)==0 ) |
begin |
enable <= #1 1'b1; |
dlc <= #1 dl; |
end |
else |
begin |
enable <= #1 1'b0; |
dlc <= #1 dlc - 1; |
end |
end |
else |
begin |
dlc <= #1 0; |
enable <= #1 1'b0; |
end |
end |
end |
end |
|
// |
// INTERRUPT LOGIC |
// |
always @(posedge clk or posedge wb_rst_i) |
begin |
if (wb_rst_i) |
begin |
rls_int <= #1 1'b0; |
rda_int <= #1 1'b0; |
ti_int <= #1 1'b0; |
thre_int <= #1 1'b0; |
ms_int <= #1 1'b0; |
end |
else |
begin |
rls_int <= #1 ier[`UART_IE_RLS] && (lsr[`UART_LS_OE] || lsr[`UART_LS_PE] || lsr[`UART_LS_FE] || lsr[`UART_LS_BI]); |
rda_int <= #1 ier[`UART_IE_RDA] && (rf_count >= {1'b0,trigger_level}); |
thre_int <= #1 threi_clear ? 0 : ier[`UART_IE_THRE] && lsr[`UART_LS_TFE]; |
ms_int <= #1 ier[`UART_IE_MS] && (| msr[3:0]); |
ti_int <= #1 ier[`UART_IE_RDA] && (counter_t == 6'b0); |
end |
end |
|
always @(posedge clk or posedge wb_rst_i) |
begin |
if (wb_rst_i) |
int_o <= #1 1'b0; |
else |
if (| {rls_int,rda_int,thre_int,ms_int,ti_int}) |
int_o <= #1 1'b1; |
else |
int_o <= #1 1'b0; |
end |
|
|
// Interrupt Identification register |
always @(posedge clk or posedge wb_rst_i) |
begin |
if (wb_rst_i) |
iir <= #1 1; |
else |
if (rls_int) // interrupt occured and is enabled (not masked) |
begin |
iir[`UART_II_II] <= #1 `UART_II_RLS; // set identification register to correct value |
iir[`UART_II_IP] <= #1 1'b0; // and clear the IIR bit 0 (interrupt pending) |
end |
else |
if (rda_int) |
begin |
iir[`UART_II_II] <= #1 `UART_II_RDA; |
iir[`UART_II_IP] <= #1 1'b0; |
end |
else |
if (ti_int) |
begin |
iir[`UART_II_II] <= #1 `UART_II_TI; |
iir[`UART_II_IP] <= #1 1'b0; |
end |
else |
if (thre_int) |
begin |
iir[`UART_II_II] <= #1 `UART_II_THRE; |
iir[`UART_II_IP] <= #1 1'b0; |
end |
else |
if (ms_int) |
begin |
iir[`UART_II_II] <= #1 `UART_II_MS; |
iir[`UART_II_IP] <= #1 1'b0; |
end |
else // no interrupt is pending |
begin |
iir[`UART_II_IP] <= #1 1'b1; |
end |
end |
|
endmodule |
/verilog/uart_top.v
0,0 → 1,168
////////////////////////////////////////////////////////////////////// |
//// //// |
//// uart_top.v //// |
//// //// |
//// //// |
//// This file is part of the "UART 16550 compatible" project //// |
//// http://www.opencores.org/cores/uart16550/ //// |
//// //// |
//// Documentation related to this project: //// |
//// - http://www.opencores.org/cores/uart16550/ //// |
//// //// |
//// Projects compatibility: //// |
//// - WISHBONE //// |
//// RS232 Protocol //// |
//// 16550D uart (mostly supported) //// |
//// //// |
//// Overview (main Features): //// |
//// UART core top level. //// |
//// //// |
//// Known problems (limits): //// |
//// Note that transmitter and receiver instances are inside //// |
//// the uart_regs.v file. //// |
//// //// |
//// To Do: //// |
//// Nothing so far. //// |
//// //// |
//// Author(s): //// |
//// - gorban@opencores.org //// |
//// - Jacob Gorban //// |
//// //// |
//// Created: 2001/05/12 //// |
//// Last Updated: 2001/05/17 //// |
//// (See log for the revision history) //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Jacob Gorban, gorban@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.4 2001/05/31 20:08:01 gorban |
// FIFO changes and other corrections. |
// |
// Revision 1.3 2001/05/21 19:12:02 gorban |
// Corrected some Linter messages. |
// |
// Revision 1.2 2001/05/17 18:34:18 gorban |
// First 'stable' release. Should be sythesizable now. Also added new header. |
// |
// Revision 1.0 2001-05-17 21:27:12+02 jacob |
// Initial revision |
// |
// |
|
`include "timescale.v" |
`include "uart_defines.v" |
|
module uart_top ( |
clk, |
|
// Wishbone signals |
wb_rst_i, wb_addr_i, wb_dat_i, wb_dat_o, wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, |
int_o, // interrupt request |
|
// UART signals |
// serial input/output |
pad_stx_o, pad_srx_i, |
|
// modem signals |
rts_o, cts_i, dtr_o, dsr_i, ri_i, dcd_i |
|
); |
|
parameter uart_data_width = 8; |
parameter uart_addr_width = `UART_ADDR_WIDTH; |
|
input clk; |
|
// WISHBONE interface |
input wb_rst_i; |
input [uart_addr_width-1:0] wb_addr_i; |
input [uart_data_width-1:0] wb_dat_i; |
output [uart_data_width-1:0] wb_dat_o; |
input wb_we_i; |
input wb_stb_i; |
input wb_cyc_i; |
output wb_ack_o; |
output int_o; |
|
// UART signals |
input pad_srx_i; |
output pad_stx_o; |
output rts_o; |
input cts_i; |
output dtr_o; |
input dsr_i; |
input ri_i; |
input dcd_i; |
|
wire pad_stx_o; |
wire rts_o; |
wire dtr_o; |
|
wire [uart_addr_width-1:0] wb_addr_i; |
wire [uart_data_width-1:0] wb_dat_i; |
wire [uart_data_width-1:0] wb_dat_o; |
|
wire we_o; // Write enable for registers |
|
// |
// MODULE INSTANCES |
// |
|
//// WISHBONE interface module |
uart_wb wb_interface( |
.clk( clk ), |
.wb_rst_i( wb_rst_i ), |
.wb_we_i( wb_we_i ), |
.wb_stb_i( wb_stb_i ), |
.wb_cyc_i( wb_cyc_i ), |
.wb_ack_o( wb_ack_o ), |
.we_o( we_o ) |
); |
|
// Registers |
uart_regs regs( |
.clk( clk ), |
.wb_rst_i( wb_rst_i ), |
.wb_addr_i( wb_addr_i ), |
.wb_dat_i( wb_dat_i ), |
.wb_dat_o( wb_dat_o ), |
.wb_we_i( we_o ), |
.modem_inputs( {cts_i, dsr_i, |
ri_i, dcd_i} ), |
.pad_stx_o( pad_stx_o ), |
.pad_srx_i( pad_srx_i ), |
.enable( enable ), |
.rts_o( rts_o ), |
.dtr_o( dtr_o ), |
.int_o( int_o ) |
); |
|
endmodule |
/verilog/uart_fifo.v
0,0 → 1,265
////////////////////////////////////////////////////////////////////// |
//// //// |
//// uart_fifo.v //// |
//// //// |
//// //// |
//// This file is part of the "UART 16550 compatible" project //// |
//// http://www.opencores.org/cores/uart16550/ //// |
//// //// |
//// Documentation related to this project: //// |
//// - http://www.opencores.org/cores/uart16550/ //// |
//// //// |
//// Projects compatibility: //// |
//// - WISHBONE //// |
//// RS232 Protocol //// |
//// 16550D uart (mostly supported) //// |
//// //// |
//// Overview (main Features): //// |
//// UART core receiver FIFO //// |
//// //// |
//// Known problems (limits): //// |
//// Note that the same FIFO is used for both transmission and //// |
//// reception but the error bit generation is ignored in tx. //// |
//// //// |
//// To Do: //// |
//// Nothing. //// |
//// //// |
//// Author(s): //// |
//// - gorban@opencores.org //// |
//// - Jacob Gorban //// |
//// //// |
//// Created: 2001/05/12 //// |
//// Last Updated: 2001/05/17 //// |
//// (See log for the revision history) //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Jacob Gorban, gorban@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2001/05/31 20:08:01 gorban |
// FIFO changes and other corrections. |
// |
// Revision 1.3 2001/05/27 17:37:48 gorban |
// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file. |
// |
// Revision 1.2 2001/05/17 18:34:18 gorban |
// First 'stable' release. Should be sythesizable now. Also added new header. |
// |
// Revision 1.0 2001-05-17 21:27:12+02 jacob |
// Initial revision |
// |
// |
|
`include "timescale.v" |
//`include "uart_defines.v" |
|
module uart_fifo (clk, |
wb_rst_i, data_in, data_out, |
// Control signals |
push, // push strobe, active high |
pop, // pop strobe, active high |
// status signals |
underrun, |
overrun, |
count, |
error_bit, |
fifo_reset |
); |
|
|
// FIFO parameters |
parameter fifo_width = `UART_FIFO_WIDTH; |
parameter fifo_depth = `UART_FIFO_DEPTH; |
parameter fifo_pointer_w = `UART_FIFO_POINTER_W; |
parameter fifo_counter_w = `UART_FIFO_COUNTER_W; |
|
input clk; |
input wb_rst_i; |
input push; |
input pop; |
input [fifo_width-1:0] data_in; |
input fifo_reset; |
output [fifo_width-1:0] data_out; |
output overrun; |
output underrun; |
output [fifo_counter_w-1:0] count; |
output error_bit; |
|
wire [fifo_width-1:0] data_out; |
|
// FIFO itself |
reg [fifo_width-1:0] fifo[fifo_depth-1:0]; |
|
// FIFO pointers |
reg [fifo_pointer_w-1:0] top; |
reg [fifo_pointer_w-1:0] bottom; |
|
reg [fifo_counter_w-1:0] count; |
reg overrun; |
reg underrun; |
|
// These registers and signals are to detect rise of of the signals. |
// Not that it slows the maximum rate by 2, meaning you must reset the signals and then |
// assert them again for the operation to repeat |
// This is done to accomodate wait states |
reg push_delay; |
reg pop_delay; |
|
wire push_rise = push_delay & push; |
wire pop_rise = pop_delay & pop; |
|
wire [fifo_pointer_w-1:0] top_plus_1 = top + 1; |
|
always @(posedge clk or posedge wb_rst_i) |
begin |
if (wb_rst_i) |
push_delay <= #1 1'b0; |
else |
push_delay <= #1 ~push; |
end |
|
always @(posedge clk or posedge wb_rst_i) |
begin |
if (wb_rst_i) |
pop_delay <= #1 1'b0; |
else |
pop_delay <= #1 ~pop; |
end |
|
|
always @(posedge clk or posedge wb_rst_i) // synchronous FIFO |
begin |
if (wb_rst_i) |
begin |
top <= #1 0; |
bottom <= #1 1; |
underrun <= #1 1'b0; |
overrun <= #1 1'b0; |
count <= #1 0; |
fifo[0] <= #1 0; |
fifo[1] <= #1 0; |
fifo[2] <= #1 0; |
fifo[3] <= #1 0; |
fifo[4] <= #1 0; |
fifo[5] <= #1 0; |
fifo[6] <= #1 0; |
fifo[7] <= #1 0; |
fifo[8] <= #1 0; |
fifo[9] <= #1 0; |
fifo[10] <= #1 0; |
fifo[11] <= #1 0; |
fifo[12] <= #1 0; |
fifo[13] <= #1 0; |
fifo[14] <= #1 0; |
fifo[15] <= #1 0; |
end |
else |
if (fifo_reset) begin |
top <= #1 0; |
bottom <= #1 1; |
underrun <= #1 1'b0; |
overrun <= #1 1'b0; |
count <= #1 0; |
end |
else |
begin |
case ({push_rise, pop_rise}) |
2'b00 : begin |
underrun <= #1 1'b0; |
overrun <= #1 1'b0; |
end |
2'b10 : if (count==fifo_depth) // overrun condition |
begin |
overrun <= #1 1'b1; |
underrun <= #1 1'b0; |
end |
else |
begin |
top <= #1 top_plus_1; |
fifo[top_plus_1] <= #1 data_in; |
underrun <= #1 0; |
overrun <= #1 0; |
count <= #1 count + 1; |
end |
2'b01 : if (~|count) |
begin |
underrun <= #1 1'b1; // underrun condition |
overrun <= #1 1'b0; |
end |
else |
begin |
bottom <= #1 bottom + 1; |
underrun <= #1 1'b0; |
overrun <= #1 1'b0; |
count <= #1 count - 1; |
end |
2'b11 : begin |
bottom <= #1 bottom + 1; |
top <= #1 top_plus_1; |
fifo[top_plus_1] <= #1 data_in; |
underrun <= #1 1'b0; |
overrun <= #1 1'b0; |
end |
endcase |
end |
|
end // always |
|
// please note though that data_out is only valid one clock after pop signal |
assign data_out = fifo[bottom]; |
|
// Additional logic for detection of error conditions (parity and framing) inside the FIFO |
// for the Line Status Register bit 7 |
|
wire [fifo_width-1:0] word0 = fifo[0]; |
wire [fifo_width-1:0] word1 = fifo[1]; |
wire [fifo_width-1:0] word2 = fifo[2]; |
wire [fifo_width-1:0] word3 = fifo[3]; |
wire [fifo_width-1:0] word4 = fifo[4]; |
wire [fifo_width-1:0] word5 = fifo[5]; |
wire [fifo_width-1:0] word6 = fifo[6]; |
wire [fifo_width-1:0] word7 = fifo[7]; |
|
wire [fifo_width-1:0] word8 = fifo[8]; |
wire [fifo_width-1:0] word9 = fifo[9]; |
wire [fifo_width-1:0] word10 = fifo[10]; |
wire [fifo_width-1:0] word11 = fifo[11]; |
wire [fifo_width-1:0] word12 = fifo[12]; |
wire [fifo_width-1:0] word13 = fifo[13]; |
wire [fifo_width-1:0] word14 = fifo[14]; |
wire [fifo_width-1:0] word15 = fifo[15]; |
|
// a 1 is returned if any of the error bits in the fifo is 1 |
assign error_bit = |(word0[1:0] | word1[1:0] | word2[1:0] | word3[1:0] | |
word4[1:0] | word5[1:0] | word6[1:0] | word7[1:0] | |
word8[1:0] | word9[1:0] | word10[1:0] | word11[1:0] | |
word12[1:0] | word13[1:0] | word14[1:0] | word15[1:0] ); |
|
endmodule |
/verilog/uart_receiver.v
0,0 → 1,335
////////////////////////////////////////////////////////////////////// |
//// //// |
//// uart_receiver.v //// |
//// //// |
//// //// |
//// This file is part of the "UART 16550 compatible" project //// |
//// http://www.opencores.org/cores/uart16550/ //// |
//// //// |
//// Documentation related to this project: //// |
//// - http://www.opencores.org/cores/uart16550/ //// |
//// //// |
//// Projects compatibility: //// |
//// - WISHBONE //// |
//// RS232 Protocol //// |
//// 16550D uart (mostly supported) //// |
//// //// |
//// Overview (main Features): //// |
//// UART core receiver logic //// |
//// //// |
//// Known problems (limits): //// |
//// None known //// |
//// //// |
//// To Do: //// |
//// Thourough testing. //// |
//// //// |
//// Author(s): //// |
//// - gorban@opencores.org //// |
//// - Jacob Gorban //// |
//// //// |
//// Created: 2001/05/12 //// |
//// Last Updated: 2001/05/17 //// |
//// (See log for the revision history) //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Jacob Gorban, gorban@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.6 2001/06/23 11:21:48 gorban |
// DL made 16-bit long. Fixed transmission/reception bugs. |
// |
// Revision 1.5 2001/06/02 14:28:14 gorban |
// Fixed receiver and transmitter. Major bug fixed. |
// |
// Revision 1.4 2001/05/31 20:08:01 gorban |
// FIFO changes and other corrections. |
// |
// Revision 1.3 2001/05/27 17:37:49 gorban |
// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file. |
// |
// Revision 1.2 2001/05/21 19:12:02 gorban |
// Corrected some Linter messages. |
// |
// Revision 1.1 2001/05/17 18:34:18 gorban |
// First 'stable' release. Should be sythesizable now. Also added new header. |
// |
// Revision 1.0 2001-05-17 21:27:11+02 jacob |
// Initial revision |
// |
// |
|
`include "timescale.v" |
//`include "uart_defines.v" |
|
module uart_receiver (clk, wb_rst_i, lcr, rf_pop, pad_srx_i, enable, rda_int, |
counter_t, counter_b, rf_count, rf_data_out, rf_error_bit, rf_overrun, rx_reset); |
|
input clk; |
input wb_rst_i; |
input [7:0] lcr; |
input rf_pop; |
input pad_srx_i; |
input enable; |
input rda_int; |
input rx_reset; |
|
output [5:0] counter_t; |
output [3:0] counter_b; |
output [`UART_FIFO_COUNTER_W-1:0] rf_count; |
output [`UART_FIFO_REC_WIDTH-1:0] rf_data_out; |
output rf_overrun; |
output rf_error_bit; |
|
reg [3:0] rstate; |
reg [3:0] rcounter16; |
reg [2:0] rbit_counter; |
reg [7:0] rshift; // receiver shift register |
reg rparity; // received parity |
reg rparity_error; |
reg rframing_error; // framing error flag |
reg rbit_in; |
reg rparity_xor; |
|
// RX FIFO signals |
reg [`UART_FIFO_REC_WIDTH-1:0] rf_data_in; |
wire [`UART_FIFO_REC_WIDTH-1:0] rf_data_out; |
reg rf_push; |
wire rf_pop; |
wire rf_underrun; |
wire rf_overrun; |
wire [`UART_FIFO_COUNTER_W-1:0] rf_count; |
wire rf_error_bit; // an error (parity or framing) is inside the fifo |
|
// RX FIFO instance |
uart_fifo #(`UART_FIFO_REC_WIDTH) fifo_rx( |
.clk( clk ), |
.wb_rst_i( wb_rst_i ), |
.data_in( rf_data_in ), |
.data_out( rf_data_out ), |
.push( rf_push ), |
.pop( rf_pop ), |
.underrun( rf_underrun ), |
.overrun( rf_overrun ), |
.count( rf_count ), |
.error_bit( rf_error_bit ), |
.fifo_reset( rx_reset ) |
); |
|
wire rcounter16_eq_7 = (rcounter16 == 4'd7); |
wire rcounter16_eq_0 = (rcounter16 == 4'd0); |
wire rcounter16_eq_1 = (rcounter16 == 4'd1); |
|
wire [3:0] rcounter16_minus_1 = rcounter16 - 4'd1; |
|
parameter sr_idle = 4'd0; |
parameter sr_rec_start = 4'd1; |
parameter sr_rec_bit = 4'd2; |
parameter sr_rec_parity = 4'd3; |
parameter sr_rec_stop = 4'd4; |
parameter sr_check_parity = 4'd5; |
parameter sr_rec_prepare = 4'd6; |
parameter sr_end_bit = 4'd7; |
parameter sr_ca_lc_parity = 4'd8; |
parameter sr_wait1 = 4'd9; |
parameter sr_push = 4'd10; |
parameter sr_last = 4'd11; |
|
always @(posedge clk or posedge wb_rst_i) |
begin |
if (wb_rst_i) |
begin |
rstate <= #1 sr_idle; |
rbit_in <= #1 1'b0; |
rcounter16 <= #1 0; |
rbit_counter <= #1 0; |
rparity_xor <= #1 1'b0; |
rframing_error <= #1 1'b0; |
rparity_error <= #1 1'b0; |
rparity <= #1 1'b0; |
rshift <= #1 0; |
rf_push <= #1 1'b0; |
rf_data_in <= #1 0; |
end |
else |
if (enable) |
begin |
case (rstate) |
sr_idle : if (pad_srx_i==1'b0) // detected a pulse (start bit?) |
begin |
rstate <= #1 sr_rec_start; |
rcounter16 <= #1 4'b1110; |
end |
else |
rstate <= #1 sr_idle; |
sr_rec_start : begin |
if (rcounter16_eq_7) // check the pulse |
if (pad_srx_i==1'b1) // no start bit |
rstate <= #1 sr_idle; |
else // start bit detected |
rstate <= #1 sr_rec_prepare; |
rcounter16 <= #1 rcounter16_minus_1; |
end |
sr_rec_prepare:begin |
case (lcr[/*`UART_LC_BITS*/1:0]) // number of bits in a word |
2'b00 : rbit_counter <= #1 3'b100; |
2'b01 : rbit_counter <= #1 3'b101; |
2'b10 : rbit_counter <= #1 3'b110; |
2'b11 : rbit_counter <= #1 3'b111; |
endcase |
if (rcounter16_eq_0) |
begin |
rstate <= #1 sr_rec_bit; |
rcounter16 <= #1 4'b1110; |
rshift <= #1 0; |
end |
else |
rstate <= #1 sr_rec_prepare; |
rcounter16 <= #1 rcounter16_minus_1; |
end |
sr_rec_bit : begin |
if (rcounter16_eq_0) |
rstate <= #1 sr_end_bit; |
if (rcounter16_eq_7) // read the bit |
case (lcr[/*`UART_LC_BITS*/1:0]) // number of bits in a word |
2'b00 : rshift[4:0] <= #1 {pad_srx_i, rshift[4:1]}; |
2'b01 : rshift[5:0] <= #1 {pad_srx_i, rshift[5:1]}; |
2'b10 : rshift[6:0] <= #1 {pad_srx_i, rshift[6:1]}; |
2'b11 : rshift[7:0] <= #1 {pad_srx_i, rshift[7:1]}; |
endcase |
rcounter16 <= #1 rcounter16_minus_1; |
end |
sr_end_bit : begin |
if (rbit_counter==3'b0) // no more bits in word |
if (lcr[`UART_LC_PE]) // choose state based on parity |
rstate <= #1 sr_rec_parity; |
else |
begin |
rstate <= #1 sr_rec_stop; |
rparity_error <= #1 1'b0; // no parity - no error :) |
end |
else // else we have more bits to read |
begin |
rstate <= #1 sr_rec_bit; |
rbit_counter <= #1 rbit_counter - 3'b1; |
end |
rcounter16 <= #1 4'b1110; |
end |
sr_rec_parity: begin |
if (rcounter16_eq_7) // read the parity |
begin |
rparity <= #1 pad_srx_i; |
rstate <= #1 sr_ca_lc_parity; |
end |
rcounter16 <= #1 rcounter16_minus_1; |
end |
sr_ca_lc_parity : begin // rcounter equals 6 |
rcounter16 <= #1 rcounter16_minus_1; |
rparity_xor <= #1 ^{rshift,rparity}; // calculate parity on all incoming data |
rstate <= #1 sr_check_parity; |
end |
sr_check_parity: begin // rcounter equals 5 |
case ({lcr[`UART_LC_EP],lcr[`UART_LC_SP]}) |
2'b00: rparity_error <= #1 ~rparity_xor; // no error if parity 1 |
2'b01: rparity_error <= #1 ~rparity; // parity should sticked to 1 |
2'b10: rparity_error <= #1 rparity_xor; // error if parity is odd |
2'b11: rparity_error <= #1 rparity; // parity should be sticked to 0 |
endcase |
rcounter16 <= #1 rcounter16_minus_1; |
rstate <= #1 sr_wait1; |
end |
sr_wait1 : if (rcounter16_eq_0) |
begin |
rstate <= #1 sr_rec_stop; |
rcounter16 <= #1 4'b1110; |
end |
else |
rcounter16 <= #1 rcounter16_minus_1; |
sr_rec_stop : begin |
if (rcounter16_eq_7) // read the parity |
begin |
rframing_error <= #1 !pad_srx_i; // no framing error if input is 1 (stop bit) |
rf_data_in <= #1 {rshift, rparity_error, rframing_error}; |
rstate <= #1 sr_push; |
end |
rcounter16 <= #1 rcounter16_minus_1; |
end |
sr_push : begin |
/////////////////////////////////////// |
// $display($time, ": received: %b", rf_data_in); |
rf_push <= #1 1'b1; |
rstate <= #1 sr_last; |
end |
sr_last : begin |
if (rcounter16_eq_1) |
rstate <= #1 sr_idle; |
rcounter16 <= #1 rcounter16_minus_1; |
rf_push <= #1 1'b0; |
end |
default : rstate <= #1 sr_idle; |
endcase |
end // if (enable) |
end // always of receiver |
|
// |
// Break condition detection. |
// Works in conjuction with the receiver state machine |
reg [3:0] counter_b; // counts the 1 (idle) signals |
|
always @(posedge clk or posedge wb_rst_i) |
begin |
if (wb_rst_i) |
counter_b <= #1 4'd11; |
else |
if (enable) // only work on enable times |
if (!pad_srx_i) |
counter_b <= #1 4'd11; // maximum character time length - 1 |
else |
if (counter_b != 4'b0) // break reached |
counter_b <= #1 counter_b - 4'd1; // decrement break counter |
end // always of break condition detection |
|
/// |
/// Timeout condition detection |
reg [5:0] counter_t; // counts the timeout condition clocks |
|
always @(posedge clk or posedge wb_rst_i) |
begin |
if (wb_rst_i) |
counter_t <= #1 6'd44; |
else |
if (enable) |
if(rf_push || rf_pop || rda_int) // counter is reset when RX FIFO is accessed or above trigger level |
counter_t <= #1 6'd44; |
else |
if (counter_t != 6'b0) // we don't want to underflow |
counter_t <= #1 counter_t - 6'd1; |
end |
|
endmodule |
/verilog/uart_wb.v
0,0 → 1,122
////////////////////////////////////////////////////////////////////// |
//// //// |
//// uart_TX_FIFO.v //// |
//// //// |
//// //// |
//// This file is part of the "UART 16550 compatible" project //// |
//// http://www.opencores.org/cores/uart16550/ //// |
//// //// |
//// Documentation related to this project: //// |
//// - http://www.opencores.org/cores/uart16550/ //// |
//// //// |
//// Projects compatibility: //// |
//// - WISHBONE //// |
//// RS232 Protocol //// |
//// 16550D uart (mostly supported) //// |
//// //// |
//// Overview (main Features): //// |
//// UART core WISHBONE interface. //// |
//// //// |
//// Known problems (limits): //// |
//// Inserts one wait state on all transfers. //// |
//// Note affected signals and the way they are affected. //// |
//// //// |
//// To Do: //// |
//// Nothing. //// |
//// //// |
//// Author(s): //// |
//// - gorban@opencores.org //// |
//// - Jacob Gorban //// |
//// //// |
//// Created: 2001/05/12 //// |
//// Last Updated: 2001/05/17 //// |
//// (See log for the revision history) //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Jacob Gorban, gorban@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.4 2001/05/31 20:08:01 gorban |
// FIFO changes and other corrections. |
// |
// Revision 1.3 2001/05/21 19:12:01 gorban |
// Corrected some Linter messages. |
// |
// Revision 1.2 2001/05/17 18:34:18 gorban |
// First 'stable' release. Should be sythesizable now. Also added new header. |
// |
// Revision 1.0 2001-05-17 21:27:13+02 jacob |
// Initial revision |
// |
// |
|
// UART core WISHBONE interface |
// |
// Author: Jacob Gorban (jacob.gorban@flextronicssemi.com) |
// Company: Flextronics Semiconductor |
// |
|
`include "timescale.v" |
|
module uart_wb (clk, |
wb_rst_i, |
wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, |
we_o // Write enable output for the core |
|
); |
|
input clk; |
|
// WISHBONE interface |
input wb_rst_i; |
input wb_we_i; |
input wb_stb_i; |
input wb_cyc_i; |
output wb_ack_o; |
output we_o; |
|
wire we_o; |
reg wb_ack_o; |
|
always @(posedge clk or posedge wb_rst_i) |
begin |
if (wb_rst_i) |
begin |
wb_ack_o <= #1 1'b0; |
end |
else |
begin |
wb_ack_o <= #1 wb_stb_i & wb_cyc_i; // 1 clock wait state on all transfers |
end |
end |
|
assign we_o = wb_we_i & wb_cyc_i & wb_stb_i; //WE for registers |
|
endmodule |
/verilog/timescale.v
0,0 → 1,3
// Timescale define |
|
`timescale 1ns/10ps |
/verilog/uart_transmitter.v
0,0 → 1,278
////////////////////////////////////////////////////////////////////// |
//// //// |
//// uart_transmitter.v //// |
//// //// |
//// //// |
//// This file is part of the "UART 16550 compatible" project //// |
//// http://www.opencores.org/cores/uart16550/ //// |
//// //// |
//// Documentation related to this project: //// |
//// - http://www.opencores.org/cores/uart16550/ //// |
//// //// |
//// Projects compatibility: //// |
//// - WISHBONE //// |
//// RS232 Protocol //// |
//// 16550D uart (mostly supported) //// |
//// //// |
//// Overview (main Features): //// |
//// UART core transmitter logic //// |
//// //// |
//// Known problems (limits): //// |
//// None known //// |
//// //// |
//// To Do: //// |
//// Thourough testing. //// |
//// //// |
//// Author(s): //// |
//// - gorban@opencores.org //// |
//// - Jacob Gorban //// |
//// //// |
//// Created: 2001/05/12 //// |
//// Last Updated: 2001/05/17 //// |
//// (See log for the revision history) //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Jacob Gorban, gorban@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.6 2001/06/23 11:21:48 gorban |
// DL made 16-bit long. Fixed transmission/reception bugs. |
// |
// Revision 1.5 2001/06/02 14:28:14 gorban |
// Fixed receiver and transmitter. Major bug fixed. |
// |
// Revision 1.4 2001/05/31 20:08:01 gorban |
// FIFO changes and other corrections. |
// |
// Revision 1.3 2001/05/27 17:37:49 gorban |
// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file. |
// |
// Revision 1.2 2001/05/21 19:12:02 gorban |
// Corrected some Linter messages. |
// |
// Revision 1.1 2001/05/17 18:34:18 gorban |
// First 'stable' release. Should be sythesizable now. Also added new header. |
// |
// Revision 1.0 2001-05-17 21:27:12+02 jacob |
// Initial revision |
// |
// |
|
`include "timescale.v" |
//`include "uart_defines.v" |
|
module uart_transmitter (clk, wb_rst_i, lcr, tf_push, wb_dat_i, enable, pad_stx_o, state, tf_count, tx_reset); |
|
input clk; |
input wb_rst_i; |
input [7:0] lcr; |
input tf_push; |
input [7:0] wb_dat_i; |
input enable; |
input tx_reset; |
output pad_stx_o; |
output [2:0] state; |
output [`UART_FIFO_COUNTER_W-1:0] tf_count; |
|
reg [2:0] state; |
reg [3:0] counter16; |
reg [2:0] bit_counter; // counts the bits to be sent |
reg [6:0] shift_out; // output shift register |
reg pad_stx_o; |
reg parity_xor; // parity of the word |
reg tf_pop; |
reg bit_out; |
|
// TX FIFO instance |
// |
// Transmitter FIFO signals |
wire [`UART_FIFO_WIDTH-1:0] tf_data_in; |
wire [`UART_FIFO_WIDTH-1:0] tf_data_out; |
wire tf_push; |
wire tf_underrun; |
wire tf_overrun; |
wire [`UART_FIFO_COUNTER_W-1:0] tf_count; |
|
assign tf_data_in = wb_dat_i; |
|
uart_fifo fifo_tx( // error bit signal is not used in transmitter FIFO |
.clk( clk ), |
.wb_rst_i( wb_rst_i ), |
.data_in( tf_data_in ), |
.data_out( tf_data_out ), |
.push( tf_push ), |
.pop( tf_pop ), |
.underrun( tf_underrun ), |
.overrun( tf_overrun ), |
.count( tf_count ), |
.fifo_reset( tx_reset ) |
); |
|
// TRANSMITTER FINAL STATE MACHINE |
|
parameter s_idle = 3'd0; |
parameter s_send_start = 3'd1; |
parameter s_send_byte = 3'd2; |
parameter s_send_parity = 3'd3; |
parameter s_send_stop = 3'd4; |
parameter s_pop_byte = 3'd5; |
|
always @(posedge clk or posedge wb_rst_i) |
begin |
if (wb_rst_i) |
begin |
state <= #1 s_idle; |
pad_stx_o <= #1 1'b1; |
counter16 <= #1 4'b0; |
shift_out <= #1 7'b0; |
bit_out <= #1 1'b0; |
parity_xor <= #1 1'b0; |
tf_pop <= #1 1'b0; |
bit_counter <= #1 3'b0; |
end |
else |
if (enable) |
begin |
case (state) |
s_idle : if (~|tf_count) // if tf_count==0 |
begin |
state <= #1 s_idle; |
pad_stx_o <= #1 1'b1; |
end |
else |
begin |
tf_pop <= #1 1'b0; |
pad_stx_o <= #1 1'b1; |
state <= #1 s_pop_byte; |
end |
s_pop_byte : begin |
tf_pop <= #1 1'b1; |
case (lcr[/*`UART_LC_BITS*/1:0]) // number of bits in a word |
2'b00 : begin |
bit_counter <= #1 3'b100; |
parity_xor <= #1 ^tf_data_out[4:0]; |
end |
2'b01 : begin |
bit_counter <= #1 3'b101; |
parity_xor <= #1 ^tf_data_out[5:0]; |
end |
2'b10 : begin |
bit_counter <= #1 3'b110; |
parity_xor <= #1 ^tf_data_out[6:0]; |
end |
2'b11 : begin |
bit_counter <= #1 3'b111; |
parity_xor <= #1 ^tf_data_out[7:0]; |
end |
endcase |
{shift_out[6:0], bit_out} <= #1 tf_data_out; |
state <= #1 s_send_start; |
end |
s_send_start : begin |
tf_pop <= #1 1'b0; |
if (~|counter16) |
counter16 <= #1 4'b1111; |
else |
if (counter16 == 4'b0001) |
begin |
counter16 <= #1 0; |
state <= #1 s_send_byte; |
end |
else |
counter16 <= #1 counter16 - 4'b0001; |
pad_stx_o <= #1 1'b0; |
end |
s_send_byte : begin |
if (~|counter16) |
counter16 <= #1 4'b1111; |
else |
if (counter16 == 4'b0001) |
begin |
if (bit_counter > 3'b0) |
begin |
bit_counter <= #1 bit_counter - 1; |
{shift_out[5:0],bit_out } <= #1 {shift_out[6:1], shift_out[0]}; |
state <= #1 s_send_byte; |
end |
else // end of byte |
if (~lcr[`UART_LC_PE]) |
begin |
state <= #1 s_send_stop; |
end |
else |
begin |
case ({lcr[`UART_LC_EP],lcr[`UART_LC_SP]}) |
2'b00: bit_out <= #1 ~parity_xor; |
2'b01: bit_out <= #1 1'b1; |
2'b10: bit_out <= #1 parity_xor; |
2'b11: bit_out <= #1 1'b0; |
endcase |
state <= #1 s_send_parity; |
end |
counter16 <= #1 0; |
end |
else |
counter16 <= #1 counter16 - 4'b0001; |
pad_stx_o <= #1 bit_out; // set output pin |
end |
s_send_parity : begin |
if (~|counter16) |
counter16 <= #1 4'b1111; |
else |
if (counter16 == 4'b0001) |
begin |
counter16 <= #1 4'b0; |
state <= #1 s_send_stop; |
end |
else |
counter16 <= #1 counter16 - 4'b0001; |
pad_stx_o <= #1 bit_out; |
end |
s_send_stop : begin |
if (~|counter16) |
counter16 <= #1 4'b1101; |
else |
if (counter16 == 4'b0001) |
begin |
counter16 <= #1 0; |
state <= #1 s_idle; |
end |
else |
counter16 <= #1 counter16 - 4'b0001; |
pad_stx_o <= #1 1'b1; |
end |
|
default : // should never get here |
state <= #1 s_idle; |
endcase |
end // end if enable |
end // transmitter logic |
|
endmodule |
/verilog/uart_defines.v
0,0 → 1,166
////////////////////////////////////////////////////////////////////// |
//// //// |
//// uart_defines.v //// |
//// //// |
//// //// |
//// This file is part of the "UART 16550 compatible" project //// |
//// http://www.opencores.org/cores/uart16550/ //// |
//// //// |
//// Documentation related to this project: //// |
//// - http://www.opencores.org/cores/uart16550/ //// |
//// //// |
//// Projects compatibility: //// |
//// - WISHBONE //// |
//// RS232 Protocol //// |
//// 16550D uart (mostly supported) //// |
//// //// |
//// Overview (main Features): //// |
//// Defines of the Core //// |
//// //// |
//// Known problems (limits): //// |
//// None //// |
//// //// |
//// To Do: //// |
//// Nothing. //// |
//// //// |
//// Author(s): //// |
//// - gorban@opencores.org //// |
//// - Jacob Gorban //// |
//// //// |
//// Created: 2001/05/12 //// |
//// Last Updated: 2001/05/17 //// |
//// (See log for the revision history) //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Jacob Gorban, gorban@opencores.org //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.5 2001/05/31 20:08:01 gorban |
// FIFO changes and other corrections. |
// |
// Revision 1.4 2001/05/21 19:12:02 gorban |
// Corrected some Linter messages. |
// |
// Revision 1.3 2001/05/17 18:34:18 gorban |
// First 'stable' release. Should be sythesizable now. Also added new header. |
// |
// Revision 1.0 2001-05-17 21:27:11+02 jacob |
// Initial revision |
// |
// |
|
`define UART_ADDR_WIDTH 3 |
|
// Register addresses |
`define UART_REG_RB 3'd0 // receiver buffer |
`define UART_REG_TR 3'd0 // transmitter |
`define UART_REG_IE 3'd1 // Interrupt enable |
`define UART_REG_II 3'd2 // Interrupt identification |
`define UART_REG_FC 3'd2 // FIFO control |
`define UART_REG_LC 3'd3 // Line Control |
`define UART_REG_MC 3'd4 // Modem control |
`define UART_REG_LS 3'd5 // Line status |
`define UART_REG_MS 3'd6 // Modem status |
`define UART_REG_DL1 3'd0 // Divisor latch bytes (1-4) |
`define UART_REG_DL2 3'd1 |
`define UART_REG_DL3 3'd4 |
`define UART_REG_DL4 3'd5 |
|
// Interrupt Enable register bits |
`define UART_IE_RDA 0 // Received Data available interrupt |
`define UART_IE_THRE 1 // Transmitter Holding Register empty interrupt |
`define UART_IE_RLS 2 // Receiver Line Status Interrupt |
`define UART_IE_MS 3 // Modem Status Interrupt |
|
// Interrupt Identification register bits |
`define UART_II_IP 0 // Interrupt pending when 0 |
`define UART_II_II 3:1 // Interrupt identification |
|
// Interrupt identification values for bits 3:1 |
`define UART_II_RLS 3'b011 // Receiver Line Status |
`define UART_II_RDA 3'b010 // Receiver Data available |
`define UART_II_TI 3'b110 // Timeout Indication |
`define UART_II_THRE 3'b001 // Transmitter Holding Register empty |
`define UART_II_MS 3'b000 // Modem Status |
|
// FIFO Control Register bits |
`define UART_FC_TL 1:0 // Trigger level |
|
// FIFO trigger level values |
`define UART_FC_1 2'b00 |
`define UART_FC_4 2'b01 |
`define UART_FC_8 2'b10 |
`define UART_FC_14 2'b11 |
|
// Line Control register bits |
`define UART_LC_BITS 1:0 // bits in character |
`define UART_LC_SB 2 // stop bits |
`define UART_LC_PE 3 // parity enable |
`define UART_LC_EP 4 // even parity |
`define UART_LC_SP 5 // stick parity |
`define UART_LC_BC 6 // Break control |
`define UART_LC_DL 7 // Divisor Latch access bit |
|
// Modem Control register bits |
`define UART_MC_DTR 0 |
`define UART_MC_RTS 1 |
`define UART_MC_OUT1 2 |
`define UART_MC_OUT2 3 |
`define UART_MC_LB 4 // Loopback mode |
|
// Line Status Register bits |
`define UART_LS_DR 0 // Data ready |
`define UART_LS_OE 1 // Overrun Error |
`define UART_LS_PE 2 // Parity Error |
`define UART_LS_FE 3 // Framing Error |
`define UART_LS_BI 4 // Break interrupt |
`define UART_LS_TFE 5 // Transmit FIFO is empty |
`define UART_LS_TE 6 // Transmitter Empty indicator |
`define UART_LS_EI 7 // Error indicator |
|
// Modem Status Register bits |
`define UART_MS_DCTS 0 // Delta signals |
`define UART_MS_DDSR 1 |
`define UART_MS_TERI 2 |
`define UART_MS_DDCD 3 |
`define UART_MS_CCTS 4 // Complement signals |
`define UART_MS_CDSR 5 |
`define UART_MS_CRI 6 |
`define UART_MS_CDCD 7 |
|
|
// FIFO parameter defines |
|
`define UART_FIFO_WIDTH 8 |
`define UART_FIFO_DEPTH 16 |
`define UART_FIFO_POINTER_W 4 |
`define UART_FIFO_COUNTER_W 5 |
// receiver fifo has width 10 because it has parity and framing error bits |
`define UART_FIFO_REC_WIDTH 10 |
/verilog-backup/uart_regs.v
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
verilog-backup/uart_regs.v
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: verilog-backup/uart_top.v
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: verilog-backup/uart_top.v
===================================================================
--- verilog-backup/uart_top.v (nonexistent)
+++ verilog-backup/uart_top.v (revision 106)
verilog-backup/uart_top.v
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: verilog-backup/uart_fifo.v
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: verilog-backup/uart_fifo.v
===================================================================
--- verilog-backup/uart_fifo.v (nonexistent)
+++ verilog-backup/uart_fifo.v (revision 106)
verilog-backup/uart_fifo.v
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: verilog-backup/uart_receiver.v
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: verilog-backup/uart_receiver.v
===================================================================
--- verilog-backup/uart_receiver.v (nonexistent)
+++ verilog-backup/uart_receiver.v (revision 106)
verilog-backup/uart_receiver.v
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: verilog-backup/uart_wb.v
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: verilog-backup/uart_wb.v
===================================================================
--- verilog-backup/uart_wb.v (nonexistent)
+++ verilog-backup/uart_wb.v (revision 106)
verilog-backup/uart_wb.v
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: verilog-backup/timescale.v
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: verilog-backup/timescale.v
===================================================================
--- verilog-backup/timescale.v (nonexistent)
+++ verilog-backup/timescale.v (revision 106)
verilog-backup/timescale.v
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: verilog-backup/uart_transmitter.v
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: verilog-backup/uart_transmitter.v
===================================================================
--- verilog-backup/uart_transmitter.v (nonexistent)
+++ verilog-backup/uart_transmitter.v (revision 106)
verilog-backup/uart_transmitter.v
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: verilog-backup/uart_defines.v
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: verilog-backup/uart_defines.v
===================================================================
--- verilog-backup/uart_defines.v (nonexistent)
+++ verilog-backup/uart_defines.v (revision 106)
verilog-backup/uart_defines.v
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property