mirror of
https://github.com/pConst/basic_verilog.git
synced 2025-01-28 07:02:55 +08:00
515 lines
14 KiB
Verilog
515 lines
14 KiB
Verilog
//
|
||
///////////////////////////////////////////////////////////////////////////////////////////
|
||
// Copyright <20> 2011, Xilinx, Inc.
|
||
// This file contains confidential and proprietary information of Xilinx, Inc. and is
|
||
// protected under U.S. and international copyright and other intellectual property laws.
|
||
///////////////////////////////////////////////////////////////////////////////////////////
|
||
//
|
||
// Disclaimer:
|
||
// This disclaimer is not a license and does not grant any rights to the materials
|
||
// distributed herewith. Except as otherwise provided in a valid license issued to
|
||
// you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
|
||
// MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
|
||
// DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
|
||
// INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
|
||
// OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
|
||
// (whether in contract or tort, including negligence, or under any other theory
|
||
// of liability) for any loss or damage of any kind or nature related to, arising
|
||
// under or in connection with these materials, including for any direct, or any
|
||
// indirect, special, incidental, or consequential loss or damage (including loss
|
||
// of data, profits, goodwill, or any type of loss or damage suffered as a result
|
||
// of any action brought by a third party) even if such damage or loss was
|
||
// reasonably foreseeable or Xilinx had been advised of the possibility of the same.
|
||
//
|
||
// CRITICAL APPLICATIONS
|
||
// Xilinx products are not designed or intended to be fail-safe, or for use in any
|
||
// application requiring fail-safe performance, such as life-support or safety
|
||
// devices or systems, Class III medical devices, nuclear facilities, applications
|
||
// related to the deployment of airbags, or any other applications that could lead
|
||
// to death, personal injury, or severe property or environmental damage
|
||
// (individually and collectively, "Critical Applications"). Customer assumes the
|
||
// sole risk and liability of any use of Xilinx products in Critical Applications,
|
||
// subject only to applicable laws and regulations governing limitations on product
|
||
// liability.
|
||
//
|
||
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
|
||
//
|
||
///////////////////////////////////////////////////////////////////////////////////////////
|
||
//
|
||
// UART Receiver with integral 16 byte FIFO buffer
|
||
//
|
||
// 8 bit, no parity, 1 stop bit
|
||
//
|
||
// This module was made for use with Spartan-6 Generation Devices and is also ideally
|
||
// suited for use with Virtex-6 and 7-Series devices.
|
||
//
|
||
// Version 1 - 8th July 2011.
|
||
// Derived from uart_rx6.vhd Version 1 (31st March 2011) by Nick Sawyer.
|
||
//
|
||
// Ken Chapman
|
||
// Xilinx Ltd
|
||
// Benchmark House
|
||
// 203 Brooklands Road
|
||
// Weybridge
|
||
// Surrey KT13 ORH
|
||
// United Kingdom
|
||
//
|
||
// chapman@xilinx.com
|
||
//
|
||
///////////////////////////////////////////////////////////////////////////////////////////
|
||
//
|
||
// Format of this file.
|
||
//
|
||
// The module defines the implementation of the logic using Xilinx primitives.
|
||
// These ensure predictable synthesis results and maximise the density of the
|
||
// implementation. The Unisim Library is used to define Xilinx primitives. It is also
|
||
// used during simulation.
|
||
// The source can be viewed at %XILINX%\verilog\src\unisims\
|
||
//
|
||
///////////////////////////////////////////////////////////////////////////////////////////
|
||
//
|
||
`timescale 1 ps / 1ps
|
||
|
||
module uart_rx6 (
|
||
input serial_in,
|
||
input en_16_x_baud,
|
||
output [7:0] data_out,
|
||
input buffer_read,
|
||
output buffer_data_present,
|
||
output buffer_half_full,
|
||
output buffer_full,
|
||
input buffer_reset,
|
||
input clk );
|
||
//
|
||
///////////////////////////////////////////////////////////////////////////////////////////
|
||
//
|
||
// wires used in uart_rx6
|
||
//
|
||
///////////////////////////////////////////////////////////////////////////////////////////
|
||
//
|
||
wire [3:0] pointer_value;
|
||
wire [3:0] pointer;
|
||
wire en_pointer;
|
||
wire zero;
|
||
wire full_int;
|
||
wire data_present_value;
|
||
wire data_present_int;
|
||
wire sample_value;
|
||
wire sample;
|
||
wire sample_dly_value;
|
||
wire sample_dly;
|
||
wire stop_bit_value;
|
||
wire stop_bit;
|
||
wire [7:0] data_value;
|
||
wire [7:0] data;
|
||
wire run_value;
|
||
wire run;
|
||
wire start_bit_value;
|
||
wire start_bit;
|
||
wire [3:0] div_value;
|
||
wire [3:0] div;
|
||
wire div_carry;
|
||
wire sample_input_value;
|
||
wire sample_input;
|
||
wire buffer_write_value;
|
||
wire buffer_write;
|
||
//
|
||
///////////////////////////////////////////////////////////////////////////////////////////
|
||
//
|
||
// Start of uart_rx6 circuit description
|
||
//
|
||
///////////////////////////////////////////////////////////////////////////////////////////
|
||
//
|
||
genvar i;
|
||
|
||
// SRL16E data storage
|
||
|
||
generate
|
||
for (i = 0 ; i <= 7 ; i = i+1)
|
||
begin : data_width_loop
|
||
|
||
(* HBLKNM = "uart_rx6_5" *)
|
||
SRL16E #(
|
||
.INIT (16'h0000))
|
||
storage_srl (
|
||
.D (data[i]),
|
||
.CE (buffer_write),
|
||
.CLK (clk),
|
||
.A0 (pointer[0]),
|
||
.A1 (pointer[1]),
|
||
.A2 (pointer[2]),
|
||
.A3 (pointer[3]),
|
||
.Q (data_out[i]));
|
||
|
||
end //generate data_width_loop;
|
||
endgenerate
|
||
|
||
(* HBLKNM = "uart_rx6_1" *)
|
||
LUT6 #(
|
||
.INIT (64'hFF00FE00FF80FF00))
|
||
pointer3_lut(
|
||
.I0 (pointer[0]),
|
||
.I1 (pointer[1]),
|
||
.I2 (pointer[2]),
|
||
.I3 (pointer[3]),
|
||
.I4 (buffer_write),
|
||
.I5 (buffer_read),
|
||
.O (pointer_value[3]));
|
||
|
||
(* HBLKNM = "uart_rx6_1" *)
|
||
FDR pointer3_flop(
|
||
.D (pointer_value[3]),
|
||
.Q (pointer[3]),
|
||
.R (buffer_reset),
|
||
.C (clk));
|
||
|
||
(* HBLKNM = "uart_rx6_1" *)
|
||
LUT6 #(
|
||
.INIT (64'hF0F0E1E0F878F0F0))
|
||
pointer2_lut(
|
||
.I0 (pointer[0]),
|
||
.I1 (pointer[1]),
|
||
.I2 (pointer[2]),
|
||
.I3 (pointer[3]),
|
||
.I4 (buffer_write),
|
||
.I5 (buffer_read),
|
||
.O (pointer_value[2]));
|
||
|
||
(* HBLKNM = "uart_rx6_1" *)
|
||
FDR pointer2_flop(
|
||
.D (pointer_value[2]),
|
||
.Q (pointer[2]),
|
||
.R (buffer_reset),
|
||
.C (clk));
|
||
|
||
(* HBLKNM = "uart_rx6_1" *)
|
||
LUT6_2 #(
|
||
.INIT (64'hCC9060CCAA5050AA))
|
||
pointer01_lut(
|
||
.I0 (pointer[0]),
|
||
.I1 (pointer[1]),
|
||
.I2 (en_pointer),
|
||
.I3 (buffer_write),
|
||
.I4 (buffer_read),
|
||
.I5 (1'b1),
|
||
.O5 (pointer_value[0]),
|
||
.O6 (pointer_value[1]));
|
||
|
||
(* HBLKNM = "uart_rx6_1" *)
|
||
FDR pointer1_flop(
|
||
.D (pointer_value[1]),
|
||
.Q (pointer[1]),
|
||
.R (buffer_reset),
|
||
.C (clk));
|
||
|
||
(* HBLKNM = "uart_rx6_1" *)
|
||
FDR pointer0_flop(
|
||
.D (pointer_value[0]),
|
||
.Q (pointer[0]),
|
||
.R (buffer_reset),
|
||
.C (clk));
|
||
|
||
(* HBLKNM = "uart_rx6_1" *)
|
||
LUT6_2 #(
|
||
.INIT (64'hF4FCF4FC040004C0))
|
||
data_present_lut(
|
||
.I0 (zero),
|
||
.I1 (data_present_int),
|
||
.I2 (buffer_write),
|
||
.I3 (buffer_read),
|
||
.I4 (full_int),
|
||
.I5 (1'b1),
|
||
.O5 (en_pointer),
|
||
.O6 (data_present_value));
|
||
|
||
(* HBLKNM = "uart_rx6_1" *)
|
||
FDR data_present_flop(
|
||
.D (data_present_value),
|
||
.Q (data_present_int),
|
||
.R (buffer_reset),
|
||
.C (clk));
|
||
|
||
(* HBLKNM = "uart_rx6_3" *)
|
||
LUT6_2 #(
|
||
.INIT (64'h0001000080000000))
|
||
full_lut(
|
||
.I0 (pointer[0]),
|
||
.I1 (pointer[1]),
|
||
.I2 (pointer[2]),
|
||
.I3 (pointer[3]),
|
||
.I4 (1'b1),
|
||
.I5 (1'b1),
|
||
.O5 (full_int),
|
||
.O6 (zero));
|
||
|
||
(* HBLKNM = "uart_rx6_4" *)
|
||
LUT6_2 #(
|
||
.INIT (64'hCCF00000AACC0000))
|
||
sample_lut(
|
||
.I0 (serial_in),
|
||
.I1 (sample),
|
||
.I2 (sample_dly),
|
||
.I3 (en_16_x_baud),
|
||
.I4 (1'b1),
|
||
.I5 (1'b1),
|
||
.O5 (sample_value),
|
||
.O6 (sample_dly_value));
|
||
|
||
(* HBLKNM = "uart_rx6_4" *)
|
||
FD sample_flop(
|
||
.D (sample_value),
|
||
.Q (sample),
|
||
.C (clk));
|
||
|
||
(* HBLKNM = "uart_rx6_4" *)
|
||
FD sample_dly_flop(
|
||
.D (sample_dly_value),
|
||
.Q (sample_dly),
|
||
.C (clk));
|
||
|
||
(* HBLKNM = "uart_rx6_4" *)
|
||
LUT6_2 #(
|
||
.INIT (64'hCAFFCAFF0000C0C0))
|
||
stop_bit_lut(
|
||
.I0 (stop_bit),
|
||
.I1 (sample),
|
||
.I2 (sample_input),
|
||
.I3 (run),
|
||
.I4 (data[0]),
|
||
.I5 (1'b1),
|
||
.O5 (buffer_write_value),
|
||
.O6 (stop_bit_value));
|
||
|
||
(* HBLKNM = "uart_rx6_4" *)
|
||
FD buffer_write_flop(
|
||
.D (buffer_write_value),
|
||
.Q (buffer_write),
|
||
.C (clk));
|
||
|
||
(* HBLKNM = "uart_rx6_4" *)
|
||
FD stop_bit_flop(
|
||
.D (stop_bit_value),
|
||
.Q (stop_bit),
|
||
.C (clk));
|
||
|
||
(* HBLKNM = "uart_rx6_2" *)
|
||
LUT6_2 #(
|
||
.INIT (64'hF0CCFFFFCCAAFFFF))
|
||
data01_lut(
|
||
.I0 (data[0]),
|
||
.I1 (data[1]),
|
||
.I2 (data[2]),
|
||
.I3 (sample_input),
|
||
.I4 (run),
|
||
.I5 (1'b1),
|
||
.O5 (data_value[0]),
|
||
.O6 (data_value[1]));
|
||
|
||
(* HBLKNM = "uart_rx6_2" *)
|
||
FD data0_flop(
|
||
.D (data_value[0]),
|
||
.Q (data[0]),
|
||
.C (clk));
|
||
|
||
(* HBLKNM = "uart_rx6_2" *)
|
||
FD data1_flop(
|
||
.D (data_value[1]),
|
||
.Q (data[1]),
|
||
.C (clk));
|
||
|
||
(* HBLKNM = "uart_rx6_2" *)
|
||
LUT6_2 #(
|
||
.INIT (64'hF0CCFFFFCCAAFFFF))
|
||
data23_lut(
|
||
.I0 (data[2]),
|
||
.I1 (data[3]),
|
||
.I2 (data[4]),
|
||
.I3 (sample_input),
|
||
.I4 (run),
|
||
.I5 (1'b1),
|
||
.O5 (data_value[2]),
|
||
.O6 (data_value[3]));
|
||
|
||
(* HBLKNM = "uart_rx6_2" *)
|
||
FD data2_flop(
|
||
.D (data_value[2]),
|
||
.Q (data[2]),
|
||
.C (clk));
|
||
|
||
(* HBLKNM = "uart_rx6_2" *)
|
||
FD data3_flop(
|
||
.D (data_value[3]),
|
||
.Q (data[3]),
|
||
.C (clk));
|
||
|
||
(* HBLKNM = "uart_rx6_2" *)
|
||
LUT6_2 #(
|
||
.INIT (64'hF0CCFFFFCCAAFFFF))
|
||
data45_lut(
|
||
.I0 (data[4]),
|
||
.I1 (data[5]),
|
||
.I2 (data[6]),
|
||
.I3 (sample_input),
|
||
.I4 (run),
|
||
.I5 (1'b1),
|
||
.O5 (data_value[4]),
|
||
.O6 (data_value[5]));
|
||
|
||
(* HBLKNM = "uart_rx6_2" *)
|
||
FD data4_flop(
|
||
.D (data_value[4]),
|
||
.Q (data[4]),
|
||
.C (clk));
|
||
|
||
(* HBLKNM = "uart_rx6_2" *)
|
||
FD data5_flop(
|
||
.D (data_value[5]),
|
||
.Q (data[5]),
|
||
.C (clk));
|
||
|
||
(* HBLKNM = "uart_rx6_2" *)
|
||
LUT6_2 #(
|
||
.INIT (64'hF0CCFFFFCCAAFFFF))
|
||
data67_lut(
|
||
.I0 (data[6]),
|
||
.I1 (data[7]),
|
||
.I2 (stop_bit),
|
||
.I3 (sample_input),
|
||
.I4 (run),
|
||
.I5 (1'b1),
|
||
.O5 (data_value[6]),
|
||
.O6 (data_value[7]));
|
||
|
||
(* HBLKNM = "uart_rx6_2" *)
|
||
FD data6_flop(
|
||
.D (data_value[6]),
|
||
.Q (data[6]),
|
||
.C (clk));
|
||
|
||
(* HBLKNM = "uart_rx6_2" *)
|
||
FD data7_flop(
|
||
.D (data_value[7]),
|
||
.Q (data[7]),
|
||
.C (clk));
|
||
|
||
(* HBLKNM = "uart_rx6_4" *)
|
||
LUT6 #(
|
||
.INIT (64'h2F2FAFAF0000FF00))
|
||
run_lut(
|
||
.I0 (data[0]),
|
||
.I1 (start_bit),
|
||
.I2 (sample_input),
|
||
.I3 (sample_dly),
|
||
.I4 (sample),
|
||
.I5 (run),
|
||
.O (run_value));
|
||
|
||
(* HBLKNM = "uart_rx6_4" *)
|
||
FD run_flop(
|
||
.D (run_value),
|
||
.Q (run),
|
||
.C (clk));
|
||
|
||
(* HBLKNM = "uart_rx6_4" *)
|
||
LUT6 #(
|
||
.INIT (64'h222200F000000000))
|
||
start_bit_lut(
|
||
.I0 (start_bit),
|
||
.I1 (sample_input),
|
||
.I2 (sample_dly),
|
||
.I3 (sample),
|
||
.I4 (run),
|
||
.I5 (1'b1),
|
||
.O (start_bit_value));
|
||
|
||
(* HBLKNM = "uart_rx6_4" *)
|
||
FD start_bit_flop(
|
||
.D (start_bit_value),
|
||
.Q (start_bit),
|
||
.C (clk));
|
||
|
||
(* HBLKNM = "uart_rx6_3" *)
|
||
LUT6_2 #(
|
||
.INIT (64'h6C0000005A000000))
|
||
div01_lut(
|
||
.I0 (div[0]),
|
||
.I1 (div[1]),
|
||
.I2 (en_16_x_baud),
|
||
.I3 (run),
|
||
.I4 (1'b1),
|
||
.I5 (1'b1),
|
||
.O5 (div_value[0]),
|
||
.O6 (div_value[1]));
|
||
|
||
(* HBLKNM = "uart_rx6_3" *)
|
||
FD div0_flop(
|
||
.D (div_value[0]),
|
||
.Q (div[0]),
|
||
.C (clk));
|
||
|
||
(* HBLKNM = "uart_rx6_3" *)
|
||
FD div1_flop(
|
||
.D (div_value[1]),
|
||
.Q (div[1]),
|
||
.C (clk));
|
||
|
||
(* HBLKNM = "uart_rx6_3" *)
|
||
LUT6_2 #(
|
||
.INIT (64'h6CCC00005AAA0000))
|
||
div23_lut(
|
||
.I0 (div[2]),
|
||
.I1 (div[3]),
|
||
.I2 (div_carry),
|
||
.I3 (en_16_x_baud),
|
||
.I4 (run),
|
||
.I5 (1'b1),
|
||
.O5 (div_value[2]),
|
||
.O6 (div_value[3]));
|
||
|
||
(* HBLKNM = "uart_rx6_3" *)
|
||
FD div2_flop(
|
||
.D (div_value[2]),
|
||
.Q (div[2]),
|
||
.C (clk));
|
||
|
||
(* HBLKNM = "uart_rx6_3" *)
|
||
FD div3_flop(
|
||
.D (div_value[3]),
|
||
.Q (div[3]),
|
||
.C (clk));
|
||
|
||
(* HBLKNM = "uart_rx6_3" *)
|
||
LUT6_2 #(
|
||
.INIT (64'h0080000088888888))
|
||
sample_input_lut(
|
||
.I0 (div[0]),
|
||
.I1 (div[1]),
|
||
.I2 (div[2]),
|
||
.I3 (div[3]),
|
||
.I4 (en_16_x_baud),
|
||
.I5 (1'b1),
|
||
.O5 (div_carry),
|
||
.O6 (sample_input_value));
|
||
|
||
(* HBLKNM = "uart_rx6_3" *)
|
||
FD sample_input_flop(
|
||
.D (sample_input_value),
|
||
.Q (sample_input),
|
||
.C (clk));
|
||
|
||
// assign internal wires to outputs
|
||
|
||
assign buffer_full = full_int;
|
||
assign buffer_half_full = pointer[3];
|
||
assign buffer_data_present = data_present_int;
|
||
|
||
endmodule
|
||
|
||
///////////////////////////////////////////////////////////////////////////////////////////
|
||
//
|
||
// END OF FILE uart_rx6.v
|
||
//
|
||
///////////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
|