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

📄 hs.vhd

📁 free hardware ip core about sparcv8,a soc cpu in vhdl
💻 VHD
📖 第 1 页 / 共 2 页
字号:
--------------------------------------------------------------------------------  This file is a part of the GRLIB VHDL IP LIBRARY--  Copyright (C) 2003, Gaisler Research----  This program is free software; you can redistribute it and/or modify--  it under the terms of the GNU General Public License as published by--  the Free Software Foundation; either version 2 of the License, or--  (at your option) any later version.----  This program is distributed in the hope that it will be useful,--  but WITHOUT ANY WARRANTY; without even the implied warranty of--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the--  GNU General Public License for more details.----  You should have received a copy of the GNU General Public License--  along with this program; if not, write to the Free Software--  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA ------------------------------------------------------------------------------- Entity:      hs-- File:        hs.vhd-- Author:      David Lindh - Gaisler Research-- Description: High speed DDR memory interface------------------------------------------------------------------------------library ieee;use ieee.std_logic_1164.all;library grlib;use grlib.stdlib.all;use grlib.amba.all;library gaisler;use gaisler.misc.all;library techmap;use techmap.gencomp.all;use techmap.allmem.all;library gaisler;use gaisler.ddrrec.all;entity hs is  generic(    tech      : in integer;    dqsize    : in integer;    dmsize    : in integer;    strobesize: in integer;    clkperiod : in integer);  port (    rst       : in std_ulogic;    clk0      : in std_ulogic;    clk90     : in std_ulogic;    clk180    : in std_ulogic;    clk270    : in std_ulogic;    hclk      : in std_ulogic;    hssi      : in  hs_in_type;    hsso      : out hs_out_type); end entity hs; architecture rtl of hs is   type wait_times_row_type is array(7 downto 0) of integer range 0 to 31;   type wait_times_matrix_type is array(7 downto 0) of wait_times_row_type;   constant DELAY_15NS  : integer := (((15*1000)-1) / (clkperiod*1000))+1;   constant DELAY_20NS  : integer := (((20*1000)-1) / (clkperiod*1000))+1;   constant DELAY_50NS  : integer := (((50*1000)-1) / (clkperiod*1000))+1;   constant DELAY_75NS  : integer := (((75*1000)-1) / (clkperiod*1000))+1;   constant DELAY_80NS  : integer := (((80*1000)-1) / (clkperiod*1000))+1;   constant DELAY_120NS : integer := (((120*1000)-1) / (clkperiod*1000))+1;                                        constant wait_times : wait_times_matrix_type :=   -- NOP,BST,READ,WRITE,ACT,PRE,RFSH,LMR     ((0, 0, 0, 0, 0, 0, 0, 0),      (0, 0, 0, 0, 0, 0, 0, 0),      (0, 0, 0, 2, DELAY_20NS, 10, 10, 10),      (0, 0, 3, 0, DELAY_20NS, 10, 10, 10),      (0, 0, DELAY_20NS, 1+DELAY_15NS+DELAY_20NS, DELAY_15NS, DELAY_20NS, DELAY_120NS, 2),      (0, 0, 0, 1+DELAY_15NS, DELAY_50NS, DELAY_20NS, DELAY_120NS, 2),      (0, 0, DELAY_20NS, 1+DELAY_15NS+DELAY_20NS, 10, DELAY_20NS, DELAY_120NS, 2),      (0, 0, DELAY_20NS, 1+DELAY_15NS+DELAY_20NS, 10, DELAY_20NS, DELAY_120NS, 2));          --signal cmdr : cmd_reg_type; signal cmdri: cmd_reg_type;   signal rwr  : rw_reg_type; signal rwri : rw_reg_type;   signal data_out      : std_logic_vector((dqsize-1) downto 0);   signal data_in       : std_logic_vector((dqsize-1) downto 0);   signal strobe_out    : std_logic_vector((strobesize-1) downto 0);   signal mask_out      : std_logic_vector((dmsize-1) downto 0);   signal dq1_i    : std_logic_vector((dqsize-1) downto 0);   signal dq1del_i : std_logic_vector((dqsize-1) downto 0);   signal dq2_i    : std_logic_vector((dqsize-1) downto 0);   signal dq1_o    : std_logic_vector((dqsize-1) downto 0);   signal dq2_o    : std_logic_vector((dqsize-1) downto 0);   signal dm1_o    : std_logic_vector((dmsize-1) downto 0);   signal dm2_o    : std_logic_vector((dmsize-1) downto 0);   signal dqs1_o, dqs2_o, w_ce, r_ce, vcc, gnd   : std_ulogic;   -- DQS delay control signal   signal uddcntl : std_ulogic;   signal lock    : std_ulogic;   signal dqsdel  : std_ulogic;   signal read    : std_ulogic;   signal dqso    : std_logic_vector((strobesize-1) downto 0);   signal ddrclkpol : std_logic_vector((strobesize-1) downto 0);   signal invrst  : std_logic;   signal clk_90  :std_ulogic;begin   -------------------------------------------------------------------------------   rwcomb : process(rst, hssi, rwr, dq1_i, dq1del_i, dq2_i)  variable v : rw_reg_type;begin  v:= rwr;  v.set_cmd := CMD_NOP;  v.set_adr := (others => '0');  v.set_cs := "11";  v.begin_read := '0';  v.begin_write := '0';   -------------------------------------------------------------------------------   -- Buffer for incoming command-------------------------------------------------------------------------------   case v.cbufstate is      when no_cmd =>         v.hs_busy := '0';         if hssi.cmd_valid = '1' then           v.next_bl  := hssi.bl; v.next_buf := hssi.buf; v.next_cas := hssi.cas;           v.next_adr := hssi.adr; v.next_cs := hssi.cs; v.next_cmd := hssi.cmd;           v.next_ml := hssi.ml; v.next_ahb := hssi.ahb;           v.cbufstate := new_cmd;         end if;      when new_cmd =>         v.hs_busy := '1';   end case;   -------------------------------------------------------------------------------  -- Send commands-------------------------------------------------------------------------------case v.cmdstate is when idle =>    v.holdcnt := 0;   if rwr.cbufstate = new_cmd then    v.rw_cmd := rwr.next_cmd;    v.rw_bl := rwr.next_bl;    v.rw_cas := 2 + conv_integer(rwr.next_cas(0))+ conv_integer(rwr.next_cas(1));    v.set_cmd := rwr.next_cmd;    v.set_adr := rwr.next_adr;    v.set_cs  := rwr.next_cs;    v.set_cke := '1';     v.cbufstate := no_cmd;    v.cmdstate := hold;      -- Read command, delay start of Read machine   if rwr.next_cmd = CMD_READ then         if rwr.next_cas = "00" then       -- cas 2            v.readwait(5) := '1';         v.bufwait(5):=  rwr.next_buf;          v.ahbwait(5) := rwr.next_ahb;         v.blwait(5) := rwr.next_bl;         v.caswait(5) := rwr.next_cas(0);               else                            -- cas 2.5 or 3         v.readwait(6) := '1';         v.bufwait(6):=  rwr.next_buf;         v.ahbwait(6) := rwr.next_ahb;         v.blwait(6) := rwr.next_bl;         v.caswait(6) := rwr.next_cas(0);      end if;       -- Calculate delay until write can begin       v.r2wholdcnt :=  rwr.rw_cas  + rwr.rw_bl/2 +2;            -- Write command, immediately start Write machine    elsif rwr.next_cmd = CMD_WRITE then      v.writewait(1) := '1';      v.bufwait(1):=  rwr.next_buf;      v.ahbwait(1) := rwr.next_ahb;      v.blwait(1) := rwr.next_bl;      v.mlwait(1) := rwr.next_ml;      -- Active command, begin count towards ealiest precharge    elsif rwr.next_cmd = CMD_ACTIVE then       v.act2precnt := DELAY_50NS-1;       end if; end if;    -- Wait until next cmd is valid to send when hold =>          v.set_cmd := CMD_NOP;     v.set_adr := (others => '0');     v.set_cs := "11";     -- Some waittimes which isn't constant     if v.rw_cmd = CMD_READ and rwr.next_cmd = CMD_WRITE then       v.wait_time := v.rw_cas  + v.rw_bl/2;     elsif v.rw_cmd = CMD_READ or v.rw_cmd = CMD_WRITE then       v.wait_time := v.rw_bl/2;     else       v.wait_time := 0;     end if;     -- Calculate total wait time     if rwr.cbufstate = new_cmd then       if ((v.holdcnt+2 >= wait_times(conv_integer(rwr.next_cmd))(conv_integer(v.rw_cmd))+ v.wait_time)           and (v.r2wholdcnt = 0 or rwr.next_cmd /= CMD_WRITE)            and (v.act2precnt = 0 or rwr.next_cmd /= CMD_PRE)) then         v.cmdstate := idle;       end if;     elsif v.holdcnt >= 4+DELAY_120NS then       v.cmdstate := idle;     end if;          v.holdcnt := v.holdcnt +1;end case;-- Separate count for time beteen a read and write and between  active and prechargeif v.r2wholdcnt /= 0 then v.r2wholdcnt := v.r2wholdcnt -1; end if;if v.act2precnt /= 0 then v.act2precnt := v.act2precnt -1; end if;--------------------------------------------------------------------------------- Delay cmd data for Read machine during CAS period-------------------------------------------------------------------------------  if v.readwait(0) = '1' or v.writewait(0) = '1' then    v.begin_read :=  v.readwait(0);    v.begin_write := v.writewait(0);    v.use_ahb := v.ahbwait(0);    v.use_buf := v.bufwait(0);    v.use_bl := v.blwait(0);    if v.writewait(0) = '1' then      v.use_ml := v.mlwait(0);    else      v.use_cas := v.caswait(0);    end if;  end if;       v.readwait := '0' & v.readwait(6 downto 1);  v.writewait := '0' & v.writewait(1);  v.bufwait(5 downto 0) :=  v.bufwait(6 downto 1);  v.ahbwait := 0 & v.ahbwait(6 downto 1);  v.blwait := 8 & v.blwait(6 downto 1);  v.mlwait := 1 & v.mlwait(1);  v.caswait := '0' & v.caswait(6 downto 1);  -------------------------------------------------------------------------------   -- Send/recieve data-------------------------------------------------------------------------------  -- Read and Write routinescase v.rwstate is  when idle =>    v.sync_adr(0)  := (v.cur_buf(0)+1) & "00";    v.sync_adr(1)  := (v.cur_buf(1)+1) & "00";    v.cmdDone   := v.cur_buf;    v.sync_write:= "00";    v.dq_dqs_oe := '1';                      v.dqs1_o    := '0';                        v.w_ce      := '0';                          v.r_ce      := '1';                           v.cnt       := 0;             if v.begin_write = '1' then       v.cur_buf(v.use_ahb)  := v.use_buf;       v.cur_ahb   := v.use_ahb;       v.dq_dqs_oe := '0';                        v.w_ce      := '1';                             v.cnt       := v.cnt +2;       if v.use_bl = 2 then         v.sync_adr(v.use_ahb) := (v.use_buf +1) & "00";       else         v.sync_adr(v.use_ahb) := v.use_buf & "01";       end if;       v.rwstate := w;            elsif v.begin_read = '1' then       v.cur_buf(v.use_ahb)   := v.use_buf;       v.cur_ahb   := v.use_ahb;       v.sync_adr(v.use_ahb)  := v.use_buf & "00";       v.sync_write(v.use_ahb) := '1';       v.cnt        := v.cnt +2;       v.cmdDone(v.use_ahb)    := v.use_buf;       if v.use_cas = '0' then      -- Cas 2 or 3          v.sync_wdata((2*dqsize)-1 downto 0) :=  dq1_i & dq2_i;       else                           -- Cas 2.5         v.sync_wdata((2*dqsize)-1 downto 0) :=  dq2_i & dq1del_i;       end if;       v.rwstate := r;     end if;  -- Write  when w =>     v.dqs1_o    := '1';                 

⌨️ 快捷键说明

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