LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; -- Design hierarchy -- top -- | -- |\_____ shreg -- | -- |\_____ hamming_dec_dmem -- | -- \_____ treg -- last modified: 21:05 / 14-Mai-2006 / V.Angelov -- additional comments 16-May-2006 J. Steckert -- Changes: -- I2C register 0..3 are updated first internally, only after writing to the 4-th register all -- new values appear at the output of the I2C slave module. -- The toggle block has to implementations : with registers and with gates. As now I2C needs more -- DFFs, the gate-option is the only possible. The clock to the toggle block is divided by 2 SSTR or -- LCLK, therefore it is symmetrical already. -- last modified: 10:14 / 24-Mai-2006 / V.Angelov ------------------------------------------------------------------------------------------------ --ENTITY ------------------------------------------------------------------------------------------------ entity top_old is --description of the outerconnections of the design port ( --Local clock (for debugging) LCLK : in std_logic; --reset (used as power on reset) rst : in std_logic; -- mode selector to configure the chip -- mode_sel(0) is 1/0 for with/without hamming -- mode_sel(1) is 1/0 for I2C/SPI -- mode_sel(2) is 1/0 for cont. clock or serial clock -- mode_sel(3) is 1/0 for Dmode/toggle mode mode_sel : in std_logic_vector(3 downto 0); oddeven : in std_logic; -- I2C to other slave devices scl_out : out std_logic; sda_bidir : inout std_logic; -- SPI/I2C SSTR : inout std_logic; -- SSTR input for SPI or data back to --I2C master freq = 300Hz SDIN : in std_logic; -- data in in both cases freq = 10kHz SCLK : in std_logic; -- clock in both cases freq = 10kHz -- SPI out gives out the serial data, for debugging purposes SDOU : out std_logic; --serial data out SDOUT : out std_logic; --3 spare signals for further use SOUT0 : out std_logic; --hm0 SOUT1 : out std_logic; --hm1 SOUT2 : out std_logic; --not s -- hamming state state_hm : out std_logic_vector( 1 downto 0); --parallel data out (drives the rectifier channels) MOSgt : out std_logic_vector(30 downto 1) ); end top_old; ------------------------------------------------------------------------------------------------ -- ARCHITECTURE ------------------------------------------------------------------------------------------------ architecture a of top_old is --shift register component shreg is generic(N : Integer := 24); port( rst_n : in std_logic; SCLK : in std_logic; SDIN : in std_logic; SSTR : in std_logic; SDOUT : out std_logic; SDOUT7s : out std_logic; PAROUT : out std_logic_vector(N downto 1) ); end component; --togle register output is toggled with 10kHz --input data arrives with 300Hz --generates the ac signal for the recitfiers component treg is generic(N : Integer := 24; regmode : Integer := 0); port( rst_n : in std_logic; CLK : in std_logic; D : in std_logic_vector(N downto 1); Dmode : in std_logic; oddeven : in std_logic; Q : out std_logic_vector(N downto 1) ); end component; --clock buffer component CLKBUF is port( PAD : in std_logic; Y : out std_logic ); end component; component CLKINT is port( A : in std_logic; Y : out std_logic ); end component; --hamming decoder component hamming_dec_dmem is port ( din : in std_logic_vector (38 downto 0); -- data from data memory dout : out std_logic_vector (31 downto 0); -- data to CPU state : out std_logic_vector ( 1 downto 0) ); end component; --i2c slave component top_i2c is generic (version : integer range 0 to 255 := 1); port ( clk_t : in std_logic; reset_t : in std_logic; -- active high -- I2C Takt und Daten (SDA ist open Drain) scl_t : in std_logic; sda_in : in std_logic; sda_out : out std_logic; -- Multiplexer- Eingänge I_5_t : in std_logic_vector(7 downto 0); I_6_t : in std_logic_vector(7 downto 0); -- Output- Register rg0q : out std_logic_vector(7 downto 0); rg1q : out std_logic_vector(7 downto 0); rg2q : out std_logic_vector(7 downto 0); rg3q : out std_logic_vector(7 downto 0); rg4q : out std_logic_vector(7 downto 0) ); end component; constant use_clk_buff : Integer := 0; --signal definitions signal PAROUT_hi : std_logic_vector(39 downto 1); signal PAROUT_spi : std_logic_vector(39 downto 1); signal PAROUT : std_logic_vector(32 downto 1); signal PAROUT_ho : std_logic_vector(32 downto 1); signal PAROUT_I2C : std_logic_vector(40 downto 1); signal state_hm_i : std_logic_vector( 1 downto 0); signal state_hm_d : std_logic_vector( 1 downto 0); signal CLK : std_logic; signal Dmode : std_logic; signal SCLK_i : std_logic; signal rst_n : std_logic; signal scl : std_logic; signal sdain : std_logic; signal I_5_t : std_logic_vector(7 downto 0); -- not used signal I_6_t : std_logic_vector(7 downto 0); -- not used signal sda_out : std_logic; signal sda_out_i : std_logic; signal LCLKd2 : std_logic; -- signal SCLKd2 : std_logic; -- signal sdou_i : std_logic; signal sdou7s_i : std_logic; ---------------------------------------------------------------------------------- --portmapping and connecting the logical blocks BEGIN-- ---------------------------------------------------------------------------------- begin --negation of the reset signal rst_n <= not rst; --settings for using or omitting clock buffer cb: if use_clk_buff = 1 generate clkb: CLKBUF port map( PAD => SCLK, Y => SCLK_i ); end generate; ncb: if use_clk_buff /= 1 generate SCLK_i <= SCLK; end generate; -- shift register with serial/parallel load and shift sreg: shreg generic map(N => 39) port map( rst_n => rst_n, SCLK => SCLK_i, SDIN => SDIN, SSTR => SSTR, SDOUT => SDOU_i, SDOUT7s => sdou7s_i, PAROUT => PAROUT_spi ); ------------------------------------------------- --Settings for i2c/serial communication -- mode_sel(1) is 1/0 for I2C/SPI -- creates MUX to the input of the hamming decoder PAROUT_hi <= PAROUT_spi when mode_sel(1)='0' else PAROUT_I2C(39 downto 1); --if i2c SSTR is used as serial data output, otherwise tristate SSTR <= sda_out when mode_sel(1)='1' else 'Z'; ------------------------------------------------ --config of hamming decoder hmdec: hamming_dec_dmem port map( din => PAROUT_hi, dout => PAROUT_ho, state => state_hm_i ); -- when hamming is not used, the status outputs are cleared state_hm_d <= "00" when mode_sel(1)='1' else state_hm_i; -- update the status pins synchronously, to avoid glitches process(SCLK_i) begin if SCLK_i'event and SCLK_i='1' then state_hm <= state_hm_d; SOUT0 <=state_hm_d(0); SOUT1 <=state_hm_d(1); end if; end process; ------------------------------------ --Toggle between hamming or not -- mode_sel(0) is 1/0 for with/without hamming with mode_sel(0) select PAROUT <= PAROUT_hi(32 downto 1) when '0', PAROUT_ho(32 downto 1) when '1', (others => '-') when others; --toggles sdout if hamming is used or not with mode_sel(0) select SDOU <= sdou7s_i when '0', sdou_i when '1', '0' when others; --back channel always raw data output of srg SDOUT <= sdou_i; SOUT2 <= not sdou_i; ----------------------------------------------------------- --If local clock is enabled in hw it can be set by sending --parout31 and parout32 =1 serial clock if others -- slocal <= PAROUT(32) & mode_sel(2); CLK <= LCLKd2 when PAROUT(32)='1' and mode_sel(2)='1' else SCLKd2; -- --------------------------------------------------- --Toggle between dmode and toggle register -- mode_sel(3) is 1/0 for Dmode/toggle mode -- can be overridden by software if jumper is set -- Dmode <= PAROUT(31) and mode_sel(3); -- TFF or DFF array or just gating (if regmode=0) oreg: treg generic map(N => MOSgt'length, regmode => 0) port map( rst_n => rst_n, CLK => CLK, Dmode => Dmode, oddeven => oddeven, D => PAROUT(MOSgt'range), Q => MOSgt ); -------------------------------------------------------- --Clock divider to generate LCLKd2 process(LCLK, rst_n) begin if rst_n='0' then LCLKd2 <= '0'; elsif LCLK'event and LCLK='1' then LCLKd2 <= not LCLKd2; end if; end process; --Clock divider to generate SCLKd2 process(SCLK_i, rst_n) begin if rst_n='0' then SCLKd2 <= '0'; elsif SCLK_i'event and SCLK_i='1' then SCLKd2 <= not SCLKd2; end if; end process; ---------------------------------------------------------- --Configures the i2c decoder (slave) scl <= SCLK_i or not mode_sel(1); sdain <= SDIN or not mode_sel(1); ------------------------ --connecting i2c i2cs: top_i2c --generic (version : integer range 0 to 255 := 1); port map ( clk_t => LCLK, reset_t => rst, -- I2C Takt und Daten (SDA ist open Drain) scl_t => scl, sda_in => sdain, sda_out => sda_out_i, -- Multiplexer- Eingänge I_5_t => I_5_t, I_6_t => I_6_t, -- Output- Register rg0q => PAROUT_I2C( 8 downto 1), rg1q => PAROUT_I2C(16 downto 9), rg2q => PAROUT_I2C(24 downto 17), rg3q => PAROUT_I2C(32 downto 25), rg4q => PAROUT_I2C(40 downto 33) ); ------------------------ --???????????? unused input to 0 ? I_5_t <= (others => '0'); I_6_t <= (others => '0'); -- i2c to other slaves scl_out <= SCLK; sda_bidir <= '0' when SDIN='0' or sda_out_i='0' else 'Z'; -- open drain -- back to the master sda_out <= '0' when sda_out_i = '0' or sda_bidir='0' else '1'; end;