alexh wrote:
Are you going to release details about the modification to MiniMig core to use an SDRAM controller rather than SRAM?
Doesnt have to be "code", just in overview.
How does latency and burstiness affect things? Did you run the SDRAM at a multiple of the MiniMig core frequency?
Hi alexh,
I don't know how exactly i can help you?
The sdram clock is 7,09Mhzx16=113MHz. I have remove the DCM from the minimig source and all clocks came from the SDRAM Controller. So I have a synchron design. Look into the attatched code. The C_7m is the clock for the minimig. If it is Low The Controller Read or Write Minimig data. If it is high the Controller read or write spihost data.
the latency is 2 and the read burst is 4.
The Spihost works with the nice old Z80 but with the power of 60MHz. For the Z80 the controller also cache 8 opcode bytes.
If i use also cache opcodes for the 68K i can make the minimig 2-4x faster i think.
--
-- Copyright (c) 2006-2007 Tobias Gubener
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity sdram is
port
(
sdata : inout std_logic_vector(15 downto 0);
sdaddr : out std_logic_vector(12 downto 0);
dqm : out std_logic_vector(3 downto 0);
sd_cs : out std_logic_vector(3 downto 0);
ba : buffer std_logic_vector(1 downto 0);
sd_we : out std_logic;
sd_ras : out std_logic;
sd_cas : out std_logic;
sysclk : in std_logic;
reset : in std_logic;
zdatawr : in std_logic_vector(7 downto 0);
zAddr : in std_logic_vector(22 downto 0);
zwr : in std_logic;
datawr : in std_logic_vector(15 downto 0);
rAddr : in std_logic_vector(22 downto 0);
rwr : in std_logic;
dwrL : in std_logic;
dwrU : in std_logic;
zstate : in std_logic_vector(2 downto 0);
dataout : out std_logic_vector(15 downto 0);
zdataout : out std_logic_vector(7 downto 0);
c_56m : out std_logic;
zena_o : out std_logic;
c_28m : out std_logic;
c_7m : out std_logic;
reset_out : out std_logic
);
end;
architecture rtl of sdram is
signal initstate :std_logic_vector(3 downto 0);
signal slow :std_logic_vector(7 downto 0);
signal pass :std_logic_vector(1 downto 0);
signal datard :std_logic;
signal sdcom_ena :std_logic;
signal isd_ras :std_logic;
signal isd_cas :std_logic;
signal isd_we :std_logic;
signal nanostate :std_logic_vector(3 downto 0);
signal ras_pos :std_logic;
signal wr_int :std_logic;
signal rd_int :std_logic;
signal init_done :std_logic;
signal Addr :std_logic_vector(22 downto 0);
signal isdaddr :std_logic_vector(12 downto 0);
signal isd_cs :std_logic_vector(3 downto 0);
signal datain :std_logic_vector(15 downto 0);
signal casaddr :std_logic_vector(10 downto 0);
signal casba :std_logic_vector(1 downto 0);
signal wr :std_logic;
signal sdwrite :std_logic;
signal nextpix :std_logic_vector(15 downto 0);
signal zena :std_logic;
signal zcache :std_logic_vector(63 downto 0);
signal zcache_addr :std_logic_vector(22 downto 0);
signal zcache_recall :std_logic;
signal fill_zcache :std_logic;
signal match_zcache :std_logic;
signal zvalid :std_logic;
signal zequal :std_logic;
signal V_cycle :std_logic;
signal T_cycle :std_logic;
signal R_cycle :std_logic;
signal Z_cycle :std_logic;
begin
Addr <= rAddr when R_cycle='1' else zAddr;
wr <= '0' when (R_cycle='1' AND rwr='0') OR (Z_cycle='1' AND zwr='0') else '1';
c_7m <= T_cycle;
sd_ras <= isd_ras or sdcom_ena;
sd_cas <= isd_cas or sdcom_ena;
sd_we <= isd_we or sdcom_ena;
sdaddr <= isdaddr;
sd_cs <= isd_cs when sdcom_ena='0' else "1111";
zena_o <= '1' when zena='1' or match_zcache='1' else '0';
reset_out <= init_done AND reset;
process (sysclk, zAddr, zcache_addr, zcache, zstate, zequal, zvalid, match_zcache, nextpix) begin
if zaddr(22 downto 3)=zcache_addr(22 downto 3) then
zequal <='1';
else
zequal <='0';
end if;
if (zstate(2)='1' or zstate(1 downto 0)="01" or (zstate="00" and zequal='1' and zvalid='1')) then
match_zcache <='1';
else
match_zcache <='0';
end if;
case match_zcache&(zaddr(2 downto 1)-zcache_addr(2 downto 1)) is
when "100"=>
if zaddr(0)='1' then
zdataout <= zcache(55 downto 48);
else
zdataout <= zcache(63 downto 56);
end if;
when "101"=>
if zaddr(0)='1' then
zdataout <= zcache(39 downto 32);
else
zdataout <= zcache(47 downto 40);
end if;
when "110"=>
if zaddr(0)='1' then
zdataout <= zcache(23 downto 16);
else
zdataout <= zcache(31 downto 24);
end if;
when "111"=>
if zaddr(0)='1' then
zdataout <= zcache(7 downto 0);
else
zdataout <= zcache(15 downto 8);
end if;
when others=>
if zaddr(0)='1' then
zdataout <= nextpix(7 downto 0);
else
zdataout <= nextpix(15 downto 8);
end if;
end case;
end process;
process (sysclk) begin
if (sysclk'event and sysclk='1') then
if nanostate(2 downto 0)="111" then
R_cycle <= '0';
V_cycle <= '0';
T_cycle <= '1';
Z_cycle <= '0';
IF slow(2 downto 0)=5 THEN
slow <= slow+3;
ELSE
slow <= slow+1;
END IF;
case slow(3 downto 0) is
when "0001" => V_cycle <= '1'; --refresh cycle
when "0000"|"1000"|"0010"|"0100"|"1010"|"1100" => R_cycle <= '1';
T_cycle <= '0';
when others => Z_cycle <= '1';
end case;
end if;
end if;
end process;
--Datenübernahme
process (sysclk, reset) begin
if reset = '0' then
zcache_recall <= '0';
zvalid <= '0';
zena <= '0';
elsif (sysclk'event and sysclk='1') then
nextpix <= sdata;
if zequal='1' and zstate="11" then
zvalid <= '0';
end if;
case nanostate(2 downto 0) is
when "000" =>
c_56m <= '0';
if fill_zcache='1' then
zcache(47 downto 32) <= nextpix;
end if;
when "001" =>
c_28m <= '0';
c_56m <= '1';
if fill_zcache='1' then
zcache(31 downto 16) <= nextpix;
end if;
when "010" =>
zcache_recall <= match_zcache;
c_56m <= '0';
if fill_zcache='1' then
zcache(15 downto 0) <= nextpix;
end if;
fill_zcache <= '0';
when "011" =>
c_28m <= '1';
c_56m <= '1';
if Z_cycle='1' then
if zcache_recall='0' then
zena <= '1';
if zstate="00" then
zcache_addr <= zaddr;
fill_zcache <= '1';
zvalid <= '1';
end if;
end if;
end if;
when "100" =>
c_56m <= '0';
when "101" =>
c_28m <= '0';
c_56m <= '1';
when "110" =>
c_56m <= '0';
if fill_zcache='1' then
zcache(63 downto 48) <= sdata;
end if;
if R_cycle='1' then
dataout <= sdata;
end if;
when "111" =>
c_28m <= '1';
zena <= '0';
c_56m <= '1';
when others =>
end case;
end if;
end process;
process (sysclk, reset, sdwrite, datain) begin
IF sdwrite='1' THEN
sdata <= datain;
ELSE
sdata <= "ZZZZZZZZZZZZZZZZ";
END IF;
if reset = '0' then
initstate <= (others => '0');
init_done <= '0';
nanostate <= "0000";
else
if (sysclk'event and sysclk='1') then
sdcom_ena <= '1';
ras_pos <= '0';
nanostate <='0'&nanostate(2 downto 0)+1;
if ras_pos='1' then
casaddr <= addr(10 downto 0);
casba <= ba;
IF R_cycle='1' THEN
datain <= datawr;
ELSE
datain <= zdatawr&zdatawr;
END IF;
end if;
case nanostate(2 downto 0) is --LATENCY=2
when "000" => pass <= "00";
when "001" => sdcom_ena <= '0';
ras_pos <= '1';
when "010" => pass <= "01";
sdwrite <= '1';
if V_cycle='1' then
wr_int <= '1';
rd_int <= '1';
else
wr_int <= wr ;
rd_int <= '0';
end if;
when "011" =>
sdcom_ena <= '0';
when "100" =>
pass <= "11";
sdwrite <= '0';
when "101" =>
when "110" =>
when "111" =>
if initstate /= "1111" then
initstate <= initstate+1;
else
init_done <='1';
end if;
when others =>
end case;
end if;
end if;
end process;
process (initstate, pass, addr, wr, datain, init_done, casaddr, rd_int, wr_int, dwrU, dwrL, casba, Z_cycle, V_cycle, zaddr) begin
isdaddr<="XXXXXXXXXXXXX";
isd_cs <= "1111"; --NOP
isd_ras <= '1';
isd_cas <= '1';
isd_we <= '1';
ba <= Addr(22 downto 21);
if wr_int='0' then
if Z_cycle='1' THEN
dqm <= ("11"& zaddr(0)& not zaddr(0));
else
dqm <= ("11"& dwrU& dwrL);
end if;
else
dqm <= "1100";
end if;
if init_done='0' then
case initstate & pass is
when "001000" => --PRECHARGE
isdaddr(10) <= '1'; --all banks
isd_cs <="0000";
isd_ras <= '0';
isd_cas <= '1';
isd_we <= '0';
when "001100"|"010000"|"010100"|"011000"|"011100"|"100000"|"100100"|"101000"|"101100"|"110000" => --AUTOREFRESH
isd_cs <="0000";
isd_ras <= '0';
isd_cas <= '0';
isd_we <= '1';
when "110100" => --LOAD MODE REGISTER
isd_cs <="0000";
isd_ras <= '0';
isd_cas <= '0';
isd_we <= '0';
ba <= "00";
isdaddr <= "0001000100010"; --BURST=4 LATENCY=2
when others => --NOP
end case;
else
case pass is
when "00" => --ACTIVE
isdaddr <= "0"& addr(20 downto 9);
isd_ras <= '0';
isd_we <= '1';
if V_cycle='1' then
isd_cs <="0000"; --AUTOREFRESH
isd_cas <= '0';
else
isd_cas <= '1';
isd_cs <= "1110"; --ACTIVE
end if;
when "01" => --READ or Write
ba <= casba;
isdaddr <= '0'& '0' & '1' & "00" & casaddr(8 downto 1);--auto precharge
isd_cs <= "1110";
isd_ras <= '1';
isd_cas <= rd_int;
isd_we <= wr_int;
when others => --NOP
end case;
end if;
end process;
end;