* Moved config/constants to central package

* Made cap of addsub selectable via signal
* Added debug reporting
    - MAX ADC Input 1
    - MAX ADC Input 2
    - MAX Scaler output
    - MAX DAC Output
* Added Async FIFO
* Added Simple Dual Port RAM
* Added Feedback Controller
* Added Xillybus Link
* Moved testbenches to seperate directory
This commit is contained in:
Greek 2020-04-26 11:35:46 +02:00
parent aa53591056
commit 779cd73e8d
18 changed files with 950 additions and 102 deletions

View File

@ -0,0 +1,213 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity memory_mapped_registers is
port (
clk : in std_logic;
reset : in std_logic;
--***AXI4-LITE INTERFACE***
-- WRITE ADDRESS CHANNEL
AWVALID : in std_logic;
AWREADY : out std_logic;
AWADDR : in std_logic_vector(1 downto 0);
AWPROT : in std_logic_vector(2 downto 0);
-- WRITE DATA CHANNEL
WVALID : in std_logic;
WREADY : out std_logic;
WDATA : in std_logic_vector(31 downto 0);
WSTRB : in std_logic_vector(3 downto 0);
-- WRITE RESPONSE CHANNEL
BVALID : out std_logic;
BREADY : in std_logic;
BRESP : out std_logic_vector(1 downto 0);
-- READ ADDRESS CHANNEL
ARVALID : in std_logic;
ARREADY : out std_logic;
ARADDR : in std_logic_vector(1 downto 0);
ARPROT : in std_logic_vector(2 downto 0);
-- READ DATA CHANNEL
RVALID : out std_logic;
RREADY : in std_logic;
RDATA : out std_logic_vector(31 downto 0);
RRESP : out std_logic_vector(1 downto 0);
-- DEBUG
reset_debug : out std_logic;
adc_data1_max : in std_logic_vector(11 downto 0);
adc_data2_max : in std_logic_vector(11 downto 0);
scaler_max : in std_logic_vector(15 downto 0);
dac_max : in std_logic_vector(15 downto 0)
-- DYNAMIC CONFIGURATION
addsub_mode : out std_logic;
delay : out std_logic_vector(7 downto 0);
factor : out std_logic_vector(3 downto 0);
);
end entity;
architecture arch of memory_mapped_registers is
--*****TYPE DECLARATION*****
type WRITE_STAGE_TYPE is (WRITE_ADDR, WRITE_DATA, WRITE_RESP);
type READ_STAGE_TYPE is (READ_ADDR, READ_DATA);
--*****SIGNAL DECLARATION*****
signal read_stage, read_stage_next : READ_STAGE_TYPE := READ_ADDR;
signal write_stage, write_stage_next : WRITE_STAGE_TYPE := WRITE_ADDR;
signal arready_next, arready, addsub_mode_next, rvalid, rvalid_next : std_logic := '0';
signal awready, awready_next, wready, wready_next, bvalid, bvalid_next : std_logic := '0';
signal rdata, rdata_next : std_logic_vector(31 downto 0) := (others => '0');
signal factor_next : std_logic_vector(3 downto 0) := (others => '0');
signal delay_next : std_logic_vector(7 downto 0) := (others => '0');
signal awaddr, awaddr_next : std_logic_vector(1 downto 0) := (others => '0');
signal reset_debug : std_logic := '0';
begin
BRESP <= (others => '0');
RRESP <= (others => '0');
AWREADY <= awready;
AWADDR <= awaddr;
WREADY <= wready;
BVALID <= bvalid;
ARREADY <= arready;
RVALID <= rvalid;
read_ctrl : process(all)
begin
--DEFAULT VALUES
read_stage_next <= read_stage;
arready_next <= arready;
rdata_next <= rdata;
rvalid_next <= rvalid;
case(read_stage)
when READ_ADDR =>
arready_next <= '1';
rvalid_next <= '0';
if (ARVALID = '1') then
case(to_integer(unsigned(ARADDR)))
when 0 =>
rdata_next <= (others => '0');
rdata_next(30) <= addsub_mode_next;
rdata_next(19 downto 16) <= factor_next;
rdata_next(7 downto 0) <= delay_next;
when 1 =>
rdata_next <= (others => '0');
rdata_next(11 downto 0) <= adc_data1_max;
rdata_next(27 downto 16)<= adc_data2_max;
when 2 =>
rdata_next <= (others => '0');
rdata_next(15 downto 0) <= dac_max;
rdata_next(31 downto 16)<= scaler_max;
when others =>
rdata_next <= (others => '0');
end case;
arready_next <= '0';
rvalid_next <= '1';
read_stage_next <= READ_DATA;
end if;
when READ_DATA =>
arready_next <= '0';
rvalid_next <= '1';
if (RREADY = '1') then
arready_next <= '1';
rvalid_next <= '0';
read_stage_next <= READ_ADDR;
end if;
end case;
end process;
read_ctrl : process(all)
begin
--DEFAULT VALUES
write_stage_next <= write_stage;
awready_next <= awready;
awaddr_next <= awaddr;
wready_next <= wready;
bvalid_next <= bvalid;
reset_debug_next <= '0';
case(write_stage)
when WRITE_ADDR =>
awready_next <= '1';
wready_next <= '0';
bvalid <= '0';
if (AWVALID = '1') then
awaddr_next <= AWADDR;
awready_next <= '0';
wready_next <= '1';
write_stage_next <= WRITE_DATA;
end if;
when WRITE_DATA =>
awready_next <= '0';
wready_next <= '1';
bvalid <= '0';
if (WVALID = '1') then
case(to_integer(unsigned(awaddr)))
when 0 =>
reset_debug_next <= WDATA(31);
addsub_mode_next <= WDATA(30);
factor_next <= WDATA(19 downto 16);
delay_next <= WDATA(7 downto 0);
when others =>
null;
end case;
wready_next <= '0';
bvalid_next <= '1';
write_stage_next <= WRITE_RESP;
end if;
when WRITE_RESP =>
awready_next <= '0';
wready_next <= '0';
bvalid_next <= '1';
if (BREADY = '1') then
bvalid_next <= '0';
awready_next <= '1';
write_stage_next <= WRITE_ADDR;
end if;
end case;
end process;
sync : process(clk)
begin
if (rising_edge(clk)) then
if (reset = '1') then
awready <= '0';
awaddr <= (others => '0');
wready <= '0';
bvalid <= '0';
arready <= '0';
rvalid <= '0';
read_stage <= READ_ADDR;
write_stage <= WRITE_ADDR;
addsub_mode <= '0';
factor <= (others => '0');
delay <= (others => '0');
rdata <= (others => '0');
else
awready <= awready_next;
awaddr <= awaddr_next;
wready <= wready_next;
bvalid <= bvalid_next;
arready <= arready_next;
rvalid <= rvalid_next;
read_stage <= read_stage_next;
write_stage <= write_stage_next;
addsub_mode <= addsub_mode_next;
factor <= factor_next;
delay <= delay_next;
rdata <= rdata_next;
end if;
end if;
end process;
end architecture;

View File

@ -10,7 +10,7 @@ use UNIMACRO.vcomponents.all;
-- Add/Sub
-- This entity adds or subtracts inputs 'A' and 'B', depending on 'mode' (1 = add, 0 = sub).
-- NOTE: In Overfolw/Underflow conditions the result is capped at max/min value.
-- If 'cap' is high, on Overfolw/Underflow conditions the result is capped at max/min value.
entity addsub is
generic (
@ -18,12 +18,13 @@ entity addsub is
DATA_WIDTH : integer := 16
);
port (
clk : std_logic;
reset : std_logic;
mode : std_logic;
A : std_logic_vector(DATA_WIDTH-1 downto 0);
B : std_logic_vector(DATA_WIDTH-1 downto 0);
RES : std_logic_vector(DATA_WIDTH-1 downto 0)
clk : in std_logic;
reset : in std_logic;
mode : in std_logic;
cap : in std_logic;
A : in std_logic_vector(DATA_WIDTH-1 downto 0);
B : in std_logic_vector(DATA_WIDTH-1 downto 0);
RES : out std_logic_vector(DATA_WIDTH-1 downto 0)
);
end entity;
@ -59,7 +60,7 @@ begin
RES <= result;
--Overflow/Underflow
if(carry = '1') then
if(carry = '1' and cap = '1') then
--ADD
if(mode = '1') then
--CAP AT MAX VALUE

90
src/async_fifo.vhd Normal file
View File

@ -0,0 +1,90 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
Library xpm;
use xpm.vcomponents.all;
-- Read and Write requests are ignored while the FIFO is in a reset state (reset busy signal high)
entity async_fifo is
generic (
DATA_WIDTH : integer := 32;
FIFO_DEPTH : integer := 16; -- (16 - 4194304)
PROG_EMPTY : integer := 3; -- MIN:3 MAX:(FIFO_DEPTH-3)
PROG_FULL : integer := 13 -- MIN:3+CDC_SYNC_STAGES MAX:(FIFO_DEPTH-3)
);
port (
wr_clk : in std_logic;
rd_clk : in std_logic;
reset : in std_logic; --wr_clk synchronous
wen : in std_logic;
ren : in std_logic;
empty : out std_logic;
almost_empty: out std_logic;
prog_empty : out std_logic;
full : out std_logic;
almost_full : out std_logic;
prog_full : out std_logic;
wr_data : in std_logic_vector(DATA_WIDTH-1 downto 0);
rd_data : out std_logic_vector(DATA_WIDTH-1 downto 0)
);
end entity;
architecture arch of async_fifo is
--*****SIGNAL DECLARATION*****
signal rd_busy, wr_busy : std_logic := '0';
begin
xpm_fifo_async_inst : xpm_fifo_async
generic map (
CDC_SYNC_STAGES => 2,
DOUT_RESET_VALUE => "0",
ECC_MODE => "no_ecc",
FIFO_MEMORY_TYPE => "auto",
FIFO_READ_LATENCY => 1,
FIFO_WRITE_DEPTH => FIFO_DEPTH,
FULL_RESET_VALUE => 1,
PROG_EMPTY_THRESH => PROG_EMPTY,
PROG_FULL_THRESH => PROG_FULL,
RD_DATA_COUNT_WIDTH => 1,
READ_DATA_WIDTH => DATA_WIDTH,
READ_MODE => "std",
RELATED_CLOCKS => 0,
USE_ADV_FEATURES => "0A0A",
WAKEUP_TIME => 0,
WRITE_DATA_WIDTH => DATA_WIDTH,
WR_DATA_COUNT_WIDTH => 1
)
port map (
almost_empty => almost_empty,
almost_full => almost_full,
data_valid => open,
dbiterr => open,
dout => rd_data,
empty => empty,
full => full,
overflow => open,
prog_empty => prog_empty,
prog_full => prog_full,
rd_data_count => open,
rd_rst_busy => rd_busy,
sbiterr => open,
underflow => open,
wr_ack => open,
wr_data_count => open,
wr_rst_busy => wr_busy,
din => wr_data,
injectdbiterr => '0',
injectsbiterr => '0',
rd_clk => rd_clk,
rd_en => ren and (not rd_busy),
rst => reset,
sleep => '0',
wr_clk => wr_clk,
wr_en => wr_en and (not wr_busy)
);
end architecture;

View File

@ -6,6 +6,12 @@ library UNISIM;
use UNISIM.VCOMPONENTS.ALL;
entity clockgen is
generic (
CLKFBOUT_MULT : integer := 41;
CLKIN1_PERIOD : real := 10.000000;
CLKOUT0_DIVIDE : integer := 41;
DIVCLK_DIVIDE : integer := 5
);
port (
clk_in : in std_logic;
clk_out : out std_logic
@ -29,11 +35,11 @@ begin
plle2_adv_inst: unisim.vcomponents.PLLE2_ADV
generic map(
BANDWIDTH => "OPTIMIZED",
CLKFBOUT_MULT => 41,
CLKFBOUT_MULT => CLKFBOUT_MULT,
CLKFBOUT_PHASE => 0.000000,
CLKIN1_PERIOD => 10.000000,
CLKIN1_PERIOD => CLKIN1_PERIOD,
CLKIN2_PERIOD => 0.000000,
CLKOUT0_DIVIDE => 41,
CLKOUT0_DIVIDE => CLKOUT0_DIVIDE,
CLKOUT0_DUTY_CYCLE => 0.500000,
CLKOUT0_PHASE => 0.000000,
CLKOUT1_DIVIDE => 1,
@ -52,7 +58,7 @@ begin
CLKOUT5_DUTY_CYCLE => 0.500000,
CLKOUT5_PHASE => 0.000000,
COMPENSATION => "ZHOLD",
DIVCLK_DIVIDE => 5,
DIVCLK_DIVIDE => DIVCLK_DIVIDE,
IS_CLKINSEL_INVERTED => '0',
IS_PWRDWN_INVERTED => '0',
IS_RST_INVERTED => '0',

View File

@ -8,14 +8,14 @@ use ieee.numeric_std.all;
-- have effectively a ring buffer that we can vary in size (up to the maximum capacity of the memory).
-- NOTE: Changing the 'delay' value may lead to glitches during the first "delay period", due to the
-- way the address generation is made. More specifically, these glitches happen when the 'delay' is
-- increased (which is unavoidable), and when it is decreased while the counter is the same as the new
-- delay [single cycle glitch].
-- increased (which is unavoidable), and when it is decreased while the momentarily counter value is
-- the same as the new delay value [single cycle glitch].
entity delay_line is
generic (
DATA_WIDTH : integer := 12;
DELAY_WIDTH : integer := 8;
MAX_DELAY : integer := 200
MAX_DELAY : integer := 200;
DELAY_WIDTH : integer := 8
);
port (
clk : in std_logic;
@ -31,16 +31,15 @@ architecture arch of delay_line is
component single_port_ram is
generic (
ADDR_WIDTH : integer := 8;
DATA_WIDTH : integer := 12;
MEMORY_DEPTH : integer := 200
DATA_WIDTH : integer := 12
);
port (
clk : in std_logic;
addr : in std_logic_vector(ADDR_WIDTH-1 downto 0);
wen : in std_logic;
ren : in std_logic;
write_data : in std_logic_vector(DATA_WIDTH-1 downto 0);
read_data : out std_logic_vector(DATA_WIDTH-1 downto 0)
wr_data : in std_logic_vector(DATA_WIDTH-1 downto 0);
rd_data : out std_logic_vector(DATA_WIDTH-1 downto 0)
);
end component;
@ -54,30 +53,29 @@ begin
ram_inst : single_port_ram
generic map(
ADDR_WIDTH => DELAY_WIDTH,
DATA_WIDTH => DATA_WIDTH,
MEMORY_DEPTH => MAX_DELAY
DATA_WIDTH => DATA_WIDTH
);
port map(
clk => clk,
addr => cnt,
addr => std_logic_vector(to_unsigned(cnt,DELAY_WIDTH)),
wen => '1',
ren => '1',
write_data => data_in,
read_data => memory_out
wr_data => data_in,
rd_data => memory_out
);
cntrl : process(all)
ctrl : process(all)
begin
-- DEFAULT VALUES
cnt_next <= cnt;
cnt_max_next <= cnt_max;
if(to_integer(unsigned(addr)) = 0) then
if(to_integer(unsigned(delay)) = 0) then
data_out <= data_in;
else
data_out <= memory_out;
-- COUNT GENERATION
cnt_max_next <= to_integer(unsigned(addr)) - 1;
cnt_max_next <= to_integer(unsigned(delay)) - 1;
if (cnt >= cnt_max) then
cnt_next <= 0;
else

75
src/dual_port_ram.vhd Normal file
View File

@ -0,0 +1,75 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
Library xpm;
use xpm.vcomponents.all;
-- NOTE: Simutanous reads and writes to the same addresses have to be prevented by external means!
entity dual_port_ram is
generic (
ADDR_WIDTH : integer := 4;
DATA_WIDTH : integer := 16
);
port (
wr_clk : in std_logic;
rd_clk : in std_logic;
rd_addr : in std_logic_vector(ADDR_WIDTH-1 downto 0);
wr_addr : in std_logic_vector(ADDR_WIDTH-1 downto 0);
wen : in std_logic;
ren : in std_logic;
wr_data : in std_logic_vector(DATA_WIDTH-1 downto 0);
rd_data : out std_logic_vector(DATA_WIDTH-1 downto 0)
);
end entity;
architecture arch of dual_port_ram is
begin
xpm_memory_sdpram_inst : xpm_memory_sdpram
generic map (
ADDR_WIDTH_A => ADDR_WIDTH,
ADDR_WIDTH_B => ADDR_WIDTH,
AUTO_SLEEP_TIME => 0,
BYTE_WRITE_WIDTH_A => DATA_WIDTH,
CLOCKING_MODE => "independent_clock",
ECC_MODE => "no_ecc",
MEMORY_INIT_FILE => "none",
MEMORY_INIT_PARAM => "0",
MEMORY_OPTIMIZATION => "true",
MEMORY_PRIMITIVE => "auto",
MEMORY_SIZE => DATA_WIDTH*(2**ADDR_WIDTH),
MESSAGE_CONTROL => 0,
READ_DATA_WIDTH_B => DATA_WIDTH,
READ_LATENCY_B => 1,
READ_RESET_VALUE_B => "0",
RST_MODE_A => "SYNC",
RST_MODE_B => "SYNC",
USE_EMBEDDED_CONSTRAINT => 1, --TODO
USE_MEM_INIT => 1,
WAKEUP_TIME => "disable_sleep",
WRITE_DATA_WIDTH_A => DATA_WIDTH,
WRITE_MODE_B => "no_change"
)
port map (
dbiterrb => open,
doutb => rd_data,
sbiterrb => open,
addra => wr_addr,
addrb => rd_addr,
clka => wr_clk,
clkb => rd_clk,
dina => wr_data,
ena => wen,
enb => ren,
injectdbiterra => '0',
injectsbiterra => '0',
regceb => '1',
rstb => '0',
sleep => '0',
wea => wen
);
end architecture;

124
src/feedback_controller.vhd Normal file
View File

@ -0,0 +1,124 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.typedef_package.all;
-- Feedback Controller
-- This entity reads from the config memory and applies the resepctive configuration when the relevant
-- timestamp is reached or exceeded. The timer starts counting when a high level is detected in the 'sync'
-- signal after a reset.
-- NOTE: This entity is continuosly reading from the memory, except when the 'reset' signal is held high.
-- Config Mapping:
-- mem_data(63) : Slot Enable
-- mem_data(62) : Addsub_mode
-- mem_data(61) : Add_input_mux
-- mem_data(47-40) : delay
-- mem_data(35-32) : factor
-- mem_data(31-0) : timestamp
entity feedback_controller is
port (
clk : in std_logic;
reset : in std_logic;
sync : in std_logic;
mem_addr : out std_logic_vector(CONFIG_MEM_ADDR_WIDTH-1 downto 0);
mem_ren : out std_logic;
mem_data : in std_logic_vector(CONFIG_DATA_WIDTH-1 downto 0);
addsub_mode : out std_logic;
add_input_mux : out std_logic;
delay : out std_logic_vector(DELAY_WIDTH-1 downto 0);
factor : out std_logic_vector(FACTOR_WIDTH-1 downto 0)
);
end entity;
architecture arch of feedback_controller is
--*****CONSTANT DECLARATION*****
constant inc : unsigned(CONFIG_MEM_ADDR_WIDTH-1 downto 0) := to_unsigned(1,CONFIG_MEM_ADDR_WIDTH);
--*****SIGNAL DECLARATION*****
signal slot_nr, slot_nr_next : std_logic_vector(CONFIG_MEM_ADDR_WIDTH-1 downto 0) : (others => '0');
signal timer : std_logic_vector(TIMESTAMP_WIDTH-1 downto 0) := (others => '0');
signal sync_arrived : std_logic;
signal addsub_mode_next, addsub_mode_sig, add_input_mux_next, add_input_mux_sig : std_logic := '0';
signal delay_next, delay_sig : std_logic_vector(DELAY_WIDTH-1 downto 0); := (others => '0');
signal factor_next, factor_sig : std_logic_vector(FACTOR_WIDTH-1 downto 0) := (others => '0');
begin
--OUTPUT SIGNALS
-- Intermediate "_sig" signals needed because we cannot read from output pins
mem_ren <= not reset;
mem_addr <= slot_nr_next; -- Use 'next' signal to "asynchronously" set addr (Save 1 clock cycle)
addsub_mode <= addsub_mode_sig;
add_input_mux <= add_input_mux_sig;
delay <= delay_sig;
factor <= factor_sig;
ctrl : process(all)
begin
--DEFAULT
slot_nr_next <= slot_nr;
addsub_mode_next <= addsub_mode_sig;
add_input_mux_next <= add_input_mux_sig;
delay_next <= delay_sig;
factor_next <= factor_sig;
if(mem_data(CONFIG_DATA_WIDTH-1) = '1') then
-- If timestamp is reached (or exceeded), apply configuration and fetch next configuration
-- slot
if (unsigned(timer) >= unsigned(mem_data(TIMESTAMP_WIDTH-1 downto 0))) then
addsub_mode_next <= mem_data(CONFIG_DATA_WIDTH-2);
add_input_mux_next <= mem_data(CONFIG_DATA_WIDTH-3);
delay_next <= mem_data(CONFIG_DATA_WIDTH-17 downto CONFIG_DATA_WIDTH-16-DELAY_WIDTH);
factor_next <= mem_data(TIMESTAMP_WIDTH+FACTOR_WIDTH-1 downto TIMESTAMP_WIDTH);
slot_nr_next <= std_logic_vector(unsigned(slot_nr) + inc);
end if;
end if;
end process;
sync : process(clk)
begin
if rising_edge(clk) then
if (reset = '1') then
slot_nr <= (others => '0');
addsub_mode_sig <= '0';
add_input_mux_sig <= '0';
delay_sig <= (others => '0');
factor_sig <= (others => '0');
else
slot_nr <= slot_nr_next;
addsub_mode_sig <= addsub_mode_next;
add_input_mux_sig <= add_input_mux_next;
delay_sig <= delay_next;
factor_sig <= factor_next;
end if;
end if;
end process;
timer : process(clk)
begin
if rising_edge(clk) then
if (reset = '1') then
timer <= (others => '0');
sync_arrived <= '0';
else
if (sync_arrived = '0') then
-- Wait for rising edge of sync pulse
if (sync = '1') then
sync_arrived <= '1';
end if;
else
timer <= std_logic_vector(unsigned(timer) + inc);
end if;
end if;
end if;
end process;
end architecture;

View File

@ -2,14 +2,23 @@ library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.typedef_package.all;
-- Architecture
--- ---------- ------ ------- ---
-- --- ---------- ------ ------- ---
--->|ADC|--->|Delay Line|--->|Scaler|--->|ADD/SUB|--->|DAC|--->
--- ---------- ------ ------- ---
-- --- ---------- ------ ------- ---
-- ^
--- ----- |
--->|ADC|---------------------|Latch|--------
--- -----
-- --- ----- --- |
--->|ADC|-------------------->|Latch|->| | |
-- --- ----- |MUX|--
-- GND--->| |
-- ---
-- Feedback Loop
-- This entity implements the feedback loop as defined above.
-- In addition to that, this entity latches and provides various max values that can be used for debug
-- purposes.
entity feedback_loop is
port (
@ -17,20 +26,27 @@ entity feedback_loop is
reset : in std_logic;
adc_data_in1 : in std_logic;
adc_data_in2 : in std_logic;
addsub_mode : in std_logic;
delay : in std_logic_vector(7 downto 0);
factor : in std_logic_vector(3 downto 0);
adc_cs_n : out std_logic;
dac_data_out : out std_logic;
dac_cs_n : out std_logic;
dac_ldac : out std_logic
dac_ldac : out std_logic;
-- DYNAMIC CONFIGURATION
addsub_mode : in std_logic; -- (1=ADD, 0=SUB)
add_input_mux : in std_logic; -- (1=ADC Input 2, 0=GND)
delay : in std_logic_vector(DELAY_WIDTH-1 downto 0); -- unsigned delay clock count
factor : in std_logic_vector(FACTOR_WIDTH-1 downto 0); -- 1Q3 Fixed Point
-- DEBUG
adc_data1_max : out std_logic_vector(ADC_DATA_WIDTH-1 downto 0);
adc_data2_max : out std_logic_vector(ADC_DATA_WIDTH-1 downto 0);
scaler_max : out std_logic_vector(DAC_DATA_WIDTH-1 downto 0);
dac_max : out std_logic_vector(DAC_DATA_WIDTH-1 downto 0)
);
end entity;
architecture arch of feedback_loop is
--*****SIGNAL DECLARATION*****
signal adc_data1, adc_data2 : std_logic_vector(11 downto 0) := (others => '0');
signal adc_data1, adc_data2 : std_logic_vector(ADC_DATA_WIDTH-1 downto 0) := (others => '0');
signal adc_done : std_logic := '0';
--*****COMPONENT DECLARATION*****
@ -38,7 +54,7 @@ architecture arch of feedback_loop is
generic(
TRANSFER_CLK_COUNT : integer := 16;
DELAY_CLK_CNT : integer := 2;
DATA_BITS : integer := 12
DATA_WIDTH : integer := 12
);
port (
sclk : in std_logic; -- PMOD-AD1
@ -47,8 +63,8 @@ architecture arch of feedback_loop is
sdata2 : in std_logic; -- PMOD-AD1
enable : in std_logic;
cs_n : out std_logic;-- PMOD-AD1
data1 : out std_logic_vector(DATA_BITS-1 downto 0);
data2 : out std_logic_vector(DATA_BITS-1 downto 0);
data1 : out std_logic_vector(DATA_WIDTH-1 downto 0);
data2 : out std_logic_vector(DATA_WIDTH-1 downto 0);
done : out std_logic
);
end component;
@ -56,13 +72,13 @@ architecture arch of feedback_loop is
component pmod_da3_ctrl is
generic(
TRANSFER_CLK_COUNT : integer := 16;
DATA_BITS : integer := 16
DATA_WIDTH : integer := 16
);
port (
sclk : in std_logic; -- PMOD-DA3
reset : in std_logic;
start : in std_logic;
data : in std_logic_vector(DATA_BITS-1 downto 0);
data : in std_logic_vector(DATA_WIDTH-1 downto 0);
cs_n : out std_logic;-- PMOD-DA3
sdata : out std_logic;-- PMOD-DA3
ldac : out std_logic;-- PMOD-DA3
@ -90,12 +106,13 @@ architecture arch of feedback_loop is
DATA_WIDTH : integer := 16
);
port (
clk : std_logic;
reset : std_logic;
mode : std_logic;
A : std_logic_vector(DATA_WIDTH-1 downto 0);
B : std_logic_vector(DATA_WIDTH-1 downto 0);
RES : std_logic_vector(DATA_WIDTH-1 downto 0)
clk : in std_logic;
reset : in std_logic;
mode : in std_logic;
cap : in std_logic;
A : in std_logic_vector(DATA_WIDTH-1 downto 0);
B : in std_logic_vector(DATA_WIDTH-1 downto 0);
RES : out std_logic_vector(DATA_WIDTH-1 downto 0)
);
end component;
@ -114,18 +131,19 @@ architecture arch of feedback_loop is
end component;
--*****SIGNAL DECLARATION*****
signal delay_out, latch_out : std_logic_vector(12 downto 0) := (others => '0');
signal scaler_out, addsub_out : std_logic_vector(15 downto 0) := (others => '0');
signal delay_out, latch_out : std_logic_vector(ADC_DATA_WIDTH downto 0) := (others => '0');
signal scaler_out, addsub_out, dac_max, scaler_max, inputA : std_logic_vector(DAC_DATA_WIDTH-1 downto 0) := (others => '0');
signal scaler_done, addsub_done : std_logic := '0';
signal adc_data1_max, adc_data2_max : std_logic_vector(ADC_DATA_WIDTH-1 downto 0) := (others => '0');
begin
--*****STAGE I*****
adc_inst : pmod_ad1_ctrl
generic map(
TRANSFER_CLK_COUNT => 16,
DELAY_CLK_CNT => 2,
DATA_BITS => 12
TRANSFER_CLK_COUNT => ADC_TRANSFER_CLK_COUNT,
DELAY_CLK_CNT => ADC_DELAY_CLK_CNT,
DATA_WIDTH => ADC_DATA_WIDTH
)
port map(
sclk => clk,
@ -142,9 +160,9 @@ begin
--*****STAGE II*****
delay_line_inst : delay_line
generic map(
DATA_WIDTH => 13,
DELAY_WIDTH => 8,
MAX_DELAY => 200
DATA_WIDTH => ADC_DATA_WIDTH+1,
DELAY_WIDTH => DELAY_WIDTH,
MAX_DELAY => MAX_DELAY
)
port map(
clk => clk,
@ -156,13 +174,13 @@ begin
--*****STAGE III*****
scaler_inst : scaler
generic map(
DATA_WIDTH => 12,
FACTOR_WIDTH => 4,
DATA_WIDTH => ADC_DATA_WIDTH,
FACTOR_WIDTH => FACTOR_WIDTH,
PIPELINE_STAGES => 1
)
port map(
clk => clk,
data_in => delay_out(11 downto 0),
data_in => delay_out(ADC_DATA_WIDTH-1 downto 0),
factor => factor,
data_out => scaler_out
);
@ -171,9 +189,9 @@ begin
begin
if (rising_edge(clk)) then
if (reset = '1') then
scaler_done <= (others => '0');
scaler_done <= '0';
else
scaler_done <= delay_out(12);
scaler_done <= delay_out(ADC_DATA_WIDTH);
end if;
end if;
end process;
@ -190,17 +208,28 @@ begin
end process;
--*****STAGE IV*****
mux: process(all)
begin
if (input_mux = '1') then
inputA <= latch_out & "0000";
else
inputA <= (others => '0');
end if;
end process;
addsub_inst : addsub
generic map(
PIPELINE_STAGES => 1,
DATA_WIDTH => 16
DATA_WIDTH => DAC_DATA_WIDTH
)
port map(
clk => clk,
reset => reset,
mode => addsub_mode,
A => scaler_out,
B => latch_out & "0000",
cap => input_mux,
A => inputA,
B => scaler_out,
RES => addsub_out
);
@ -218,8 +247,8 @@ begin
--*****STAGE V*****
dac_inst : pmod_da3_ctrl
generic map(
TRANSFER_CLK_COUNT => 16,
DATA_BITS => 16
TRANSFER_CLK_COUNT => DAC_TRANSFER_CLK_COUNT,
DATA_WIDTH => DAC_DATA_WIDTH
)
port map(
sclk => clk,
@ -232,4 +261,36 @@ begin
done => open
);
--*****DEBUG*****
process(clk)
begin
if (rising_edge(clk)) then
if (reset = '1' or reset_debug = '1') then
adc_data1_max <= (others => '0');
adc_data2_max <= (others => '0');
dac_max <= (others => '0');
scaler_max <= (others => '0');
-- ADC MAX VALUES
elsif (adc_done = '1') then
if (to_integer(unsigned(adc_data1)) >= to_integer(unsigned(adc_data1_max))) then
adc_data1_max <= adc_data1;
elsif (to_integer(unsigned(adc_data2)) >= to_integer(unsigned(adc_data2_max))) then
adc_data2_max <= adc_data2;
end if;
-- DAC MAX VALUES
elsif (addsub_done = '1') then
if (to_integer(unsigned(addsub_out)) >= to_integer(unsigned(dac_max))) then
dac_max <= addsub_out;
end if;
-- SCALER MAX VALUES
elsif (scaler_done = '1') then
if (to_integer(unsigned(scaler_out)) >= to_integer(unsigned(scaler_max))) then
scaler_max <= scaler_out;
end if;
end if;
end if;
end process;
end architecture;

View File

@ -2,6 +2,8 @@ library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.typedef_package.all;
entity open_loop is
port (
clk : in std_logic;
@ -17,7 +19,7 @@ end entity;
architecture arch of open_loop is
--*****SIGNAL DECLARATION*****
signal interconnect : std_logic_vector(15 downto 0) := (others => '0');
signal interconnect : std_logic_vector(DAC_DATA_WIDTH-1 downto 0) := (others => '0');
signal adc_done : std_logic := '0';
--*****COMPONENT DECLARATION*****
@ -25,7 +27,7 @@ architecture arch of open_loop is
generic(
TRANSFER_CLK_COUNT : integer := 16;
DELAY_CLK_CNT : integer := 2;
DATA_BITS : integer := 12
DATA_WIDTH : integer := 12
);
port (
sclk : in std_logic; -- PMOD-AD1
@ -34,8 +36,8 @@ architecture arch of open_loop is
sdata2 : in std_logic; -- PMOD-AD1
enable : in std_logic;
cs_n : out std_logic;-- PMOD-AD1
data1 : out std_logic_vector(DATA_BITS-1 downto 0);
data2 : out std_logic_vector(DATA_BITS-1 downto 0);
data1 : out std_logic_vector(DATA_WIDTH-1 downto 0);
data2 : out std_logic_vector(DATA_WIDTH-1 downto 0);
done : out std_logic
);
end component;
@ -43,13 +45,13 @@ architecture arch of open_loop is
component pmod_da3_ctrl is
generic(
TRANSFER_CLK_COUNT : integer := 16;
DATA_BITS : integer := 16
DATA_WIDTH : integer := 16
);
port (
sclk : in std_logic; -- PMOD-DA3
reset : in std_logic;
start : in std_logic;
data : in std_logic_vector(DATA_BITS-1 downto 0);
data : in std_logic_vector(DATA_WIDTH-1 downto 0);
cs_n : out std_logic;-- PMOD-DA3
sdata : out std_logic;-- PMOD-DA3
ldac : out std_logic;-- PMOD-DA3
@ -62,9 +64,9 @@ begin
--*****COMPONENT INSTANTIATION*****
adc : pmod_ad1_ctrl
generic map(
TRANSFER_CLK_COUNT => 16,
DELAY_CLK_CNT => 2,
DATA_BITS => 12
TRANSFER_CLK_COUNT => ADC_TRANSFER_CLK_COUNT,
DELAY_CLK_CNT => ADC_DELAY_CLK_CNT,
DATA_WIDTH => ADC_DATA_WIDTH
)
port map(
sclk => clk,
@ -73,15 +75,15 @@ begin
sdata2 => '0',
enable => '1',
cs_n => adc_cs_n,
data1 => interconnect(15 downto 4),
data1 => interconnect(DAC_DATA_WIDTH-1 downto DAC_DATA_WIDTH-ADC_DATA_WIDTH),
data2 => open,
done => adc_done
);
dac : pmod_da3_ctrl
generic map(
TRANSFER_CLK_COUNT => 16,
DATA_BITS => 16
TRANSFER_CLK_COUNT => DAC_TRANSFER_CLK_COUNT,
DATA_WIDTH => DAC_DATA_WIDTH
)
port map(
sclk => clk,

View File

@ -14,7 +14,7 @@ entity pmod_ad1_ctrl is
generic(
TRANSFER_CLK_COUNT : integer := 16;
DELAY_CLK_CNT : integer := 2;
DATA_BITS : integer := 12
DATA_WIDTH : integer := 12
);
port (
sclk : in std_logic; -- PMOD-AD1
@ -23,8 +23,8 @@ entity pmod_ad1_ctrl is
sdata2 : in std_logic; -- PMOD-AD1
enable : in std_logic;
cs_n : out std_logic;-- PMOD-AD1
data1 : out std_logic_vector(DATA_BITS-1 downto 0);
data2 : out std_logic_vector(DATA_BITS-1 downto 0);
data1 : out std_logic_vector(DATA_WIDTH-1 downto 0);
data2 : out std_logic_vector(DATA_WIDTH-1 downto 0);
done : out std_logic
);
end entity;
@ -35,9 +35,9 @@ architecture arch of pmod_ad1_ctrl is
type STAGE_TYPE is (IDLE, TRANSFER, DELAY);
--*****SIGNAL DECLARATIONS*****
signal buf1, buf2, buf1_next, buf2_next : std_logic_vector(DATA_BITS-1 downto 0) := (others => '0');
signal buf1, buf2, buf1_next, buf2_next : std_logic_vector(DATA_WIDTH-1 downto 0) := (others => '0');
signal stage, stage_next : STAGE_TYPE := IDLE;
signal count, count_next : integer range 0 to 16 := 0;
signal count, count_next : integer range 0 to TRANSFER_CLK_COUNT := 0;
-- Output Signals
signal cs_n_next : std_logic := '1';
signal done_next : std_logic := '0';
@ -65,8 +65,8 @@ begin
-- to shift out the initial zero bits of the tranfer.
when TRANSFER =>
-- Shift Bits into buffer
buf1_next <= buf1(DATA_BITS-2 downto 0) & sdata1;
buf2_next <= buf2(DATA_BITS-2 downto 0) & sdata2;
buf1_next <= buf1(DATA_WIDTH-2 downto 0) & sdata1;
buf2_next <= buf2(DATA_WIDTH-2 downto 0) & sdata2;
cs_n_next <= '0';
if (count = TRANSFER_CLK_COUNT) then
stage_next <= DELAY;

View File

@ -13,13 +13,13 @@ use ieee.numeric_std.all;
entity pmod_da3_ctrl is
generic(
TRANSFER_CLK_COUNT : integer := 16;
DATA_BITS : integer := 16
DATA_WIDTH : integer := 16
);
port (
sclk : in std_logic; -- PMOD-DA3
reset : in std_logic;
start : in std_logic;
data : in std_logic_vector(DATA_BITS-1 downto 0);
data : in std_logic_vector(DATA_WIDTH-1 downto 0);
cs_n : out std_logic;-- PMOD-DA3
sdata : out std_logic;-- PMOD-DA3
ldac : out std_logic;-- PMOD-DA3
@ -33,9 +33,9 @@ architecture arch of pmod_da3_ctrl is
type STAGE_TYPE is (IDLE, TRANSFER);
--*****SIGNAL DECLARATIONS*****
signal buf, buf_next : std_logic_vector(DATA_BITS-1 downto 0) := (others => '0');
signal buf, buf_next : std_logic_vector(DATA_WIDTH-1 downto 0) := (others => '0');
signal stage, stage_next : STAGE_TYPE := IDLE;
signal count, count_next : integer range 0 to 16 := 0;
signal count, count_next : integer range 0 to TRANSFER_CLK_COUNT := 0;
-- Output Signals
signal cs_n_next : std_logic := '1';
signal sdata_next : std_logic := '0';
@ -63,13 +63,13 @@ begin
cs_n_next <= '0';
count_next <= 1;
-- Shift first bit into DAC
buf_next <= data(DATA_BITS-2 downto 0) & '0';
sdata_next <= data(DATA_BITS-1);
buf_next <= data(DATA_WIDTH-2 downto 0) & '0';
sdata_next <= data(DATA_WIDTH-1);
end if;
when TRANSFER =>
-- Shift Bits into DAC
buf_next <= buf(DATA_BITS-2 downto 0) & '0';
sdata_next <= buf(DATA_BITS-1);
buf_next <= buf(DATA_WIDTH-2 downto 0) & '0';
sdata_next <= buf(DATA_WIDTH-1);
cs_n_next <= '0';
if (count = TRANSFER_CLK_COUNT) then
cs_n_next <= '1';

View File

@ -8,16 +8,15 @@ use xpm.vcomponents.all;
entity single_port_ram is
generic (
ADDR_WIDTH : integer := 8;
DATA_WIDTH : integer := 12;
MEMORY_DEPTH : integer := 200
DATA_WIDTH : integer := 12
);
port (
clk : in std_logic;
addr : in std_logic_vector(ADDR_WIDTH-1 downto 0);
wen : in std_logic;
ren : in std_logic;
write_data : in std_logic_vector(DATA_WIDTH-1 downto 0);
read_data : out std_logic_vector(DATA_WIDTH-1 downto 0)
wr_data : in std_logic_vector(DATA_WIDTH-1 downto 0);
rd_data : out std_logic_vector(DATA_WIDTH-1 downto 0)
);
end entity;
@ -35,7 +34,7 @@ begin
MEMORY_INIT_PARAM => "0",
MEMORY_OPTIMIZATION => "true",
MEMORY_PRIMITIVE => "auto",
MEMORY_SIZE => DATA_WIDTH*MEMORY_DEPTH,
MEMORY_SIZE => DATA_WIDTH*(2**ADDR_WIDTH),
MESSAGE_CONTROL => 0,
READ_DATA_WIDTH_A => DATA_WIDTH,
READ_LATENCY_A => 1,
@ -48,11 +47,11 @@ begin
)
port map (
dbiterra => open,
douta => read_data,
douta => rd_data,
sbiterra => open,
addra => addr,
clka => clk,
dina => write_data,
dina => wr_data,
ena => (ren or wen),
injectdbiterra => '0',
injectsbiterra => '0',

View File

@ -39,7 +39,7 @@ architecture arch of top is
);
end component;
--*****DIGNAL DECLARATION*****
--*****SIGNAL DECLARATION*****
signal clk_20 : std_logic := '0';
begin

65
src/typedef_package.vhd Normal file
View File

@ -0,0 +1,65 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package typedef_package is
--*****CONSTANT DECLARATIONS*****
-- FIXED
constant ADC_DATA_WIDTH : integer := 12;--*
constant DAC_DATA_WIDTH : integer := 16;--*
--* If these values are changed, the signal mappings in 'xillybus_link' have to be updated.
constant ADC_TRANSFER_CLK_COUNT : integer := 16;
constant ADC_DELAY_CLK_CNT : integer := 2;
constant DAC_TRANSFER_CLK_COUNT : integer := 16;
constant MAX_DELAY : integer := 200;
constant DELAY_WIDTH : integer := 8; --at least log2(MAX_DELAY)
constant FACTOR_WIDTH : integer := 4;
constant TIMESTAMP_WIDTH : integer := 32;
--XILLYBUS
constant DEBUG_FIFO_DATA_WIDTH : integer := 32;
constant DEBUG_FIFO_DEPTH : integer := 16;
constant CONFIG_MEM_DATA_WIDTH : integer := 32;
constant CONFIG_DATA_WIDTH : integer := CONFIG_MEM_DATA_WIDTH*2;
constant CONFIG_MEM_ADDR_WIDTH : integer := 15;
--***CLOCKGEN SETTINGS***
--100 MHz IN, 20 MHz OUT
constant CLKFBOUT_MULT : integer := 41;
constant CLKIN1_PERIOD : real := 10.000000;
constant CLKOUT0_DIVIDE : integer := 41;
constant DIVCLK_DIVIDE : integer := 5;
--TODO: 3-stage sync to delay write-mode 1 clk cycle
--*****FUNCTION DECLARATIONS*****
function log2c(constant value : in integer) return integer;
end package;
package body typedef_package is
--*****FUNCTION DEFINITIONS*****
function log2c(constant value : in integer) return integer is
variable ret_value : integer;
variable cur_value : integer;
begin
ret_value := 0;
cur_value := 1;
while cur_value < value loop
ret_value := ret_value + 1;
cur_value := cur_value * 2;
end loop;
return ret_value;
end function log2c;
end package body;

214
src/xillybus_link.vhd Normal file
View File

@ -0,0 +1,214 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.typedef_package.all;
-- Xillybus Link
-- This entity is the link between the xillybus IP core, and the rest of the FPGA logic.
-- This entity contains asynchronous FIFOs and RAMs handling the clock domain crossing between
-- the xillybus and the FPGA logic.
-- The current xillybus IP core is configured for a 32-bit FPGA-to-HOST FIFO used for sending debug
-- stats to the host every "DEBUG_SEND_INTERVAL" clock cycles, and 32-bit HOST-to-FPGA 16-bit address
-- memory for configuration. The 32-bit wide 16-bit address interface is converted into 2 32-bit wide
-- 15-bit address RAMs, effectively increasing the internal config to 64-bits.
-- NOTE: It has to be made sure that the read and write port to not access the smae address at the same
-- time
entity xillybus_link is
generic (
DEBUG_SEND_INTERVAL : integer := 20000000
);
port (
--***XILLYBUS IF***
xillybus_clk : in std_logic;
-- FIFO
fifo_rd_data : out std_logic_vector(DEBUG_FIFO_DATA_WIDTH-1 downto 0);
fifo_ren : in std_logic;
fifo_empty : out std_logic;
-- RAM
mem_addr : in std_logic_vector(CONFIG_MEM_ADDR_WIDTH downto 0);
mem_wr_data : in std_logic_vector(CONFIG_MEM_DATA_WIDTH-1 downto 0);
mem_wen : in std_logic;
--***FPGA IF***
fpga_clk : in std_logic;
reset : in std_logic;
-- Dynamic Configuration
config_addr : in std_logic_vector(CONFIG_MEM_ADDR_WIDTH-1 downto 0);
config_ren : in std_logic;
config_data : out std_logic_vector(CONFIG_DATA_WIDTH-1 downto 0);
-- DEBUG
adc_data1_max : in std_logic_vector(ADC_DATA_WIDTH-1 downto 0);
adc_data2_max : in std_logic_vector(ADC_DATA_WIDTH-1 downto 0);
scaler_max : in std_logic_vector(DAC_DATA_WIDTH-1 downto 0);
dac_max : in std_logic_vector(DAC_DATA_WIDTH-1 downto 0)
);
end entity;
architecture arch of xillybus_link is
--*****COMPONENT DECLARATION*****
component dual_port_ram is
generic (
ADDR_WIDTH : integer := 8;
DATA_WIDTH : integer := 16;
MEMORY_DEPTH : integer := 20
);
port (
wr_clk : in std_logic;
rd_clk : in std_logic;
rd_addr : in std_logic_vector(ADDR_WIDTH-1 downto 0);
wr_addr : in std_logic_vector(ADDR_WIDTH-1 downto 0);
wen : in std_logic;
ren : in std_logic;
wr_data : in std_logic_vector(DATA_WIDTH-1 downto 0);
rd_data : out std_logic_vector(DATA_WIDTH-1 downto 0)
);
end component;
component async_fifo is
generic (
DATA_WIDTH : integer := 32;
FIFO_DEPTH : integer := 16; -- (16 - 4194304)
PROG_EMPTY : integer := 3; -- MIN:3 MAX:(FIFO_DEPTH-3)
PROG_FULL : integer := 13 -- MIN:3+CDC_SYNC_STAGES MAX:(FIFO_DEPTH-3)
);
port (
wr_clk : in std_logic;
rd_clk : in std_logic;
reset : in std_logic; --wr_clk synchronous
wen : in std_logic;
ren : in std_logic;
empty : out std_logic;
almost_empty: out std_logic;
prog_empty : out std_logic;
full : out std_logic;
almost_full : out std_logic;
prog_full : out std_logic;
wr_data : in std_logic_vector(DATA_WIDTH-1 downto 0);
rd_data : out std_logic_vector(DATA_WIDTH-1 downto 0)
);
end component;
--*****TYPE DEFINITION*****
type STAGE_TYPE is (WAIT_COUNTER, WAIT_FIFO, SEND1, SEND2);
--*****SIGNAL DEFINITION*****
signal cnt, cnt_next : integer range 0 to DEBUG_SEND_INTERVAL := 0;
signal stage : STAGE_TYPE := WAIT_COUNTER;
signal fifo_almost_full, fifo_wen : std_logic := '0';
signal fifo_wr_data : std_logic_vector(DEBUG_FIFO_DATA_WIDTH-1 downto 0) := (others => '0');
begin
--*****COMPONENT INSTANTIATION*****
config_mem_high : dual_port_ram
generic map (
ADDR_WIDTH => CONFIG_MEM_ADDR_WIDTH,
DATA_WIDTH => CONFIG_MEM_DATA_WIDTH
)
port map (
wr_clk => xillybus_clk,
rd_clk => fpga_clk,
rd_addr => config_addr,
wr_addr => mem_addr(CONFIG_MEM_ADDR_WIDTH downto 1),
wen => mem_wen and (not mem_addr(0)), -- Only even adresses
ren => config_ren,
wr_data => mem_wr_data,
rd_data => config_data(CONFIG_DATA_WIDTH-1 downto CONFIG_MEM_DATA_WIDTH)
);
config_mem_low : dual_port_ram
generic map (
ADDR_WIDTH => CONFIG_MEM_ADDR_WIDTH,
DATA_WIDTH => CONFIG_MEM_DATA_WIDTH
)
port map (
wr_clk => xillybus_clk,
rd_clk => fpga_clk,
rd_addr => config_addr,
wr_addr => mem_addr(CONFIG_MEM_ADDR_WIDTH downto 1),
wen => mem_wen and (mem_addr(0)), -- Only odd adresses
ren => config_ren,
wr_data => mem_wr_data,
rd_data => config_data(CONFIG_MEM_DATA_WIDTH-1 downto 0)
);
debug_fifo : async_fifo
generic map (
DATA_WIDTH => DEBUG_FIFO_DATA_WIDTH,
FIFO_DEPTH => DEBUG_FIFO_DEPTH
)
port map(
wr_clk => fpga_clk,
rd_clk => xillybus_clk,
reset => reset,
wen => fifo_wen,
ren => fifo_ren,
empty => fifo_empty,
almost_empty=> open,
prog_empty => open,
full => open,
almost_full => fifo_almost_full,
prog_full => open,
wr_data => fifo_wr_data,
rd_data => fifo_rd_data
);
debug_prc : process(all)
begin
-- DEFAULT VALUES
stage_next <= stage;
cnt_next <= cnt;
fifo_wen <= '0';
fifo_wr_data<= (others => '0');
case (stage)
when WAIT_COUNTER =>
if(cnt = DEBUG_SEND_INTERVAL) then
if(fifo_almost_full = '1') then
stage_next => WAIT_FIFO;
else
stage_next => SEND1;
end if;
else
cnt_next => cnt + 1;
end if;
when WAIT_FIFO =>
if(fifo_almost_full = '0') then
stage_next => SEND1;
end if;
when SEND1 =>
fifo_wen <= '1';
fifo_wr_data(11 downto 0) <= adc_data1_max;
fifo_wr_data(27 downto 16) <= adc_data2_max;
stage_next <= SEND2;
when SEND2 =>
fifo_wen <= '1';
fifo_wr_data(15 downto 0) <= dac_max;
fifo_wr_data(31 downto 16) <= scaler_max;
stage_next <= WAIT_COUNTER;
cnt_next <= 0;
end case;
end process;
sync : process(fpga_clk)
begin
if rising_edge(fpga_clk) then
if(reset = '1') then
stage <= WAIT_COUNTER;
cnt <= 0;
else
stage <= stage_next;
cnt <= cnt_next;
end if;
end if;
end process;
end architecture;