---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 15:54:09 02/16/2016 -- Design Name: -- Module Name: TTC_cntr - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use IEEE.std_logic_misc.all; use work.amc13_pack.all; -- Uncomment the following library declaration if using -- arithmetic functions with Signed or Unsigned values --use IEEE.NUMERIC_STD.ALL; -- Uncomment the following library declaration if instantiating -- any Xilinx primitives in this code. library UNISIM; use UNISIM.VComponents.all; Library UNIMACRO; use UNIMACRO.vcomponents.all; entity AMC_cntr is Port ( UsrClk : in STD_LOGIC; clk125 : in STD_LOGIC; sysclk : in STD_LOGIC; ipb_clk : in STD_LOGIC; resetCntr : in STD_LOGIC; DB_cmd : in STD_LOGIC; AMC_if_data : in STD_LOGIC_VECTOR(15 downto 0); Cntr_DATA : in array12x16; Cntr_ADDR : out STD_LOGIC_VECTOR(11 downto 0); ipb_addr : in STD_LOGIC_VECTOR(15 downto 0); ipb_rdata : out STD_LOGIC_VECTOR(31 downto 0)); end AMC_cntr; architecture Behavioral of AMC_cntr is signal div : std_logic_vector(11 downto 0) := (others =>'0'); signal div_l : std_logic_vector(10 downto 0) := (others =>'0'); signal div_l2 : std_logic_vector(10 downto 0) := (others =>'0'); signal CntrRstCycle : std_logic := '0'; signal counter_wa : std_logic_vector(10 downto 0) := (others => '0'); signal counter_ra : std_logic_vector(10 downto 0) := (others => '0'); signal counter_DIA : std_logic_vector(31 downto 0) := (others => '0'); signal counter_DOA : std_logic_vector(31 downto 0) := (others => '0'); signal counter_DOB : std_logic_vector(31 downto 0) := (others => '0'); signal we_counter : std_logic_vector(1 downto 0) := (others => '0'); signal buffer_DOB : std_logic_vector(31 downto 0) := (others => '0'); signal buffer_RSTB : std_logic := '0'; signal we_buffer : std_logic_vector(1 downto 0) := (others => '0'); signal startSyncRegs : std_logic_vector(3 downto 0) := (others =>'0'); signal DataType : std_logic_vector(1 downto 0) := (others => '0'); signal DataType_l : std_logic_vector(1 downto 0) := (others => '0'); signal DataType_l2 : std_logic_vector(1 downto 0) := (others => '0'); signal DataType_q : std_logic_vector(1 downto 0) := (others => '0'); signal tmp : std_logic_vector(31 downto 0) := (others => '0'); signal ec_div : std_logic_vector(1 downto 0) := (others => '0'); signal start : std_logic := '0'; signal data : std_logic_vector(31 downto 0) := (others => '0'); signal DB_cmd_l : std_logic := '0'; signal carry_m : std_logic := '0'; signal DB_en : std_logic := '0'; signal carry_h : std_logic := '0'; signal sr : std_logic_vector(4 downto 0) := (others => '0'); signal toggle : std_logic := '0'; signal toggle_q : std_logic := '0'; signal ec_rdata : std_logic := '0'; signal ec_wdata : std_logic := '0'; begin Cntr_ADDR <= div; process(UsrClk, Cntr_Data, CntrRstCycle) variable CntrDataOR : std_logic_vector(15 downto 0); begin CntrDataOR := AMC_if_data; for i in 0 to 11 loop CntrDataOR := CntrDataOR or Cntr_Data(i); end loop; if(CntrRstCycle = '1')then data <= (others => '0'); tmp <= (others => '0'); elsif(UsrClk'event and UsrClk = '1')then if(ec_div(0) = '1')then data <= tmp; tmp(15 downto 0) <= CntrDataOR; end if; if(ec_div(1) = '1')then if(DataType = "11")then tmp(31 downto 16) <= (others => '0'); else tmp(31 downto 16) <= CntrDataOR; end if; end if; end if; end process; --i_sample_data : SRL16E -- port map ( -- Q => sample_data, -- SRL data output -- A0 => '1', -- Select[0] input -- A1 => '0', -- Select[1] input -- A2 => '0', -- Select[2] input -- A3 => '0', -- Select[3] input -- CE => '1', -- Clock enable input -- CLK => UsrClk, -- Clock input -- D => ec_div -- SRL data input -- ); i_ec_div1 : SRL16E port map ( Q => ec_div(1), -- SRL data output A0 => '0', -- Select[0] input A1 => '0', -- Select[1] input A2 => '1', -- Select[2] input A3 => '0', -- Select[3] input CE => '1', -- Clock enable input CLK => UsrClk, -- Clock input D => ec_div(0) -- SRL data input ); start <= sr(0); process(UsrClk, CntrRstCycle) begin if(CntrRstCycle = '1')then startSyncRegs <= (others => '0'); ec_div(0) <= '0'; div <= (others => '0'); div_l <= (others => '0'); div_l2 <= (others => '0'); DataType <= "10"; elsif(UsrClk'event and UsrClk = '1')then startSyncRegs <= startSyncRegs(2 downto 0) & start; -- if(startSyncRegs(3 downto 2) = "01")then -- start_edge <= '1'; -- else -- start_edge <= '0'; -- end if; -- rst_ec_div <= start_edge; if(startSyncRegs(3 downto 2) = "01")then ec_div(0) <= '1'; else ec_div(0) <= '0'; end if; if(ec_div /= "00")then div <= div + 1 + DataType(1); end if; if(div(11 downto 3) = "110000101" or div(11 downto 5) = "1100010")then DataType <= "00";-- 32 bit counter elsif(div(11 downto 6) = "111000" or div(11 downto 9) = "110")then DataType <= "01";-- register elsif(div(11 downto 10) /= "11" and div(7 downto 5) = "010")then DataType <= "11";-- register of daq_link else DataType <= "10";-- 48 bit counter end if; if(ec_div(0) = '1')then div_l <= div(11 downto 1); div_l2 <= div_l; DataType_l <= DataType; DataType_l2 <= DataType_l; end if; end if; end process; g_counter: for i in 0 to 1 generate i_counter : BRAM_TDP_MACRO generic map ( BRAM_SIZE => "36Kb", -- Target BRAM, "18Kb" or "36Kb" DEVICE => "7SERIES", -- Target Device: "VIRTEX5", "VIRTEX6", "7SERIES", "SPARTAN6" WRITE_MODE_A => "READ_FIRST", -- "WRITE_FIRST", "READ_FIRST" or "NO_CHANGE" READ_WIDTH_A => 16, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") READ_WIDTH_B => 16, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") WRITE_WIDTH_A => 16, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") WRITE_WIDTH_B => 16) -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") port map ( DOA => counter_DOA(i*16+15 downto i*16), -- Output port-A data, width defined by READ_WIDTH_A parameter DOB => counter_DOB(i*16+15 downto i*16), -- Output port-B data, width defined by READ_WIDTH_B parameter ADDRA => counter_wa, -- Input port-A address, width defined by Port A depth ADDRB => ipb_addr(10 downto 0), -- Input port-B address, width defined by Port B depth CLKA => clk125, -- 1-bit input port-A clock CLKB => clk125, -- 1-bit input port-B clock DIA => counter_DIA(i*16+15 downto i*16), -- Input port-A data, width defined by WRITE_WIDTH_A parameter DIB => x"0000", -- Input port-B data, width defined by WRITE_WIDTH_B parameter ENA => '1', -- 1-bit input port-A enable ENB => ec_rdata, -- 1-bit input port-B enable REGCEA => '0', -- 1-bit input port-A output register enable REGCEB => '0', -- 1-bit input port-B output register enable RSTA => '0', -- 1-bit input port-A reset RSTB => ipb_addr(15), -- 1-bit input port-B reset WEA => we_counter, -- Input port-A write enable, width defined by Port A depth WEB => "00" -- Input port-B write enable, width defined by Port B depth ); i_buffer : BRAM_TDP_MACRO generic map ( BRAM_SIZE => "36Kb", -- Target BRAM, "18Kb" or "36Kb" DEVICE => "7SERIES", -- Target Device: "VIRTEX5", "VIRTEX6", "7SERIES", "SPARTAN6" WRITE_MODE_A => "READ_FIRST", -- "WRITE_FIRST", "READ_FIRST" or "NO_CHANGE" READ_WIDTH_A => 16, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") READ_WIDTH_B => 16, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") WRITE_WIDTH_A => 16, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") WRITE_WIDTH_B => 16) -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") port map ( DOA => open, -- Output port-A data, width defined by READ_WIDTH_A parameter DOB => buffer_DOB(i*16+15 downto i*16), -- Output port-B data, width defined by READ_WIDTH_B parameter ADDRA => counter_wa, -- Input port-A address, width defined by Port A depth ADDRB => ipb_addr(10 downto 0), -- Input port-B address, width defined by Port B depth CLKA => clk125, -- 1-bit input port-A clock CLKB => clk125, -- 1-bit input port-B clock DIA => counter_DIA(i*16+15 downto i*16), -- Input port-A data, width defined by WRITE_WIDTH_A parameter DIB => x"0000", -- Input port-B data, width defined by WRITE_WIDTH_B parameter ENA => '1', -- 1-bit input port-A enable ENB => ec_rdata, -- 1-bit input port-B enable REGCEA => '0', -- 1-bit input port-A output register enable REGCEB => '0', -- 1-bit input port-B output register enable RSTA => '0', -- 1-bit input port-A reset RSTB => buffer_RSTB, -- 1-bit input port-B reset WEA => we_buffer, -- Input port-A write enable, width defined by Port A depth WEB => "00" -- Input port-B write enable, width defined by Port B depth ); end generate; buffer_RSTB <= not ipb_addr(15); we_counter(1) <= we_counter(0); we_buffer(1) <= we_buffer(0); ipb_rdata <= counter_DOB or buffer_DOB; process(ipb_clk) begin if(ipb_clk'event and ipb_clk = '1')then toggle <= not toggle; end if; end process; process(clk125) begin if(clk125'event and clk125 = '1')then toggle_q <= toggle; ec_rdata <= toggle xor toggle_q; if(DB_cmd = '1' and ec_wdata = '1')then DB_cmd_l <= '1'; elsif(sr(0) = '1' and and_reduce(counter_wa) = '1')then DB_cmd_l <= '0'; end if; if(sr(0) = '1' and and_reduce(counter_wa) = '1')then DB_en <= DB_cmd_l; end if; if(sr(0) = '1')then DataType_q <= DataType_l2; end if; if(resetCntr = '1')then counter_wa <= (others => '0'); elsif(CntrRstCycle = '1')then counter_wa <= counter_wa + 1; elsif(sr(0) = '1')then counter_wa <= div_l2; elsif(DataType_q(1) = '1')then counter_wa(0) <= (sr(2) or sr(4)) and not sr(3); end if; if(resetCntr = '1')then CntrRstCycle <= '1'; elsif(and_reduce(counter_wa) = '1')then CntrRstCycle <= '0'; end if; if(CntrRstCycle = '1')then sr <= "00000"; elsif(sr(3 downto 0) = x"0")then sr <= "00001"; else sr <= sr(3 downto 0) & '0'; end if; if(sr(2) = '1')then if(DataType_q(0) = '0' and counter_DOA(15 downto 0) > counter_DIA(15 downto 0))then carry_m <= '1'; else carry_m <= '0'; end if; end if; if(sr(3) = '1')then if(carry_m = '1' and counter_DOA(31 downto 16) = x"ffff")then carry_h <= '1'; else carry_h <= '0'; end if; end if; if(CntrRstCycle = '1')then counter_DIA <= (others => '0'); elsif(sr(0) = '1')then counter_DIA <= data; elsif(sr(3) = '1' and DataType_q(0) = '0')then counter_DIA(31 downto 16) <= counter_DOA(31 downto 16) + carry_m; elsif(sr(4) = '1')then counter_DIA <= x"0000" & (counter_DOA(15 downto 0) + carry_h); end if; we_counter(0) <= sr(3) or (sr(4) and DataType_q(1) and not DataType_q(0)) or CntrRstCycle; we_buffer(0) <= (DB_en and(sr(3) or (sr(4) and DataType_q(1) and not DataType_q(0)))) or CntrRstCycle; end if; end process; i_ec_wdata : SRL16E generic map ( INIT => X"0000") port map ( Q => ec_wdata, -- SRL data output A0 => '1', -- Select[0] input A1 => '0', -- Select[1] input A2 => '0', -- Select[2] input A3 => '0', -- Select[3] input CE => '1', -- Clock enable input CLK => clk125, -- Clock input D => ec_rdata -- SRL data input ); end Behavioral;