📄 intface.v
字号:
// --------------------------------------------------------------------
// >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
// --------------------------------------------------------------------
// Copyright (c) 2001 - 2008 by Lattice Semiconductor Corporation
// --------------------------------------------------------------------
//
// Permission:
//
// Lattice Semiconductor grants permission to use this code for use
// in synthesis for any Lattice programmable logic product. Other
// use of this code, including the selling or duplication of any
// portion is strictly prohibited.
//
// Disclaimer:
//
// This VHDL or Verilog source code is intended as a design reference
// which illustrates how these types of functions can be implemented.
// It is the user's responsibility to verify their design for
// consistency and functionality through the use of formal
// verification methods. Lattice Semiconductor provides no warranty
// regarding the use or functionality of this code.
//
// --------------------------------------------------------------------
//
// Lattice Semiconductor Corporation
// 5555 NE Moore Court
// Hillsboro, OR 97214
// U.S.A
//
// TEL: 1-800-Lattice (USA and Canada)
// 503-268-8001 (other locations)
//
// web: http://www.latticesemi.com/
// email: techsupport@latticesemi.com
//
// --------------------------------------------------------------------
// Code Revision History :
// --------------------------------------------------------------------
// Ver: | Author |Mod. Date |Changes Made:
// V1.0 | | | Initial ver
// V1.1 | S.R. |18/12/08 | modified to support Mico8
//
// --------------------------------------------------------------------
`ifndef INTFACE_FILE
`define INTFACE_FILE
`define MODEM
`include "txcver_fifo.v"
`timescale 1ns/10ps
module intface #(parameter CLK_IN_MHZ = 25,
parameter BAUD_RATE = 115200,
parameter ADDRWIDTH = 3,
parameter DATAWIDTH = 8,
parameter FIFO = 0)
(
// Global reset and clock
reset,
clk,
// wishbone interface
adr_i,
dat_i,
dat_o,
stb_i,
cyc_i,
we_i,
sel_i,
bte_i,
ack_o,
intr,
// Registers
rbr,
rbr_fifo,
thr,
// Rising edge of registers read/write strobes
rbr_rd,
thr_wr,
lsr_rd,
`ifdef MODEM
msr_rd,
msr,
mcr,
`endif
// Receiver/Transmitter control
databits,
stopbits,
parity_en,
parity_even,
parity_stick,
tx_break,
// Receiver/Transmitter status
rx_rdy,
overrun_err,
parity_err,
frame_err,
break_int,
thre,
temt,
fifo_empty,
fifo_empty_thr,
thr_rd,
fifo_almost_full,
divisor
);
input reset ;
input clk;
output fifo_empty_thr;
input fifo_empty;
input fifo_almost_full;
input thr_rd;
input [7:0] adr_i;
input [15:0] dat_i;
input we_i ;
input stb_i;
input cyc_i;
input [3:0] sel_i;
input [1:0] bte_i;
input [7:0] rbr_fifo;
input [DATAWIDTH-1:0] rbr;
input rx_rdy ;
input overrun_err ;
input parity_err ;
input frame_err ;
input break_int ;
input thre ;
input temt ;
output lsr_rd ;
output [15:0] dat_o ;
output intr ;
output ack_o;
output [DATAWIDTH-1:0] thr ;
output rbr_rd;
output thr_wr;
output [1:0] databits;
output [1:0] stopbits;
output parity_en ;
output parity_even ;
output parity_stick;
output tx_break ;
`ifdef MODEM
output msr_rd ;
input [DATAWIDTH-1:0] msr ;
output [1:0] mcr ;
`endif
output [15:0] divisor;
reg ack_o;
reg [DATAWIDTH-1:0] data_8bit ;
wire [15:0] dat_o ;
wire [DATAWIDTH-1:0] thr_fifo;
reg [DATAWIDTH-1:0] thr_nonfifo;
generate
if (FIFO == 1)
assign thr = thr_fifo;
else
assign thr = thr_nonfifo;
endgenerate
reg [6:0] lsr;
reg [6:0] lcr;
wire [3:0] iir ;
`ifdef MODEM
reg [3:0] ier ;
`else
reg [2:0] ier ;
`endif
wire rx_rdy_int ;
wire thre_int ;
wire dataerr_int ;
wire data_err ;
wire thr_wr_strobe;
wire rbr_rd_strobe;
wire iir_rd_strobe;
reg iir_rd_strobe_delay;
wire lsr_rd_strobe;
wire div_wr_strobe;
wire lsr_rd;
reg lsr2_r, lsr3_r, lsr4_r;
reg thr_wr;
wire rbr_rd_fifo;
reg rbr_rd_nonfifo;
generate
if (FIFO == 1)
assign rbr_rd = rbr_rd_fifo;
else
assign rbr_rd = rbr_rd_nonfifo;
endgenerate
`ifdef MODEM
wire modem_stat ;
wire modem_int ;
wire msr_rd_strobe;
wire msr_rd ;
reg [1:0] mcr ;
reg msr_rd_strobe_detect;
`endif
// FIFO signals for FIFO mode
wire fifo_full_thr;
wire fifo_empty_thr;
wire fifo_almost_full_thr;
wire fifo_almost_empty_thr;
wire [8:0] fifo_din_thr;
reg fifo_wr_thr;
reg fifo_wr_q_thr;
wire fifo_wr_pulse_thr;
// UART baud 16x clock generator
reg [15:0] divisor;
always @(posedge clk or posedge reset) begin
if (reset)
divisor <= ((CLK_IN_MHZ*1000*1000)/(BAUD_RATE));
else if (div_wr_strobe)
divisor <= dat_i[15:0];
end
//changed for mico8 support from 5bit to 3 bit reg_addr
parameter A_RBR = 3'b000;
parameter A_THR = 3'b000;
parameter A_IER = 3'b001;
parameter A_IIR = 3'b010;
parameter A_LCR = 3'b011;
parameter A_LSR = 3'b101;
parameter A_DIV = 3'b111;
`ifdef MODEM
parameter A_MSR = 5'b11000;
parameter A_MCR = 5'b10000;
`endif
always @(posedge clk or posedge reset) begin
if (reset)
thr_wr <= 1'b0;
else
thr_wr <= thr_wr_strobe;
end
assign lsr_rd = lsr_rd_strobe;
assign rbr_rd_fifo = rbr_rd_strobe;
always @(posedge clk or posedge reset) begin
if (reset)
rbr_rd_nonfifo <= 1'b0;
else
rbr_rd_nonfifo <= rbr_rd_strobe;
end
`ifdef MODEM
assign msr_rd = msr_rd_strobe;
`endif
////////////////////////////////////////////////////////////////////////////////
// Registers Read/Write Control Signals
////////////////////////////////////////////////////////////////////////////////
generate
if (FIFO == 1)
assign thr_wr_strobe = (adr_i[ADDRWIDTH-1:0] == A_THR) && cyc_i && stb_i && we_i && ~fifo_full_thr && ~ack_o;
else
assign thr_wr_strobe = (adr_i[ADDRWIDTH-1:0] == A_THR) && cyc_i && stb_i && we_i;
endgenerate
generate
if (FIFO == 1)
assign rbr_rd_strobe = (adr_i[ADDRWIDTH-1:0] == A_RBR) && cyc_i && stb_i && ~we_i && ~fifo_empty && ~ack_o;
else
assign rbr_rd_strobe = (adr_i[ADDRWIDTH-1:0] == A_RBR) && cyc_i && stb_i && ~we_i;
endgenerate
generate
if (FIFO == 1)
assign iir_rd_strobe = (adr_i[ADDRWIDTH-1:0] == A_IIR) && cyc_i && stb_i && ~we_i && ~ack_o;
else
assign iir_rd_strobe = (adr_i[ADDRWIDTH-1:0] == A_IIR) && cyc_i && stb_i && ~we_i;
endgenerate
generate
if (FIFO == 1)
assign lsr_rd_strobe = (adr_i[ADDRWIDTH-1:0] == A_LSR) && cyc_i && stb_i && ~we_i && ~ack_o;
else
assign lsr_rd_strobe = (adr_i[ADDRWIDTH-1:0] == A_LSR) && cyc_i && stb_i && ~we_i;
endgenerate
`ifdef MODEM
assign msr_rd_strobe = (adr_i[ADDRWIDTH-1:0] == A_MSR) && cyc_i && stb_i && ~we_i;
`endif
assign div_wr_strobe = (adr_i[ADDRWIDTH-1:0] == A_DIV) && cyc_i && stb_i && we_i;
////////////////////////////////////////////////////////////////////////////////
// Registers Read/Write Operation
////////////////////////////////////////////////////////////////////////////////
generate
if (FIFO == 1) begin
always @(cyc_i or stb_i or we_i or adr_i or rbr_fifo or iir
`ifdef MODEM
or msr
`endif
or lsr)
begin
case (adr_i[ADDRWIDTH-1:0])
A_RBR: data_8bit <= rbr_fifo;
A_IIR: data_8bit <= {4'b0000, iir};
A_LSR: data_8bit <= {1'b0,lsr};
`ifdef MODEM
A_MSR: data_8bit <= msr;
`endif
default: data_8bit <= 8'b11111111;
endcase
end
end
else begin
// Register Read
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -