* 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:
parent
aa53591056
commit
779cd73e8d
213
src/UNUSED/memory_mapped_registers.vhd
Normal file
213
src/UNUSED/memory_mapped_registers.vhd
Normal 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;
|
||||||
@ -10,7 +10,7 @@ use UNIMACRO.vcomponents.all;
|
|||||||
|
|
||||||
-- Add/Sub
|
-- Add/Sub
|
||||||
-- This entity adds or subtracts inputs 'A' and 'B', depending on 'mode' (1 = add, 0 = 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
|
entity addsub is
|
||||||
generic (
|
generic (
|
||||||
@ -18,12 +18,13 @@ entity addsub is
|
|||||||
DATA_WIDTH : integer := 16
|
DATA_WIDTH : integer := 16
|
||||||
);
|
);
|
||||||
port (
|
port (
|
||||||
clk : std_logic;
|
clk : in std_logic;
|
||||||
reset : std_logic;
|
reset : in std_logic;
|
||||||
mode : std_logic;
|
mode : in std_logic;
|
||||||
A : std_logic_vector(DATA_WIDTH-1 downto 0);
|
cap : in std_logic;
|
||||||
B : std_logic_vector(DATA_WIDTH-1 downto 0);
|
A : in std_logic_vector(DATA_WIDTH-1 downto 0);
|
||||||
RES : 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;
|
end entity;
|
||||||
|
|
||||||
@ -59,7 +60,7 @@ begin
|
|||||||
RES <= result;
|
RES <= result;
|
||||||
|
|
||||||
--Overflow/Underflow
|
--Overflow/Underflow
|
||||||
if(carry = '1') then
|
if(carry = '1' and cap = '1') then
|
||||||
--ADD
|
--ADD
|
||||||
if(mode = '1') then
|
if(mode = '1') then
|
||||||
--CAP AT MAX VALUE
|
--CAP AT MAX VALUE
|
||||||
|
|||||||
90
src/async_fifo.vhd
Normal file
90
src/async_fifo.vhd
Normal 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;
|
||||||
@ -6,6 +6,12 @@ library UNISIM;
|
|||||||
use UNISIM.VCOMPONENTS.ALL;
|
use UNISIM.VCOMPONENTS.ALL;
|
||||||
|
|
||||||
entity clockgen is
|
entity clockgen is
|
||||||
|
generic (
|
||||||
|
CLKFBOUT_MULT : integer := 41;
|
||||||
|
CLKIN1_PERIOD : real := 10.000000;
|
||||||
|
CLKOUT0_DIVIDE : integer := 41;
|
||||||
|
DIVCLK_DIVIDE : integer := 5
|
||||||
|
);
|
||||||
port (
|
port (
|
||||||
clk_in : in std_logic;
|
clk_in : in std_logic;
|
||||||
clk_out : out std_logic
|
clk_out : out std_logic
|
||||||
@ -29,11 +35,11 @@ begin
|
|||||||
plle2_adv_inst: unisim.vcomponents.PLLE2_ADV
|
plle2_adv_inst: unisim.vcomponents.PLLE2_ADV
|
||||||
generic map(
|
generic map(
|
||||||
BANDWIDTH => "OPTIMIZED",
|
BANDWIDTH => "OPTIMIZED",
|
||||||
CLKFBOUT_MULT => 41,
|
CLKFBOUT_MULT => CLKFBOUT_MULT,
|
||||||
CLKFBOUT_PHASE => 0.000000,
|
CLKFBOUT_PHASE => 0.000000,
|
||||||
CLKIN1_PERIOD => 10.000000,
|
CLKIN1_PERIOD => CLKIN1_PERIOD,
|
||||||
CLKIN2_PERIOD => 0.000000,
|
CLKIN2_PERIOD => 0.000000,
|
||||||
CLKOUT0_DIVIDE => 41,
|
CLKOUT0_DIVIDE => CLKOUT0_DIVIDE,
|
||||||
CLKOUT0_DUTY_CYCLE => 0.500000,
|
CLKOUT0_DUTY_CYCLE => 0.500000,
|
||||||
CLKOUT0_PHASE => 0.000000,
|
CLKOUT0_PHASE => 0.000000,
|
||||||
CLKOUT1_DIVIDE => 1,
|
CLKOUT1_DIVIDE => 1,
|
||||||
@ -52,7 +58,7 @@ begin
|
|||||||
CLKOUT5_DUTY_CYCLE => 0.500000,
|
CLKOUT5_DUTY_CYCLE => 0.500000,
|
||||||
CLKOUT5_PHASE => 0.000000,
|
CLKOUT5_PHASE => 0.000000,
|
||||||
COMPENSATION => "ZHOLD",
|
COMPENSATION => "ZHOLD",
|
||||||
DIVCLK_DIVIDE => 5,
|
DIVCLK_DIVIDE => DIVCLK_DIVIDE,
|
||||||
IS_CLKINSEL_INVERTED => '0',
|
IS_CLKINSEL_INVERTED => '0',
|
||||||
IS_PWRDWN_INVERTED => '0',
|
IS_PWRDWN_INVERTED => '0',
|
||||||
IS_RST_INVERTED => '0',
|
IS_RST_INVERTED => '0',
|
||||||
|
|||||||
@ -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).
|
-- 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
|
-- 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
|
-- 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
|
-- increased (which is unavoidable), and when it is decreased while the momentarily counter value is
|
||||||
-- delay [single cycle glitch].
|
-- the same as the new delay value [single cycle glitch].
|
||||||
|
|
||||||
entity delay_line is
|
entity delay_line is
|
||||||
generic (
|
generic (
|
||||||
DATA_WIDTH : integer := 12;
|
DATA_WIDTH : integer := 12;
|
||||||
DELAY_WIDTH : integer := 8;
|
MAX_DELAY : integer := 200;
|
||||||
MAX_DELAY : integer := 200
|
DELAY_WIDTH : integer := 8
|
||||||
);
|
);
|
||||||
port (
|
port (
|
||||||
clk : in std_logic;
|
clk : in std_logic;
|
||||||
@ -31,16 +31,15 @@ architecture arch of delay_line is
|
|||||||
component single_port_ram is
|
component single_port_ram is
|
||||||
generic (
|
generic (
|
||||||
ADDR_WIDTH : integer := 8;
|
ADDR_WIDTH : integer := 8;
|
||||||
DATA_WIDTH : integer := 12;
|
DATA_WIDTH : integer := 12
|
||||||
MEMORY_DEPTH : integer := 200
|
|
||||||
);
|
);
|
||||||
port (
|
port (
|
||||||
clk : in std_logic;
|
clk : in std_logic;
|
||||||
addr : in std_logic_vector(ADDR_WIDTH-1 downto 0);
|
addr : in std_logic_vector(ADDR_WIDTH-1 downto 0);
|
||||||
wen : in std_logic;
|
wen : in std_logic;
|
||||||
ren : in std_logic;
|
ren : in std_logic;
|
||||||
write_data : in std_logic_vector(DATA_WIDTH-1 downto 0);
|
wr_data : in std_logic_vector(DATA_WIDTH-1 downto 0);
|
||||||
read_data : out std_logic_vector(DATA_WIDTH-1 downto 0)
|
rd_data : out std_logic_vector(DATA_WIDTH-1 downto 0)
|
||||||
);
|
);
|
||||||
end component;
|
end component;
|
||||||
|
|
||||||
@ -54,30 +53,29 @@ begin
|
|||||||
ram_inst : single_port_ram
|
ram_inst : single_port_ram
|
||||||
generic map(
|
generic map(
|
||||||
ADDR_WIDTH => DELAY_WIDTH,
|
ADDR_WIDTH => DELAY_WIDTH,
|
||||||
DATA_WIDTH => DATA_WIDTH,
|
DATA_WIDTH => DATA_WIDTH
|
||||||
MEMORY_DEPTH => MAX_DELAY
|
|
||||||
);
|
);
|
||||||
port map(
|
port map(
|
||||||
clk => clk,
|
clk => clk,
|
||||||
addr => cnt,
|
addr => std_logic_vector(to_unsigned(cnt,DELAY_WIDTH)),
|
||||||
wen => '1',
|
wen => '1',
|
||||||
ren => '1',
|
ren => '1',
|
||||||
write_data => data_in,
|
wr_data => data_in,
|
||||||
read_data => memory_out
|
rd_data => memory_out
|
||||||
);
|
);
|
||||||
|
|
||||||
cntrl : process(all)
|
ctrl : process(all)
|
||||||
begin
|
begin
|
||||||
-- DEFAULT VALUES
|
-- DEFAULT VALUES
|
||||||
cnt_next <= cnt;
|
cnt_next <= cnt;
|
||||||
cnt_max_next <= cnt_max;
|
cnt_max_next <= cnt_max;
|
||||||
|
|
||||||
if(to_integer(unsigned(addr)) = 0) then
|
if(to_integer(unsigned(delay)) = 0) then
|
||||||
data_out <= data_in;
|
data_out <= data_in;
|
||||||
else
|
else
|
||||||
data_out <= memory_out;
|
data_out <= memory_out;
|
||||||
-- COUNT GENERATION
|
-- COUNT GENERATION
|
||||||
cnt_max_next <= to_integer(unsigned(addr)) - 1;
|
cnt_max_next <= to_integer(unsigned(delay)) - 1;
|
||||||
if (cnt >= cnt_max) then
|
if (cnt >= cnt_max) then
|
||||||
cnt_next <= 0;
|
cnt_next <= 0;
|
||||||
else
|
else
|
||||||
|
|||||||
75
src/dual_port_ram.vhd
Normal file
75
src/dual_port_ram.vhd
Normal 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
124
src/feedback_controller.vhd
Normal 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;
|
||||||
@ -2,14 +2,23 @@ library ieee;
|
|||||||
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
||||||
use ieee.numeric_std.all;
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
use work.typedef_package.all;
|
||||||
|
|
||||||
-- Architecture
|
-- Architecture
|
||||||
--- ---------- ------ ------- ---
|
-- --- ---------- ------ ------- ---
|
||||||
--->|ADC|--->|Delay Line|--->|Scaler|--->|ADD/SUB|--->|DAC|--->
|
--->|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
|
entity feedback_loop is
|
||||||
port (
|
port (
|
||||||
@ -17,20 +26,27 @@ entity feedback_loop is
|
|||||||
reset : in std_logic;
|
reset : in std_logic;
|
||||||
adc_data_in1 : in std_logic;
|
adc_data_in1 : in std_logic;
|
||||||
adc_data_in2 : 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;
|
adc_cs_n : out std_logic;
|
||||||
dac_data_out : out std_logic;
|
dac_data_out : out std_logic;
|
||||||
dac_cs_n : 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;
|
end entity;
|
||||||
|
|
||||||
architecture arch of feedback_loop is
|
architecture arch of feedback_loop is
|
||||||
|
|
||||||
--*****SIGNAL DECLARATION*****
|
--*****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';
|
signal adc_done : std_logic := '0';
|
||||||
|
|
||||||
--*****COMPONENT DECLARATION*****
|
--*****COMPONENT DECLARATION*****
|
||||||
@ -38,7 +54,7 @@ architecture arch of feedback_loop is
|
|||||||
generic(
|
generic(
|
||||||
TRANSFER_CLK_COUNT : integer := 16;
|
TRANSFER_CLK_COUNT : integer := 16;
|
||||||
DELAY_CLK_CNT : integer := 2;
|
DELAY_CLK_CNT : integer := 2;
|
||||||
DATA_BITS : integer := 12
|
DATA_WIDTH : integer := 12
|
||||||
);
|
);
|
||||||
port (
|
port (
|
||||||
sclk : in std_logic; -- PMOD-AD1
|
sclk : in std_logic; -- PMOD-AD1
|
||||||
@ -47,8 +63,8 @@ architecture arch of feedback_loop is
|
|||||||
sdata2 : in std_logic; -- PMOD-AD1
|
sdata2 : in std_logic; -- PMOD-AD1
|
||||||
enable : in std_logic;
|
enable : in std_logic;
|
||||||
cs_n : out std_logic;-- PMOD-AD1
|
cs_n : out std_logic;-- PMOD-AD1
|
||||||
data1 : 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_BITS-1 downto 0);
|
data2 : out std_logic_vector(DATA_WIDTH-1 downto 0);
|
||||||
done : out std_logic
|
done : out std_logic
|
||||||
);
|
);
|
||||||
end component;
|
end component;
|
||||||
@ -56,13 +72,13 @@ architecture arch of feedback_loop is
|
|||||||
component pmod_da3_ctrl is
|
component pmod_da3_ctrl is
|
||||||
generic(
|
generic(
|
||||||
TRANSFER_CLK_COUNT : integer := 16;
|
TRANSFER_CLK_COUNT : integer := 16;
|
||||||
DATA_BITS : integer := 16
|
DATA_WIDTH : integer := 16
|
||||||
);
|
);
|
||||||
port (
|
port (
|
||||||
sclk : in std_logic; -- PMOD-DA3
|
sclk : in std_logic; -- PMOD-DA3
|
||||||
reset : in std_logic;
|
reset : in std_logic;
|
||||||
start : 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
|
cs_n : out std_logic;-- PMOD-DA3
|
||||||
sdata : out std_logic;-- PMOD-DA3
|
sdata : out std_logic;-- PMOD-DA3
|
||||||
ldac : 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
|
DATA_WIDTH : integer := 16
|
||||||
);
|
);
|
||||||
port (
|
port (
|
||||||
clk : std_logic;
|
clk : in std_logic;
|
||||||
reset : std_logic;
|
reset : in std_logic;
|
||||||
mode : std_logic;
|
mode : in std_logic;
|
||||||
A : std_logic_vector(DATA_WIDTH-1 downto 0);
|
cap : in std_logic;
|
||||||
B : std_logic_vector(DATA_WIDTH-1 downto 0);
|
A : in std_logic_vector(DATA_WIDTH-1 downto 0);
|
||||||
RES : 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;
|
end component;
|
||||||
|
|
||||||
@ -114,18 +131,19 @@ architecture arch of feedback_loop is
|
|||||||
end component;
|
end component;
|
||||||
|
|
||||||
--*****SIGNAL DECLARATION*****
|
--*****SIGNAL DECLARATION*****
|
||||||
signal delay_out, latch_out : std_logic_vector(12 downto 0) := (others => '0');
|
signal delay_out, latch_out : std_logic_vector(ADC_DATA_WIDTH downto 0) := (others => '0');
|
||||||
signal scaler_out, addsub_out : std_logic_vector(15 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 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
|
begin
|
||||||
|
|
||||||
--*****STAGE I*****
|
--*****STAGE I*****
|
||||||
adc_inst : pmod_ad1_ctrl
|
adc_inst : pmod_ad1_ctrl
|
||||||
generic map(
|
generic map(
|
||||||
TRANSFER_CLK_COUNT => 16,
|
TRANSFER_CLK_COUNT => ADC_TRANSFER_CLK_COUNT,
|
||||||
DELAY_CLK_CNT => 2,
|
DELAY_CLK_CNT => ADC_DELAY_CLK_CNT,
|
||||||
DATA_BITS => 12
|
DATA_WIDTH => ADC_DATA_WIDTH
|
||||||
)
|
)
|
||||||
port map(
|
port map(
|
||||||
sclk => clk,
|
sclk => clk,
|
||||||
@ -142,9 +160,9 @@ begin
|
|||||||
--*****STAGE II*****
|
--*****STAGE II*****
|
||||||
delay_line_inst : delay_line
|
delay_line_inst : delay_line
|
||||||
generic map(
|
generic map(
|
||||||
DATA_WIDTH => 13,
|
DATA_WIDTH => ADC_DATA_WIDTH+1,
|
||||||
DELAY_WIDTH => 8,
|
DELAY_WIDTH => DELAY_WIDTH,
|
||||||
MAX_DELAY => 200
|
MAX_DELAY => MAX_DELAY
|
||||||
)
|
)
|
||||||
port map(
|
port map(
|
||||||
clk => clk,
|
clk => clk,
|
||||||
@ -156,13 +174,13 @@ begin
|
|||||||
--*****STAGE III*****
|
--*****STAGE III*****
|
||||||
scaler_inst : scaler
|
scaler_inst : scaler
|
||||||
generic map(
|
generic map(
|
||||||
DATA_WIDTH => 12,
|
DATA_WIDTH => ADC_DATA_WIDTH,
|
||||||
FACTOR_WIDTH => 4,
|
FACTOR_WIDTH => FACTOR_WIDTH,
|
||||||
PIPELINE_STAGES => 1
|
PIPELINE_STAGES => 1
|
||||||
)
|
)
|
||||||
port map(
|
port map(
|
||||||
clk => clk,
|
clk => clk,
|
||||||
data_in => delay_out(11 downto 0),
|
data_in => delay_out(ADC_DATA_WIDTH-1 downto 0),
|
||||||
factor => factor,
|
factor => factor,
|
||||||
data_out => scaler_out
|
data_out => scaler_out
|
||||||
);
|
);
|
||||||
@ -171,9 +189,9 @@ begin
|
|||||||
begin
|
begin
|
||||||
if (rising_edge(clk)) then
|
if (rising_edge(clk)) then
|
||||||
if (reset = '1') then
|
if (reset = '1') then
|
||||||
scaler_done <= (others => '0');
|
scaler_done <= '0';
|
||||||
else
|
else
|
||||||
scaler_done <= delay_out(12);
|
scaler_done <= delay_out(ADC_DATA_WIDTH);
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
@ -190,17 +208,28 @@ begin
|
|||||||
end process;
|
end process;
|
||||||
|
|
||||||
--*****STAGE IV*****
|
--*****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
|
addsub_inst : addsub
|
||||||
generic map(
|
generic map(
|
||||||
PIPELINE_STAGES => 1,
|
PIPELINE_STAGES => 1,
|
||||||
DATA_WIDTH => 16
|
DATA_WIDTH => DAC_DATA_WIDTH
|
||||||
)
|
)
|
||||||
port map(
|
port map(
|
||||||
clk => clk,
|
clk => clk,
|
||||||
reset => reset,
|
reset => reset,
|
||||||
mode => addsub_mode,
|
mode => addsub_mode,
|
||||||
A => scaler_out,
|
cap => input_mux,
|
||||||
B => latch_out & "0000",
|
A => inputA,
|
||||||
|
B => scaler_out,
|
||||||
RES => addsub_out
|
RES => addsub_out
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -218,8 +247,8 @@ begin
|
|||||||
--*****STAGE V*****
|
--*****STAGE V*****
|
||||||
dac_inst : pmod_da3_ctrl
|
dac_inst : pmod_da3_ctrl
|
||||||
generic map(
|
generic map(
|
||||||
TRANSFER_CLK_COUNT => 16,
|
TRANSFER_CLK_COUNT => DAC_TRANSFER_CLK_COUNT,
|
||||||
DATA_BITS => 16
|
DATA_WIDTH => DAC_DATA_WIDTH
|
||||||
)
|
)
|
||||||
port map(
|
port map(
|
||||||
sclk => clk,
|
sclk => clk,
|
||||||
@ -232,4 +261,36 @@ begin
|
|||||||
done => open
|
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;
|
end architecture;
|
||||||
@ -2,6 +2,8 @@ library ieee;
|
|||||||
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
||||||
use ieee.numeric_std.all;
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
use work.typedef_package.all;
|
||||||
|
|
||||||
entity open_loop is
|
entity open_loop is
|
||||||
port (
|
port (
|
||||||
clk : in std_logic;
|
clk : in std_logic;
|
||||||
@ -17,7 +19,7 @@ end entity;
|
|||||||
architecture arch of open_loop is
|
architecture arch of open_loop is
|
||||||
|
|
||||||
--*****SIGNAL DECLARATION*****
|
--*****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';
|
signal adc_done : std_logic := '0';
|
||||||
|
|
||||||
--*****COMPONENT DECLARATION*****
|
--*****COMPONENT DECLARATION*****
|
||||||
@ -25,7 +27,7 @@ architecture arch of open_loop is
|
|||||||
generic(
|
generic(
|
||||||
TRANSFER_CLK_COUNT : integer := 16;
|
TRANSFER_CLK_COUNT : integer := 16;
|
||||||
DELAY_CLK_CNT : integer := 2;
|
DELAY_CLK_CNT : integer := 2;
|
||||||
DATA_BITS : integer := 12
|
DATA_WIDTH : integer := 12
|
||||||
);
|
);
|
||||||
port (
|
port (
|
||||||
sclk : in std_logic; -- PMOD-AD1
|
sclk : in std_logic; -- PMOD-AD1
|
||||||
@ -34,8 +36,8 @@ architecture arch of open_loop is
|
|||||||
sdata2 : in std_logic; -- PMOD-AD1
|
sdata2 : in std_logic; -- PMOD-AD1
|
||||||
enable : in std_logic;
|
enable : in std_logic;
|
||||||
cs_n : out std_logic;-- PMOD-AD1
|
cs_n : out std_logic;-- PMOD-AD1
|
||||||
data1 : 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_BITS-1 downto 0);
|
data2 : out std_logic_vector(DATA_WIDTH-1 downto 0);
|
||||||
done : out std_logic
|
done : out std_logic
|
||||||
);
|
);
|
||||||
end component;
|
end component;
|
||||||
@ -43,13 +45,13 @@ architecture arch of open_loop is
|
|||||||
component pmod_da3_ctrl is
|
component pmod_da3_ctrl is
|
||||||
generic(
|
generic(
|
||||||
TRANSFER_CLK_COUNT : integer := 16;
|
TRANSFER_CLK_COUNT : integer := 16;
|
||||||
DATA_BITS : integer := 16
|
DATA_WIDTH : integer := 16
|
||||||
);
|
);
|
||||||
port (
|
port (
|
||||||
sclk : in std_logic; -- PMOD-DA3
|
sclk : in std_logic; -- PMOD-DA3
|
||||||
reset : in std_logic;
|
reset : in std_logic;
|
||||||
start : 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
|
cs_n : out std_logic;-- PMOD-DA3
|
||||||
sdata : out std_logic;-- PMOD-DA3
|
sdata : out std_logic;-- PMOD-DA3
|
||||||
ldac : out std_logic;-- PMOD-DA3
|
ldac : out std_logic;-- PMOD-DA3
|
||||||
@ -62,9 +64,9 @@ begin
|
|||||||
--*****COMPONENT INSTANTIATION*****
|
--*****COMPONENT INSTANTIATION*****
|
||||||
adc : pmod_ad1_ctrl
|
adc : pmod_ad1_ctrl
|
||||||
generic map(
|
generic map(
|
||||||
TRANSFER_CLK_COUNT => 16,
|
TRANSFER_CLK_COUNT => ADC_TRANSFER_CLK_COUNT,
|
||||||
DELAY_CLK_CNT => 2,
|
DELAY_CLK_CNT => ADC_DELAY_CLK_CNT,
|
||||||
DATA_BITS => 12
|
DATA_WIDTH => ADC_DATA_WIDTH
|
||||||
)
|
)
|
||||||
port map(
|
port map(
|
||||||
sclk => clk,
|
sclk => clk,
|
||||||
@ -73,15 +75,15 @@ begin
|
|||||||
sdata2 => '0',
|
sdata2 => '0',
|
||||||
enable => '1',
|
enable => '1',
|
||||||
cs_n => adc_cs_n,
|
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,
|
data2 => open,
|
||||||
done => adc_done
|
done => adc_done
|
||||||
);
|
);
|
||||||
|
|
||||||
dac : pmod_da3_ctrl
|
dac : pmod_da3_ctrl
|
||||||
generic map(
|
generic map(
|
||||||
TRANSFER_CLK_COUNT => 16,
|
TRANSFER_CLK_COUNT => DAC_TRANSFER_CLK_COUNT,
|
||||||
DATA_BITS => 16
|
DATA_WIDTH => DAC_DATA_WIDTH
|
||||||
)
|
)
|
||||||
port map(
|
port map(
|
||||||
sclk => clk,
|
sclk => clk,
|
||||||
|
|||||||
@ -14,7 +14,7 @@ entity pmod_ad1_ctrl is
|
|||||||
generic(
|
generic(
|
||||||
TRANSFER_CLK_COUNT : integer := 16;
|
TRANSFER_CLK_COUNT : integer := 16;
|
||||||
DELAY_CLK_CNT : integer := 2;
|
DELAY_CLK_CNT : integer := 2;
|
||||||
DATA_BITS : integer := 12
|
DATA_WIDTH : integer := 12
|
||||||
);
|
);
|
||||||
port (
|
port (
|
||||||
sclk : in std_logic; -- PMOD-AD1
|
sclk : in std_logic; -- PMOD-AD1
|
||||||
@ -23,8 +23,8 @@ entity pmod_ad1_ctrl is
|
|||||||
sdata2 : in std_logic; -- PMOD-AD1
|
sdata2 : in std_logic; -- PMOD-AD1
|
||||||
enable : in std_logic;
|
enable : in std_logic;
|
||||||
cs_n : out std_logic;-- PMOD-AD1
|
cs_n : out std_logic;-- PMOD-AD1
|
||||||
data1 : 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_BITS-1 downto 0);
|
data2 : out std_logic_vector(DATA_WIDTH-1 downto 0);
|
||||||
done : out std_logic
|
done : out std_logic
|
||||||
);
|
);
|
||||||
end entity;
|
end entity;
|
||||||
@ -35,9 +35,9 @@ architecture arch of pmod_ad1_ctrl is
|
|||||||
type STAGE_TYPE is (IDLE, TRANSFER, DELAY);
|
type STAGE_TYPE is (IDLE, TRANSFER, DELAY);
|
||||||
|
|
||||||
--*****SIGNAL DECLARATIONS*****
|
--*****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 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
|
-- Output Signals
|
||||||
signal cs_n_next : std_logic := '1';
|
signal cs_n_next : std_logic := '1';
|
||||||
signal done_next : std_logic := '0';
|
signal done_next : std_logic := '0';
|
||||||
@ -65,8 +65,8 @@ begin
|
|||||||
-- to shift out the initial zero bits of the tranfer.
|
-- to shift out the initial zero bits of the tranfer.
|
||||||
when TRANSFER =>
|
when TRANSFER =>
|
||||||
-- Shift Bits into buffer
|
-- Shift Bits into buffer
|
||||||
buf1_next <= buf1(DATA_BITS-2 downto 0) & sdata1;
|
buf1_next <= buf1(DATA_WIDTH-2 downto 0) & sdata1;
|
||||||
buf2_next <= buf2(DATA_BITS-2 downto 0) & sdata2;
|
buf2_next <= buf2(DATA_WIDTH-2 downto 0) & sdata2;
|
||||||
cs_n_next <= '0';
|
cs_n_next <= '0';
|
||||||
if (count = TRANSFER_CLK_COUNT) then
|
if (count = TRANSFER_CLK_COUNT) then
|
||||||
stage_next <= DELAY;
|
stage_next <= DELAY;
|
||||||
|
|||||||
@ -13,13 +13,13 @@ use ieee.numeric_std.all;
|
|||||||
entity pmod_da3_ctrl is
|
entity pmod_da3_ctrl is
|
||||||
generic(
|
generic(
|
||||||
TRANSFER_CLK_COUNT : integer := 16;
|
TRANSFER_CLK_COUNT : integer := 16;
|
||||||
DATA_BITS : integer := 16
|
DATA_WIDTH : integer := 16
|
||||||
);
|
);
|
||||||
port (
|
port (
|
||||||
sclk : in std_logic; -- PMOD-DA3
|
sclk : in std_logic; -- PMOD-DA3
|
||||||
reset : in std_logic;
|
reset : in std_logic;
|
||||||
start : 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
|
cs_n : out std_logic;-- PMOD-DA3
|
||||||
sdata : out std_logic;-- PMOD-DA3
|
sdata : out std_logic;-- PMOD-DA3
|
||||||
ldac : 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);
|
type STAGE_TYPE is (IDLE, TRANSFER);
|
||||||
|
|
||||||
--*****SIGNAL DECLARATIONS*****
|
--*****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 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
|
-- Output Signals
|
||||||
signal cs_n_next : std_logic := '1';
|
signal cs_n_next : std_logic := '1';
|
||||||
signal sdata_next : std_logic := '0';
|
signal sdata_next : std_logic := '0';
|
||||||
@ -63,13 +63,13 @@ begin
|
|||||||
cs_n_next <= '0';
|
cs_n_next <= '0';
|
||||||
count_next <= 1;
|
count_next <= 1;
|
||||||
-- Shift first bit into DAC
|
-- Shift first bit into DAC
|
||||||
buf_next <= data(DATA_BITS-2 downto 0) & '0';
|
buf_next <= data(DATA_WIDTH-2 downto 0) & '0';
|
||||||
sdata_next <= data(DATA_BITS-1);
|
sdata_next <= data(DATA_WIDTH-1);
|
||||||
end if;
|
end if;
|
||||||
when TRANSFER =>
|
when TRANSFER =>
|
||||||
-- Shift Bits into DAC
|
-- Shift Bits into DAC
|
||||||
buf_next <= buf(DATA_BITS-2 downto 0) & '0';
|
buf_next <= buf(DATA_WIDTH-2 downto 0) & '0';
|
||||||
sdata_next <= buf(DATA_BITS-1);
|
sdata_next <= buf(DATA_WIDTH-1);
|
||||||
cs_n_next <= '0';
|
cs_n_next <= '0';
|
||||||
if (count = TRANSFER_CLK_COUNT) then
|
if (count = TRANSFER_CLK_COUNT) then
|
||||||
cs_n_next <= '1';
|
cs_n_next <= '1';
|
||||||
|
|||||||
@ -8,16 +8,15 @@ use xpm.vcomponents.all;
|
|||||||
entity single_port_ram is
|
entity single_port_ram is
|
||||||
generic (
|
generic (
|
||||||
ADDR_WIDTH : integer := 8;
|
ADDR_WIDTH : integer := 8;
|
||||||
DATA_WIDTH : integer := 12;
|
DATA_WIDTH : integer := 12
|
||||||
MEMORY_DEPTH : integer := 200
|
|
||||||
);
|
);
|
||||||
port (
|
port (
|
||||||
clk : in std_logic;
|
clk : in std_logic;
|
||||||
addr : in std_logic_vector(ADDR_WIDTH-1 downto 0);
|
addr : in std_logic_vector(ADDR_WIDTH-1 downto 0);
|
||||||
wen : in std_logic;
|
wen : in std_logic;
|
||||||
ren : in std_logic;
|
ren : in std_logic;
|
||||||
write_data : in std_logic_vector(DATA_WIDTH-1 downto 0);
|
wr_data : in std_logic_vector(DATA_WIDTH-1 downto 0);
|
||||||
read_data : out std_logic_vector(DATA_WIDTH-1 downto 0)
|
rd_data : out std_logic_vector(DATA_WIDTH-1 downto 0)
|
||||||
);
|
);
|
||||||
end entity;
|
end entity;
|
||||||
|
|
||||||
@ -35,7 +34,7 @@ begin
|
|||||||
MEMORY_INIT_PARAM => "0",
|
MEMORY_INIT_PARAM => "0",
|
||||||
MEMORY_OPTIMIZATION => "true",
|
MEMORY_OPTIMIZATION => "true",
|
||||||
MEMORY_PRIMITIVE => "auto",
|
MEMORY_PRIMITIVE => "auto",
|
||||||
MEMORY_SIZE => DATA_WIDTH*MEMORY_DEPTH,
|
MEMORY_SIZE => DATA_WIDTH*(2**ADDR_WIDTH),
|
||||||
MESSAGE_CONTROL => 0,
|
MESSAGE_CONTROL => 0,
|
||||||
READ_DATA_WIDTH_A => DATA_WIDTH,
|
READ_DATA_WIDTH_A => DATA_WIDTH,
|
||||||
READ_LATENCY_A => 1,
|
READ_LATENCY_A => 1,
|
||||||
@ -48,11 +47,11 @@ begin
|
|||||||
)
|
)
|
||||||
port map (
|
port map (
|
||||||
dbiterra => open,
|
dbiterra => open,
|
||||||
douta => read_data,
|
douta => rd_data,
|
||||||
sbiterra => open,
|
sbiterra => open,
|
||||||
addra => addr,
|
addra => addr,
|
||||||
clka => clk,
|
clka => clk,
|
||||||
dina => write_data,
|
dina => wr_data,
|
||||||
ena => (ren or wen),
|
ena => (ren or wen),
|
||||||
injectdbiterra => '0',
|
injectdbiterra => '0',
|
||||||
injectsbiterra => '0',
|
injectsbiterra => '0',
|
||||||
|
|||||||
@ -39,7 +39,7 @@ architecture arch of top is
|
|||||||
);
|
);
|
||||||
end component;
|
end component;
|
||||||
|
|
||||||
--*****DIGNAL DECLARATION*****
|
--*****SIGNAL DECLARATION*****
|
||||||
signal clk_20 : std_logic := '0';
|
signal clk_20 : std_logic := '0';
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|||||||
65
src/typedef_package.vhd
Normal file
65
src/typedef_package.vhd
Normal 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
214
src/xillybus_link.vhd
Normal 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;
|
||||||
Loading…
Reference in New Issue
Block a user