diff --git a/designs/MINI-LFR/MINI_LFR_top.vhd b/designs/MINI-LFR/MINI_LFR_top.vhd --- a/designs/MINI-LFR/MINI_LFR_top.vhd +++ b/designs/MINI-LFR/MINI_LFR_top.vhd @@ -140,6 +140,9 @@ ARCHITECTURE beh OF MINI_LFR_top IS SIGNAL ahbi_m_ext : AHB_Mst_In_Type; SIGNAL ahbo_m_ext : soc_ahb_mst_out_vector(NB_AHB_MASTER-1+1 DOWNTO 1):= (OTHERS => ahbm_none); + SIGNAL SRAM_CE_V : STD_LOGIC_VECTOR(1 downto 0); + + BEGIN -- beh ----------------------------------------------------------------------------- @@ -262,8 +265,9 @@ BEGIN -- beh nSRAM_BE2 => SRAM_nBE(2), nSRAM_BE3 => SRAM_nBE(3), nSRAM_WE => SRAM_nWE, - nSRAM_CE => SRAM_CE, + nSRAM_CE => SRAM_CE_V, nSRAM_OE => SRAM_nOE, + nSRAM_READY=> open, apbi_ext => apbi_ext, apbo_ext => apbo_ext, @@ -271,5 +275,7 @@ BEGIN -- beh ahbo_s_ext => ahbo_s_ext, ahbi_m_ext => ahbi_m_ext, ahbo_m_ext => ahbo_m_ext); + + SRAM_CE <= SRAM_CE_V(0); END beh; diff --git a/lib/lpp/lpp_cna/APB_LFR_CAL.vhd b/lib/lpp/lpp_cna/APB_LFR_CAL.vhd new file mode 100644 --- /dev/null +++ b/lib/lpp/lpp_cna/APB_LFR_CAL.vhd @@ -0,0 +1,181 @@ +------------------------------------------------------------------------------ +-- This file is a part of the LPP VHDL IP LIBRARY +-- Copyright (C) 2009 - 2015, Laboratory of Plasmas Physic - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +------------------------------------------------------------------------------ +-- Author : Alexis Jeandet +-- Mail : alexis.jeandet@member.fsf.org +------------------------------------------------------------------------------ +library ieee; +use ieee.std_logic_1164.all; +use IEEE.numeric_std.all; +library grlib; +use grlib.amba.all; +use grlib.stdlib.all; +use grlib.devices.all; +library lpp; +use lpp.lpp_amba.all; +use lpp.lpp_cna.all; +use lpp.apb_devices_list.all; + +entity apb_lfr_cal is + generic ( + pindex : integer := 0; + paddr : integer := 0; + pmask : integer := 16#fff#; + tech : integer := 0; + PRESZ : integer := 8; + CPTSZ : integer := 16; + datawidth : integer := 18; + dacresolution : integer := 12; + abits : integer := 8 + ); + port ( + rstn : in std_logic; + clk : in std_logic; + apbi : in apb_slv_in_type; + apbo : out apb_slv_out_type; + SDO : out std_logic; + SCK : out std_logic; + SYNC : out std_logic; + SMPCLK : out std_logic + ); +end entity; + +--! @details Les deux registres (apbi,apbo) permettent de gérer la communication sur le bus +--! et les sorties seront cablées vers le convertisseur. + +architecture ar_apb_lfr_cal of apb_lfr_cal is + +constant REVISION : integer := 1; + +constant pconfig : apb_config_type := ( + 0 => ahb_device_reg (VENDOR_LPP, LPP_CNA, 0, REVISION, 0), + 1 => apb_iobar(paddr, pmask)); + +signal pre : STD_LOGIC_VECTOR(PRESZ-1 downto 0); +signal N : STD_LOGIC_VECTOR(CPTSZ-1 downto 0); +signal Reload : std_logic; +signal DATA_IN : STD_LOGIC_VECTOR(datawidth-1 downto 0); +signal WEN : STD_LOGIC; +signal LOAD_ADDRESSN : STD_LOGIC; +signal ADDRESS_IN : STD_LOGIC_VECTOR(abits-1 downto 0); +signal ADDRESS_OUT : STD_LOGIC_VECTOR(abits-1 downto 0); +signal INTERLEAVED : STD_LOGIC; +signal DAC_CFG : STD_LOGIC_VECTOR(3 downto 0); +signal Rdata : std_logic_vector(31 downto 0); + +begin + +cal: lfr_cal_driver + generic map( + tech => tech, + PRESZ => PRESZ, + CPTSZ => CPTSZ, + datawidth => datawidth, + abits => abits + ) + Port map( + clk => clk, + rstn => rstn, + pre => pre, + N => N, + Reload => Reload, + DATA_IN => DATA_IN, + WEN => WEN, + LOAD_ADDRESSN => LOAD_ADDRESSN, + ADDRESS_IN => ADDRESS_IN, + ADDRESS_OUT => ADDRESS_OUT, + INTERLEAVED => INTERLEAVED, + DAC_CFG => DAC_CFG, + SYNC => SYNC, + DOUT => SDO, + SCLK => SCK, + SMPCLK => SMPCLK + ); + + process(rstn,clk) + begin + if(rstn='0')then + pre <= (others=>'1'); + N <= (others=>'1'); + Reload <= '1'; + DATA_IN <= (others=>'0'); + WEN <= '1'; + LOAD_ADDRESSN <= '1'; + ADDRESS_IN <= (others=>'1'); + INTERLEAVED <= '0'; + DAC_CFG <= (others=>'0'); + Rdata <= (others=>'0'); + elsif(clk'event and clk='1')then + + + --APB Write OP + if (apbi.psel(pindex) and apbi.penable and apbi.pwrite) = '1' then + case apbi.paddr(abits-1 downto 2) is + when "000000" => + DAC_CFG <= apbi.pwdata(3 downto 0); + Reload <= apbi.pwdata(4); + INTERLEAVED <= apbi.pwdata(5); + when "000001" => + pre <= apbi.pwdata(PRESZ-1 downto 0); + when "000010" => + N <= apbi.pwdata(CPTSZ-1 downto 0); + when "000011" => + ADDRESS_IN <= apbi.pwdata(abits-1 downto 0); + LOAD_ADDRESSN <= '0'; + when "000100" => + DATA_IN <= apbi.pwdata(datawidth-1 downto 0); + WEN <= '0'; + when others => + null; + end case; + else + LOAD_ADDRESSN <= '1'; + WEN <= '1'; + end if; + + --APB Read OP + if (apbi.psel(pindex) and (not apbi.pwrite)) = '1' then + case apbi.paddr(abits-1 downto 2) is + when "000000" => + Rdata(3 downto 0) <= DAC_CFG; + Rdata(4) <= Reload; + Rdata(5) <= INTERLEAVED; + Rdata(31 downto 6) <= (others => '0'); + when "000001" => + Rdata(PRESZ-1 downto 0) <= pre; + Rdata(31 downto PRESZ) <= (others => '0'); + when "000010" => + Rdata(CPTSZ-1 downto 0) <= N; + Rdata(31 downto CPTSZ) <= (others => '0'); + when "000011" => + Rdata(abits-1 downto 0) <= ADDRESS_OUT; + Rdata(31 downto abits) <= (others => '0'); + when "000100" => + Rdata(datawidth-1 downto 0) <= DATA_IN; + Rdata(31 downto datawidth) <= (others => '0'); + when others => + Rdata <= (others => '0'); + end case; + end if; + + end if; + apbo.pconfig <= pconfig; + end process; + +apbo.prdata <= Rdata when apbi.penable = '1'; +end architecture ar_apb_lfr_cal; \ No newline at end of file diff --git a/lib/lpp/lpp_cna/RAM_READER.vhd b/lib/lpp/lpp_cna/RAM_READER.vhd new file mode 100644 --- /dev/null +++ b/lib/lpp/lpp_cna/RAM_READER.vhd @@ -0,0 +1,117 @@ +------------------------------------------------------------------------------ +-- This file is a part of the LPP VHDL IP LIBRARY +-- Copyright (C) 2009 - 2015, Laboratory of Plasmas Physic - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +------------------------------------------------------------------------------ +-- Author : Alexis Jeandet +-- Mail : alexis.jeandet@member.fsf.org +------------------------------------------------------------------------------ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +entity RAM_READER is + Generic( + datawidth : integer := 18; + dacresolution : integer := 12; + abits : integer := 8 + ); + Port ( + clk : in STD_LOGIC; --! clock input + rstn : in STD_LOGIC; --! Active low restet input + DATA_IN : in STD_LOGIC_VECTOR (datawidth-1 downto 0); --! DATA input vector -> connect to RAM DATA output + ADDRESS : out STD_LOGIC_VECTOR (abits-1 downto 0); --! ADDRESS output vector -> connect to RAM read ADDRESS input + REN : out STD_LOGIC; --! Active low read enable -> connect to RAM read enable + DATA_OUT : out STD_LOGIC_VECTOR (dacresolution-1 downto 0); --! DATA output vector + SMP_CLK : in STD_LOGIC; --! Sampling clock input, each rising edge will provide a DATA to the output and read a new one in RAM + INTERLEAVED : in STD_LOGIC --! When 1, interleaved mode is actived. + ); +end RAM_READER; + +architecture Behavioral of RAM_READER is +CONSTANT interleaved_sz : integer := dacresolution/(datawidth-dacresolution); + +signal ADDRESS_R : STD_LOGIC_VECTOR (abits-1 downto 0):=(others=>'0'); +signal SAMPLE_R : STD_LOGIC_VECTOR (dacresolution-1 downto 0):=(others=>'0'); +signal INTERLEAVED_SAMPLE_R : STD_LOGIC_VECTOR (dacresolution-1 downto 0):=(others=>'0'); +signal SMP_CLK_R : STD_LOGIC; +signal interleavedCNTR : integer range 0 to interleaved_sz; +signal REN_R : STD_LOGIC:='1'; +signal interleave : STD_LOGIC:='0'; +signal loadEvent : STD_LOGIC:='0'; +signal loadEvent_R : STD_LOGIC:='0'; +signal loadEvent_R2 : STD_LOGIC:='0'; +begin + +REN <= REN_R; +DATA_OUT <= SAMPLE_R; +ADDRESS <= ADDRESS_R; +interleave <= '1' when interleavedCNTR=interleaved_sz else '0'; + +loadEvent <= SMP_CLK and not SMP_CLK_R ; + +process(clk,rstn) +begin + if rstn='0' then + SMP_CLK_R <= '0'; + loadEvent_R <= '0'; + loadEvent_R2 <= '0'; + elsif clk'event and clk='1' then + SMP_CLK_R <= SMP_CLK; + loadEvent_R <= loadEvent; + loadEvent_R2 <= loadEvent_R; + end if; +end process; + +process(clk,rstn) +begin + if rstn='0' then + ADDRESS_R <= (others=>'0'); + SAMPLE_R <= (others=>'0'); + INTERLEAVED_SAMPLE_R <= (others=>'0'); + REN_R <= '1'; + interleavedCNTR <= 0; + elsif clk'event and clk='1' then + if loadEvent = '1' then + if(interleave='0') then + REN_R <= '0'; + end if; + else + REN_R <= '1'; + end if; + + if REN_R = '0' then + ADDRESS_R <= std_logic_vector(UNSIGNED(ADDRESS_R) + 1); --Automatic increment on each read + end if; + + if loadEvent_R2='1' then + if(interleave='1') then + interleavedCNTR <= 0; + SAMPLE_R <= INTERLEAVED_SAMPLE_R; + else + if interleaved='1' then + interleavedCNTR <= interleavedCNTR + 1; + else + interleavedCNTR <= 0; + end if; + SAMPLE_R <= DATA_IN(dacresolution-1 downto 0); + INTERLEAVED_SAMPLE_R(dacresolution-1 downto 0) <= INTERLEAVED_SAMPLE_R(datawidth-dacresolution-1 downto 0) & DATA_IN(datawidth-1 downto dacresolution); + end if; + end if; + end if; +end process; + +end Behavioral; diff --git a/lib/lpp/lpp_cna/RAM_WRITER.vhd b/lib/lpp/lpp_cna/RAM_WRITER.vhd new file mode 100644 --- /dev/null +++ b/lib/lpp/lpp_cna/RAM_WRITER.vhd @@ -0,0 +1,68 @@ +------------------------------------------------------------------------------ +-- This file is a part of the LPP VHDL IP LIBRARY +-- Copyright (C) 2009 - 2015, Laboratory of Plasmas Physic - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +------------------------------------------------------------------------------ +-- Author : Alexis Jeandet +-- Mail : alexis.jeandet@member.fsf.org +------------------------------------------------------------------------------ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +entity RAM_WRITER is + Generic( + datawidth : integer := 18; + abits : integer := 8 + ); + Port ( + clk : in STD_LOGIC; --! clk input + rstn : in STD_LOGIC; --! Active low reset input + DATA_IN : in STD_LOGIC_VECTOR (datawidth-1 downto 0); --! DATA input vector + DATA_OUT : out STD_LOGIC_VECTOR (datawidth-1 downto 0); --! DATA output vector + WEN_IN : in STD_LOGIC; --! Active low Write Enable input + WEN_OUT : out STD_LOGIC; --! Active low Write Enable output + LOAD_ADDRESSN : in STD_LOGIC; --! Active low address load input + ADDRESS_IN : in STD_LOGIC_VECTOR (abits-1 downto 0); --! Adress input vector + ADDRESS_OUT : out STD_LOGIC_VECTOR (abits-1 downto 0) --! Adress output vector + ); +end RAM_WRITER; + +architecture Behavioral of RAM_WRITER is + +signal ADDRESS_R : STD_LOGIC_VECTOR (abits-1 downto 0):=(others=>'0'); +begin + +ADDRESS_OUT <= ADDRESS_R; +-- pass through connections for DATA and WEN +DATA_OUT <= DATA_IN; +WEN_OUT <= WEN_IN; + +process(clk,rstn) +begin + if rstn='0' then + ADDRESS_R <= (others=>'0'); + elsif clk'event and clk='1' then + if LOAD_ADDRESSN = '0' then + ADDRESS_R <= ADDRESS_IN; + elsif WEN_IN = '0' then + ADDRESS_R <= STD_LOGIC_VECTOR(UNSIGNED(ADDRESS_R) + 1); + end if; + end if; +end process; + +end Behavioral; + diff --git a/lib/lpp/lpp_cna/SPI_DAC_DRIVER.vhd b/lib/lpp/lpp_cna/SPI_DAC_DRIVER.vhd new file mode 100644 --- /dev/null +++ b/lib/lpp/lpp_cna/SPI_DAC_DRIVER.vhd @@ -0,0 +1,105 @@ +------------------------------------------------------------------------------ +-- This file is a part of the LPP VHDL IP LIBRARY +-- Copyright (C) 2009 - 2015, Laboratory of Plasmas Physic - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +------------------------------------------------------------------------------ +-- Author : Alexis Jeandet +-- Mail : alexis.jeandet@member.fsf.org +------------------------------------------------------------------------------ + + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +entity SPI_DAC_DRIVER is + Generic( + datawidth : INTEGER := 16; + MSBFIRST : INTEGER := 1 + ); + Port ( + clk : in STD_LOGIC; + rstn : in STD_LOGIC; + DATA : in STD_LOGIC_VECTOR(datawidth-1 downto 0); + SMP_CLK : in STD_LOGIC; + SYNC : out STD_LOGIC; + DOUT : out STD_LOGIC; + SCLK : out STD_LOGIC + ); +end entity SPI_DAC_DRIVER; + +architecture behav of SPI_DAC_DRIVER is +signal SHIFTREG : STD_LOGIC_VECTOR(datawidth-1 downto 0):=(others=>'0'); +signal INPUTREG : STD_LOGIC_VECTOR(datawidth-1 downto 0):=(others=>'0'); +signal SMP_CLK_R : STD_LOGIC:='0'; +signal shiftcnt : INTEGER:=0; +signal shifting : STD_LOGIC:='0'; +signal shifting_R : STD_LOGIC:='0'; +begin + +DOUT <= SHIFTREG(datawidth-1); + +MSB:IF MSBFIRST=1 GENERATE + INPUTREG <= DATA; +END GENERATE; + +LSB:IF MSBFIRST=0 GENERATE + INPUTREG(datawidth-1 downto 0) <= DATA(0 to datawidth-1); +END GENERATE; + +SCLK <= clk; + +process(clk,rstn) +begin + if rstn='0' then + shifting_R <= '0'; + SMP_CLK_R <= '0'; + elsif clk'event and clk='1' then + SMP_CLK_R <= SMP_CLK; + shifting_R <= shifting; + end if; +end process; + +process(clk,rstn) +begin + if rstn='0' then + shifting <= '0'; + SHIFTREG <= (others=>'0'); + SYNC <= '0'; + shiftcnt <= 0; + elsif clk'event and clk='1' then + if(SMP_CLK='1' and SMP_CLK_R='0') then + SYNC <= '1'; + shifting <= '1'; + else + SYNC <= '0'; + if shiftcnt = datawidth-1 then + shifting <= '0'; + end if; + end if; + if shifting_R='1' then + shiftcnt <= shiftcnt + 1; + SHIFTREG <= SHIFTREG (datawidth-2 downto 0) & '0'; + else + SHIFTREG <= INPUTREG; + shiftcnt <= 0; + end if; + end if; +end process; + +end architecture behav; + + diff --git a/lib/lpp/lpp_cna/dynamic_freq_div.vhd b/lib/lpp/lpp_cna/dynamic_freq_div.vhd new file mode 100644 --- /dev/null +++ b/lib/lpp/lpp_cna/dynamic_freq_div.vhd @@ -0,0 +1,99 @@ +------------------------------------------------------------------------------ +-- This file is a part of the LPP VHDL IP LIBRARY +-- Copyright (C) 2009 - 2015, Laboratory of Plasmas Physic - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +------------------------------------------------------------------------------ +-- Author : Alexis Jeandet +-- Mail : alexis.jeandet@member.fsf.org +------------------------------------------------------------------------------ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +entity dynamic_freq_div is + generic( + PRESZ : integer range 1 to 32:=4; + PREMAX : integer := 16#FFFFFF#; + CPTSZ : integer range 1 to 32:=16 + ); + Port ( + clk : in STD_LOGIC; + rstn : in STD_LOGIC; + pre : in STD_LOGIC_VECTOR(PRESZ-1 downto 0); + N : in STD_LOGIC_VECTOR(CPTSZ-1 downto 0); + Reload : in std_logic; + clk_out : out STD_LOGIC + ); +end dynamic_freq_div; + +architecture Behavioral of dynamic_freq_div is +constant prescaller_reg_sz : integer := 2**PRESZ; +constant PREMAX_max : STD_LOGIC_VECTOR(PRESZ-1 downto 0):=(others => '1'); +signal cpt_reg : std_logic_vector(CPTSZ-1 downto 0):=(others => '0'); +signal prescaller_reg : std_logic_vector(prescaller_reg_sz-1 downto 0):=(others => '0'); +signal internal_clk : std_logic:='0'; +signal internal_clk_reg : std_logic:='0'; +signal clk_out_reg : std_logic:='0'; + +begin + +max0: if (UNSIGNED(PREMAX_max) < PREMAX) generate + +internal_clk <= prescaller_reg(to_integer(unsigned(pre))) when (to_integer(unsigned(pre))<=UNSIGNED(PREMAX_max)) else + prescaller_reg(to_integer(UNSIGNED(PREMAX_max))); +end generate; +max1: if UNSIGNED(PREMAX_max) > PREMAX generate +internal_clk <= prescaller_reg(to_integer(unsigned(pre))) when (to_integer(unsigned(pre))<=PREMAX) else + prescaller_reg(PREMAX); +end generate; + + + +prescaller: process(rstn, clk) +begin +if rstn='0' then + prescaller_reg <= (others => '0'); +elsif clk'event and clk = '1' then + prescaller_reg <= std_logic_vector(UNSIGNED(prescaller_reg) + 1); +end if; +end process; + + +clk_out <= clk_out_reg; + +counter: process(rstn, clk) +begin +if rstn='0' then + cpt_reg <= (others => '0'); + internal_clk_reg <= '0'; + clk_out_reg <= '0'; +elsif clk'event and clk = '1' then + internal_clk_reg <= internal_clk; + if Reload = '1' then + clk_out_reg <= '0'; + cpt_reg <= (others => '0'); + elsif (internal_clk = '1' and internal_clk_reg = '0') then + if cpt_reg = N then + clk_out_reg <= not clk_out_reg; + cpt_reg <= (others => '0'); + else + cpt_reg <= std_logic_vector(UNSIGNED(cpt_reg) + 1); + end if; + end if; +end if; +end process; + +end Behavioral; diff --git a/lib/lpp/lpp_cna/lfr_cal_driver.vhd b/lib/lpp/lpp_cna/lfr_cal_driver.vhd new file mode 100644 --- /dev/null +++ b/lib/lpp/lpp_cna/lfr_cal_driver.vhd @@ -0,0 +1,146 @@ +------------------------------------------------------------------------------ +-- This file is a part of the LPP VHDL IP LIBRARY +-- Copyright (C) 2009 - 2015, Laboratory of Plasmas Physic - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +------------------------------------------------------------------------------ +-- Author : Alexis Jeandet +-- Mail : alexis.jeandet@member.fsf.org +------------------------------------------------------------------------------ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +LIBRARY techmap; +USE techmap.gencomp.ALL; + +library lpp; +use lpp.lpp_cna.all; + + +entity lfr_cal_driver is + generic( + tech : integer := 0; + PRESZ : integer range 1 to 32:=4; + PREMAX : integer := 16#FFFFFF#; + CPTSZ : integer range 1 to 32:=16; + datawidth : integer := 18; + abits : integer := 8 + ); + Port ( + clk : in STD_LOGIC; + rstn : in STD_LOGIC; + pre : in STD_LOGIC_VECTOR(PRESZ-1 downto 0); + N : in STD_LOGIC_VECTOR(CPTSZ-1 downto 0); + Reload : in std_logic; + DATA_IN : in STD_LOGIC_VECTOR(datawidth-1 downto 0); + WEN : in STD_LOGIC; + LOAD_ADDRESSN : IN STD_LOGIC; + ADDRESS_IN : IN STD_LOGIC_VECTOR(abits-1 downto 0); + ADDRESS_OUT : OUT STD_LOGIC_VECTOR(abits-1 downto 0); + INTERLEAVED : IN STD_LOGIC; + DAC_CFG : IN STD_LOGIC_VECTOR(3 downto 0); + SYNC : out STD_LOGIC; + DOUT : out STD_LOGIC; + SCLK : out STD_LOGIC; + SMPCLK : out STD_lOGIC + ); +end lfr_cal_driver; + +architecture Behavioral of lfr_cal_driver is +constant dacresolution : integer := 12; +signal RAM_DATA_IN : STD_LOGIC_VECTOR(datawidth-1 downto 0); +signal RAM_WEN : STD_LOGIC; +signal RAM_WADDR : STD_LOGIC_VECTOR(abits-1 downto 0); +signal RAM_DATA_OUT : STD_LOGIC_VECTOR(datawidth-1 downto 0); +signal RAM_RADDR : STD_LOGIC_VECTOR(abits-1 downto 0); +signal RAM_REN : STD_LOGIC; +signal DAC_DATA : STD_LOGIC_VECTOR(dacresolution-1 downto 0); +signal SMP_CLK : STD_LOGIC; +signal DAC_INPUT : STD_LOGIC_VECTOR(15 downto 0); + +begin + +ADDRESS_OUT <= RAM_WADDR; +DAC_INPUT <= DAC_CFG & DAC_DATA; +SMPCLK <= SMP_CLK; + +dac_drv: SPI_DAC_DRIVER + Generic map( + datawidth => 16, + MSBFIRST => 1 + ) + Port map( + clk => clk, + rstn => rstn, + DATA => DAC_INPUT, + SMP_CLK => SMP_CLK, + SYNC => SYNC, + DOUT => DOUT, + SCLK => SCLK + ); + +freqGen: dynamic_freq_div + generic map( + PRESZ => PRESZ, + PREMAX => PREMAX, + CPTSZ => CPTSZ + ) + Port map( clk => clk, + rstn => rstn, + pre => pre, + N => N, + Reload => Reload, + clk_out => SMP_CLK + ); + + +ramWr: RAM_WRITER + Generic map( + datawidth => datawidth, + abits => abits + ) + Port map( + clk => clk, + rstn => rstn, + DATA_IN => DATA_IN, + DATA_OUT => RAM_DATA_IN, + WEN_IN => WEN, + WEN_OUT => RAM_WEN, + LOAD_ADDRESSN => LOAD_ADDRESSN, + ADDRESS_IN => ADDRESS_IN, + ADDRESS_OUT => RAM_WADDR + ); + +ramRd: RAM_READER + Generic map( + datawidth => datawidth, + dacresolution => dacresolution, + abits => abits + ) + Port map( + clk => clk, + rstn => rstn, + DATA_IN => RAM_DATA_OUT, + ADDRESS => RAM_RADDR, + REN => RAM_REN, + DATA_OUT => DAC_DATA, + SMP_CLK => SMP_CLK, + INTERLEAVED => INTERLEAVED + ); + +SRAM : syncram_2p + GENERIC MAP(tech, abits, datawidth) + PORT MAP(clk, RAM_REN, RAM_RADDR, RAM_DATA_OUT, clk, RAM_WEN, RAM_WADDR, RAM_DATA_IN); + +end Behavioral; diff --git a/lib/lpp/lpp_cna/lpp_cna.vhd b/lib/lpp/lpp_cna/lpp_cna.vhd --- a/lib/lpp/lpp_cna/lpp_cna.vhd +++ b/lib/lpp/lpp_cna/lpp_cna.vhd @@ -31,6 +31,127 @@ use lpp.lpp_amba.all; package lpp_cna is +component apb_lfr_cal is + generic ( + pindex : integer := 0; + paddr : integer := 0; + pmask : integer := 16#fff#; + tech : integer := 0; + PRESZ : integer := 8; + CPTSZ : integer := 16; + datawidth : integer := 18; + dacresolution : integer := 12; + abits : integer := 8); + port ( + rstn : in std_logic; + clk : in std_logic; + apbi : in apb_slv_in_type; + apbo : out apb_slv_out_type; + SDO : out std_logic; + SCK : out std_logic; + SYNC : out std_logic; + SMPCLK : out std_logic + ); +end component; + +component SPI_DAC_DRIVER is + Generic( + datawidth : INTEGER := 16; + MSBFIRST : INTEGER := 1 + ); + Port ( + clk : in STD_LOGIC; + rstn : in STD_LOGIC; + DATA : in STD_LOGIC_VECTOR(datawidth-1 downto 0); + SMP_CLK : in STD_LOGIC; + SYNC : out STD_LOGIC; + DOUT : out STD_LOGIC; + SCLK : out STD_LOGIC + ); +end component; + +component dynamic_freq_div is + generic( + PRESZ : integer range 1 to 32:=4; + PREMAX : integer := 16#FFFFFF#; + CPTSZ : integer range 1 to 32:=16 + ); + Port ( + clk : in STD_LOGIC; + rstn : in STD_LOGIC; + pre : in STD_LOGIC_VECTOR(PRESZ-1 downto 0); + N : in STD_LOGIC_VECTOR(CPTSZ-1 downto 0); + Reload : in std_logic; + clk_out : out STD_LOGIC + ); +end component; + +component lfr_cal_driver is + generic( + tech : integer := 0; + PRESZ : integer range 1 to 32:=4; + PREMAX : integer := 16#FFFFFF#; + CPTSZ : integer range 1 to 32:=16; + datawidth : integer := 18; + abits : integer := 8 + ); + Port ( + clk : in STD_LOGIC; + rstn : in STD_LOGIC; + pre : in STD_LOGIC_VECTOR(PRESZ-1 downto 0); + N : in STD_LOGIC_VECTOR(CPTSZ-1 downto 0); + Reload : in std_logic; + DATA_IN : in STD_LOGIC_VECTOR(datawidth-1 downto 0); + WEN : in STD_LOGIC; + LOAD_ADDRESSN : IN STD_LOGIC; + ADDRESS_IN : IN STD_LOGIC_VECTOR(abits-1 downto 0); + ADDRESS_OUT : OUT STD_LOGIC_VECTOR(abits-1 downto 0); + INTERLEAVED : IN STD_LOGIC; + DAC_CFG : IN STD_LOGIC_VECTOR(3 downto 0); + SYNC : out STD_LOGIC; + DOUT : out STD_LOGIC; + SCLK : out STD_LOGIC; + SMPCLK : out STD_lOGIC + ); +end component; + +component RAM_READER is + Generic( + datawidth : integer := 18; + dacresolution : integer := 12; + abits : integer := 8 + ); + Port ( + clk : in STD_LOGIC; --! clock input + rstn : in STD_LOGIC; --! Active low restet input + DATA_IN : in STD_LOGIC_VECTOR (datawidth-1 downto 0); --! DATA input vector -> connect to RAM DATA output + ADDRESS : out STD_LOGIC_VECTOR (abits-1 downto 0); --! ADDRESS output vector -> connect to RAM read ADDRESS input + REN : out STD_LOGIC; --! Active low read enable -> connect to RAM read enable + DATA_OUT : out STD_LOGIC_VECTOR (dacresolution-1 downto 0); --! DATA output vector + SMP_CLK : in STD_LOGIC; --! Sampling clock input, each rising edge will provide a DATA to the output and read a new one in RAM + INTERLEAVED : in STD_LOGIC --! When 1, interleaved mode is actived. + ); +end component; + + +component RAM_WRITER is + Generic( + datawidth : integer := 18; + abits : integer := 8 + ); + Port ( + clk : in STD_LOGIC; --! clk input + rstn : in STD_LOGIC; --! Active low reset input + DATA_IN : in STD_LOGIC_VECTOR (datawidth-1 downto 0); --! DATA input vector + DATA_OUT : out STD_LOGIC_VECTOR (datawidth-1 downto 0); --! DATA output vector + WEN_IN : in STD_LOGIC; --! Active low Write Enable input + WEN_OUT : out STD_LOGIC; --! Active low Write Enable output + LOAD_ADDRESSN : in STD_LOGIC; --! Active low address load input + ADDRESS_IN : in STD_LOGIC_VECTOR (abits-1 downto 0); --! Adress input vector + ADDRESS_OUT : out STD_LOGIC_VECTOR (abits-1 downto 0) --! Adress output vector + ); +end component; + component APB_DAC is generic ( pindex : integer := 0;