Čeština / English
Login

SVN Repository / Prohlížení

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

ide_dmach_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(25 downto 0) := (others => 'Z');
  56        CLK     : in std_logic; -- Hodiny radice (min. 4x vetsi, nez hodiny SPI)
  57        RST			:	in std_logic; -- RESET radice
  58  			-- DMA kanal
  59        READ_EN :	out std_logic;	-- Data z radice jsou pripraveny
  60        WRITE_EN:	out std_logic;	-- Radic pripraven prijimat data
  61        ACCEPT  :	in std_logic;	-- Data prijata/platna data na vstupu
  62        DATA_IN : in std_logic_vector(7 downto 0) := (others => '0');
  63        DATA_OUT: out std_logic_vector(7 downto 0) := (others => '0');
  64  
  65        -- Interni rozhrani
  66        DI      : out std_logic;   -- Serial data out (MOSI)
  67        DI_REQ  : in std_logic;   -- DI request
  68        DO      : in std_logic;   -- Serial data in (MISO)
  69        DO_VLD  : in std_logic;   -- DO valid
  70        CS      : in std_logic    -- internal SPI active
  71     );
  72  end IDE_ctrl;
  73  
  74  architecture basic of IDE_ctrl is
  75  -- system casovani, zatim se pocita s PIO 0
  76  -- ior/iow ma byt nahozen az za 70 ns po platne adrese
  77  constant IORW_VALID : integer := 70 / CLK_PERIOD + 1; -- 4
  78  -- ior/iow ma drzet nejmene 290 ns (pro 8-bitovy rezim...)
  79  constant IORW_HOLD : integer := 290 / CLK_PERIOD; -- 14
  80  -- po shozeni iow maji byt data pritomna jeste min. 30 ns
  81  constant IOW_HOLD : integer := 30 / CLK_PERIOD + 1; -- 2
  82  -- po shozeni ior jsou data pritomna jeste 5ns - shodime ior pozdeji
  83  constant IOR_HOLD : integer := 5 / CLK_PERIOD + 1; -- 1
  84  
  85  constant IO_DELAY : integer := (IORW_HOLD + IORW_VALID + IOW_HOLD + 2);
  86  subtype tcntr is integer range 0 to (IORW_HOLD + 1);
  87  signal  delcntr : tcntr := 0; -- pocitadlo casovani
  88  signal  delcntr_rst : std_logic := '1'; -- povoleni pocitadla
  89      -- datove vodice d15 - d0:
  90  type    RWstate is (SIdle,SRAVld,SWAVld,SIowHold,SIorHold,SWHold,SRHold);
  91  signal  pstate    : RWstate := SIdle; -- actual state
  92  signal  nstate    : RWstate := SIdle; -- next state
  93  signal  cmp_avld : std_logic;
  94  signal  cmp_rwhold : std_logic;
  95  signal  cmp_rhold : std_logic;
  96  signal  cmp_whold : std_logic;
  97  -- signal  cmp_state_ch : std_logic;
  98  signal  state_ch : std_logic;
  99  
 100  
 101  --signal  data_out_mux : std_logic_vector(15 downto 0);
 102  signal  data    : std_logic_vector(15 downto 0) := (others => 'Z');
 103  signal  Ddata_in  : std_logic_vector(16 downto 0);
 104  signal  data_in_valid : std_logic := '0';
 105  signal  data_out_buff : std_logic_vector(15 downto 0);
 106  signal  Ddata_out : std_logic_vector(16 downto 0);
 107  signal  data_out_ready   : std_logic := '0';
 108  signal  DmaRQ   : std_logic;
 109  signal  DmaACK   : std_logic := '1';
 110  signal  iow     : std_logic := '1'; -- zapis na disk
 111  signal  ior     : std_logic := '1'; -- cteni z disku
 112  signal  read_data     : std_logic; -- chceme cist data
 113  signal  write_data    : std_logic; -- chceme zapsat data
 114  signal  ctrl_out : std_logic_vector(7 downto 0) := (others => '0');
 115  signal  ctrl_in : std_logic_vector(7 downto 0) := (others => '0');
 116  signal  ctrl_adc_out : std_logic_vector(7 downto 0) := (others => 'Z');
 117  signal  ctrl_write    : std_logic; -- chceme zapsat ridici bity
 118     -- adresace registru v disku, vyvody CS1, CS0, DA2, DA1, DA0
 119  signal  reg_addr: std_logic_vector(4 downto 0);
 120  signal  buff_addr: std_logic_vector(4 downto 0);
 121  signal  reg_adc_addr: std_logic_vector(4 downto 0);
 122  signal  reg_addr_ready : std_logic := '0';
 123  signal  Ctrl_Reg  : std_logic_vector(1 downto 0) := (others => '0');
 124  
 125  constant DEL_DMA_RW0 : integer := 240 / CLK_PERIOD; -- 12
 126  constant DEL_DMA_HOLD0 : integer := 280 / CLK_PERIOD; -- 14
 127  constant DEL_DMA_WAIT0 : integer := 480 / CLK_PERIOD; -- 24
 128  constant DEL_DMA_RW1 : integer := 80 / CLK_PERIOD; -- 4
 129  constant DEL_DMA_HOLD1 : integer := (100+CLK_PERIOD-1) / CLK_PERIOD; -- 5
 130  constant DEL_DMA_WAIT1 : integer := (150+CLK_PERIOD-1) / CLK_PERIOD; -- 8
 131  
 132  
 133  signal  BSDOut  : std_logic_vector(7 downto 0);
 134  signal  BSDIn  : std_logic_vector(7 downto 0);
 135  signal  BSAdr  : std_logic_vector(10 downto 0);
 136  signal  BSWe : std_logic := '0';
 137  signal  BDAdr  : std_logic_vector(9 downto 0) := (others => '0');
 138  signal  BDWe : std_logic := '0';
 139  signal  BDOutEn : std_logic := '0';
 140  signal  BDOut  : std_logic_vector(15 downto 0);
 141  
 142  constant SPD_VALID : integer := (70+CLK_PERIOD-1) / CLK_PERIOD; -- 4
 143  constant SPD_HOLD : integer := 360 / CLK_PERIOD; -- 18
 144  constant SPD_WAIT : integer := (390+CLK_PERIOD-1) / CLK_PERIOD; -- 20
 145  
 146  signal  spd_addr_en : std_logic := '0';
 147  signal  spd_out  : std_logic_vector(7 downto 0);
 148  signal  spd_addr  : std_logic_vector(4 downto 0);
 149  signal  spd_addr_buff  : std_logic_vector(4 downto 0);
 150  signal  spd_out_buff  : std_logic_vector(7 downto 0);
 151  signal  write_spd : std_logic := '0';
 152  signal  spd_en : std_logic := '0';
 153  signal  spd_iow : std_logic := '1';
 154  signal  SpdCnt : std_logic_vector(5 downto 0) := (others => '0');
 155  type    Spdstate is (SIdle,SVal,SHold,SWait);
 156  signal  pSstate    : Spdstate := SIdle; -- actual state
 157  signal  nSstate    : Spdstate := SIdle; -- next state
 158  signal  spdcmpval : std_logic := '0';
 159  signal  spdcmphold : std_logic := '0';
 160  signal  spdcmpwait : std_logic := '0';
 161  
 162  signal  DmaRun : std_logic := '0';
 163  signal  NDmaRun : std_logic := '1';
 164  signal  DmaRst : std_logic := '1';
 165  signal  DmaCtrlW  : std_logic := '0';
 166  signal  DmaBlock  : std_logic_vector(1 downto 0) := (others => '0');
 167  signal  DmaIRW : std_logic := '0';
 168  signal  DMA_Cnt_Rst : std_logic := '1';
 169  signal  DmaInc : std_logic := '0';
 170  signal  cmpDmaHold : std_logic := '0';
 171  signal  cmpDmaWait : std_logic := '0';
 172  signal  cmpDmaRW : std_logic := '0';
 173  signal  DmaEnd : std_logic := '0';
 174  signal  spd_res : std_logic := '0';
 175  signal  DmaCnt : std_logic_vector(5 downto 0) := (others => '0');
 176  signal  DmaSpd : std_logic := '0';
 177  signal  DmaDir : std_logic := '0';
 178  signal  NDmaDir   : std_logic := '1';
 179  type    DMAstate is (SIdle,SRun,SWR,SHold,SWait);
 180  signal  pDstate    : DMAstate := SIdle; -- actual state
 181  signal  nDstate    : DMAstate := SIdle; -- next state
 182  signal  BDOutWr : std_logic := '0';
 183  
 184  signal  ch_next  : std_logic := '0';
 185  signal  ch_first : std_logic := '0';
 186  signal  ch_run   : std_logic := '0';
 187  signal  ch_dir   : std_logic := '0';
 188  signal  br_wr    : std_logic := '0';
 189  signal  ch_addr  : std_logic_vector(10 downto 0) := (others => '0');
 190  signal  ch_dst   : std_logic_vector(10 downto 0) := (others => '0');
 191  signal  br_addr  : std_logic_vector(10 downto 0) := (others => '0');
 192  signal  cmp_ch   : std_logic := '0';
 193  signal  ch_out_b : std_logic_vector(7 downto 0) := (others => '0');
 194  signal  br_in    : std_logic_vector(7 downto 0) := (others => '0');
 195  signal  CH_wr_en : std_logic := '0';
 196  type    CHstate is (sStart,SwRead,SRead,SWrite);
 197  signal  pCstate    : CHstate := sStart; -- actual state
 198  signal  nCstate    : CHstate := sStart; -- next state
 199  signal  ch_out    : std_logic_vector(23 downto 0) := (others => '0');
 200  signal  ch_wr : std_logic := '0';
 201  signal  ch_accept : std_logic := '0';
 202  signal  ch_in     : std_logic_vector(23 downto 0) := (others => '0');
 203  
 204     component SPI_adc
 205        generic (
 206           ADDR_WIDTH : integer;
 207           DATA_WIDTH : integer;
 208           ADDR_OUT_WIDTH : integer;
 209           BASE_ADDR  : integer;
 210           DELAY  : integer
 211        );
 212        port (
 213           CLK      : in  std_logic;
 214  
 215           CS       : in  std_logic;
 216           DO       : in  std_logic;
 217           DO_VLD   : in  std_logic;
 218           DI       : out std_logic;
 219           DI_REQ   : in  std_logic;
 220  
 221           ADDR     : out  std_logic_vector(ADDR_OUT_WIDTH-1 downto 0);
 222           DATA_OUT : out  std_logic_vector(DATA_WIDTH-1 downto 0);
 223           DATA_IN  : in   std_logic_vector(DATA_WIDTH-1 downto 0);
 224  
 225           WRITE_EN : out  std_logic;
 226           READ_EN  : out  std_logic
 227        );
 228     end component;
 229  
 230     for SPI_adc_data: SPI_adc use entity work.SPI_adc(autoincrement);
 231     for SPI_adc_spd: SPI_adc use entity work.SPI_adc(autoincrement);
 232  
 233     component RAMB16_S9_S18
 234     port (
 235        DIA   : in  std_logic_vector(7 downto 0);   -- DATA IN
 236        DIPA  : in  std_logic_vector(0 downto 0);    -- DATA IN PARITY
 237        ADDRA : in  std_logic_vector(10 downto 0);    -- ADDRESS
 238        ENA   : in  std_logic;                       -- ENABLE
 239        WEA   : in  std_logic;                       -- WRITE ENABLE
 240        SSRA  : in  std_logic;                       -- SET/RESET
 241        CLKA  : in  std_logic;                       -- CLK
 242        DOA   : out std_logic_vector(7 downto 0);   -- DATA OUT
 243        DOPA  : out std_logic_vector(0 downto 0);     -- DATA OUT PARITY
 244  
 245        DIB   : in  std_logic_vector(15 downto 0);   -- DATA IN
 246        DIPB  : in  std_logic_vector(1 downto 0);    -- DATA IN PARITY
 247        ADDRB : in  std_logic_vector(9 downto 0);    -- ADDRESS
 248        ENB   : in  std_logic;                       -- ENABLE
 249        WEB   : in  std_logic;                       -- WRITE ENABLE
 250        SSRB  : in  std_logic;                       -- SET/RESET
 251        CLKB  : in  std_logic;                       -- CLK
 252        DOB   : out std_logic_vector(15 downto 0);   -- DATA OUT
 253        DOPB  : out std_logic_vector(1 downto 0)    -- DATA OUT PARITY
 254     );
 255     end component;
 256  
 257  begin
 258  -- 0-15 data
 259  -- 16 RESET
 260  -- 17 IOW
 261  -- 18 IOR
 262  -- 19-23 DA0 DA1 DA2 CS0 CS1
 263  -- 24 DMARQ
 264  -- 25 DMAACK
 265  -- datove vodice
 266  idec: for i in 0 to 15 generate
 267   IDE(i) <= data(i);
 268  end generate;
 269  
 270  -- adresni vodice
 271  iaddr: for i in 0 to 4 generate
 272   IDE(19+i) <= reg_addr(i);
 273  end generate;
 274  
 275  DmaRQ <= IDE(24);IDE(25) <= DmaACK;
 276  BDOutWr <= '1' when (BDOutEn = '1' AND DmaDir = '1') else '0';
 277  
 278  data <= data_out_buff when data_out_ready='1' else
 279  				("00000000" & spd_out_buff) when spd_en='1' else
 280        	BDOut when BDOutWr='1' else
 281  				(others => 'Z');
 282  
 283  --data_out_mux <= BDOut when (BDOutWr = '1') else data_out_buff;
 284  --data <= data_out_mux when (data_out_ready = '1' OR BDOutWr = '1') else (others => 'Z');
 285  
 286  IDE(16) <= ctrl_out(0); -- RESET-
 287  ctrl_in <= DmaRun & DmaRQ & DmaSpd & DmaDir & "00" & DmaBlock(1 downto 0) when (Ctrl_Reg = "01") else
 288  DmaACK & DmaRQ & DmaIRW & reg_addr(4 downto 0);
 289  
 290  cmp_avld <= '1' when (delcntr = IORW_VALID) else '0';
 291  cmp_rwhold <= '1' when (delcntr = IORW_HOLD) else '0';
 292  cmp_rhold <= '1' when (delcntr = IOR_HOLD) else '0';
 293  cmp_whold <= '1' when (delcntr = IOW_HOLD) else '0';
 294  -- cmp_state_ch <= '0' when (pstate = nstate) else '1';
 295  
 296  reg_addr <= buff_addr when (reg_addr_ready = '1') else
 297    spd_addr_buff when (spd_addr_en = '1') else "11000";
 298  
 299  NDmaDir <= '1' when (DmaDir = '0') else '0';
 300  IDE(17) <= (iow AND spd_iow) when (DmaIRW='0') else NDmaDir;
 301  IDE(18) <= ior when (DmaIRW='0') else DmaDir;
 302  
 303     SPI_adc_cmd: SPI_adc
 304        generic map(
 305           ADDR_WIDTH => 15,
 306           DATA_WIDTH => 17,
 307           ADDR_OUT_WIDTH => 5,
 308           BASE_ADDR  => 16#0180#,
 309           DELAY  => IO_DELAY
 310        )
 311        port map(
 312           CLK      => CLK,
 313  
 314           CS       => CS,
 315           DO       => DO,
 316           DO_VLD   => DO_VLD,
 317           DI       => DI,
 318           DI_REQ   => DI_REQ,
 319  
 320           ADDR     => reg_adc_addr,
 321           DATA_IN  => Ddata_in,
 322           READ_EN  => read_data,
 323  
 324           DATA_OUT => Ddata_out,
 325           WRITE_EN => write_data
 326        );
 327  
 328     SPI_adc_spd: SPI_adc
 329        generic map(
 330           ADDR_WIDTH => 16,
 331           DATA_WIDTH => 8,
 332           ADDR_OUT_WIDTH => 5,
 333           BASE_ADDR  => 16#0000#,
 334           DELAY  => 0
 335        )
 336        port map(
 337           CLK      => CLK,
 338  
 339           CS       => CS,
 340           DO       => DO,
 341           DO_VLD   => DO_VLD,
 342           DI       => DI,
 343           DI_REQ   => DI_REQ,
 344  
 345           ADDR     => spd_addr,
 346           DATA_IN  => "00000000",
 347           READ_EN  => open,
 348  
 349           DATA_OUT => spd_out,
 350           WRITE_EN => write_spd
 351        );
 352  
 353     SPI_adc_ctrl: SPI_adc
 354        generic map(
 355           ADDR_WIDTH => 8,
 356           DATA_WIDTH => 8,
 357           ADDR_OUT_WIDTH => 2,
 358           BASE_ADDR  => 16#04#,
 359           DELAY => 1
 360        )
 361        port map(
 362           CLK      => CLK,
 363  
 364           CS       => CS,
 365           DO       => DO,
 366           DO_VLD   => DO_VLD,
 367           DI       => DI,
 368           DI_REQ   => DI_REQ,
 369  
 370           ADDR     => Ctrl_Reg,
 371           DATA_IN  => ctrl_in,
 372           READ_EN  => open,
 373  
 374           DATA_OUT => ctrl_adc_out,
 375           WRITE_EN => ctrl_write
 376        );
 377  
 378     SPI_adc_data: SPI_adc
 379        generic map(
 380           ADDR_WIDTH => 16,
 381           DATA_WIDTH => 8,
 382           ADDR_OUT_WIDTH => 11,
 383           BASE_ADDR  => 16#0800#,
 384           DELAY => 1
 385        )
 386        port map(
 387           CLK      => CLK,
 388  
 389           CS       => CS,
 390           DO       => DO,
 391           DO_VLD   => DO_VLD,
 392           DI       => DI,
 393           DI_REQ   => DI_REQ,
 394  
 395           ADDR     => BSAdr,
 396           DATA_IN  => BSDIn,
 397           READ_EN  => open,
 398  
 399           DATA_OUT => BSDOut,
 400           WRITE_EN => BSWe
 401        );
 402  
 403  WRITE_EN <= CH_wr_en;
 404  br_in <= BSDOut when ch_run='0' else DATA_IN;
 405  br_addr <= BSAdr when ch_run='0' else ch_addr;
 406  br_wr <= BSWe when ch_run='0' else (ACCEPT and CH_wr_en);
 407  
 408     BUF: RAMB16_S9_S18
 409     port map(
 410        DIA   => br_in,
 411        DIPA  => "0",
 412        ADDRA => br_addr,
 413        ENA   => '1',
 414        WEA   => br_wr,
 415        SSRA  => '0',
 416        CLKA  => CLK,
 417        DOA   => BSDIn,
 418        DOPA  => open,
 419  
 420        DIB   => data,
 421        DIPB  => "00",
 422        ADDRB => BDAdr,
 423        ENB   => '1',
 424        WEB   => BDWe,
 425        SSRB  => '0',
 426        CLKB  => CLK,
 427        DOB   => BDOut,
 428        DOPB  => open
 429     );
 430  
 431  spdcmpval <= '1' when (SpdCnt = SPD_VALID) else '0';
 432  spdcmphold <= '1' when (SpdCnt = SPD_HOLD) else '0';
 433  spdcmpwait <= '1' when (SpdCnt = SPD_WAIT) else '0';
 434  
 435     spd_addr_store: process(CLK)
 436     begin
 437        if CLK'event and CLK = '1' then
 438        	if write_spd = '1' then
 439        		spd_addr_buff <= spd_addr;
 440        		spd_out_buff <= spd_out;
 441  				end if;
 442        end if;
 443     end process;
 444  
 445     spd_cnt: process(CLK,spd_res)
 446     begin
 447     		if spd_res = '1' then
 448     			SpdCnt <= (others => '0');
 449     		elsif CLK'event and CLK = '1' then
 450       		SpdCnt <= SpdCnt + 1;
 451        end if;
 452     end process;
 453  
 454     spd_tick: process(CLK,RST)
 455     begin
 456    		if RST = '1' then
 457    			pSstate <= SIdle;
 458        elsif CLK'event and CLK = '1' then
 459  				pSstate <= nSstate;
 460        end if;
 461     end process;
 462  
 463     spd_FSA: process(pSstate,spdcmpval,spdcmphold,spdcmpwait,write_spd)
 464     begin
 465        case pSstate is
 466          when SIdle =>
 467  		   		nSstate <= SIdle;
 468          	if write_spd = '1' then
 469  	       		nSstate <= SVal;
 470  	       	end if;
 471          when SVal =>
 472         		nSstate <= SVal;
 473          	if (spdcmpval = '1') then
 474          		nSstate <= SHold;
 475          	end if;
 476          when SHold =>
 477        		nSstate <= SHold;
 478          	if (spdcmphold = '1') then
 479          		nSstate <= SWait;
 480          	end if;
 481          when SWait =>
 482         		nSstate <= SWait;
 483          	if (spdcmpwait = '1') then
 484          		nSstate <= SIdle;
 485          	end if;
 486       end case;
 487     end process;
 488  
 489     spd_logic: process(pSstate)
 490     begin
 491     		spd_addr_en <= '0';
 492     		spd_en <= '0';
 493     		spd_iow <= '1';
 494     		spd_res <= '0';
 495        case pSstate is
 496          when SIdle =>
 497  		   		spd_res <= '1';
 498          when SVal =>
 499     				spd_addr_en <= '1';
 500          when SHold =>
 501     				spd_addr_en <= '1';
 502     				spd_iow <= '0';
 503     				spd_en <= '1';
 504          when SWait =>
 505     				spd_en <= '1';
 506     				spd_addr_en <= '1';
 507       end case;
 508     end process;
 509  
 510  -- ******** normal *******
 511  
 512     data_store: process(CLK)
 513     begin
 514        if CLK'event and CLK = '1' then
 515        	if write_data = '1' then
 516        		data_out_buff <= Ddata_out(15 downto 0);
 517  				end if;
 518        end if;
 519     end process;
 520  
 521     data_in_store: process(CLK)
 522     begin
 523        if CLK'event and CLK = '1' then
 524        	if data_in_valid = '1' then
 525        		Ddata_in <= '0' & data;
 526  				end if;
 527        end if;
 528     end process;
 529  
 530     addr_store: process(CLK)
 531     begin
 532        if CLK'event and CLK = '1' then
 533        	if (read_data = '1') or (write_data = '1') then
 534        		buff_addr <= reg_adc_addr;
 535  				end if;
 536        end if;
 537     end process;
 538  
 539     ctrl_set: process(CLK,RST)
 540     begin
 541    		if RST = '1' then
 542  			  ctrl_out <= (others => '0');
 543  			elsif CLK'event and CLK = '1' then
 544           if ctrl_write = '1' AND Ctrl_Reg = "00" then
 545           	ctrl_out <= ctrl_adc_out;
 546           end if;
 547        end if;
 548     end process;
 549  
 550     rw_tick: process(CLK,RST)
 551     begin
 552    		if RST = '1' then
 553    			pstate <= SIdle;
 554        elsif CLK'event and CLK = '1' then
 555  				pstate <= nstate;
 556        end if;
 557     end process;
 558  
 559     del_tick: process(CLK,delcntr_rst)
 560     begin
 561    		if delcntr_rst = '1' then
 562    			delcntr <= 0;
 563        elsif CLK'event and CLK = '1' then
 564        	if state_ch = '1' then
 565        		delcntr <= 0;
 566        	else
 567  					delcntr <= delcntr + 1;
 568  	      end if;
 569        end if;
 570     end process;
 571  
 572     rw_FSA: process(pstate,cmp_avld,cmp_rwhold,cmp_rhold,cmp_whold,read_data,write_data)
 573     begin
 574  	   	state_ch <= '0';
 575        case pstate is
 576          --RW Idle
 577          when SIdle =>
 578  		   		nstate <= SIdle;
 579          	if read_data = '1' then
 580  	       		nstate <= SRAVld;
 581  				   	state_ch <= '1';
 582  	       	elsif write_data = '1' then
 583  	       		nstate <= SWAVld;
 584  				   	state_ch <= '1';
 585  	       	end if;
 586          when SRAVld =>
 587         		nstate <= SRAVld;
 588          	if (cmp_avld = '1') then
 589          		nstate <= SIorHold;
 590  				   	state_ch <= '1';
 591          	end if;
 592          when SWAVld =>
 593         		nstate <= SWAVld;
 594          	if (cmp_avld = '1') then
 595          		nstate <= SIowHold;
 596  				   	state_ch <= '1';
 597          	end if;
 598          when SIorHold =>
 599         		nstate <= SIorHold;
 600          	if (cmp_rwhold = '1') then
 601          		nstate <= SRHold;
 602  				   	state_ch <= '1';
 603          	end if;
 604          when SIowHold =>
 605         		nstate <= SIowHold;
 606          	if (cmp_rwhold = '1') then
 607          		nstate <= SWHold;
 608  				   	state_ch <= '1';
 609          	end if;
 610          when SRHold =>
 611         		nstate <= SRHold;
 612          	if (cmp_rhold = '1') then
 613          		nstate <= SIdle;
 614  				   	state_ch <= '1';
 615          	end if;
 616          when SWHold =>
 617         		nstate <= SWHold;
 618          	if (cmp_whold = '1') then
 619          		nstate <= SIdle;
 620  				   	state_ch <= '1';
 621          	end if;
 622       end case;
 623     end process;
 624  
 625     rw_logic: process(pstate)
 626     begin
 627        data_out_ready <= '0';
 628        ior <= '1';
 629        iow <= '1';
 630        data_in_valid <= '0';
 631        reg_addr_ready <= '1';
 632        delcntr_rst <= '0';
 633        case pstate is
 634          --RW Idle
 635          when SIdle =>
 636  		      delcntr_rst <= '1';
 637  		      reg_addr_ready <= '0';
 638          when SRAVld =>
 639          when SWAVld =>
 640          when SIorHold =>
 641  		      ior <= '0';
 642  		      data_in_valid <= '1';
 643          when SIowHold =>
 644  		      iow <= '0';
 645            data_out_ready <= '1';
 646          when SRHold =>
 647          when SWHold =>
 648            data_out_ready <= '1';
 649       end case;
 650     end process;
 651  
 652  -- ******************* DMA Sekce ********************
 653  -- ctrl registr = R/W: DmaRun DmaRst DmaSpd DmaDir N/A N/A DmaBlock(2)
 654  -- DmaSpd = 0/1 -> Dma0/Dma1
 655  -- DmaDir = 0/1 -> R/W
 656  -- pri R je misto DmaRst DmaRQ
 657  
 658  DmaCtrlW <= '1' when ctrl_write = '1' AND Ctrl_Reg = "01" else '0';
 659  DmaRst <= ctrl_adc_out(6) OR RST when Ctrl_Reg = "01" else RST;
 660  NDmaRun <= '0' when (DmaRun = '1' AND DmaRQ = '1') else '1';
 661  DmaEnd <= '0' when (BDAdr(9 downto 8) = DmaBlock(1 downto 0)) else '1';
 662  cmpDmaRW <= '1' when (DmaCnt = DEL_DMA_RW0 AND DmaSpd = '0') OR
 663  	(DmaCnt = DEL_DMA_RW1 AND DmaSpd = '1') else '0';
 664  cmpDmaHold <= '1' when (DmaCnt = DEL_DMA_HOLD0 AND DmaSpd = '0') OR
 665  	(DmaCnt = DEL_DMA_HOLD1 AND DmaSpd = '1') else '0';
 666  cmpDmaWait <= '1' when (DmaCnt = DEL_DMA_WAIT0 AND DmaSpd = '0') OR
 667  	(DmaCnt = DEL_DMA_WAIT1 AND DmaSpd = '1') else '0';
 668  
 669     ctrl_dma_set: process(CLK,RST)
 670     begin
 671    		if RST = '1' then
 672  			  DmaRun <= '0';
 673  			  DmaSpd <= '0';
 674  			elsif CLK'event and CLK = '1' then
 675           if DmaCtrlW = '1' then
 676           	DmaBlock <= ctrl_adc_out(1 downto 0);
 677           	DmaRun <= ctrl_adc_out(7);
 678           	DmaSpd <= ctrl_adc_out(5);
 679           	DmaDir <= ctrl_adc_out(4);
 680           else
 681            if DmaEnd = '1' then DmaRun <= '0';
 682            end if;
 683           end if;
 684        end if;
 685     end process;
 686  
 687     Dma_Addr: process(CLK,DmaRst,DmaCtrlW,DmaInc)
 688     begin
 689     		if DmaRst = '1' then
 690     			BDAdr(7 downto 0) <= (others => '0');
 691     		else
 692  	      if CLK'event and CLK = '1' then
 693  	        if DmaCtrlW = '1' then
 694  	          BDAdr(9 downto 8) <= ctrl_adc_out(1 downto 0);
 695  	        else
 696  		      	if DmaInc = '1' then
 697  		      		BDAdr <= BDAdr + 1;
 698  						end if;
 699  					end if;
 700  	      end if;
 701  	    end if;
 702     end process;
 703  
 704     DMA_tick: process(CLK,DmaRst)
 705     begin
 706    		if DmaRst = '1' then
 707    			pDstate <= SIdle;
 708        elsif CLK'event and CLK = '1' then
 709  				pDstate <= nDstate;
 710        end if;
 711     end process;
 712  
 713     DMA_cnt_tick: process(CLK,DMA_Cnt_Rst,DmaRst)
 714     begin
 715    		if DmaRst = '1' then
 716    			DmaCnt <= (others => '0');
 717        elsif CLK'event and CLK = '1' then
 718        	if DMA_Cnt_Rst = '1' then
 719        		DmaCnt <= (others => '0');
 720        	else
 721  					DmaCnt <= DmaCnt + 1;
 722  	      end if;
 723        end if;
 724     end process;
 725  
 726     DMA_FSA: process(pDstate,DmaRun,cmpDmaRW,cmpDmaHold,cmpDmaWait,DMARQ,DmaEnd,NDmaDir)
 727     begin
 728        BDWe <= '0';
 729        DmaInc <= '0';
 730        case pDstate is
 731          when SIdle =>
 732  		   		nDstate <= SIdle;
 733          	if (DmaRun = '1') AND (DmaEnd = '0') then
 734  	       		nDstate <= SRun;
 735  	       	end if;
 736          when SRun =>
 737  		   		nDstate <= SRun;
 738          	if (DmaRun = '1') AND (DmaRQ = '1') then
 739  	       		nDstate <= SWR;
 740  	       	end if;
 741          when SWR =>
 742         		nDstate <= SWR;
 743          	if (cmpDmaRW = '1') then
 744          		nDstate <= SHold;
 745          		BDWe <= NDmaDir;
 746          	end if;
 747          when SHold =>
 748         		nDstate <= SHold;
 749          	if (cmpDmaHold = '1') then
 750          		nDstate <= SWait;
 751          		DmaInc <= '1';
 752          	end if;
 753          when SWait =>
 754         		nDstate <= SWait;
 755         		if (DmaEnd = '1') then
 756          		nDstate <= SIdle;
 757          	else
 758  	        	if (cmpDmaWait = '1') then
 759  	        		nDstate <= SRun;
 760  	        	end if;
 761  	        end if;
 762       end case;
 763     end process;
 764  
 765     DMA_logic: process(pDstate,NDmaRun)
 766     begin
 767        BDOutEn <= '0';
 768        DmaIRW <= '0';
 769        DMA_Cnt_Rst <= '0';
 770        DmaACK <= '1';
 771        case pDstate is
 772          --RW Idle
 773          when SIdle =>
 774  		      DMA_Cnt_Rst <= '1';
 775          when SRun =>
 776        		DmaACK <= NDmaRun;
 777  		      DMA_Cnt_Rst <= '1';
 778          when SWR =>
 779            DmaIRW <= '1';
 780            BDOutEn <= '1';
 781        		DmaACK <= '0';
 782          when SHold =>
 783        		DmaACK <= '0';
 784            BDOutEn <= '1';
 785          when SWait =>
 786        		DmaACK <= '0';
 787       end case;
 788     end process;
 789  
 790  -- ******************* DMA Kanal ********************
 791  
 792  ch_in <= ch_run & ACCEPT & ch_dst & ch_addr;
 793     SPI_adc_CH: SPI_adc
 794        generic map(
 795           ADDR_WIDTH => 8,
 796           DATA_WIDTH => 24,
 797           ADDR_OUT_WIDTH => 1,
 798           BASE_ADDR  => 16#10#,
 799           DELAY => 0
 800        )
 801        port map(
 802           CLK      => CLK,
 803  
 804           CS       => CS,
 805           DO       => DO,
 806           DO_VLD   => DO_VLD,
 807           DI       => DI,
 808           DI_REQ   => DI_REQ,
 809  
 810           ADDR     => open,
 811  				 DATA_IN  => ch_in,
 812           READ_EN  => open,
 813  
 814           DATA_OUT => ch_out,
 815           WRITE_EN => ch_wr
 816        );
 817  
 818     CH_konf_wr: process(CLK,ch_wr,RST,ACCEPT,ch_next)
 819     begin
 820    		if RST = '1' then
 821    			ch_run <= '0';
 822    			ch_dir <= '0';
 823    			ch_addr <= (others => '0');
 824    			ch_dst <= (others => '0');
 825        elsif CLK'event and CLK = '1' then
 826        	if ch_wr = '1' then
 827        		ch_run <= ch_out(23);
 828  	  			ch_dir <= ch_out(22);
 829  	  			ch_addr <= ch_out(10 downto 0);
 830  	  			ch_dst <= ch_out(21 downto 11);
 831        	else
 832        		if ch_next='1'  then
 833        			ch_addr <= ch_addr + 1;
 834        		end if;
 835        		if cmp_ch='1' and ACCEPT='1' then
 836        			ch_run <= '0';
 837        		end if;
 838  	      end if;
 839        end if;
 840     end process;
 841  
 842     cmp_ch <= '1' when ch_addr=ch_dst else '0';
 843  
 844     CH_cnt_tick: process(CLK,ch_run,RST)
 845     begin
 846    		if ch_run = '0' or RST='1' then
 847    			pCstate <= sStart;
 848        elsif CLK'event and CLK = '1' then
 849        	pCstate <= nCstate;
 850        end if;
 851     end process;
 852  
 853     CH_FSA: process(pCstate,ch_dir)
 854     begin
 855        case pCstate is
 856          when sStart =>
 857         		nCstate <= SwRead;
 858          	if (ch_dir = '1') then
 859  	       		nCstate <= SWrite;
 860  	       	end if;
 861          when SwRead =>
 862  	       	nCstate <= SRead;
 863          when SRead =>
 864  	       	nCstate <= SRead;
 865          when SWrite =>
 866  	       	nCstate <= SWrite;
 867       end case;
 868     end process;
 869  
 870     CH_logic: process(pCstate)
 871     begin
 872        ch_first <= '0';
 873       	READ_EN <= '0';
 874       	CH_wr_en <= '0';
 875        case pCstate is
 876          when sStart =>
 877          when SwRead =>
 878        		ch_first <= '1';
 879          when SRead =>
 880          	READ_EN <= '1';
 881          when SWrite =>
 882          	CH_wr_en <= '1';
 883       end case;
 884     end process;
 885  
 886  	 ch_next <= ch_first or ACCEPT;
 887  	 DATA_OUT <= ch_out_b when ch_accept='0' else BSDIn;
 888  
 889     CH_acc_buff: process(CLK)
 890     begin
 891  			if CLK'event and CLK = '1' then
 892        	ch_accept <= ACCEPT;
 893        end if;
 894     end process;
 895  
 896     CH_out_buff: process(CLK,ch_next)
 897     begin
 898  			if CLK'event and CLK = '1' and ch_next='1' then
 899        	ch_out_b <= BSDIn;
 900        end if;
 901     end process;
 902  
 903  end basic;
 904  
Zobrazeno: 679744x Naposledy: 28.6.2022 19:57:25