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

📄 ddr_sdr.vhd

📁 ddr verilog代码,实现DDR内存控制
💻 VHD
📖 第 1 页 / 共 3 页
字号:
                        tras_cnt_q <= TRAS-1;
                        state_q   <= ST_RFSH_4;
                     else
                        state_q   <= ST_RFSH_3;
                     end if;
                  end if;
                  
               when ST_RFSH_3 =>
                  if ct_cnt_q=1 then
                     state_q    <= ST_WAIT_CMD;
                  end if;
                  
               when ST_RFSH_4 =>
                  if tras_cnt_q = 0 then
                     state_q <= ST_WAIT_CMD;
                  else
                     tras_cnt_q <= tras_cnt_q -1;
                  end if;
               
               when RD_PRECH => 
                  sdr_if_q    <= COMMAND(PRECHARGE);
                  ld_ct_cnt_q <= true;
                  state_q     <= ST_RD_ACTIVATE;
                  a_int_q(auto_precharge) <= '1';  -- precharge all

               when ST_READ1 =>
                  state_q <= ST_WAIT_CMD;
                 
               when ST_RD_ACTIVATE =>
                  if ct_cnt_q=1 then
                     ld_ct_cnt_q <= true;
                     sdr_if_q <= COMMAND(ACTIVE);
                     a_int_q  <= row_adr_q;  -- ROW address
                     state_q <= ST_WAIT_RD;                                             
                  end if;
                  
               when ST_WAIT_RD =>
                  if ct_cnt_q=1 then
                     start_rd := true;
                     a_int_q       <= col_adr_q;  -- Col Address
                     sdr_if_q      <= COMMAND(BURST_RD); -- set burst read command
                     state_q <= ST_READ1;
                  end if;
            end case;
            
            sdr_if2_q  <= sdr_if_q;
            ba_int2_q  <= ba_int_q;
            a_int2_q   <= a_int_q;
            cke_int2_q <= cke_int_q;
            
            -- Write Control Signals
            if start_wr then 
               wr_ena_q    <= '1';
            else
               wr_ena_q    <= '0';
            end if;
            
            wr_ena2_q    <= wr_ena_q;
            wr_ena3_q    <= wr_ena2_q;
            
            -- Data Input Shiftreg 
            if wr_ena2_q='1' then
               shift_q(0) <= data_in; -- 2 clocks delayed MUX signal
            end if;
            
            -- Read Control Signals
            if start_rd then
               rd_ena_q <= true;
               bus_switch_q(0) <= '1';
            else
               rd_ena_q <= false;
               bus_switch_q(0) <= '0';
            end if;
            -- On and off-switching for Tristate buffer 
            -- is controlled by bus_switch_q
            bus_switch_q(bus_switch_q'LEFT downto 1) <= bus_switch_q(bus_switch_q'LEFT-1 downto 0);
            z_q  <= bus_switch_q(bus_switch_q'LEFT) or bus_switch_q(bus_switch_q'LEFT-1); 
            ----------------------------------------------------
            
            -- cycle time counter
            if ld_ct_cnt_q then
               ct_cnt_q <= sdr_if_q.ct;
            elsif ct_cnt_q > 0 then
               ct_cnt_q <= ct_cnt_q -1;
            end if;

            ct0_q <= ct_cnt_q=1;
            
            -- delay time counter
            if ld_del_cnt_q then
               del_cnt_q <= 3;
            elsif del_cnt_q > 0 then
               del_cnt_q <= del_cnt_q -1;
            end if;
            del0_q <= del_cnt_q=1;
            
            -- Wait time shift register for Read2Write and Write2Read delay
            -- Note that there is 1 more clock needed for a change from WRITE to READ
            -- due to pipeline delay, compared to READ to WRITE
            if start_rd or start_wr then 
               w_srg_q <= "000111";
            else
               w_srg_q <= '0' & w_srg_q(w_srg_q'LEFT downto 1);
            end if;

         end if;
      end process;

      process(sys_clk, rst_int_n)
      begin
         if rst_int_n='0' then
            shift_q(1) <= (others=>'0');
         elsif falling_edge(sys_clk) then
            shift_q(1) <= shift_q(0);
         end if;
      end process;
      
      -- Create iob FFs without reset
      process (sys_clk) is
      begin
         if rising_edge(sys_clk) then  
            for n in 0 to DDR_DQS_WIDTH-1 loop
               if wr_ena2_q='1' or wr_ena3_q='1' then -- ML: verlaengert + noch 1 clock
                  dqsz_q(n) <= '0';
               else
                  dqsz_q(n) <= '1';
               end if;
            end loop;  
         end if;
      end process;

      process (sys_clk270)
      begin  
         if rising_edge(sys_clk270) then  
            for n in 0 to DDR_DATA_WIDTH-1 loop
               tristate_q(n) <= z_q='1';
            end loop;
         end if;
      end process ;

      ------------------------------------------------------------------------------------------------------------------------------------------------
      -- ctrl signals on negative edge, all FFs without Async Reset
      ------------------------------------------------------------------------------------------------------------------------------------------------
      process (sys_clk) is
      begin  
         if falling_edge(sys_clk) then
            case mux_q is
               when NORMAL => -- Read Command
                  ras_qn       <= sdr_if_q.ras_n;
                  cas_qn       <= sdr_if_q.cas_n; 
                  we_qn        <= sdr_if_q.we_n; 
                  cs_qn        <= sdr_if_q.cs_n; 
                  ba_q         <= ba_int_q; 
                  a_q          <= a_int_q;
                  cke_q        <= cke_int_q;
               when DELAYED => -- Write Command
                  ras_qn       <= sdr_if2_q.ras_n;
                  cas_qn       <= sdr_if2_q.cas_n; 
                  we_qn        <= sdr_if2_q.we_n; 
                  cs_qn        <= sdr_if2_q.cs_n; 
                  ba_q         <= ba_int2_q; 
                  a_q          <= a_int2_q;
                  cke_q        <= cke_int2_q;
            end case;
         end if;
      end process;

      -- Data MSBs, e.g. (31 downto 16)  
      ddr_data(U_DATA_WIDTH-1 downto U_DATA_WIDTH/2) <= shift_q(0)(U_DATA_WIDTH/2-1 downto 0);
      -- Data LSBs, e.g. (15 downto 0)  
      ddr_data(U_DATA_WIDTH/2-1 downto 0)            <= shift_q(1)(U_DATA_WIDTH-1 downto U_DATA_WIDTH/2);
      
      ------------------------------------------------------------------------------------------------------------------------------------------------
      -- DDR-FFs and Tristate Buffers
      ------------------------------------------------------------------------------------------------------------------------------------------------
      -- SDRAM Clock
      fddr1 : entity work.my_fddr
         port map( d0 => '0',
                   d1 => '1',
                   ce => '1',
                   c1 => clk_int,
                   r  => '0',
                   s  => '0',
                   q  => sdr_clk
                   );
                   
      fddr2 : entity work.my_fddr
         port map( d0 => '1',
                   d1 => '0',
                   ce => '1',
                   c1 => clk_int,
                   r  => '0',
                   s  => '0',
                   q  => sdr_clk_n
                   );
      -- Data OUT FFs
      gen_d1: for n in 0 to DDR_DATA_WIDTH-1 generate
      begin 
         fddr3 : entity work.my_fddr
            port map( d0 => ddr_data(n),
                      d1 => ddr_data(n + DDR_DATA_WIDTH),
                      ce => '1',
                      c1 => sys_clk270,
                      r  => '0',
                      s  => '0',
                      q  => d2sdr(n));
      end generate gen_d1;
      
      -- DQS OUT FFs
      gen_d2: for n in 0 to DDR_DQS_WIDTH-1 generate
      begin 
         fddr4 : entity work.my_fddr
            port map( d0 => '0',
                      d1 => '1',
                      ce => '1',
                      c1 => sys_clk,
                      r  => wr_ena3_qn,
                      s  => '0',
                      q  => dqs(n));
      end generate gen_d2;
      
      -- Usage of DM signals not supported in this version
      dm_q <= (others=>'0');
      
      gen3: for n in 0 to DDR_DATA_WIDTH-1 generate
         data(n) <= 'Z' when tristate_q(n) else d2sdr(n);
      end generate;

      wr_ena3_qn <= not wr_ena3_q;
      
      -- Tristate-Buffer fuer dqs_q      
      gen_dqs : for n in 0 to DDR_DQS_WIDTH-1 generate
         dqs_q(n) <= 'Z' when dqsz_q(n)='1' else dqs(n);
      end generate gen_dqs;

      ------------------------------------------------------------------------------------------------------------------------------------------------
      -- READ DATA Processing
      ------------------------------------------------------------------------------------------------------------------------------------------------
      process (sys_clk)
      begin  
         if rising_edge(sys_clk) then
         
            -- sample HI-data word with rising edge
            data_hi_q <= data;
            
            -- store HI- und LO- data word  in 32bit output register
            data_out_q <= data_hi_q & data_lo2_q;
            
         end if;
      end process;
      
      process(sys_clk)
      begin
         if rising_edge(sys_clk) then
            -- derive window for valid data from rd_ena_q
            rd_ena_del_q <= rd_ena_del_q(rd_ena_del_q'LEFT-1 downto 0) & rd_ena_q;
            
         end if;
      end process;

      data_vld_q <= '1' when rd_ena_del_q(rd_ena_del_q'LEFT) else '0';
      
      process (sys_clk)
      begin  
         if falling_edge(sys_clk) then
         
            -- sample LO- word with falling edge
            data_lo1_q <= data;
            
            -- 1 clock additional delay to store HI- and LO-word
            -- with the next rising edge as 32bit word
            data_lo2_q <= data_lo1_q;
         end if;
      end process;

      -----------------------------------------------      
      -- Write Data Processing
      -----------------------------------------------      
      data_req_q <= '1' when wr_ena_q='1' else '0';
         
      ------------------------------------------------------------------------------
      -- wait counter for first 200 us
      ------------------------------------------------------------------------------
      init_cnt: block
         signal init_cnt_q : unsigned (0 to 13); 
      begin
         process (sys_clk, rst_int_n) is
         begin 
            if rst_int_n = '0' then  
               init_cnt_q <= (others => '0');
               init_cnt0_q <= false;
               init_cnt1_q <= false;
            elsif rising_edge(sys_clk) then
               
               init_cnt0_q <= init_cnt_q=1;
               init_cnt1_q <= init_cnt_q=2;
               
               if ld_init_cnt_q then
                  init_cnt_q <= conv_unsigned(get_init_max -1, init_cnt_q'length);
                  init_cnt0_q <= false;  
                  init_cnt1_q <= false;  
               elsif init_cnt_q /= 0 then
                  init_cnt_q <= init_cnt_q -1;
               end if;
               
            end if;
         end process;
      end block init_cnt;

      ------------------------------------------------------------------------------------------------------------------------------------------------
      -- wait counter for 200 clk cycles for dll
      ------------------------------------------------------------------------------------------------------------------------------------------------
      dll_cnt: block
         constant DLL_DELAY : integer := 200 -1;
         signal dll_cnt_q : integer range 0 to DLL_DELAY;
      begin
         process (sys_clk, rst_int_n) is
         begin 
            if rst_int_n='0' then
               dll_cnt0_q <= false;
               dll_cnt_q  <= DLL_DELAY;
            elsif rising_edge(sys_clk) then  
               if ld_dll_cnt_q then
                  dll_cnt_q  <= DLL_DELAY;
               elsif dll_cnt_q > 0 then
                  dll_cnt_q <= dll_cnt_q -1;
               end if;
               dll_cnt0_q <= dll_cnt_q = 1;
               
            end if;
         end process;
      end block dll_cnt;
   end block ctrl;

end architecture behave;


⌨️ 快捷键说明

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