⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdramcntl.vhd

📁 xst3_video.ZIP是基于XILINX的XST3开发板的视频采集源码
💻 VHD
📖 第 1 页 / 共 4 页
字号:
                                        -- this insures the clock is stable before enabling the SDRAM
                                        -- it also insures a clean startup if the SDRAM is currently in self-refresh mode
            cke_x   <= NO;
          end if;
          status    <= "0001";

          -----------------------------------------------------------
          -- precharge all SDRAM banks after power-on initialization 
          -----------------------------------------------------------
        when INITPCHG =>
          cmd_x               <= PCHG_CMD;
          sAddr_x(CMDBIT_POS) <= ALL_BANKS;  -- precharge all banks
          timer_x             <= RP_CYCLES;  -- set timer for precharge operation duration
          rfshCntr_x          <= RFSH_OPS;  -- set counter for refresh ops needed after precharge
          state_x             <= INITRFSH;
          status              <= "0010";

          -----------------------------------------------------------
          -- refresh the SDRAM a number of times after initial precharge 
          -----------------------------------------------------------
        when INITRFSH =>
          cmd_x      <= RFSH_CMD;
          timer_x    <= RFC_CYCLES;     -- set timer to refresh operation duration
          rfshCntr_x <= rfshCntr_r - 1;  -- decrement refresh operation counter
          if rfshCntr_r = 1 then
            state_x  <= INITSETMODE;    -- set the SDRAM mode once all refresh ops are done
          end if;
          status     <= "0011";

          -----------------------------------------------------------
          -- set the mode register of the SDRAM 
          -----------------------------------------------------------
        when INITSETMODE =>
          cmd_x   <= MODE_CMD;
          sAddr_x <= (others=>'0');          sAddr_x(MODE'range) <= MODE;              -- output mode register bits on the SDRAM address bits          timer_x <= MODE_CYCLES;       -- set timer for mode setting operation duration
          state_x <= RW;
          status  <= "0100";

          -----------------------------------------------------------
          -- process read/write/refresh operations after initialization is done 
          -----------------------------------------------------------
        when RW                                      =>
          -----------------------------------------------------------
          -- highest priority operation: row refresh 
          -- do a refresh operation if the refresh counter is non-zero
          -----------------------------------------------------------
          if rfshCntr_r /= 0 then
                                        -- wait for any row activations, writes or reads to finish before doing a precharge
            if (activateInProgress = NO) and (wrInProgress = NO) and (rdInProgress = NO) then
              cmd_x                       <= PCHG_CMD;  -- initiate precharge of the SDRAM
              sAddr_x(CMDBIT_POS)         <= ALL_BANKS;  -- precharge all banks
              timer_x                     <= RP_CYCLES;  -- set timer for this operation
              activeFlag_x                <= (others => NO);  -- all rows are inactive after a precharge operation
              state_x                     <= REFRESHROW;  -- refresh the SDRAM after the precharge
            end if;
            status                        <= "0101";
            -----------------------------------------------------------
            -- do a host-initiated read operation 
            -----------------------------------------------------------
          elsif rd = YES then
                                        -- Wait one clock cycle if the bank address has just changed and each bank has its own active row.
            -- This gives extra time for the row activation circuitry.
            if (ba_x = ba_r) or (MULTIPLE_ACTIVE_ROWS = false) then
                                        -- activate a new row if the current read is outside the active row or bank
              if doActivate = YES then
                                        -- activate new row only if all previous activations, writes, reads are done
                if (activateInProgress = NO) and (wrInProgress = NO) and (rdInProgress = NO) then
                  cmd_x                   <= PCHG_CMD;  -- initiate precharge of the SDRAM
                  sAddr_x(CMDBIT_POS)     <= ONE_BANK;  -- precharge this bank
                  timer_x                 <= RP_CYCLES;  -- set timer for this operation
                  activeFlag_x(bankIndex) <= NO;  -- rows in this bank are inactive after a precharge operation
                  state_x                 <= ACTIVATE;  -- activate the new row after the precharge is done
                end if;
                                        -- read from the currently active row if no previous read operation
                                        -- is in progress or if pipeline reads are enabled
                                        -- we can always initiate a read even if a write is already in progress
              elsif (rdInProgress = NO) or PIPE_EN then
                cmd_x                     <= READ_CMD;  -- initiate a read of the SDRAM
                                        -- insert a flag into the pipeline shift register that will exit the end
                                        -- of the shift register when the data from the SDRAM is available
                rdPipeline_x              <= READ & rdPipeline_r(rdPipeline_r'high downto 1);
                opBegun_x                 <= YES;  -- tell the host the requested operation has begun
              end if;
            end if;
            status                        <= "0110";
            -----------------------------------------------------------
            -- do a host-initiated write operation 
            -----------------------------------------------------------
          elsif wr = YES then
                                        -- Wait one clock cycle if the bank address has just changed and each bank has its own active row.
            -- This gives extra time for the row activation circuitry.
            if (ba_x = ba_r) or (MULTIPLE_ACTIVE_ROWS = false) then
                                        -- activate a new row if the current write is outside the active row or bank
              if doActivate = YES then
                                        -- activate new row only if all previous activations, writes, reads are done
                if (activateInProgress = NO) and (wrInProgress = NO) and (rdInProgress = NO) then
                  cmd_x                   <= PCHG_CMD;  -- initiate precharge of the SDRAM
                  sAddr_x(CMDBIT_POS)     <= ONE_BANK;  -- precharge this bank
                  timer_x                 <= RP_CYCLES;  -- set timer for this operation
                  activeFlag_x(bankIndex) <= NO;  -- rows in this bank are inactive after a precharge operation
                  state_x                 <= ACTIVATE;  -- activate the new row after the precharge is done
                end if;
                                        -- write to the currently active row if no previous read operations are in progress
              elsif rdInProgress = NO then
                cmd_x                     <= WRITE_CMD;  -- initiate the write operation
                sDataDir_x                <= OUTPUT;  -- turn on drivers to send data to SDRAM
                                        -- set timer so precharge doesn't occur too soon after write operation
                wrTimer_x                 <= WR_CYCLES;
                                        -- insert a flag into the 1-bit pipeline shift register that will exit on the
                                        -- next cycle.  The write into SDRAM is not actually done by that time, but
                                        -- this doesn't matter to the host
                wrPipeline_x(0)           <= WRITE;
                opBegun_x                 <= YES;  -- tell the host the requested operation has begun
              end if;
            end if;
            status                        <= "0111";
            -----------------------------------------------------------
            -- do a host-initiated self-refresh operation 
            -----------------------------------------------------------
          elsif doSelfRfsh = YES then
                                        -- wait until all previous activations, writes, reads are done
            if (activateInProgress = NO) and (wrInProgress = NO) and (rdInProgress = NO) then
              cmd_x                       <= PCHG_CMD;  -- initiate precharge of the SDRAM
              sAddr_x(CMDBIT_POS)         <= ALL_BANKS;  -- precharge all banks
              timer_x                     <= RP_CYCLES;  -- set timer for this operation
              activeFlag_x                <= (others => NO);  -- all rows are inactive after a precharge operation
              state_x                     <= SELFREFRESH;  -- self-refresh the SDRAM after the precharge
            end if;
            status                        <= "1000";
            -----------------------------------------------------------
            -- no operation
            -----------------------------------------------------------
          else
            state_x                       <= RW;  -- continue to look for SDRAM operations to execute
            status                        <= "1001";
          end if;

          -----------------------------------------------------------
          -- activate a row of the SDRAM 
          -----------------------------------------------------------
        when ACTIVATE                        =>
          cmd_x                   <= ACTIVE_CMD;
          sAddr_x                 <= (others => '0');  -- output the address for the row to be activated
          sAddr_x(row'range)      <= row;
          activeBank_x            <= bank;
          activeRow_x(bankIndex)  <= row;  -- store the new active SDRAM row address
          activeFlag_x(bankIndex) <= YES;  -- the SDRAM is now active
          rasTimer_x              <= RAS_CYCLES;  -- minimum time before another precharge can occur 
          timer_x                 <= RCD_CYCLES;  -- minimum time before a read/write operation can occur
          state_x                 <= RW;  -- return to do read/write operation that initiated this activation
          status                  <= "1010";

          -----------------------------------------------------------
          -- refresh a row of the SDRAM         
          -----------------------------------------------------------
        when REFRESHROW =>
          cmd_x      <= RFSH_CMD;
          timer_x    <= RFC_CYCLES;     -- refresh operation interval
          rfshCntr_x <= rfshCntr_r - 1;  -- decrement the number of needed row refreshes
          state_x    <= RW;             -- process more SDRAM operations after refresh is done
          status     <= "1011";

          -----------------------------------------------------------
          -- place the SDRAM into self-refresh and keep it there until further notice           
          -----------------------------------------------------------
        when SELFREFRESH            =>
          if (doSelfRfsh = YES) or (lock = NO) then
                                        -- keep the SDRAM in self-refresh mode as long as requested and until there is a stable clock
            cmd_x        <= RFSH_CMD;   -- output the refresh command; this is only needed on the first clock cycle
            cke_x        <= NO;         -- disable the SDRAM clock
          else
                                        -- else exit self-refresh mode and start processing read and write operations
            cke_x        <= YES;        -- restart the SDRAM clock
            rfshCntr_x   <= 0;          -- no refreshes are needed immediately after leaving self-refresh
            activeFlag_x <= (others => NO);  -- self-refresh deactivates all rows
            timer_x      <= XSR_CYCLES;  -- wait this long until read and write operations can resume
            state_x      <= RW;
          end if;
          status         <= "1100";

          -----------------------------------------------------------
          -- unknown state
          -----------------------------------------------------------
        when others =>
          state_x <= INITWAIT;          -- reset state if in erroneous state
          status  <= "1101";

      end case;
    end if;
  end process combinatorial;


  -----------------------------------------------------------
  -- update registers on the appropriate clock edge     
  -----------------------------------------------------------

  update : process(rst, clk)
  begin

    if rst = YES then
      -- asynchronous reset
      state_r      <= INITWAIT;
      activeFlag_r <= (others => NO);
      rfshCntr_r   <= 0;
      timer_r      <= 0;
      refTimer_r   <= REF_CYCLES;
      rasTimer_r   <= 0;
      wrTimer_r    <= 0;
      nopCntr_r    <= 0;
      opBegun_r    <= NO;
      rdPipeline_r <= (others => '0');
      wrPipeline_r <= (others => '0');
      cke_r        <= NO;
      cmd_r        <= NOP_CMD;
      ba_r         <= (others => '0');
      sAddr_r      <= (others => '0');
      sData_r      <= (others => '0');
      sDataDir_r   <= INPUT;
      hDOut_r      <= (others => '0');
    elsif rising_edge(clk) then
      state_r      <= state_x;
      activeBank_r <= activeBank_x;
      activeRow_r  <= activeRow_x;
      activeFlag_r <= activeFlag_x;
      rfshCntr_r   <= rfshCntr_x;
      timer_r      <= timer_x;
      refTimer_r   <= refTimer_x;
      rasTimer_r   <= rasTimer_x;
      wrTimer_r    <= wrTimer_x;
      nopCntr_r    <= nopCntr_x;
      opBegun_r    <= opBegun_x;
      rdPipeline_r <= rdPipeline_x;
      wrPipeline_r <= wrPipeline_x;
      cke_r        <= cke_x;
      cmd_r        <= cmd_x;
      ba_r         <= ba_x;
      sAddr_r      <= sAddr_x;
      sData_r      <= sData_x;
      sDataDir_r   <= sDataDir_x;
      hDOut_r      <= hDOut_x;
    end if;

    -- the register that gets data from the SDRAM and holds it for the host
    -- is clocked on the opposite edge.  We don't use this register if IN_PHASE=TRUE.
    if rst = YES then
      hDOutOppPhase_r <= (others => '0');
    elsif falling_edge(clk) then
      hDOutOppPhase_r <= hDOutOppPhase_x;
    end if;

  end process update;

end arch;




--------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -