VHDL中的SDRAM控制器

我必须为VHDL中的课程开发一个SDRAM控制器。但这是我第一次使用VHDL,它具有非常重要的学习曲线。

我已经从github(https://github.com/christianmiyoshi/SDRAM_Controller_VHDL/blob/master/sdram_controller.vhd)下载了一个SDRAM控制器,我正在尝试完成它。

我试图在地址中写入数据,然后再读取,但我无法读取单个数据。我不知道我的问题是在写作还是在阅读过程中。

有人可以帮助我吗?

谢谢大家!

library ieee;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity ram_controller is
port(
    clk : in std_logic;
    reset: in std_logic;
    refresh: in std_logic;
    read_write_enable: in std_logic;
    write_n: in std_logic;
    address: in std_logic_vector(21 downto 0);
    data_in: in std_logic_vector(15 downto 0);
    dqmu: in std_logic;
    dqml: in std_logic;
    ready: out std_logic;
    done: out std_logic;
    data_out: out std_logic_vector(15 downto 0);

    single_burst: in std_logic; --0 single y 1 burst

    SDRAM_CKE: out std_logic;
    SDRAM_CS_N: out std_logic;
    SDRAM_RAS_N: out std_logic;
    SDRAM_CAS_N: out std_logic;
    SDRAM_WE_N: out std_logic;
    SDRAM_BA: out std_logic_vector(1 downto 0);
    SDRAM_SA: out std_logic_vector(11 downto 0);
    SDRAM_DQ: inout std_logic_vector(15 downto 0);
    SDRAM_DQM: out std_logic_vector(1 downto 0)
);
end entity;


architecture behavior of ram_controller is


type state_type is (init_ckeLow,init_stableclock,init_wait,init_nopCommand,init_prechargeAll,init_refresh_1,init_mode,init_refresh_2,idle,refresh_state,activate_row,activate_rcd,read_write,ras1,ras2,precharge);
signal state: state_type := init_ckeLow;

signal ticks: std_logic_vector(7 downto 0) := (others => '0');
signal ticks_ref: integer := 0;
signal ticks_ref_refresh: integer := 0;


constant burstMode: std_logic := '0';
constant casLatency: std_logic_vector(2 downto 0) := "010";
constant burstType: std_logic := '0';
constant burstLength: std_logic_vector(2 downto 0) := "000";

--signal highz_output: std_logic:= '0';

constant MODE_REG: std_logic_vector(11 downto 0) := "00" & burstMode & "00" & casLatency & burstType & burstLength;
constant MODE_REG_BURST: std_logic_vector(11 downto 0) := "000000100111";
signal command: std_logic_vector(3 downto 0);
signal row: std_logic_vector(11 downto 0);
signal column: std_logic_vector(7 downto 0);
signal bank: std_logic_vector(1 downto 0);

signal sd_busdir_x: std_logic:='0';

-- Command truth table
-- CS_N,RAS_N,CAS_N,WE_N
constant CMD_actIVATE:  std_logic_vector(3 downto 0) := "0011";
constant CMD_PRECHARGE: std_logic_vector(3 downto 0) := "0010";
constant CMD_WRITE:     std_logic_vector(3 downto 0) := "0100";
constant CMD_READ:      std_logic_vector(3 downto 0) := "0101";
constant CMD_MODE:      std_logic_vector(3 downto 0) := "0000";
constant CMD_NOP:       std_logic_vector(3 downto 0) := "0111";
constant CMD_REFRESH:   std_logic_vector(3 downto 0) := "0001";

signal address_buffer: std_logic_vector(21 downto 0) := (others => '0');
signal data_in_buffer: std_logic_vector(15 downto 0) := (others => '0');
signal dqu_buffer: std_logic := '0';
signal dql_buffer: std_logic := '0';
signal ready_buffer: std_logic := '0';
signal done_buffer: std_logic := '0';
signal data_out_buffer: std_logic_vector(15 downto 0) := (others => '0');

signal CKE: std_logic;
signal CS_N: std_logic;
signal RAS_N: std_logic;
signal CAS_N: std_logic;
signal WE_N: std_logic;
signal BA: std_logic_vector(1 downto 0);
signal SA: std_logic_vector(11 downto 0);
signal DQ: std_logic_vector(15 downto 0);
signal DQM: std_logic_vector(1 downto 0);
signal contador : std_logic_vector(15 downto 0) := x"0000";
signal modo: std_logic := '0';
begin

(CS_N,WE_N) <= command;

SDRAM_CKE <= CKE;
SDRAM_CS_N <= CS_N;
SDRAM_RAS_N <= RAS_N;
SDRAM_CAS_N <= CAS_N;
SDRAM_WE_N <= WE_N;
SDRAM_BA <= BA;
SDRAM_SA <= SA;
--SDRAM_DQ <= DQ;
SDRAM_DQM <= DQM;


--SA <= address_buffer;
SDRAM_DQ <= data_in_buffer when sd_busdir_x = '1' else (others => 'Z');
DQM <= dqu_buffer & dql_buffer;


ready <= ready_buffer;
done <= done_buffer;
data_out <= data_out_buffer;



bank <= address(21 downto 20);
row <= address(19 downto 8);
column <= address(7 downto 0);

process(clk,reset)
begin
if reset = '0' then
    state <= init_ckeLow;
    ticks_ref <= 0;
elsif rising_edge(clk) then
    if ticks_ref /= 0 then
        ticks_ref <= ticks_ref - 1;
    else
        -- micron datasheet instructions
        -- Frequency = 100 Mhz => period of 10ns
        -- 1: Apply Vdd and Vddq simultaneously
        case state is
            when init_ckeLow =>
                -- 2: Assert and hold CKE ant LVTTL logic low
                ticks_ref <= 10;
                CKE <= '0';             
                state <= init_stableclock;
            when init_stableclock =>    
                -- 3: Provide stable clock
                ticks_ref <= 10;
                state <= init_wait;
            when init_wait=>
                -- 4: Wait at least 100us
                -- 5: bring cke high at some point of the period
                -- with command inhibit or nop
                --ticks_ref <= 10000;
                ticks_ref <= 2; -- debugadd
                state <= init_nopCommand;
            when init_nopCommand =>
                --ticks_ref <= 10000;
                ticks_ref <= 2; -- debug
                CKE <= '1';
                command <= CMD_NOP;
                state <= init_prechargeAll;
            when init_prechargeAll =>
                -- 6: perform precharge all
                -- 7: wait at leas t_RP
                command <= CMD_PRECHARGE;
                BA <= "00";
                SA(10) <= '1'; -- all banks
                ticks_ref <= 2;
                ticks_ref_refresh <= 8;
                state <= init_refresh_1;
            when init_refresh_1 =>
                -- auto refresj period: < 64 ns
                if ticks_ref_refresh = 0 then
                    state <= init_mode;
                else
                    ticks_ref_refresh <= ticks_ref_refresh - 1;
                    command <= CMD_REFRESH;
                    ticks_ref <= 7;
                end if;
            when init_mode =>
                command <= CMD_MODE;
                if single_burst = '0' then
                    SA <= MODE_REG;
                    modo <= '0';
                else
                    SA <= MODE_REG_BURST;
                    modo <= '1';
                end if;
                BA <= "00";
                ticks_ref <= 2;
                ticks_ref_refresh <= 8;
                state <= init_refresh_2;
            when init_refresh_2 =>
                if ticks_ref_refresh = 0 then
                    state <= idle;
                    --done_buffer <= '1';
                else
                    ticks_ref_refresh <= ticks_ref_refresh - 1;
                    command <= CMD_REFRESH;
                    ticks_ref <= 7;
                end if;
            when idle =>
                done_buffer <= '0';
                contador <= (others => '0');
                if read_write_enable = '1' then
                    -- tras: active to precharge: 45 ns min,120000ns max
                    state <= activate_row;
                    command <= CMD_actIVATE;
                    SA <= row;
                    BA <= bank;
                    --done_buffer <= '0';
                elsif refresh = '1' then
                    state <= refresh_state;
                    command <= CMD_REFRESH;
                    ticks_ref <= 7;
                    --done_buffer <= '0';
                end if;
            when refresh_state =>
                state <= idle;
                --done_buffer <= '1';
            when activate_row =>
                --trcd 20 ns
                command <= CMD_NOP;
                state <= activate_rcd;
                data_in_buffer <= data_in;
                ticks_ref <= 1;
            when activate_rcd =>
                -- trcs = 20ns min
                state <=read_write;
                SA <= "0000" & column;
                if write_n = '0' then
                    command <= CMD_WRITE;

                    dqu_buffer <=  dqmu;
                    dql_buffer <= dqml;
                    sd_busdir_x <= '1';  
                else
                    command <= CMD_READ;
                end if;

            when read_write =>
                --command <= CMD_NOP;
                state <= ras1;
                --if modo='0' then
                    --sd_busdir_x <= '0';
                --end if;
            when ras1 =>
                state <= ras2;
                command <= CMD_NOP;
            when ras2 =>
                -- trp = 20ns min
                if modo='1' and contador <= x"00FF" then
                    data_in_buffer <= data_in;
                    state <= ras2;
                    contador <= contador +1;
                else
                    contador <= (others => '0');
                    state <= precharge;
                    sd_busdir_x <= '0';
                    command <= CMD_PRECHARGE;
                    SA(10) <= '1';
                    data_out_buffer <= SDRAM_DQ;
                    ticks_ref <= 2;
                end if;
            when precharge =>
                state <= idle;
                done_buffer <= '1';
                ticks_ref <= 1;
        end case;
    end if; 
end if;
end process;




end architecture;

[enter image description here][1]


  [1]: https://i.stack.imgur.com/CaqqL.png
ZIer0921 回答:VHDL中的SDRAM控制器

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/3110899.html

大家都在问