Čeština / English
Login

SVN Repository / Prohlížení

Aktuální adresář: FITkit / trunk / fpga / ctrls / ide /

ide_pio_ctrl.vhd

   1  -- ide_ctrl.vhd : IDE Controler
   2  -- Copyright (C) 2009 Brno University of Technology,
   3  --                    Faculty of Information Technology
   4  -- Author(s): Stanislav Sigmund <xsigmu02 AT stud.fit.vutbr.cz>
   5  --
   6  -- LICENSE TERMS
   7  --
   8  -- Redistribution and use in source and binary forms, with or without
   9  -- modification, are permitted provided that the following conditions
  10  -- are met:
  11  -- 1. Redistributions of source code must retain the above copyright
  12  --    notice, this list of conditions and the following disclaimer.
  13  -- 2. Redistributions in binary form must reproduce the above copyright
  14  --    notice, this list of conditions and the following disclaimer in
  15  --    the documentation and/or other materials provided with the
  16  --    distribution.
  17  -- 3. All advertising materials mentioning features or use of this software
  18  --    or firmware must display the following acknowledgement:
  19  --
  20  --      This product includes software developed by the University of
  21  --      Technology, Faculty of Information Technology, Brno and its
  22  --      contributors.
  23  --
  24  -- 4. Neither the name of the Company nor the names of its contributors
  25  --    may be used to endorse or promote products derived from this
  26  --    software without specific prior written permission.
  27  --
  28  -- This software or firmware is provided ``as is'', and any express or implied
  29  -- warranties, including, but not limited to, the implied warranties of
  30  -- merchantability and fitness for a particular purpose are disclaimed.
  31  -- In no event shall the company or contributors be liable for any
  32  -- direct, indirect, incidental, special, exemplary, or consequential
  33  -- damages (including, but not limited to, procurement of substitute
  34  -- goods or services; loss of use, data, or profits; or business
  35  -- interruption) however caused and on any theory of liability, whether
  36  -- in contract, strict liability, or tort (including negligence or
  37  -- otherwise) arising in any way out of the use of this software, even
  38  -- if advised of the possibility of such damage.
  39  --
  40  -- $Id$
  41  --
  42  --
  43  
  44  library ieee;
  45  use ieee.std_logic_1164.all;
  46  use ieee.std_logic_arith.all;
  47  use ieee.std_logic_unsigned.all;
  48  
  49  entity IDE_ctrl is
  50        generic (
  51           CLK_PERIOD  : integer := 20
  52        );
  53     port (
  54        -- Reset a synchronizace
  55        IDE     : inout std_logic_vector(45 downto 1) := (others => 'Z');
  56        CLK     : in std_logic; -- Hodiny radice (min. 4x vetsi, nez hodiny SPI)
  57        RST			:	in std_logic; -- RESET radice
  58        INTRQ		:	out std_logic;	-- Zadost o preruseni
  59  
  60        -- Interni rozhrani
  61        DI      : out std_logic;   -- Serial data out (MOSI)
  62        DI_REQ  : in std_logic;   -- DI request
  63        DO      : in std_logic;   -- Serial data in (MISO)
  64        DO_VLD  : in std_logic;   -- DO valid
  65        CS      : in std_logic    -- internal SPI active
  66     );
  67  end IDE_ctrl;
  68  
  69  architecture basic of IDE_ctrl is
  70  -- system casovani, zatim se pocita s PIO 0
  71  -- ior/iow ma byt nahozen az za 70 ns po platne adrese
  72  constant IORW_VALID : integer := 70 / CLK_PERIOD + 1; -- 4
  73  -- ior/iow ma drzet nejmene 290 ns (pro 8-bitovy rezim...)
  74  constant IORW_HOLD : integer := 290 / CLK_PERIOD; -- 14
  75  -- po shozeni iow maji byt data pritomna jeste min. 30 ns
  76  constant IOW_HOLD : integer := 30 / CLK_PERIOD + 1; -- 2
  77  -- po shozeni ior jsou data pritomna jeste 5ns - shodime ior pozdeji
  78  constant IOR_HOLD : integer := 5 / CLK_PERIOD + 1; -- 1
  79  
  80  constant IO_DELAY : integer := (IORW_HOLD + IORW_VALID + IOW_HOLD + 2);
  81  subtype tcntr is integer range 0 to (IORW_HOLD + 1);
  82  signal  delcntr : tcntr := 0; -- pocitadlo casovani
  83  signal  delcntr_rst : std_logic := '1'; -- povoleni pocitadla
  84      -- datove vodice d15 - d0:
  85  type    RWstate is (SIdle,SRAVld,SWAVld,SIowHold,SIorHold,SWHold,SRHold);
  86  signal  pstate    : RWstate := SIdle; -- actual state
  87  signal  nstate    : RWstate := SIdle; -- next state
  88  signal  cmp_avld : std_logic;
  89  signal  cmp_rwhold : std_logic;
  90  signal  cmp_rhold : std_logic;
  91  signal  cmp_whold : std_logic;
  92  -- signal  cmp_state_ch : std_logic;
  93  signal  state_ch : std_logic;
  94  
  95  
  96  signal  data    : std_logic_vector(15 downto 0) := (others => 'Z');
  97  signal  data_in  : std_logic_vector(16 downto 0);
  98  signal  data_in_valid : std_logic := '0';
  99  signal  data_out_buff : std_logic_vector(15 downto 0);
 100  signal  data_out : std_logic_vector(16 downto 0);
 101  signal  data_out_ready   : std_logic := '0';
 102  signal  iow     : std_logic := '1'; -- zapis na disk
 103  signal  ior     : std_logic := '1'; -- cteni z disku
 104  signal  read_data     : std_logic; -- chceme cist data
 105  signal  write_data    : std_logic; -- chceme zapsat data
 106  signal  ctrl_out : std_logic_vector(8 downto 0) := (others => '0');
 107  signal  ctrl_in : std_logic_vector(8 downto 0) := (others => '0');
 108  signal  ctrl_adc_out : std_logic_vector(8 downto 0) := (others => 'Z');
 109  signal  ctrl_write    : std_logic; -- chceme zapsat ridici bity
 110     -- adresace registru v disku, vyvody CS1, CS0, DA2, DA1, DA0
 111  signal  reg_addr: std_logic_vector(4 downto 0);
 112  signal  buff_addr: std_logic_vector(4 downto 0);
 113  signal  reg_adc_addr: std_logic_vector(4 downto 0);
 114  signal  reg_addr_ready : std_logic := '0';
 115  
 116     component SPI_adc
 117        generic (
 118           ADDR_WIDTH : integer;
 119           DATA_WIDTH : integer;
 120           ADDR_OUT_WIDTH : integer;
 121           BASE_ADDR  : integer;
 122           DELAY  : integer
 123        );
 124        port (
 125           CLK      : in  std_logic;
 126  
 127           CS       : in  std_logic;
 128           DO       : in  std_logic;
 129           DO_VLD   : in  std_logic;
 130           DI       : out std_logic;
 131           DI_REQ   : in  std_logic;
 132  
 133           ADDR     : out  std_logic_vector(ADDR_OUT_WIDTH-1 downto 0);
 134           DATA_OUT : out  std_logic_vector(DATA_WIDTH-1 downto 0);
 135           DATA_IN  : in   std_logic_vector(DATA_WIDTH-1 downto 0);
 136  
 137           WRITE_EN : out  std_logic;
 138           READ_EN  : out  std_logic
 139        );
 140     end component;
 141  
 142  begin
 143  -- datove vodice
 144  
 145  idec: for i in 0 to 7 generate
 146   IDE(23+2*i) <= data(i);
 147   IDE(36-2*i) <= data(i+8);
 148  end generate;
 149  
 150  data <= data_out_buff when data_out_ready = '1' else (others => 'Z');
 151  
 152  -- IDE(13) = IORDY
 153  INTRQ <= IDE(9);
 154  
 155  IDE(39) <= ctrl_out(0); -- RESET-
 156  ctrl_in <= (others => '0');
 157     -- zemnici vodice
 158  IDE(38) <= '0';IDE(21) <= '0';IDE(18) <= '0';IDE(16) <= '0';
 159  IDE(14) <= '0';IDE(10) <= '0';-- IDE(0) <= '0';
 160  
 161  cmp_avld <= '1' when (delcntr = IORW_VALID) else '0';
 162  cmp_rwhold <= '1' when (delcntr = IORW_HOLD) else '0';
 163  cmp_rhold <= '1' when (delcntr = IOR_HOLD) else '0';
 164  cmp_whold <= '1' when (delcntr = IOW_HOLD) else '0';
 165  -- cmp_state_ch <= '0' when (pstate = nstate) else '1';
 166  
 167  IDE(2) <= reg_addr(4);IDE(3) <= reg_addr(3);
 168  IDE(4) <= reg_addr(2);IDE(7) <= reg_addr(1);
 169  IDE(5) <= reg_addr(0); -- cs1, cs0, da2, da1, da0
 170  reg_addr <= buff_addr when reg_addr_ready = '1' else "11000";
 171  
 172  IDE(17) <= iow;
 173  IDE(15) <= ior;
 174  
 175  -- nezapojene vyvody
 176  -- DASP- DIAG- IOCS16- DMACK- CSEL
 177  IDE(1) <= 'Z';IDE(6) <= 'Z';IDE(8) <= 'Z';IDE(11) <= 'Z';IDE(12) <= 'Z';
 178  -- IORDY DMARQ keypin_20, nic
 179  IDE(13) <= 'Z';IDE(19) <= 'Z';IDE(20) <= 'Z';IDE(40) <= 'Z';IDE(41) <= 'Z';
 180  -- nic nic nic nic
 181  IDE(42) <= 'Z';IDE(43) <= 'Z';IDE(44) <= 'Z';IDE(45) <= 'Z';
 182  
 183     SPI_adc_data: SPI_adc
 184        generic map(
 185           ADDR_WIDTH => 7,
 186           DATA_WIDTH => 17,
 187           ADDR_OUT_WIDTH => 5,
 188           BASE_ADDR  => 16#00#,
 189           DELAY  => IO_DELAY
 190        )
 191        port map(
 192           CLK      => CLK,
 193  
 194           CS       => CS,
 195           DO       => DO,
 196           DO_VLD   => DO_VLD,
 197           DI       => DI,
 198           DI_REQ   => DI_REQ,
 199  
 200           ADDR     => reg_adc_addr,
 201           DATA_IN  => data_in,
 202           READ_EN  => read_data,
 203  
 204           DATA_OUT => data_out,
 205           WRITE_EN => write_data
 206        );
 207  
 208     SPI_adc_ctrl: SPI_adc
 209        generic map(
 210           ADDR_WIDTH => 7,
 211           DATA_WIDTH => 9,
 212           ADDR_OUT_WIDTH => 1,
 213           BASE_ADDR  => 16#20#,
 214           DELAY => 0
 215        )
 216        port map(
 217           CLK      => CLK,
 218  
 219           CS       => CS,
 220           DO       => DO,
 221           DO_VLD   => DO_VLD,
 222           DI       => DI,
 223           DI_REQ   => DI_REQ,
 224  
 225           ADDR     => open,
 226           DATA_IN  => ctrl_in,
 227           READ_EN  => open,
 228  
 229           DATA_OUT => ctrl_adc_out,
 230           WRITE_EN => ctrl_write
 231        );
 232     data_store: process(CLK)
 233     begin
 234        if CLK'event and CLK = '1' then
 235        	if write_data = '1' then
 236        		data_out_buff <= data_out(15 downto 0);
 237  				end if;
 238        end if;
 239     end process;
 240  
 241     data_in_store: process(CLK)
 242     begin
 243        if CLK'event and CLK = '1' then
 244        	if data_in_valid = '1' then
 245        		data_in <= '0' & data;
 246  				end if;
 247        end if;
 248     end process;
 249  
 250     addr_store: process(CLK)
 251     begin
 252        if CLK'event and CLK = '1' then
 253        	if (read_data = '1') or (write_data = '1') then
 254        		buff_addr <= reg_adc_addr;
 255  				end if;
 256        end if;
 257     end process;
 258  
 259     ctrl_set: process(CLK,RST)
 260     begin
 261    		if RST = '1' then
 262  			  ctrl_out <= (others => '0');
 263  			elsif CLK'event and CLK = '1' then
 264           if ctrl_write = '1' then
 265           	ctrl_out <= ctrl_adc_out;
 266           end if;
 267        end if;
 268     end process;
 269  
 270     rw_tick: process(CLK,RST)
 271     begin
 272    		if RST = '1' then
 273    			pstate <= SIdle;
 274        elsif CLK'event and CLK = '1' then
 275  				pstate <= nstate;
 276        end if;
 277     end process;
 278  
 279     del_tick: process(CLK,delcntr_rst)
 280     begin
 281    		if delcntr_rst = '1' then
 282    			delcntr <= 0;
 283        elsif CLK'event and CLK = '1' then
 284        	if state_ch = '1' then
 285        		delcntr <= 0;
 286        	else
 287  					delcntr <= delcntr + 1;
 288  	      end if;
 289        end if;
 290     end process;
 291  
 292     rw_FSA: process(pstate,cmp_avld,cmp_rwhold,cmp_rhold,cmp_whold,read_data,write_data)
 293     begin
 294  	   	state_ch <= '0';
 295        case pstate is
 296          --RW Idle
 297          when SIdle =>
 298  		   		nstate <= SIdle;
 299          	if read_data = '1' then
 300  	       		nstate <= SRAVld;
 301  				   	state_ch <= '1';
 302  	       	elsif write_data = '1' then
 303  	       		nstate <= SWAVld;
 304  				   	state_ch <= '1';
 305  	       	end if;
 306          when SRAVld =>
 307         		nstate <= SRAVld;
 308          	if (cmp_avld = '1') then
 309          		nstate <= SIorHold;
 310  				   	state_ch <= '1';
 311          	end if;
 312          when SWAVld =>
 313         		nstate <= SWAVld;
 314          	if (cmp_avld = '1') then
 315          		nstate <= SIowHold;
 316  				   	state_ch <= '1';
 317          	end if;
 318          when SIorHold =>
 319         		nstate <= SIorHold;
 320          	if (cmp_rwhold = '1') then
 321          		nstate <= SRHold;
 322  				   	state_ch <= '1';
 323          	end if;
 324          when SIowHold =>
 325         		nstate <= SIowHold;
 326          	if (cmp_rwhold = '1') then
 327          		nstate <= SWHold;
 328  				   	state_ch <= '1';
 329          	end if;
 330          when SRHold =>
 331         		nstate <= SRHold;
 332          	if (cmp_rhold = '1') then
 333          		nstate <= SIdle;
 334  				   	state_ch <= '1';
 335          	end if;
 336          when SWHold =>
 337         		nstate <= SWHold;
 338          	if (cmp_whold = '1') then
 339          		nstate <= SIdle;
 340  				   	state_ch <= '1';
 341          	end if;
 342       end case;
 343     end process;
 344  
 345     rw_logic: process(pstate)
 346     begin
 347        data_out_ready <= '0';
 348        ior <= '1';
 349        iow <= '1';
 350        data_in_valid <= '0';
 351        reg_addr_ready <= '1';
 352        delcntr_rst <= '0';
 353        case pstate is
 354          --RW Idle
 355          when SIdle =>
 356  		      delcntr_rst <= '1';
 357  		      reg_addr_ready <= '0';
 358          when SRAVld =>
 359          when SWAVld =>
 360          when SIorHold =>
 361  		      ior <= '0';
 362  		      data_in_valid <= '1';
 363          when SIowHold =>
 364  		      iow <= '0';
 365            data_out_ready <= '1';
 366          when SRHold =>
 367          when SWHold =>
 368            data_out_ready <= '1';
 369       end case;
 370     end process;
 371  
 372  end basic;
 373  
Zobrazeno: 679816x Naposledy: 28.6.2022 21:25:54