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

Subversion Repositories uart16550

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 6 to Rev 7
    Reverse comparison

Rev 6 → Rev 7

/trunk/verilog/ToDo.txt File deleted \ No newline at end of file
/trunk/verilog/UART_regs.v
1,15 → 1,72
// UART core registers
//////////////////////////////////////////////////////////////////////
//// ////
//// 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: 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// Includes transmission and reception tasks
// CVS Revision History
//
// Author: Jacob Gorban (jacob.gorban@flextronicssemi.com)
// Company: Flextronics Semiconductor
// $Log: not supported by cvs2svn $
// Revision 1.0 2001-05-17 21:27:11+02 jacob
// Initial revision
//
// Filename: UART_regs.v
//
// Releases:
// 1.1 First release
//
 
`include "timescale.v"
`include "UART_defines.v"
 
27,7 → 84,7
modem_inputs,
stx_o, srx_i,
enable,
rts_o, dtr_o
rts_o, dtr_o, int_o
);
 
input clk;
38,7 → 95,7
input wb_we_i;
 
output [3:0] ier;
output [7:0] iir;
output [3:0] iir;
output [3:0] fcr; /// bits 7,6,2,1 of fcr. Other bits are ignored
output [4:0] mcr;
output [7:0] lcr;
52,10 → 109,11
output enable;
output rts_o;
output dtr_o;
output int_o;
 
wire [3:0] modem_inputs;
reg enable;
reg stx_o;
wire stx_o; // received from transmitter module
wire srx_i;
 
reg [7:0] wb_dat_o;
65,7 → 123,7
 
 
reg [3:0] ier;
reg [7:0] iir;
reg [3:0] iir;
reg [3:0] fcr; /// bits 7,6,2,1 of fcr. Other bits are ignored
reg [4:0] mcr;
reg [7:0] lcr;
72,30 → 130,13
reg [7:0] lsr;
reg [7:0] msr;
reg [31:0] dl; // 32-bit divisor latch
 
reg start_dlc; // activate dlc on writing to DL1
reg lsr_mask;
reg [31:0] dlc; // 32-bit divisor latch counter
reg int_o;
 
// Transmitter FIFO signals
wire [`FIFO_WIDTH-1:0] tf_data_in;
wire [`FIFO_WIDTH-1:0] tf_data_out;
reg tf_push;
reg tf_pop;
wire tf_underrun;
wire tf_overrun;
wire [`FIFO_COUNTER_W-1:0] tf_count;
reg [3:0] trigger_level; // trigger level of the receiver FIFO
 
// Receiver FIFO signals
reg [`FIFO_REC_WIDTH-1:0] rf_data_in;
wire [`FIFO_REC_WIDTH-1:0] rf_data_out;
reg rf_push;
reg rf_pop;
wire rf_underrun;
wire rf_overrun;
wire [`FIFO_COUNTER_W-1:0] rf_count;
wire rf_error_bit; // an error (parity or framing) is inside the fifo
 
reg [3:0] trigger_level; // trigger level of the receiver FIFO
 
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)
110,7 → 151,6
: ~{cts_i,dsr_i,ri_i,dcd_i};
 
assign dlab = lcr[`LC_DL];
assign tf_data_in = wb_dat_i;
assign loopback = mcr[4];
 
// assign modem outputs
117,30 → 157,51
assign rts_o = mcr[`MC_RTS];
assign dtr_o = mcr[`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 INSTANCES
//
// FIFO signals
reg tf_push;
reg rf_pop;
wire [`FIFO_REC_WIDTH-1:0] rf_data_out;
wire rf_error_bit; // an error (parity or framing) is inside the fifo
wire [`FIFO_COUNTER_W-1:0] rf_count;
wire [`FIFO_COUNTER_W-1:0] tf_count;
wire [2:0] state;
wire [5:0] counter_t;
wire [3:0] counter_b;
 
UART_TX_FIFO fifo_tx(clk, wb_rst_i, tf_data_in, tf_data_out,
tf_push, tf_pop, tf_underrun, tf_overrun, tf_count);
// Transmitter Instance
UART_transmitter transmitter(clk, wb_rst_i, lcr, tf_push, wb_dat_i, enable, stx_o, state, tf_count);
 
UART_RX_FIFO fifo_rx(clk, wb_rst_i, rf_data_in, rf_data_out,
rf_push, rf_pop, rf_underrun, rf_overrun, rf_count, rf_error_bit);
// Receiver FIFO parameters redefine
defparam fifo_rx.fifo_width = `FIFO_REC_WIDTH;
// Receiver Instance
UART_receiver receiver(clk, wb_rst_i, lcr, rf_pop, srx_i, enable, rda_int,
counter_t, counter_b, rf_count, rf_data_out, rf_error_bit, rf_overrun);
 
always @(posedge clk) // synchrounous reading
//always @(wb_we_i or wb_addr_i or dlab or dl or rf_data_out or ier or iir or lcr or lsr or msr)
always @(posedge clk or posedge wb_rst_i) // synchrounous reading
if (wb_rst_i)
begin
wb_dat_o <= #1 8'b0;
rf_pop <= #1 0;
lsr_mask <= #1 0;
end
else
if (~wb_we_i) //if (we're not writing)
case (wb_addr_i)
`REG_RB : begin // Receiver FIFO or DL byte 1
rf_pop <= #1 1;
wb_dat_o <= #1 dlab ? dl[`DL1] : rf_data_out;
`REG_RB : if (dlab) // Receiver FIFO or DL byte 1
wb_dat_o <= #1 dl[`DL1];
else
begin
rf_pop <= #1 1; // advance read pointer
wb_dat_o <= #1 rf_data_out[9:2];
end
 
`REG_IE : wb_dat_o <= #1 dlab ? dl[`DL2] : ier;
`REG_II : wb_dat_o <= #1 iir;
`REG_II : wb_dat_o <= #1 {4'b1100,iir};
`REG_LC : wb_dat_o <= #1 lcr;
`REG_LS : if (dlab)
wb_dat_o <= #1 dl[`DL4];
147,8 → 208,7
else
begin
wb_dat_o <= #1 lsr;
// clear read bits
lsr <= #1 lsr & 8'b00000001;
lsr_mask <= #1 1;
end
`REG_MS : wb_dat_o <= #1 msr;
`REG_DL3: wb_dat_o <= #1 dlab ? dl[`DL3] : 8'b0;
173,13 → 233,15
// Interrupt Enable Register or DL2
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i)
begin
ier <= #1 4'b0000; // no interrupts after reset
dl[`DL2] <= #1 8'b0;
end
else
if (wb_we_i && wb_addr_i==`REG_IE)
if (dlab)
begin
dl[`DL2] <= #1 wb_dat_i;
// dlc <= #1 dl; // reset the counter to dl value
end
else
ier <= #1 wb_dat_i[3:0]; // ier uses only 4 lsb
196,27 → 258,43
// Modem Control Register or DL3
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i)
mcr <= #1 5'b00000; // no interrupts after reset
begin
mcr <= #1 5'b0; // no interrupts after reset
dl[`DL3] <= #1 8'b0;
end
else
if (wb_we_i && wb_addr_i==`REG_MC)
if (dlab)
begin
dl[`DL3] <= #1 wb_dat_i;
// dlc <= #1 dl;
end
else
mcr <= #1 wb_dat_i[4:0];
 
// TX_FIFO or DL1
always @(posedge clk or posedge wb_rst_i)
if (!wb_rst_i && wb_we_i && wb_addr_i==`REG_TR)
if (wb_rst_i)
begin
dl[`DL1] <= #1 8'b0;
tf_push <= #1 0;
start_dlc <= #1 0;
end
else
if (wb_we_i && wb_addr_i==`REG_TR)
if (dlab)
begin
dl[`DL1] <= #1 wb_dat_i;
dlc <= #1 dl;
start_dlc <= #1 1; // enable DL counter
tf_push <= #1 0;
end
else
tf_push <= #1 1;
begin
tf_push <= #1 1;
start_dlc <= #1 0;
end
else
begin
start_dlc <= #1 0;
tf_push <= #1 0;
end
 
// Receiver FIFO trigger level selection logic (asynchronous mux)
always @(fcr[`FC_TL])
227,43 → 305,13
2'b11 : trigger_level <= #1 14;
endcase
// FIFO push and pop signals reset
// DL4 write
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i)
tf_push <= #1 0;
dl[`DL4] <= #1 8'b0;
else
if (tf_push == 1)
tf_push <= #1 0;
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i)
tf_pop <= #1 0;
else
if (tf_pop == 1)
tf_pop <= #1 0;
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i)
rf_push <= #1 0;
else
if (rf_push == 1)
rf_push <= #1 0;
 
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i)
rf_pop <= #1 0;
else
if (rf_pop == 1)
rf_pop <= #1 0;
 
 
// DL4 write
always @(posedge clk)
if (!wb_rst_i && wb_we_i && wb_addr_i==`REG_DL4)
begin
if (wb_we_i && wb_addr_i==`REG_DL4)
dl[`DL4] <= #1 wb_dat_i;
// dlc <= #1 dl;
end
 
//
// STATUS REGISTERS //
276,49 → 324,70
msr[`MS_CDCD:`MS_CCTS] <= #1 {dcd, ri, dsr, cts};
end
 
// Divisor Latches reset
always @(posedge wb_rst_i)
dl <= #1 32'b0;
 
always @(posedge wb_rst_i)
// Line Status Register
always @(posedge clk or posedge wb_rst_i)
begin
dlc <= #1 32'hffffffff; // no enable signal will be generated
if (wb_rst_i)
lsr <= #1 8'b01100000;
else
if (lsr_mask)
lsr <= #1 lsr & 8'b00000001;
else
begin
lsr[0] <= #1 (rf_count!=0); // 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==0); // break counter reached 0
lsr[5] <= #1 (tf_count==0); // transmitter fifo is empty
lsr[6] <= #1 (tf_count==0 && (state == /*`S_IDLE */ 0)); // transmitter empty
lsr[7] <= #1 rf_error_bit;
end
end
 
 
// Line Status Register is after the transmitter
 
// Enable signal generation logic
always @(posedge clk)
always @(posedge clk or posedge wb_rst_i)
begin
if (|dl) // if dl<>0
if (enable)
dlc <= #1 dl;
if (wb_rst_i)
begin
dlc <= #1 32'hffffff00;
enable <= #1 0;
end
else
begin
if (start_dlc)
begin
enable <= #1 0;
dlc <= #1 dl;
end
else
dlc <= #1 dlc - 1; // decrease count
else
dlc <= #1 32'hffffffff; // so that no enable signal will be generated
begin
if (dl!=32'b0)
begin
if ( (dlc-1)==0 )
begin
enable <= #1 1;
dlc <= #1 dl;
end
else
begin
enable <= #1 0;
dlc <= #1 dlc - 1;
end
end
else
begin
dlc <= #1 32'hffffff0A;
enable <= #1 0;
end
end
end
end
 
always @(dlc)
if (~|dlc) // dlc==0 ?
enable = 1;
else
enable = 0;
 
//
// INTERRUPT LOGIC
//
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
 
reg [5:0] counter_t; // counts the timeout condition clocks
 
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
begin
rls_int <= #1 0;
335,12 → 404,24
ms_int <= #1 | msr[7:4]; // modem interrupt is pending when one of the modem inputs is asserted
ti_int <= #1 (counter_t == 0);
end
 
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
int_o <= #1 0;
else
if (| {rls_int,rda_int,thre_int,ms_int,ti_int})
int_o <= #1 1;
else
int_o <= #1 0;
end
 
 
// Interrupt Identification register
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
iir <= #1 8'b11000000;
iir <= #1 0;
else
if (rls_int && ier[`IE_RLS]) // interrupt occured and is enabled (not masked)
begin
354,7 → 435,7
iir[`II_IP] <= #1 1;
end
else
if (ti_int) // this interupt is not maskable
if (ti_int) // this interupt is not maskable ???
begin
iir[`II_II] <= #1 `II_TI;
iir[`II_IP] <= #1 1;
375,379 → 456,6
begin
iir[`II_IP] <= #1 0;
end
 
 
 
end
 
 
 
//
// TRANSMITTER LOGIC
//
 
`define S_IDLE 0
`define S_SEND_START 1
`define S_SEND_BYTE 2
`define S_SEND_PARITY 3
`define S_SEND_STOP 4
`define S_POP_BYTE 5
 
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 bit_out;
reg parity_xor; // parity of the word
 
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
begin
state <= #1 `S_IDLE;
stx_o <= #1 0;
counter16 <= #1 0;
end
else
if (enable)
begin
case (state)
`S_IDLE : if (~|tf_count) // if tf_count==0
begin
state <= #1 `S_IDLE;
stx_o <= #1 0;
end
else
begin
tf_pop <= #1 1;
stx_o <= #1 0;
state <= #1 `S_POP_BYTE;
end
`S_POP_BYTE : begin
tf_pop <= #1 0;
case (lcr[/*`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
if (~|counter16)
counter16 <= #1 4'b1111;
else
if (counter16 == 1)
begin
counter16 <= #1 0;
state <= #1 `S_SEND_BYTE;
end
else
counter16 <= #1 counter16 - 1;
stx_o <= #1 1;
end
`S_SEND_BYTE : begin
if (~|counter16)
counter16 <= #1 4'b1111;
else
if (counter16 == 1)
begin
if (|bit_counter) // if bit_counter>0
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[`LC_PE])
begin
state <= #1 `S_SEND_STOP;
end
else
begin
case ({lcr[`LC_EP],lcr[`LC_SP]})
2'b00: bit_out <= #1 ~parity_xor;
2'b01: bit_out <= #1 1;
2'b10: bit_out <= #1 parity_xor;
2'b11: bit_out <= #1 0;
endcase
state <= #1 `S_SEND_PARITY;
end
counter16 <= #1 0;
end
else
counter16 <= #1 counter16 - 1;
stx_o <= #1 bit_out; // set output pin
end
`S_SEND_PARITY : begin
if (~|counter16)
counter16 <= #1 4'b1111;
else
if (counter16 == 1)
begin
counter16 <= #1 0;
state <= #1 `S_SEND_STOP;
end
else
counter16 <= #1 counter16 - 1;
stx_o <= #1 bit_out;
end
`S_SEND_STOP : begin
if (~|counter16)
counter16 <= #1 4'b1111;
else
if (counter16 == 1)
begin
counter16 <= #1 0;
state <= #1 `S_IDLE;
end
else
counter16 <= #1 counter16 - 1;
stx_o <= #1 0;
end
 
default : // should never get here
state <= #1 `S_IDLE;
endcase
end // end if enable
end // transmitter logic
 
 
///
/// RECEIVER LOGIC
///
 
`define SR_IDLE 0
`define SR_REC_START 1
`define SR_REC_BIT 2
`define SR_REC_PARITY 3
`define SR_REC_STOP 4
`define SR_CHECK_PARITY 5
`define SR_REC_PREPARE 6
`define SR_END_BIT 7
`define SR_CALC_PARITY 8
`define SR_WAIT1 9
`define SR_PUSH 10
`define SR_LAST 11
 
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;
 
wire rcounter16_eq_7 = (rcounter16 == 7);
wire rcounter16_eq_0 = (rcounter16 == 0);
wire [3:0] rcounter16_minus_1 = rcounter16 - 1;
 
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
begin
rstate <= #1 `SR_IDLE;
rbit_in <= #1 0;
rcounter16 <= #1 0;
rbit_counter <= #1 0;
rparity_xor <= #1 0;
rframing_error <= #1 0;
rparity_error <= #1 0;
rshift <= #1 0;
end
else
if (enable)
begin
case (rstate)
`SR_IDLE : if (srx_i==1) // 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 (srx_i==0) // 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[/*`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[/*`LC_BITS*/1:0]) // number of bits in a word
2'b00 : rshift[4:0] <= #1 {srx_i, rshift[4:1]};
2'b01 : rshift[5:0] <= #1 {srx_i, rshift[5:1]};
2'b10 : rshift[6:0] <= #1 {srx_i, rshift[6:1]};
2'b11 : rshift[7:0] <= #1 {srx_i, rshift[7:1]};
endcase
rcounter16 <= #1 rcounter16_minus_1;
end
`SR_END_BIT : begin
if (rbit_counter==0) // no more bits in word
if (lcr[`LC_PE]) // choose state based on parity
rstate <= #1 `SR_REC_PARITY;
else
begin
rstate <= #1 `SR_REC_STOP;
rparity_error <= #1 0; // no parity - no error :)
end
else // else we have more bits to read
begin
rstate <= #1 `SR_REC_BIT;
rbit_counter <= #1 rbit_counter - 1;
end
rcounter16 <= #1 4'b1110;
end
`SR_REC_PARITY: begin
if (rcounter16_eq_7) // read the parity
begin
rparity <= #1 srx_i;
rstate <= #1 `SR_CALC_PARITY;
end
rcounter16 <= #1 rcounter16_minus_1;
end
`SR_CALC_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[`LC_EP],lcr[`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
begin
rcounter16 <= #1 rcounter16_minus_1;
// rstate <= #1 `SR_WAIT1;
end
`SR_REC_STOP : begin
if (rcounter16_eq_7) // read the parity
begin
rframing_error <= #1 srx_i; // no framing error if input is 0 (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;
rstate <= #1 `SR_LAST;
end
`SR_LAST : begin
if (rcounter16_eq_0)
rstate <= #1 `SR_IDLE;
rcounter16 <= #1 rcounter16_minus_1;
rf_push <= #1 0;
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 0 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 (srx_i)
begin
counter_b <= #1 4'd11; // maximum character time length - 1
lsr[`LS_BI] <= #1 0; // break off
end
else
if (counter_b == 0) // break reached
lsr[`LS_BI] <= #1 1; // break detected flag set
else
counter_b <= #1 counter_b - 1; // decrement break counter
end // always of break condition detection
 
///
/// Timeout condition detection
 
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 != 0) // we don't want to underflow
counter_t <= #1 counter_t - 1;
end
 
// Line Status Register
always @(posedge clk or wb_rst_i)
begin
if (wb_rst_i)
lsr <= #1 8'b01100000;
else
begin
lsr[0] <= #1 (rf_count!=0); // data in receiver fifo available
lsr[1] <= #1 rf_overrun; // Receiver overrun error
lsr[2] <= #1 rf_data_out[1]; // parity error bit
//lsr[4] (break interrupt is done in break detection, after the receiver FSM)
lsr[3] <= #1 rf_data_out[0]; // framing error bit
lsr[5] <= #1 (tf_count==0); // transmitter fifo is empty
lsr[6] <= #1 (tf_count==0 && state == `S_IDLE); // transmitter empty
lsr[7] <= #1 rf_error_bit;
end
end
 
endmodule
/trunk/verilog/FIFO_inc.v
1,10 → 1,89
/// File: FIFO_inc.v
/// Author: Jacob Gorban, Flextronics Semiconductor
///
/// This file is FIFO logic. It should be included in your FIFO.
/// A module envelope should be created in the parent file.
/// The reason for creating this in a included module is being able to create custom FIFOs,
/// like modules with different ports or additional logic on the FIFO except the standard, easily
//////////////////////////////////////////////////////////////////////
//// ////
//// FIFO_inc.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): ////
//// This file is synchronic FIFO logic. It should be included ////
//// in your FIFO. A module envelope should be created in the ////
//// parent file. The reason for creating this in a included ////
//// module is being able to create custom FIFOs, like modules ////
//// with different ports or additional logic on the FIFO ////
//// except the standard, easily. ////
//// ////
//// Notice that asserting push signals actually writes on the ////
//// next clock after asserting push. ////
//// But the pop signal moves the pointer to the next valid ////
//// signal. In other words, the output of the FIFO is always ////
//// the signal that is the next signal to be read, so you read ////
//// the next byte from FIFO and assert the pop signal on the ////
//// same clock to move to next byte. ////
//// ////
//// Also, there's a rise detection on the push and pop signals, ////
//// so holding the signals for a long time won't repeat ////
//// operation. You should deassert these signals and then ////
//// assert at the time needed. ////
//// ////
//// Known problems (limits): ////
//// No known problems. But pay attent to implementation. ////
//// ////
//// To Do: ////
//// Nothing or verification. ////
//// ////
//// 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.0 2001-05-17 21:27:10+02 jacob
// Initial revision
//
//
 
// FIFO parameters
parameter fifo_width = `FIFO_WIDTH;
35,26 → 114,68
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) // synchronous FIFO
always @(posedge push or posedge pop or posedge wb_rst_i) // asynchronous FIFO
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
push_delay <= #1 0;
else
push_delay <= #1 ~push;
end
 
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
pop_delay <= #1 0;
else
pop_delay <= #1 ~pop;
end
 
 
always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
begin
if (wb_rst_i==1)
begin
top <= #1 0;
bottom <= #1 0;
bottom <= #1 1;
underrun <= #1 0;
overrun <= #1 0;
count <= #1 0;
fifo[0] <= #1 8'b0;
fifo[1] <= #1 8'b0;
fifo[2] <= #1 8'b0;
fifo[3] <= #1 8'b0;
fifo[4] <= #1 8'b0;
fifo[5] <= #1 8'b0;
fifo[6] <= #1 8'b0;
fifo[7] <= #1 8'b0;
fifo[8] <= #1 8'b0;
fifo[9] <= #1 8'b0;
fifo[10] <= #1 8'b0;
fifo[11] <= #1 8'b0;
fifo[12] <= #1 8'b0;
fifo[13] <= #1 8'b0;
fifo[14] <= #1 8'b0;
fifo[15] <= #1 8'b0;
end
else
begin
case ({push, pop})
// 2'b00 : begin // this will never happen, really
// underrun <= #1 0;
// overrun <= #1 0;
// end
case ({push_rise, pop_rise})
2'b00 : begin // this will never happen, really
underrun <= #1 0;
overrun <= #1 0;
end
2'b10 : if (count==fifo_depth) // overrun condition
begin
overrun <= #1 1;
89,16 → 210,8
end
endcase
end
 
end // always
 
always @(posedge clk)
begin
if (overrun)
overrun <= #1 0;
if (underrun)
underrun <= #1 0;
end
 
 
// please note though that data_out is only valid one clock after pop signal
assign data_out = fifo[bottom];
/trunk/verilog/UART_top.v
1,11 → 1,72
// UART Wishbone-compatible core top level
//////////////////////////////////////////////////////////////////////
//// ////
//// 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// Author: Jacob Gorban (jacob.gorban@flextronicssemi.com)
// Company: Flextronics Semiconductor
// CVS Revision History
//
// Releases:
// 1.1 First release
// $Log: not supported by cvs2svn $
// Revision 1.0 2001-05-17 21:27:12+02 jacob
// Initial revision
//
//
 
`include "timescale.v"
`include "UART_defines.v"
79,6 → 140,7
UART_wb wb_interface(
.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( wb_we_i ),
111,7 → 173,8
.srx_i( srx_i ),
.enable( enable ),
.rts_o( rts_o ),
.dtr_o( dtr_o )
.dtr_o( dtr_o ),
.int_o( int_o )
);
 
endmodule
/trunk/verilog/UART_receiver.v
0,0 → 1,307
//////////////////////////////////////////////////////////////////////
//// ////
//// 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.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, srx_i, enable, rda_int,
counter_t, counter_b, rf_count, rf_data_out, rf_error_bit, rf_overrun);
 
input clk;
input wb_rst_i;
input [7:0] lcr;
input rf_pop;
input srx_i;
input enable;
input rda_int;
 
output [5:0] counter_t;
output [3:0] counter_b;
output [`FIFO_COUNTER_W-1:0] rf_count;
output [`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 [`FIFO_REC_WIDTH-1:0] rf_data_in;
wire [`FIFO_REC_WIDTH-1:0] rf_data_out;
reg rf_push;
wire rf_pop;
wire rf_underrun;
wire rf_overrun;
wire [`FIFO_COUNTER_W-1:0] rf_count;
wire rf_error_bit; // an error (parity or framing) is inside the fifo
 
// RX FIFO instance
UART_RX_FIFO fifo_rx(clk, wb_rst_i, rf_data_in, rf_data_out,
rf_push, rf_pop, rf_underrun, rf_overrun, rf_count, rf_error_bit);
 
// Receiver FIFO parameters redefine
defparam fifo_rx.fifo_width = `FIFO_REC_WIDTH;
 
 
wire rcounter16_eq_7 = (rcounter16 == 7);
wire rcounter16_eq_0 = (rcounter16 == 0);
wire [3:0] rcounter16_minus_1 = rcounter16 - 1;
 
`define SR_IDLE 0
`define SR_REC_START 1
`define SR_REC_BIT 2
`define SR_REC_PARITY 3
`define SR_REC_STOP 4
`define SR_CHECK_PARITY 5
`define SR_REC_PREPARE 6
`define SR_END_BIT 7
`define SR_CALC_PARITY 8
`define SR_WAIT1 9
`define SR_PUSH 10
`define SR_LAST 11
 
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
begin
rstate <= #1 `SR_IDLE;
rbit_in <= #1 0;
rcounter16 <= #1 0;
rbit_counter <= #1 0;
rparity_xor <= #1 0;
rframing_error <= #1 0;
rparity_error <= #1 0;
rparity <= #1 0;
rshift <= #1 0;
rf_push <= #1 0;
rf_data_in <= #1 0;
end
else
if (enable)
begin
case (rstate)
`SR_IDLE : if (srx_i==1) // 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 (srx_i==0) // 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[/*`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[/*`LC_BITS*/1:0]) // number of bits in a word
2'b00 : rshift[4:0] <= #1 {srx_i, rshift[4:1]};
2'b01 : rshift[5:0] <= #1 {srx_i, rshift[5:1]};
2'b10 : rshift[6:0] <= #1 {srx_i, rshift[6:1]};
2'b11 : rshift[7:0] <= #1 {srx_i, rshift[7:1]};
endcase
rcounter16 <= #1 rcounter16_minus_1;
end
`SR_END_BIT : begin
if (rbit_counter==0) // no more bits in word
if (lcr[`LC_PE]) // choose state based on parity
rstate <= #1 `SR_REC_PARITY;
else
begin
rstate <= #1 `SR_REC_STOP;
rparity_error <= #1 0; // no parity - no error :)
end
else // else we have more bits to read
begin
rstate <= #1 `SR_REC_BIT;
rbit_counter <= #1 rbit_counter - 1;
end
rcounter16 <= #1 4'b1110;
end
`SR_REC_PARITY: begin
if (rcounter16_eq_7) // read the parity
begin
rparity <= #1 srx_i;
rstate <= #1 `SR_CALC_PARITY;
end
rcounter16 <= #1 rcounter16_minus_1;
end
`SR_CALC_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[`LC_EP],lcr[`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 srx_i; // no framing error if input is 0 (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;
rstate <= #1 `SR_LAST;
end
`SR_LAST : begin
if (rcounter16_eq_0)
rstate <= #1 `SR_IDLE;
rcounter16 <= #1 rcounter16_minus_1;
rf_push <= #1 0;
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 0 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 (srx_i)
counter_b <= #1 4'd11; // maximum character time length - 1
else
if (counter_b != 0) // break reached
counter_b <= #1 counter_b - 1; // 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 != 0) // we don't want to underflow
counter_t <= #1 counter_t - 1;
end
endmodule
/trunk/verilog/UART_wb.v
1,3 → 1,73
//////////////////////////////////////////////////////////////////////
//// ////
//// 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.0 2001-05-17 21:27:13+02 jacob
// Initial revision
//
//
 
// UART core WISHBONE interface
//
// Author: Jacob Gorban (jacob.gorban@flextronicssemi.com)
11,11 → 81,8
 
module UART_wb (clk,
wb_rst_i,
//wb_dat_i, wb_dat_o, wb_addr_i,
wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o,
//int_o,
wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_addr_i,
we_o // Write enable output for the core
//dat_i, dat_o, addr_i
);
 
23,7 → 90,7
 
// WISHBONE interface
input wb_rst_i;
//input [`ADDR_WIDTH-1:0] wb_addr_i;
input [`ADDR_WIDTH-1:0] wb_addr_i;
//input [7:0] wb_dat_i;
//output [7:0] wb_dat_o;
input wb_we_i;
35,7 → 102,7
//output [`ADDR_WIDTH-1:0] addr_i;
//output [7:0] dat_i;
 
reg we_o;
wire we_o;
reg wb_ack_o;
//reg [7:0] wb_dat_i;
//reg [7:0] wb_dat_o;
44,14 → 111,14
begin
if (wb_rst_i == 1)
begin
we_o <= #1 0;
wb_ack_o <= #1 0;
end
else
begin
we_o <= #1 wb_we_i & wb_cyc_i & wb_stb_i; //WE for registers
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
/trunk/verilog/UART_RX_FIFO.v
1,22 → 1,76
// UART core receiver FIFO
//////////////////////////////////////////////////////////////////////
//// ////
//// UART_RX_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): ////
//// Read the FIFO_inc.v notes ////
//// ////
//// 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// Author: Jacob Gorban (jacob.gorban@flextronicssemi.com)
// Company: Flextronics Semiconductor
// CVS Revision History
//
// Filename: UART_RX_FIFO.v
// $Log: not supported by cvs2svn $
// Revision 1.0 2001-05-17 21:27:12+02 jacob
// Initial revision
//
// The standard FIFO logic is in the FIFO_inc.v file
// Additional logic is in this file.
//
// Releases:
// 1.1 First release
//
 
 
`include "timescale.v"
`include "UART_defines.v"
 
module UART_RX_FIFO (clk,
module UART_RX_FIFO (clk,
wb_rst_i, data_in, data_out,
// Control signals
push, // push strobe, active high
/trunk/verilog/UART_transmitter.v
0,0 → 1,249
//////////////////////////////////////////////////////////////////////
//// ////
//// 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.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, stx_o, state, tf_count);
 
input clk;
input wb_rst_i;
input [7:0] lcr;
input tf_push;
input [7:0] wb_dat_i;
input enable;
output stx_o;
output state;
output [`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 stx_o;
reg parity_xor; // parity of the word
reg tf_pop;
reg bit_out;
 
// TX FIFO instance
//
// Transmitter FIFO signals
wire [`FIFO_WIDTH-1:0] tf_data_in;
wire [`FIFO_WIDTH-1:0] tf_data_out;
wire tf_push;
wire tf_underrun;
wire tf_overrun;
wire [`FIFO_COUNTER_W-1:0] tf_count;
 
assign tf_data_in = wb_dat_i;
 
UART_TX_FIFO fifo_tx(clk, wb_rst_i, tf_data_in, tf_data_out,
tf_push, tf_pop, tf_underrun, tf_overrun, tf_count);
 
// TRANSMITTER FINAL STATE MACHINE
 
`define S_IDLE 0
`define S_SEND_START 1
`define S_SEND_BYTE 2
`define S_SEND_PARITY 3
`define S_SEND_STOP 4
`define S_POP_BYTE 5
 
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
begin
state <= #1 `S_IDLE;
stx_o <= #1 0;
counter16 <= #1 0;
shift_out <= #1 0;
bit_out <= #1 0;
parity_xor <= #1 0;
tf_pop <= #1 0;
bit_counter <= #1 0;
end
else
if (enable)
begin
case (state)
`S_IDLE : if (~|tf_count) // if tf_count==0
begin
state <= #1 `S_IDLE;
stx_o <= #1 0;
end
else
begin
tf_pop <= #1 0;
stx_o <= #1 0;
state <= #1 `S_POP_BYTE;
end
`S_POP_BYTE : begin
tf_pop <= #1 1;
case (lcr[/*`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 0;
if (~|counter16)
counter16 <= #1 4'b1111;
else
if (counter16 == 1)
begin
counter16 <= #1 0;
state <= #1 `S_SEND_BYTE;
end
else
counter16 <= #1 counter16 - 1;
stx_o <= #1 1;
end
`S_SEND_BYTE : begin
if (~|counter16)
counter16 <= #1 4'b1111;
else
if (counter16 == 1)
begin
if (|bit_counter) // if bit_counter>0
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[`LC_PE])
begin
state <= #1 `S_SEND_STOP;
end
else
begin
case ({lcr[`LC_EP],lcr[`LC_SP]})
2'b00: bit_out <= #1 ~parity_xor;
2'b01: bit_out <= #1 1;
2'b10: bit_out <= #1 parity_xor;
2'b11: bit_out <= #1 0;
endcase
state <= #1 `S_SEND_PARITY;
end
counter16 <= #1 0;
end
else
counter16 <= #1 counter16 - 1;
stx_o <= #1 bit_out; // set output pin
end
`S_SEND_PARITY : begin
if (~|counter16)
counter16 <= #1 4'b1111;
else
if (counter16 == 1)
begin
counter16 <= #1 0;
state <= #1 `S_SEND_STOP;
end
else
counter16 <= #1 counter16 - 1;
stx_o <= #1 bit_out;
end
`S_SEND_STOP : begin
if (~|counter16)
counter16 <= #1 4'b1111;
else
if (counter16 == 1)
begin
counter16 <= #1 0;
state <= #1 `S_IDLE;
end
else
counter16 <= #1 counter16 - 1;
stx_o <= #1 0;
end
 
default : // should never get here
state <= #1 `S_IDLE;
endcase
end // end if enable
end // transmitter logic
endmodule
/trunk/verilog/UART_defines.v
1,12 → 1,70
// UART core define
//////////////////////////////////////////////////////////////////////
//// ////
//// 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// Author: Jacob Gorban (jacob.gorban@flextronicssemi.com)
// Company: Flextronics Semiconductor
// CVS Revision History
//
// Filename: UART_defines.v
// $Log: not supported by cvs2svn $
// Revision 1.0 2001-05-17 21:27:11+02 jacob
// Initial revision
//
// Releases:
// 1.1 First release
//
 
`define ADDR_WIDTH 3
/trunk/verilog/UART_TX_FIFO.v
1,17 → 1,72
// UART core transmitter FIFO
//////////////////////////////////////////////////////////////////////
//// ////
//// 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 transmitter FIFO. ////
//// ////
//// Known problems (limits): ////
//// Read the FIFO_inc.v notes ////
//// ////
//// 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// Author: Jacob Gorban (jacob.gorban@flextronicssemi.com)
// Company: Flextronics Semiconductor
// CVS Revision History
//
// Filename: UART_TX_FIFO.v
// $Log: not supported by cvs2svn $
// Revision 1.0 2001-05-17 21:27:13+02 jacob
// Initial revision
//
// The actual FIFO logic is in the FIFO_inc.v file
//
// Releases:
// 1.1 First release
//
 
 
`include "timescale.v"
`include "UART_defines.v"
 
/trunk/verilog/UART_test.v
1,3 → 1,73
//////////////////////////////////////////////////////////////////////
//// ////
//// UART_test.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 test bench ////
//// ////
//// Known problems (limits): ////
//// A very simple test bench. Creates two UARTS and sends ////
//// data on to the other. ////
//// ////
//// To Do: ////
//// More complete testing should be done!!! ////
//// ////
//// 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.0 2001-05-17 21:27:12+02 jacob
// Initial revision
//
//
 
`include "timescale.v"
module UART_test ();
 
156,7 → 226,7
end
endtask
 
// The test sequance
// The test sequence
initial
begin
#1 wb_rst_ir = 1;
174,12 → 244,14
@(posedge clk);
// restore normal registers
cycle(1, `REG_LC, 8'b00011011);
$display("sending : %b", 8'b01101011);
cycle(1, 0, 8'b01101011);
@(posedge clk);
@(posedge clk);
$display("sending : %b", 8'b01000101);
cycle(1, 0, 8'b01000101);
#100;
wait (uart_snd.regs.state==0 && uart_snd.regs.tf_count==0);
wait (uart_snd.regs.state==0 && uart_snd.regs.transmitter.tf_count==0);
#100;
$finish;
188,6 → 260,8
// receiver side
initial
begin
//$monitor($time, " State: ", uart_rcv.regs.receiver.rstate);
$monitor($time, " stx_i: ", uart_snd.regs.transmitter.fifo_tx.fifo[1], uart_snd.regs.transmitter.fifo_tx.top);
#11;
wb1_stb_ir = 0;
wb1_cyc_ir = 0;

powered by: WebSVN 2.1.0

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