Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
//---------------------------------------------------------------------------//
// Copyright (c) 2008 Xilinx Inc.
//
// Project : Programmable Wave Generator
// Module
: meta_harden.v
// Parent
: Various
// Children : None
//
// Description:
//
This is a basic meta-stability hardener; it double synchronizes an
//
asynchronous signal onto a new clock domain.
//
// Parameters:
//
None
//
// Notes
:
//
// Multicycle and False Paths, Timing Exceptions
//
A tighter timing constraint should be placed between the signal_meta
//
and signal_dst flip-flops to allow for meta-stability settling time
//
`timescale 1ns/1ps
module meta_harden (
input
clk_dst,
input
rst_dst,
clock
input
signal_src,
output reg
signal_dst
);
// Destination clock
// Reset - synchronous to destination
// Asynchronous signal to be synchronized
// Synchronized signal
//************************************************************************
***
// Register declarations
//************************************************************************
***
reg
has
signal_meta;
metastable.
// The second sampling (signal_dst) has
// a much lower probability of being
// metastable
//************************************************************************
***
// Code
//************************************************************************
***
always @(posedge clk_dst)
begin
if (rst_dst)
begin
signal_meta <= 1'b0;
signal_dst <= 1'b0;
end
else // if !rst_dst
begin
signal_meta <= signal_src;
signal_dst <= signal_meta;
end // if rst
end // always
endmodule
META HARDEN
//---------------------------------------------------------------------------//
// Copyright (c) 2008 Xilinx Inc.
//
// Project : Programmable Wave Generator
// Module
: meta_harden.v
// Parent
: Various
// Children : None
//
// Description:
//
This is a basic meta-stability hardener; it double synchronizes an
//
asynchronous signal onto a new clock domain.
//
// Parameters:
//
None
//
// Notes
:
//
// Multicycle and False Paths, Timing Exceptions
//
A tighter timing constraint should be placed between the signal_meta
//
and signal_dst flip-flops to allow for meta-stability settling time
//
`timescale 1ns/1ps
module meta_harden (
input
clk_dst,
// Destination clock
input
clock
input
output reg
);
rst_dst,
signal_src,
signal_dst
//************************************************************************
***
// Register declarations
//************************************************************************
***
reg
has
signal_meta;
metastable.
// The second sampling (signal_dst) has
// a much lower probability of being
// metastable
//************************************************************************
***
// Code
//************************************************************************
***
always @(posedge clk_dst)
begin
if (rst_dst)
begin
signal_meta <= 1'b0;
signal_dst <= 1'b0;
end
else // if !rst_dst
begin
signal_meta <= signal_src;
signal_dst <= signal_meta;
end // if rst
end // always
endmodule
FIFO TESTBENCH
//---------------------------------------------------------------------------//
// Copyright (c) 2009 Xilinx Inc.
//
// Project : Programmable Wave Generator
// Module
: tb_fifo.v
// Parent
: tb_uart_rx
// Children : none
//
// Description:
//
This module is a generic FIFO for testbench applications. It stores
data
//
internally in a verilog memory, and provides access to it via the
tasks
//
and functions push, pop, is_empty, is_full.
//
// Parameters:
//
WIDTH
: Width of the data to be pushed and popped
//
DEPTH
: Number of entries. The FIFO will signal full when
DEPTH-1
//
entries are in the FIFO
//
// Tasks:
//
push
: Pushes data into the FIFO - if the FIFO is full, an
//
error message is generated
//
// Functions:
//
//
is_empty
: Returns 1 if the FIFO is empty
//
pop
: Returns the element at the front of the FIFO
//
//
// Internal variables:
//
reg [WIDTH-1:0] data [0:DEPTH-1] - the array for storing data
//
integer
head
- head pointer
//
integer
tail
- tail pointer
//
// Notes
:
//
//
// Multicycle and False Paths
//
None - this is a testbench file only, and is not intended for
synthesis
//
// All times in this testbench are expressed in units of nanoseconds, with
a
// precision of 1ps increments
`timescale 1ns/1ps
module tb_fifo ();
//************************************************************************
***
// Parameter definitions
//************************************************************************
***
parameter
parameter
WIDTH
DEPTH
= 8;
= 256;
//************************************************************************
***
// Register declarations
//************************************************************************
***
reg [WIDTH-1:0] data [0:DEPTH-1]; // the array for storing data
integer
head;
// head pointer
integer
tail;
// tail pointer
//************************************************************************
***
// Functions
//************************************************************************
***
function [31:0] next_ptr;
input [31:0] ptr;
begin
next_ptr = (ptr + 1) % DEPTH;
end
endfunction
function is_empty;
input ignore; // A function must have at least one input
begin
is_empty = (head == tail);
end
endfunction
function is_full;
input ignore; // A function must have at least one input
begin
is_full = (next_ptr(head) == tail);
end
endfunction
function [WIDTH-1:0] pop;
input ignore; // A function must have at least one input
begin
if (is_empty(0))
begin
$display ("%t ERROR: Popping an empty FIFO in %m",$realtime);
pop = {WIDTH{1'bx}};
end
else
begin
pop = data[tail];
tail = next_ptr(tail);
end
end
endfunction
//************************************************************************
***
// Tasks
//************************************************************************
***
task push (
input [WIDTH-1:0] new_data
);
begin
if (is_full(0))
begin
$display ("%t ERROR: Pushing a full FIFO in %m",$realtime);
end
else
begin
data[head] = new_data;
head = next_ptr(head);
end
end
// task
endtask // full
//************************************************************************
***
// Code
//************************************************************************
***
initial
begin
head = 0;
tail = 0;
end
endmodule
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////
//////
module tb_led;
// Inputs
reg clk_rx;
reg rst_clk_rx;
reg [7:0] rx_data;
reg rx_data_rdy;
// Outputs
wire [7:0] led_o;
// Instantiate the Unit Under Test (UUT)
led_ctl uut (
.clk_rx(clk_rx),
.rst_clk_rx(rst_clk_rx),
.rx_data(rx_data),
.rx_data_rdy(rx_data_rdy),
.led_o(led_o)
);
initial begin
// Initialize Inputs
clk_rx = 0;
rst_clk_rx = 1'b1;
rx_data = 0;
rx_data_rdy = 0;
end
always # 4 clk_rx=~clk_rx;
always
begin
# 6 rst_clk_rx=1'b0;
rx_data = 1'b1;
rx_data_rdy = 1'b1;
end
endmodule
//////////////////////////////////////////////////////////////////////////
//////
// Company:
// Engineer:
//
// Create Date:
12:24:44 04/11/2012
// Design Name:
meta_harden
// Module Name:
C:/Documents and
Settings/Administrator/Desktop/uart_led/tb_meta.v
// Project Name: uart_led
// Target Device:
// Tool versions:
// Description:
//
// Verilog Test Fixture created by ISE for module: meta_harden
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////
//////
module tb_meta;
// Inputs
reg clk_dst;
reg rst_dst;
reg signal_src;
// Outputs
wire signal_dst;
// Instantiate the Unit Under Test (UUT)
meta_harden uut (
.clk_dst(clk_dst),
.rst_dst(rst_dst),
.signal_src(signal_src),
.signal_dst(signal_dst)
);
initial begin
// Initialize Inputs
clk_dst = 0;
rst_dst = 1'b1;
signal_src = 0;
end
always # 5 clk_dst=~clk_dst;
always
begin
# 6 rst_dst=1'b0;
signal_src = 1'b1;
end
endmodule
//************************************************************************
***
// Parameter definitions
//************************************************************************
***
//************************************************************************
***
// Register declarations
//************************************************************************
***
reg
reg
reg
enabled = 1'b0;
[7:0]
[7:0]
my_data;
char_received;
//************************************************************************
***
// Tasks
//************************************************************************
***
// Enables the checker
task enable;
input new_enable;
begin
enabled = new_enable;
end
endtask
task is_done (
);
begin
if (!tb.tb_char_fifo_i0.is_empty(1'b0))
$display("%t ERROR Data FIFO is not empty when expected",$realtime);
end
endtask
//************************************************************************
***
// Code
//************************************************************************
***
always @(posedge strobe)
begin
if (enabled)
begin
my_data = tb.tb_char_fifo_i0.pop();
char_received = data_in;
#1; // Wait to ensure that the output data is valid after the rising
// edge of the strobe
if (data_in !== my_data)
begin
$display(
"%t ERROR Character mismatch. Expected %x (%c), received %x
(%c)",
$realtime, my_data, my_data, data_in, data_in);
end
else
begin
$display("%t
Character received %x (%c)", $realtime,
my_data,my_data);
end
end // if enabled
end // always
always @(posedge frm_err)
begin
if (enabled)
begin
$display("%t ERROR Frame Error Detected", $realtime);
end // if enabled
end // always
endmodule
//////////////////////////////////////////////////////////////////////////
//////
module tb_uart;
// Inputs
reg clk_pin;
reg rst_pin;
reg rxd_pin;
// Outputs
wire [7:0] led_pins;
// Instantiate the Unit Under Test (UUT)
uart_led uut (
.clk_pin(clk_pin),
.rst_pin(rst_pin),
.rxd_pin(rxd_pin),
.led_pins(led_pins)
);
initial begin
// Initialize Inputs
clk_pin = 0;
rst_pin = 1'b1;
rxd_pin = 0;
end
always # 4 clk_pin=~clk_pin;
always
begin
# 6 rst_pin=1'b0;
rxd_pin=1'b1;
end
endmodule
//
at a time (when invoked through one of its tasks), at a specified
bit
//
period. The character is sent using the RS232 protocol; START, 8
data
//
bits (LSbit first), STOP.
//
// Parameters:
//
// Tasks:
//
send_char_bitper : Sends a character at the specified bit period
//
(in NANOSECONDS)
//
set_bitper
: Sets the default bit period in NANOSECONDS
//
send_char
: Sends a character at the default bit period
//
send_char_push
: Sends a character at the default bit period, and
//
pushes the character into the data FIFO
//
// Functions:
//
// Internal variables:
//
reg [63:0]
bit_period
//
//
// Notes
:
//
//
// Multicycle and False Paths
//
None - this is a testbench file only, and is not intended for
synthesis
//
// All times in this testbench are expressed in units of nanoseconds, with
a
// precision of 1ps increments
`timescale 1ns/1ps
module tb_uart_driver (
output
data_out
);
//************************************************************************
***
// Parameter definitions
//************************************************************************
***
parameter BAUD_RATE = 57_600; // This is the default bit rate - can be
// overridden by "set_bitper"
//************************************************************************
***
// Register declarations
//************************************************************************
***
data_out_reg = 1'b1;
//************************************************************************
***
// Tasks
//************************************************************************
***
// The bit period is in nanoseconds since you can't pass a real to a
task
task set_bitper;
input [63:0] new_bit_per;
begin
bit_period = new_bit_per;
end
endtask
task send_char_bitper (
input [7:0] char,
input [63:0] bit_per
);
integer
i;
begin
$display ("%t
Sending character %x (%c)",$realtime, char,char);
data_out_reg = 1'b0; // send start bit
#(bit_per);
for (i=0; i<=7; i=i+1)
begin
data_out_reg = char[i];
#(bit_per);
end
data_out_reg = 1'b1; // send stop bit
#(bit_per);
end
endtask
task send_char (
input [7:0] char
);
begin
send_char_bitper(char,bit_period);
end
endtask
task send_char_push (
input [7:0] char
);
begin
tb.tb_char_fifo_i0.push(char);
send_char(char);
end
endtask
//************************************************************************
***
// Code
//************************************************************************
***
assign data_out = data_out_reg;
endmodule
//---------------------------------------------------------------------------//
// Copyright (c) 2009 Xilinx Inc.
//
// Project : Programmable Wave Generator
// Module
: tb_uart_rx.v
// Parent
: Testcase
// Children : tb_uart_driver, tb_resp_checker, tb_fifo, uart_rx
//
// Description:
//
This is the top level module for the testbench for the uart_rx
module.
//
// Parameters:
//
// Tasks:
//
// Internal variables:
//
// Notes
:
//
//
// Multicycle and False Paths
//
None - this is a testbench file only, and is not intended for
synthesis
//
// All times in this testbench are expressed in units of nanoseconds, with
a
// precision of 1ps increments
`timescale 1ns/1ps
module tb_uart_rx ();
//************************************************************************
***
// Parameter definitions
//************************************************************************
***
parameter FIFO_DEPTH=256;
parameter BAUD_RATE = 115_200;
`ifdef CLK100
parameter CLOCK_RATE = 100_000_000; // Clock period
`else
parameter CLOCK_RATE = 50_000_000; // Clock period
`endif
parameter PERIOD = 1_000_000_000.0/CLOCK_RATE;
//************************************************************************
***
// Register declarations
//************************************************************************
***
reg
clk = 1'b0;
wire
rst;
wire
rxd_i;
wire [7:0]
wire
wire
rx_data;
rx_data_rdy;
frm_err;
//************************************************************************
***
// Code
//************************************************************************
***
// Generate the clock
initial
begin
clk = 0;
forever
begin
#(PERIOD/2.0) clk = ~clk;
end // forever
end // initial
// Instantiate the reset generator
tb_resetgen tb_resetgen_i0 (
.clk
.reset
(clk),
(rst)
);
// Instantiate the data fifo
tb_fifo #(
.WIDTH(8),
.DEPTH(FIFO_DEPTH)
) tb_char_fifo_i0 ();
// Instantiate the data generator
tb_uart_driver #(
.BAUD_RATE (BAUD_RATE)
) tb_uart_driver_i0 (
.data_out (rxd_i)
);
// Instantiate the data checker
tb_resp_checker tb_resp_checker_i0 (
.strobe
(rx_data_rdy),
.frm_err
(frm_err),
.data_in
(rx_data)
);
uart_rx #(
.BAUD_RATE
.CLOCK_RATE
) uart_rx_i0 (
.clk_rx
.rst_clk_rx
.rxd_i
.rx_data
.rx_data_rdy
.frm_err
(BAUD_RATE),
(CLOCK_RATE)
(clk),
(rst),
(rxd_i),
(rx_data),
(rx_data_rdy),
(frm_err)
);
endmodule
// Company:
// Engineer:
//
// Create Date:
12:29:08 04/11/2012
// Design Name:
uart_rx
// Module Name:
C:/Documents and
Settings/Administrator/Desktop/uart_led/tb_uartrx.v
// Project Name: uart_led
// Target Device:
// Tool versions:
// Description:
//
// Verilog Test Fixture created by ISE for module: uart_rx
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////
//////
module tb_uartrx;
// Inputs
reg clk_rx;
reg rst_clk_rx;
reg rxd_i;
// Outputs
wire [7:0] rx_data;
wire rx_data_rdy;
wire frm_err;
// Instantiate the Unit Under Test (UUT)
uart_rx uut (
.clk_rx(clk_rx),
.rst_clk_rx(rst_clk_rx),
.rxd_i(rxd_i),
.rx_data(rx_data),
.rx_data_rdy(rx_data_rdy),
.frm_err(frm_err)
);
initial begin
// Initialize Inputs
clk_rx = 0;
rst_clk_rx = 1'b1;
rxd_i = 0;
end
always # 4 clk_rx=~clk_rx;
always
begin
# 6 rst_clk_rx=1'b0;
rxd_i =1'b1;
end
endmodule
tn uart rx ctl
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////
//////
// Company:
// Engineer:
//
// Create Date:
12:39:11 04/11/2012
// Design Name:
uart_rx_ctl
// Module Name:
C:/Documents and
Settings/Administrator/Desktop/uart_led/tb_uartrx_ctl.v
// Project Name: uart_led
// Target Device:
// Tool versions:
// Description:
//
// Verilog Test Fixture created by ISE for module: uart_rx_ctl
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////
//////
module tb_uartrx_ctl;
// Inputs
reg clk_rx;
reg rst_clk_rx;
reg baud_x16_en;
reg rxd_clk_rx;
// Outputs
wire [7:0] rx_data;
wire rx_data_rdy;
wire frm_err;
// Instantiate the Unit Under Test (UUT)
uart_rx_ctl uut (
.clk_rx(clk_rx),
.rst_clk_rx(rst_clk_rx),
.baud_x16_en(baud_x16_en),
.rxd_clk_rx(rxd_clk_rx),
.rx_data(rx_data),
.rx_data_rdy(rx_data_rdy),
.frm_err(frm_err)
);
initial begin
// Initialize Inputs
clk_rx = 0;
rst_clk_rx = 0;
baud_x16_en = 0;
rxd_clk_rx = 0;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
end
endmodule
test
uart rx
//---------------------------------------------------------------------------//
// Copyright (c) 2009 Xilinx Inc.
//
// Project : Programmable Wave Generator
// Module
: test_uart_rx
// Parent
: None
// Children : tb_uart_rx
//
// Description:
//
This module is a test for the uart receiver
//
// Parameters:
//
None
//
// Global variables:
//
Only those provided by the tb_fifo
//
//
// Notes
:
//
// Multicycle and False Paths
//
None - this is a testbench file only, and is not intended for
synthesis
//
// All times in this testbench are expressed in units of nanoseconds, with
a
Starting simulation",$realtime);
tb.tb_uart_driver_i0.send_char_push(char_to_send);
// Wait 20us between characters - not necessary for protocol
// Remove the delay to test back-to-back characters
#20_000;
end
#500_000 ; // Wait 500us after last char
// Check that the all data was received
tb.tb_resp_checker_i0.is_done;
$stop;
$finish;
end
endmodule
//---------------------------------------------------------------------------//
// Copyright (c) 2008 Xilinx Inc.
//
// Project : Programmable Wave Generator
// Module
: uart_baud_gen.v
// Parent
: uart_rx and uart_tx
// Children : None
//
// Description:
//
Generates a 16x Baud enable. This signal is generated 16 times per
bit
//
at the correct baud rate as determined by the parameters for the
system
//
clock frequency and the Baud rate
//
// Parameters:
//
BAUD_RATE : Baud rate - set to 57,600bps by default
//
CLOCK_RATE: Clock rate - set to 50MHz by default
//
// Local Parameters:
//
OVERSAMPLE_RATE: The oversampling rate - 16 x BAUD_RATE
//
DIVIDER
: The number of clocks per baud_x16_en
//
CNT_WIDTH : Width of the counter
//
// Notes
:
//
1) Divider must be at least 2 (thus CLOCK_RATE must be at least 32x
//
BAUD_RATE)
//
//
//
//
`timescale 1ns/1ps
module uart_baud_gen (
// Write side inputs
input
clk,
input
rst,
output
baud_x16_en
);
// Clock input
// Active HIGH reset - synchronous to clk
// Oversampled Baud rate enable
//************************************************************************
***
// Constant Functions
//************************************************************************
***
// Generate the ceiling of the log base 2 - i.e. the number of bits
// required to hold N values. A vector of size clogb2(N) will hold the
// values 0 to N-1
function integer clogb2;
input [31:0] value;
reg
[31:0] my_value;
begin
my_value = value - 1;
for (clogb2 = 0; my_value > 0; clogb2 = clogb2 + 1)
my_value = my_value >> 1;
end
endfunction
//
//************************************************************************
***
// Parameter definitions
//************************************************************************
***
parameter BAUD_RATE
parameter CLOCK_RATE
= 57_600;
= 50_000_000;
// Baud rate
if (internal_count == {CNT_WID{1'b0}})
begin
internal_count
<= OVERSAMPLE_VALUE;
end
else // internal_count is not 0
begin
internal_count
<= internal_count_m_1;
end
end // if rst
end // always
assign baud_x16_en = baud_x16_en_reg;
endmodule
UART LED
//---------------------------------------------------------------------------//
// Copyright (c) 2009 Xilinx Inc.
//
// Project : Programmable Wave Generator
// Module
: uart_led.v
// Parent
: None
// Children : uart_rx.v led_ctl.v
//
// Description:
//
Ties the UART receiver to the LED controller
//
// Parameters:
//
None
//
// Local Parameters:
//
// Notes
:
//
// Multicycle and False Paths
//
None
//
`timescale 1ns/1ps
module uart_led (
// Write side inputs
input
clk_pin,
input
rst_pin,
input
output
rxd_pin,
[7:0] led_pins
);
//************************************************************************
***
// Parameter definitions
//************************************************************************
***
parameter BAUD_RATE
`ifdef CLK100
parameter CLOCK_RATE
`else
parameter CLOCK_RATE
`endif
= 115_200;
= 100_000_000;
= 50_000_000;
//************************************************************************
***
// Reg declarations
//************************************************************************
***
//************************************************************************
***
// Wire declarations
//************************************************************************
***
// Pins
wire
wire
wire
wire [7:0]
rst_i;
clk_i;
rxd_i;
led_o;
// Output of BUFG
wire
clk_rx;
// Synchronized reset
wire
rst_clk_rx;
// Between uart_rx and led_ctl
wire [7:0]
rx_data;
// Data output of uart_rx
wire
rx_data_rdy; // Data ready output of uart_rx
//************************************************************************
***
// Code
//************************************************************************
***
IBUFG IBUFG_clk_i0
IBUF IBUF_rxd_i0
IBUF IBUF_rst_i0
BUFG
(.I (clk_pin),
(.I (rxd_pin),
(.I (rst_pin),
.O (clk_i));
.O (rxd_i));
.O (rst_i));
(rxd_i),
.rx_data_rdy (rx_data_rdy),
.rx_data
(rx_data),
.frm_err
()
);
led_ctl led_ctl_i0 (
.clk_rx
(clk_rx),
.rst_clk_rx (rst_clk_rx),
.rx_data
(rx_data),
.rx_data_rdy (rx_data_rdy),
.led_o
(led_o)
);
OBUF
OBUF
OBUF
OBUF
OBUF
OBUF
OBUF
OBUF
OBUF_led_i0
OBUF_led_i1
OBUF_led_i2
OBUF_led_i3
OBUF_led_i4
OBUF_led_i5
OBUF_led_i6
OBUF_led_i7
endmodule
(.I(led_o[0]),
(.I(led_o[1]),
(.I(led_o[2]),
(.I(led_o[3]),
(.I(led_o[4]),
(.I(led_o[5]),
(.I(led_o[6]),
(.I(led_o[7]),
.O(led_pins[0]));
.O(led_pins[1]));
.O(led_pins[2]));
.O(led_pins[3]));
.O(led_pins[4]));
.O(led_pins[5]));
.O(led_pins[6]));
.O(led_pins[7]));