---------------------------------------------------------------------------------- -- Company: University of Connecticut -- Engineer: Igor Senderovich -- -- Create Date: 10:35:58 10/24/2007 -- Design Name: -- Module Name: Programmer_ctrl - Behavioral -- Description: Coordinates reading of a "program" packet and instructs the DAC ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; library FPGA_BasicComp; use FPGA_BasicComp.BasicComp.all; entity Programmer_ctrl is Port ( Clk : in STD_LOGIC; Rst : in STD_LOGIC; DAC_iGo : out STD_LOGIC; DACReg_En : out STD_LOGIC; DAC_Addr : out STD_LOGIC_VECTOR (4 downto 0); DAC_D : out STD_LOGIC_VECTOR (13 downto 0); DAC_Done : in STD_LOGIC; DAC_Qmax : in STD_LOGIC_VECTOR (13 downto 0); DAC_Q_GainModeChan : in STD_LOGIC_VECTOR (13 downto 0); state_En : out STD_LOGIC; state_D : out STD_LOGIC_VECTOR (2 downto 0); state_Q : in STD_LOGIC_VECTOR (2 downto 0); TxRx_Go : out STD_LOGIC; TxRx_RiW : out STD_LOGIC; TxRx_A : out STD_LOGIC_VECTOR (7 downto 0); TxRx_Q : in STD_LOGIC_VECTOR (7 downto 0); TxRx_D : out STD_LOGIC_VECTOR (7 downto 0); TxRx_Done : in STD_LOGIC; db1 : out STD_LOGIC; db2 : out STD_LOGIC ); end Programmer_ctrl; architecture Behavioral of Programmer_ctrl is function LT(L: STD_LOGIC_VECTOR (13 downto 0); R: STD_LOGIC_VECTOR (13 downto 0)) return BOOLEAN is begin return conv_integer(L) < conv_integer(R); end; signal InitGo, En, Go_PacketSkip, Go_Byte, Go_NextStep, Go_LatchMSB, Go_ChState : STD_LOGIC; signal TxRx_Go_uLen, TxRx_Go_uAutoRd, TxRx_Go_uPktSkip, TxRx_Go_RxInh1, TxRx_Go_RxInh2 : STD_LOGIC; signal Done_PacketSkip, Done_CPLenH, Done_CPLenL, Done_Byte, Done_RxInh : STD_LOGIC; signal PermitNextByte, WrVoltData, ByteParity, EnCnt, DataStage, MaskStage: STD_LOGIC; signal Addr : STD_LOGIC_VECTOR (4 downto 0); signal Cnt : STD_LOGIC_VECTOR (5 downto 0); signal MaskByteNum : STD_LOGIC_VECTOR (1 downto 0); signal Data, VoltDataMSB: STD_LOGIC_VECTOR (7 downto 0); signal VoltData, CensoredVoltData, GainMode : STD_LOGIC_VECTOR (13 downto 0); signal Mask : STD_LOGIC_VECTOR (31 downto 0); type MaskChunks is array (integer range <>) of STD_LOGIC_VECTOR (7 downto 0); signal MaskByte : MaskChunks (3 downto 0); signal i : integer range 3 downto 0; --signal dbtmp : STD_LOGIC; begin En <= '1' when (state_Q="110") else '0'; -- Get packet "Go" control ------------------------------------------------ -- Define InitGo u1: Pulse_Delay port map (Clk, En, InitGo); -- Temporarily inhibit packet reception uRxInh1: wrToAddr port map (Clk, Rst, InitGo, X"11", "00001000", TxRx_Go_RxInh1, TxRx_A, TxRx_D, TxRx_RiW, TxRx_Done, Done_RxInh); -- Get LSByte of packet length (to see if it's a full packet) uLen: getByte port map (Clk, Rst, Done_RxInh, X"20", Data, Done_CPLenL, TxRx_Go_uLen, TxRx_RiW, TxRx_A, TxRx_Q, TxRx_Done); u2: Counter4bit port map (Clk, Rst, Done_Byte, Go_NextStep); Go_Byte <= (Done_CPLenL or (Go_NextStep and (EnCnt or MaskStage))) and not Go_PacketSkip; Go_PacketSkip <= '1' when (Go_NextStep and not EnCnt)='1' else -- done 32-word count '1' when (Done_CPLenL='1' and Data < "01010101") -- not full packet else '0'; uPktSkip: wrToAddr port map (Clk,Rst,Go_PacketSkip, X"11","00000010", TxRx_Go_uPktSkip,TxRx_A,TxRx_D,TxRx_RiW,TxRx_Done, Done_PacketSkip); -- Enable packet reception again uRxInh2: wrToAddr port map (Clk, Rst, Done_PacketSkip, X"11", "00000000", TxRx_Go_RxInh2, TxRx_A, TxRx_D, TxRx_RiW, TxRx_Done, Go_ChState); state_En <= Go_ChState; state_D <= "111" when (Go_ChState and not MaskStage)='1' else "010" when (Go_ChState and MaskStage)='1' else "ZZZ"; -- Mask Storage ------------------------------------------------------------ Mask(7 downto 0) <= MaskByte(0); Mask(15 downto 8) <= MaskByte(1); Mask(23 downto 16) <= MaskByte(2); Mask(31 downto 24) <= MaskByte(3); masksave : process (Clk, Rst, MaskStage, Go_Byte, Done_Byte, Done_CPLenL, MaskByteNum) begin if (Rst ='1' or InitGo='1') then MaskByteNum <= "00"; MaskStage <= '0'; DataStage <= '0'; for i in 3 downto 0 loop MaskByte(i) <= X"00"; end loop; else if falling_edge(Clk) then if Done_CPLenL='1' then MaskStage <= '1'; elsif Go_Byte='1' and MaskByteNum="11" then MaskStage <= '0'; else MaskStage <= MaskStage; end if; if Done_Byte='1' then DataStage <= not MaskStage; end if; end if; if falling_edge(Clk) and (Go_Byte and not DataStage)='1' then MaskByteNum <= MaskByteNum + "01"; else MaskByteNum <= MaskByteNum; end if; if (MaskStage='1') then if falling_edge(Clk) and Done_Byte='1' then MaskByte(conv_integer(MaskByteNum)) <= Data; end if; else MaskByteNum <= MaskByteNum; end if; end if; end process; -- End of Mask Storage ----------------------------------------------------- -- shift through packet, reading byte by byte on Go_Byte ------------------- -- first 4 bytes being the input mask ------------------- uAutoRd: AutoRd port map (Clk, Rst, Go_Byte, Data, Done_Byte, TxRx_Go_uAutoRd, TxRx_RiW, TxRx_A, TxRx_Q, TxRx_Done); -- Voltage recording/setting section ------------------------------------- Go_LatchMSB <= Done_Byte and not ByteParity; r1: Reg8bit port map (Clk, Rst, Go_LatchMSB, Data, VoltDataMSB); WrVoltData <= Done_Byte and ByteParity and DataStage and Mask(conv_integer(Addr)); DACReg_En <= WrVoltData; DAC_iGo <= not WrVoltData; DAC_Addr <= Addr when WrVoltData='1' else "ZZZZZ"; -- VoltData <= VoltDataMSB (5 downto 0) & Data; -- DAC_D <= VoltData when (VoltData < DAC_Qmax) else DAC_Qmax; VoltData <= VoltDataMSB (5 downto 0) & Data; -- CensoredVoltData <= VoltData when LT(VoltData, DAC_Qmax) else DAC_Qmax; CensoredVoltData <= VoltData when (VoltData < DAC_Qmax) else DAC_Qmax; -- ensure the gain selection channel does not exceed ~5V -- (actual value set in ConfigParam component) -- GainMode <= VoltData when LT(VoltData, DAC_Q_GainModeChan) -- else DAC_Q_GainModeChan; GainMode <= VoltData when (VoltData < DAC_Q_GainModeChan) else DAC_Q_GainModeChan; DAC_D <= GainMode when Addr="10010" else CensoredVoltData; ------------------------------------------------------------------------- Addr <= Cnt(5 downto 1); ByteParity <= Cnt(0); --byte counter inside 2-byte word bookkeeping : process (Clk,Rst,Go_Byte) begin if Rst='1' or InitGo='1' then Cnt <= "000000"; EnCnt <='1'; else if DataStage='1' then --counter if falling_edge(Clk) and Go_Byte='1' then Cnt <= Cnt + ("00000" & EnCnt); end if; -- counter enable if rising_edge(Clk) then if Cnt="111111" then EnCnt <= '0'; else EnCnt <= '1'; end if; end if; end if; end if; end process; TxRx_Go <= TxRx_Go_RxInh2 or TxRx_Go_RxInh1 or TxRx_Go_uAutoRd or TxRx_Go_uPktSkip or TxRx_Go_uLen; -- db1 <= EnCnt; -- db2 <= Done_Byte; -- dbproc : process (Clk, Rst, Done_CPLenL) begin -- if Rst='1' then -- dbtmp <= '0'; -- else -- if falling_edge(Clk) and (Go_Byte and not DataStage) = '1' then -- dbtmp <= '1'; -- else -- dbtmp <= dbtmp; -- end if; -- end if; -- end process; end Behavioral;