URL
https://opencores.org/ocsvn/spdif_transmitter/spdif_transmitter/trunk
Subversion Repositories spdif_transmitter
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 2 to Rev 3
- ↔ Reverse comparison
Rev 2 → Rev 3
/spdif_transmitter/trunk/testbench/spdif_decoder.h
0,0 → 1,46
#ifndef SPDIF_DECODER_H |
#define SPDIF_DECODER_H |
|
#include <systemc.h> |
|
#define SPDIF_MAX_BITS 24 |
|
//------------------------------------------------------------- |
// spdif_decoder: Decoder for SPDIF signal |
//------------------------------------------------------------- |
SC_MODULE (spdif_decoder) |
{ |
public: |
// Clock and Reset |
sc_in <bool> clk_i; |
sc_in <bool> rst_i; |
|
// I/O |
sc_in <bool> rx_i; |
|
// Constructor |
SC_HAS_PROCESS(spdif_decoder); |
spdif_decoder(sc_module_name name): sc_module(name), |
m_rx_fifo(1024) |
{ |
m_divisor = 0; |
m_bits = 16; |
SC_CTHREAD(input, clk_i.pos()); |
} |
|
public: |
sc_uint <SPDIF_MAX_BITS> read(void) { return m_rx_fifo.read(); } |
bool read_ready(void) { return m_rx_fifo.num_available() > 0; } |
void set_clock_div(int divisor) { m_divisor = divisor; } |
void set_bit_width(int bits) { m_bits = bits; } |
|
private: |
void input(void); |
|
sc_fifo < sc_uint<SPDIF_MAX_BITS> > m_rx_fifo; |
|
int m_divisor; |
int m_bits; |
}; |
|
#endif |
/spdif_transmitter/trunk/testbench/spdif_tb.h
0,0 → 1,65
#ifndef SPDIF_TB_H |
#define SPDIF_TB_H |
|
#include "sc_vpi_clock.h" |
#include "spdif_vpi.h" |
|
#include "spdif_decoder.h" |
#include "spdif_driver.h" |
|
#define AUDIO_CLK_DIV 4 |
|
class spdif_tb: public sc_module |
{ |
public: |
SC_HAS_PROCESS(spdif_tb); |
|
sc_signal <bool> rst_i; |
sc_signal <bool> audio_clk_i; |
sc_signal <bool> spdif_o; |
sc_signal <sc_uint<32> > sample_i; |
sc_signal <bool> sample_req_o; |
|
spdif_tb(sc_module_name name): sc_module(name), |
m_dut("tb_top"), |
m_vpi_clk("tb_top.clk_i"), |
m_decoder("m_decoder"), |
m_driver("m_driver"), |
m_tx_fifo("m_tx_fifo") |
{ |
m_dut.clk_i(m_vpi_clk.m_clk); |
m_dut.rst_i(rst_i); |
m_dut.audio_clk_i(audio_clk_i); |
m_dut.spdif_o(spdif_o); |
m_dut.sample_i(sample_i); |
m_dut.sample_req_o(sample_req_o); |
|
m_decoder.clk_i(m_vpi_clk.m_clk); |
m_decoder.rst_i(rst_i); |
m_decoder.rx_i(spdif_o); |
m_decoder.set_clock_div(AUDIO_CLK_DIV); |
|
m_driver.clk_i(m_vpi_clk.m_clk); |
m_driver.rst_i(rst_i); |
m_driver.sample_req_i(sample_req_o); |
m_driver.sample_data_o(sample_i); |
|
SC_CTHREAD(drive, m_vpi_clk.m_clk); |
SC_CTHREAD(monitor, m_vpi_clk.m_clk); |
|
SC_CTHREAD(audio_clk, m_vpi_clk.m_clk); |
} |
|
spdif_vpi m_dut; |
sc_vpi_clock m_vpi_clk; |
spdif_decoder m_decoder; |
spdif_driver m_driver; |
|
sc_fifo < sc_uint<32> > m_tx_fifo; |
|
void drive(void); |
void monitor(void); |
void audio_clk(void); |
}; |
|
#endif |
/spdif_transmitter/trunk/testbench/spdif_driver.cpp
0,0 → 1,20
#include "spdif_driver.h" |
|
//----------------------------------------------------------------- |
// output: Drive tx data |
//----------------------------------------------------------------- |
void spdif_driver::output(void) |
{ |
wait(); |
sc_assert(m_tx_fifo.num_available() > 0); |
|
while (true) |
{ |
sample_data_o.write(m_tx_fifo.read()); |
|
wait(); |
|
while (!sample_req_i.read()) |
wait(); |
} |
} |
/spdif_transmitter/trunk/testbench/sc_vpi_clock.h
0,0 → 1,72
#ifndef __SC_VPI_CLOCK_H__ |
#define __SC_VPI_CLOCK_H__ |
|
#include <systemc.h> |
#include <vpi_user.h> |
|
|
static int sc_vpi_clock_after_delay(p_cb_data cb_data); |
|
class sc_vpi_clock |
{ |
public: |
|
sc_signal <bool> m_clk; |
int m_low_ns; |
int m_high_ns; |
|
sc_module_name m_name; |
|
vpiHandle m_vpi_handle; |
|
sc_vpi_clock(sc_module_name name) : m_clk(name), m_name(name) |
{ |
m_low_ns = 5; |
m_high_ns = 5; |
|
m_vpi_handle = vpi_handle_by_name((const char*)name, NULL); |
sc_assert(m_vpi_handle != NULL); |
} |
|
void start(void) { after_delay(); } |
|
int after_delay(void) |
{ |
bool clk_next = !m_clk.read(); |
s_vpi_time vpi_time_s; |
s_cb_data cb_data_s; |
|
vpi_time_s.type = vpiSimTime; |
vpi_time_s.high = 0; |
vpi_time_s.low = 0; |
|
s_vpi_value value_s; |
value_s.format = vpiIntVal; |
value_s.value.integer = clk_next; |
vpi_put_value(m_vpi_handle, &value_s, &vpi_time_s, vpiInertialDelay); |
|
// Setup wait time |
vpi_time_s.high = 0; |
vpi_time_s.low = clk_next ? m_high_ns : m_low_ns; |
vpi_time_s.type = vpiSimTime; |
|
m_clk.write(clk_next); |
|
// Attach value change callbacks for outputs |
cb_data_s.user_data = (PLI_BYTE8*)this; |
cb_data_s.reason = cbAfterDelay; |
cb_data_s.cb_rtn = sc_vpi_clock_after_delay; |
cb_data_s.time = &vpi_time_s; |
cb_data_s.value = NULL; |
vpi_register_cb(&cb_data_s); |
} |
}; |
|
static int sc_vpi_clock_after_delay(p_cb_data cb_data) |
{ |
sc_vpi_clock *p = (sc_vpi_clock*)cb_data->user_data; |
return p->after_delay(); |
} |
|
|
#endif |
/spdif_transmitter/trunk/testbench/spdif_driver.h
0,0 → 1,38
#ifndef SPDIF_DRIVER_H |
#define SPDIF_DRIVER_H |
|
#include <systemc.h> |
|
//------------------------------------------------------------- |
// spdif_driver: |
//------------------------------------------------------------- |
SC_MODULE (spdif_driver) |
{ |
public: |
// Clock and Reset |
sc_in <bool> clk_i; |
sc_in <bool> rst_i; |
|
// I/O |
sc_in <bool> sample_req_i; |
sc_out <sc_uint<32> > sample_data_o; |
|
// Constructor |
SC_HAS_PROCESS(spdif_driver); |
spdif_driver(sc_module_name name): sc_module(name), |
m_tx_fifo(2048) |
{ |
SC_CTHREAD(output, clk_i.pos()); |
} |
|
public: |
void write(sc_uint <32> data) { m_tx_fifo.write(data); } |
bool write_empty(void) { return m_tx_fifo.num_available() == 0; } |
|
private: |
void output(void); |
|
sc_fifo < sc_uint<32> > m_tx_fifo; |
}; |
|
#endif |
/spdif_transmitter/trunk/testbench/spdif_vpi.h
0,0 → 1,48
#ifndef SPDIF_VPI_H |
#define SPDIF_VPI_H |
|
#include "sc_vpi_module.h" |
|
class spdif_vpi: public sc_vpi_module |
{ |
public: |
sc_in <bool> clk_i; |
sc_in <bool> rst_i; |
sc_in <bool> audio_clk_i; |
sc_out <bool> spdif_o; |
sc_in <sc_uint<32> > sample_i; |
sc_out <bool> sample_req_o; |
|
void read_outputs(void) |
{ |
sc_vpi_module_read_output_int(spdif_o, "spdif_o"); |
sc_vpi_module_read_output_int(sample_req_o, "sample_req_o"); |
} |
|
void write_inputs(void) |
{ |
sc_vpi_module_write_input_int(clk_i, "clk_i"); |
sc_vpi_module_write_input_int(rst_i, "rst_i"); |
sc_vpi_module_write_input_int(audio_clk_i, "audio_clk_i"); |
sc_vpi_module_write_input_int(sample_i, "sample_i"); |
} |
|
spdif_vpi(sc_module_name name): |
sc_vpi_module(name) |
, clk_i ("clk_i") |
, rst_i ("rst_i") |
, audio_clk_i ("audio_clk_i") |
, spdif_o ("spdif_o") |
, sample_i ("sample_i") |
, sample_req_o ("sample_req_o") |
{ |
register_signal("clk_i"); |
register_signal("rst_i"); |
register_signal("audio_clk_i"); |
register_signal("spdif_o"); |
register_signal("sample_i"); |
register_signal("sample_req_o"); |
} |
}; |
|
#endif |
/spdif_transmitter/trunk/testbench/spdif_decoder.cpp
0,0 → 1,116
#include "spdif_decoder.h" |
|
#define PREAMBLE_Z 0x17 |
#define PREAMBLE_Y 0x27 |
#define PREAMBLE_X 0x47 |
|
#define SPDIF_PREAMBLE_L 0 |
#define SPDIF_PREAMBLE_H 3 |
#define SPDIF_PREAMBLE_W 4 |
|
#define SPDIF_SAMPLE_L 4 |
#define SPDIF_SAMPLE_H 27 |
#define SPDIF_SAMPLE_W 24 |
|
#define SPDIF_NVALID_L 28 |
#define SPDIF_NVALID_H 28 |
#define SPDIF_NVALID_W 1 |
|
#define SPDIF_PARITY_L 31 |
#define SPDIF_PARITY_H 31 |
#define SPDIF_PARITY_W 1 |
|
#define SPDIF_FIELD(v,n) v.range(SPDIF_##n##_H, SPDIF_##n##_L) |
|
//----------------------------------------------------------------- |
// input: Handle rx data |
//----------------------------------------------------------------- |
void spdif_decoder::input(void) |
{ |
sc_uint <64> bmc_data = 0; |
sc_uint <32> data = 0; |
|
do |
{ |
wait(); |
} |
while (rst_i.read()); |
|
bool last_rx = false; |
int subframe = 0; |
bool rx = false; |
while (true) |
{ |
rx = rx_i.read(); |
|
// Detect transition in preamble |
if (rx == false && last_rx == true) |
{ |
// Wait for half a bit time to sample mid bit |
wait(m_divisor/2); |
|
// Preamble leading bits were 0111 |
bmc_data = 0x7; |
|
// Capture remaining timeslots |
for (int i=4;i<64;i++) |
{ |
wait(m_divisor); |
rx = rx_i.read(); |
bmc_data[i] = rx; |
} |
|
// Check preamble type is expected |
if (subframe == 0) |
sc_assert(bmc_data.range(7,0) == PREAMBLE_Z); |
else if (subframe & 1) |
sc_assert(bmc_data.range(7,0) == PREAMBLE_Y); |
else |
sc_assert(bmc_data.range(7,0) == PREAMBLE_X); |
|
if (++subframe == 384) |
subframe = 0; |
|
// Decode BMC data |
for (int i=0;i<64;i+=2) |
{ |
if (bmc_data[i+0] != bmc_data[i+1]) |
data[i/2] = 1; |
else |
data[i/2] = 0; |
} |
|
// Check parity |
int ones_count = 0; |
for (int i=SPDIF_PREAMBLE_H+1;i<SPDIF_PARITY_L;i++) |
if (data[i]) |
ones_count += 1; |
|
if (ones_count & 1) |
sc_assert(SPDIF_FIELD(data, PARITY)); |
else |
sc_assert(!SPDIF_FIELD(data, PARITY)); |
|
sc_uint <SPDIF_SAMPLE_W> sample = SPDIF_FIELD(data, SAMPLE); |
|
// Valid sample |
if (!SPDIF_FIELD(data, NVALID)) |
{ |
sc_assert(m_rx_fifo.num_free() > 0); |
|
if (m_bits == 16) |
m_rx_fifo.write(sample >> (SPDIF_SAMPLE_W - 16)); |
else if (m_bits == 20) |
m_rx_fifo.write(sample >> (SPDIF_SAMPLE_W - 20)); |
else if (m_bits == 24) |
m_rx_fifo.write(sample >> (SPDIF_SAMPLE_W - 24)); |
else |
sc_assert(!"Unsupported bit width"); |
} |
} |
else |
wait(); |
|
last_rx = rx; |
} |
} |
/spdif_transmitter/trunk/testbench/spdif_tb.cpp
0,0 → 1,96
#include "spdif_tb.h" |
|
//----------------------------------------------------------------- |
// sc_main_tb |
//----------------------------------------------------------------- |
static int attach_system_c(p_cb_data user_data) |
{ |
spdif_tb * u_tb = new spdif_tb("spdif_tb"); |
|
// Initialize SystemC |
sc_start(0, SC_NS); |
|
// Start clock |
u_tb->m_vpi_clk.start(); |
} |
//----------------------------------------------------------------- |
// _register |
//----------------------------------------------------------------- |
static void _register(void) |
{ |
s_cb_data cb_data_s; |
cb_data_s.user_data = NULL; |
cb_data_s.reason = cbStartOfSimulation; |
cb_data_s.cb_rtn = attach_system_c; |
cb_data_s.time = NULL; |
cb_data_s.value = NULL; |
vpi_register_cb(&cb_data_s); |
} |
|
void (*vlog_startup_routines[])() = |
{ |
_register, |
0 |
}; |
|
//----------------------------------------------------------------- |
// audio_clk: Produce audio clock |
//----------------------------------------------------------------- |
void spdif_tb::audio_clk(void) |
{ |
// Reset |
rst_i.write(true); |
wait(5); |
rst_i.write(false); |
wait(1); |
|
while (1) |
{ |
wait(AUDIO_CLK_DIV/2); |
audio_clk_i.write(!audio_clk_i.read()); |
} |
} |
//----------------------------------------------------------------- |
// drive: Drive input sequence |
//----------------------------------------------------------------- |
void spdif_tb::drive(void) |
{ |
sc_uint <32> data; |
int interations = 2000; |
|
// Drive input data |
while (interations--) |
{ |
data.range(15,0) = rand(); |
data.range(31,16) = rand(); |
m_tx_fifo.write(data.range(15,0)); |
m_tx_fifo.write(data.range(31,16)); |
|
m_driver.write(data); |
} |
} |
//----------------------------------------------------------------- |
// monitor: Check output data |
//----------------------------------------------------------------- |
void spdif_tb::monitor(void) |
{ |
do |
{ |
wait(); |
} |
while (rst_i.read()); |
|
while (1) |
{ |
sc_uint <16> data = m_tx_fifo.read(); |
sc_uint <16> rx_data = m_decoder.read(); |
|
printf("EXPECT: %04x\n", (unsigned)data); |
printf("GOT: %04x\n", (unsigned)rx_data); |
|
sc_assert(rx_data == data); |
|
if (m_tx_fifo.num_available() == 0) |
m_dut.stopSimulation(); |
} |
} |
/spdif_transmitter/trunk/testbench/tb_top.v
0,0 → 1,40
`timescale 1ns / 1ns |
|
//----------------------------------------------------------------- |
// Module: Auto generated top |
//----------------------------------------------------------------- |
module tb_top(); |
|
reg clk_i; |
reg rst_i; |
reg audio_clk_i; |
wire spdif_o; |
reg [31:0] sample_i; |
wire sample_req_o; |
|
//----------------------------------------------------------------- |
// DUT |
//----------------------------------------------------------------- |
spdif dut |
( |
.clk_i(clk_i) |
, .rst_i(rst_i) |
, .audio_clk_i(audio_clk_i) |
, .spdif_o(spdif_o) |
, .sample_i(sample_i) |
, .sample_req_o(sample_req_o) |
); |
|
//----------------------------------------------------------------- |
// Trace |
//----------------------------------------------------------------- |
initial |
begin |
if (`TRACE) |
begin |
$dumpfile("waveform.vcd"); |
$dumpvars(0,tb_top); |
end |
end |
|
endmodule |
/spdif_transmitter/trunk/testbench/makefile
0,0 → 1,58
######################################################### |
# Vars |
######################################################### |
SYSTEMC_HOME ?= /usr/local/systemc-2.3.1 |
|
TRACE ?= 1 |
|
DUT_NAME = spdif |
RTL_DUT = ../rtl/spdif.v |
|
######################################################### |
# Source |
######################################################### |
SRC = $(wildcard *.cpp) |
|
SRC_V = tb_top.v |
SRC_V += $(RTL_DUT) |
SRC_V += ../rtl/spdif_core.v |
|
OBJ = $(patsubst %.cpp,%.o,$(SRC)) |
|
VPI_OBJ = dut |
|
######################################################### |
# CFLAGS |
######################################################### |
INC_PATH = -I. |
INC_PATH += -I/usr/include/iverilog |
INC_PATH += -I$(SYSTEMC_HOME)/include |
|
VINC_PATH = -I. -I../rtl |
VFLAGS = -DTRACE=$(TRACE) |
|
CFLAGS = -c -fpic |
|
LIB_OPT = $(SYSTEMC_HOME)/lib-linux64/libsystemc.a |
|
EXE = output.out |
|
######################################################### |
# Rules |
######################################################### |
all: run |
|
%.o : %.cpp |
gcc -c $(INC_PATH) $(CFLAGS) $< -o $@ |
|
$(VPI_OBJ).vpi: $(OBJ) |
g++ -shared -o $(VPI_OBJ).vpi -Wl,--whole-archive $(LIB_OPT) $(OBJ) -Wl,--no-whole-archive |
|
$(EXE) : $(SRC_V) |
iverilog -o $(EXE) $(SRC_V) $(VINC_PATH) $(VFLAGS) |
|
run: $(EXE) $(VPI_OBJ).vpi |
vvp -M. -m$(VPI_OBJ) $(EXE) -vcd |
|
clean: |
rm -rf $(OBJ) dut.vpi *.vcd *.out |
/spdif_transmitter/trunk/testbench/sc_vpi_module.h
0,0 → 1,145
#ifndef __SC_VPI_MODULE_H__ |
#define __SC_VPI_MODULE_H__ |
|
#include <systemc.h> |
#include <assert.h> |
#include <vpi_user.h> |
|
static int sc_vpi_module_value_change(p_cb_data cb_data); |
|
#define sc_vpi_module_read_output_int(obj, name) \ |
{ \ |
s_vpi_value value_s; \ |
s_vpi_time vpi_time_s; \ |
\ |
value_s.format = vpiIntVal; \ |
\ |
vpi_time_s.type = vpiSimTime; \ |
vpi_time_s.high = 0; \ |
vpi_time_s.low = 0; \ |
\ |
std::string path = m_hdl_name; \ |
path = path + "." + name; \ |
vpiHandle handle = vpi_handle_by_name(path.c_str(), NULL); \ |
assert(handle != NULL); \ |
\ |
vpi_get_value(handle, &value_s); \ |
obj.write(value_s.value.integer); \ |
} |
|
#define sc_vpi_module_write_input_int(obj, name) \ |
{ \ |
s_vpi_value value_s; \ |
s_vpi_time vpi_time_s; \ |
\ |
value_s.format = vpiIntVal; \ |
\ |
vpi_time_s.type = vpiSimTime; \ |
vpi_time_s.high = 0; \ |
vpi_time_s.low = 0; \ |
\ |
std::string path = m_hdl_name; \ |
path = path + "." + name; \ |
vpiHandle handle = vpi_handle_by_name(path.c_str(), NULL); \ |
assert(handle != NULL); \ |
\ |
value_s.value.integer = obj.read(); \ |
vpi_put_value(handle, &value_s, &vpi_time_s, vpiInertialDelay); \ |
} |
|
class sc_vpi_module |
{ |
public: |
std::string m_hdl_name; |
uint64_t m_last_time; |
sc_signal<bool> m_stop; |
|
sc_vpi_module(sc_module_name name) : m_hdl_name((std::string)name) |
{ |
m_last_time = 0; |
m_stop.write(false); |
} |
|
// Simulation control |
void stopSimulation() { m_stop.write(true); } |
bool isStopped() { return m_stop.read(); } |
|
virtual void read_outputs(void) { } |
virtual void write_inputs(void) { } |
|
bool register_signal(const char *name) |
{ |
static s_vpi_value value_s; |
static s_vpi_time vpi_time; |
s_cb_data cb_data_s; |
|
vpi_time.high = 0; |
vpi_time.low = 0; |
vpi_time.type = vpiSimTime; |
|
// For each I/O |
std::string path = m_hdl_name; |
path = path + "." + name; |
vpiHandle handle = vpi_handle_by_name(path.c_str(), NULL); |
if (!handle) |
return false; |
|
// Attach value change callbacks for outputs |
cb_data_s.user_data = (PLI_BYTE8*)this; |
cb_data_s.reason = cbValueChange; |
cb_data_s.cb_rtn = sc_vpi_module_value_change; |
cb_data_s.time = &vpi_time; |
cb_data_s.value = &value_s; |
|
value_s.format = vpiIntVal; |
|
cb_data_s.obj = handle; |
vpi_register_cb(&cb_data_s); |
|
return true; |
} |
|
int value_change(void) |
{ |
s_vpi_time vpi_time_s; |
|
vpi_time_s.type = vpiSimTime; |
vpi_time_s.high = 0; |
vpi_time_s.low = 0; |
|
// Outputs |
read_outputs(); |
|
// Get current time |
uint64_t time_value = 0; |
s_vpi_time time_now; |
time_now.type = vpiSimTime; |
vpi_get_time (0, &time_now); |
|
time_value = time_now.high; |
time_value <<= 32; |
time_value |= time_now.low; |
|
// Update systemC TB |
if(sc_pending_activity()) |
sc_start((int)(time_value-m_last_time),SC_NS); |
|
m_last_time = time_value; |
|
// Inputs |
write_inputs(); |
|
if (isStopped()) |
vpi_sim_control(vpiFinish, 0); |
|
return 0; |
} |
}; |
|
static int sc_vpi_module_value_change(p_cb_data cb_data) |
{ |
sc_vpi_module *p = (sc_vpi_module*)cb_data->user_data; |
return p->value_change(); |
} |
|
#endif |
/spdif_transmitter/trunk/rtl/spdif_core.v
167,10 → 167,6
// Left Channel (but not start of block)? |
else |
preamble_r = PREAMBLE_X; // X(M) |
|
// If previous timeslot ended with a 1, invert preamble |
if (spdif_o) |
preamble_r = ~preamble_r; |
end |
|
always @ (posedge rst_i or posedge clk_i ) |
/spdif_transmitter/trunk/README.md
0,0 → 1,37
### SPDIF Transmitter |
|
Github: [http://github.com/ultraembedded/cores](https://github.com/ultraembedded/cores/tree/master/spdif) |
|
This is a simple SPDIF transmitter module written in Verilog. |
|
This module can either generate its own audio clock by dividing down clk_i or can use an external audio clock to drive the output stream via audio_clk_i. |
|
For external clocking mode, the audio_clk_i clock rate should be: |
* 32KHz - 4.096MHz |
* 44.1KHz - 5.6448MHz |
* 48KHz - 6.144MHz |
|
Note that in external clocking mode, the frequency of clk_i must be more than 4 x audio_clk_i frequency. |
|
For internal clocking mode, the clk_i input is divided to roughly the right frequency required for chosen the sample rate. This isn't going to be exact! |
|
The input interface expects 32-bits (2 x 16-bit audio samples) to be provided to it on 'sample_i' and held until 'sample_req_o' is pulsed (data pop request). |
|
This allows connection to a simple FIFO for audio samples. |
|
##### Testing |
|
Tested on a Pioneer VSX D510 over TOSLINK and also on a cheap no-brand Ebay D/A converter. |
|
The supplied testbench requires the SystemC libraries and Icarus Verilog, both of which are available for free. |
|
##### Configuration |
|
* CLK_RATE_KHZ - Clock speed (clk_i) in KHz |
* AUDIO_RATE - Audio sample rate, e.g. 44100 or 48000 |
* AUDIO_CLK_SRC - Can be INTERNAL or EXTERNAL |
|
##### Size / Performance |
|
With the default configuration... |
* the design contains 69 flops, 3 adders, 2 comparators, 11 multiplexers (according to ISE). |