Revision 232
Added by markw almost 11 years ago
mist_5200_sdcard/pll_pal_post.qip | ||
---|---|---|
set_global_assignment -name IP_TOOL_NAME "ALTPLL"
|
||
set_global_assignment -name IP_TOOL_VERSION "13.0"
|
||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "pll_pal_post.vhd"]
|
||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_pal_post.cmp"]
|
||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_pal_post.ppf"]
|
mist_5200_sdcard/pll_pal_pre.qip | ||
---|---|---|
set_global_assignment -name IP_TOOL_NAME "ALTPLL"
|
||
set_global_assignment -name IP_TOOL_VERSION "13.0"
|
||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "pll_pal_pre.vhd"]
|
||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_pal_pre.cmp"]
|
||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_pal_pre.ppf"]
|
mist_5200_sdcard/data_io.wcfg | ||
---|---|---|
<?xml version="1.0" encoding="UTF-8"?>
|
||
<wave_config>
|
||
<wave_state>
|
||
</wave_state>
|
||
<db_ref_list>
|
||
<db_ref path="data_io.wdb" id="1" type="auto">
|
||
<top_modules>
|
||
<top_module name="data_io_tb" />
|
||
<top_module name="numeric_std" />
|
||
<top_module name="std_logic_1164" />
|
||
<top_module name="std_logic_arith" />
|
||
<top_module name="std_logic_textio" />
|
||
<top_module name="std_logic_unsigned" />
|
||
<top_module name="textio" />
|
||
</top_modules>
|
||
</db_ref>
|
||
</db_ref_list>
|
||
<WVObjectSize size="19" />
|
||
<wvobject fp_name="/data_io_tb/reset_n" type="logic" db_ref_id="1">
|
||
<obj_property name="ElementShortName">reset_n</obj_property>
|
||
<obj_property name="ObjectShortName">reset_n</obj_property>
|
||
</wvobject>
|
||
<wvobject fp_name="/data_io_tb/request" type="logic" db_ref_id="1">
|
||
<obj_property name="ElementShortName">request</obj_property>
|
||
<obj_property name="ObjectShortName">request</obj_property>
|
||
</wvobject>
|
||
<wvobject fp_name="/data_io_tb/write" type="logic" db_ref_id="1">
|
||
<obj_property name="ElementShortName">write</obj_property>
|
||
<obj_property name="ObjectShortName">write</obj_property>
|
||
</wvobject>
|
||
<wvobject fp_name="/data_io_tb/ready" type="logic" db_ref_id="1">
|
||
<obj_property name="ElementShortName">ready</obj_property>
|
||
<obj_property name="ObjectShortName">ready</obj_property>
|
||
</wvobject>
|
||
<wvobject fp_name="/data_io_tb/spi_miso" type="logic" db_ref_id="1">
|
||
<obj_property name="ElementShortName">spi_miso</obj_property>
|
||
<obj_property name="ObjectShortName">spi_miso</obj_property>
|
||
</wvobject>
|
||
<wvobject fp_name="/data_io_tb/spi_mosi" type="logic" db_ref_id="1">
|
||
<obj_property name="ElementShortName">spi_mosi</obj_property>
|
||
<obj_property name="ObjectShortName">spi_mosi</obj_property>
|
||
</wvobject>
|
||
<wvobject fp_name="/data_io_tb/spi_clk" type="logic" db_ref_id="1">
|
||
<obj_property name="ElementShortName">spi_clk</obj_property>
|
||
<obj_property name="ObjectShortName">spi_clk</obj_property>
|
||
</wvobject>
|
||
<wvobject fp_name="/data_io_tb/spi_tx_data" type="array" db_ref_id="1">
|
||
<obj_property name="ElementShortName">spi_tx_data[7:0]</obj_property>
|
||
<obj_property name="ObjectShortName">spi_tx_data[7:0]</obj_property>
|
||
<obj_property name="Radix">HEXRADIX</obj_property>
|
||
</wvobject>
|
||
<wvobject fp_name="/data_io_tb/spi_rx_data" type="array" db_ref_id="1">
|
||
<obj_property name="ElementShortName">spi_rx_data[7:0]</obj_property>
|
||
<obj_property name="ObjectShortName">spi_rx_data[7:0]</obj_property>
|
||
<obj_property name="Radix">HEXRADIX</obj_property>
|
||
</wvobject>
|
||
<wvobject fp_name="/data_io_tb/spi_busy" type="logic" db_ref_id="1">
|
||
<obj_property name="ElementShortName">spi_busy</obj_property>
|
||
<obj_property name="ObjectShortName">spi_busy</obj_property>
|
||
</wvobject>
|
||
<wvobject fp_name="/data_io_tb/spi_enable" type="logic" db_ref_id="1">
|
||
<obj_property name="ElementShortName">spi_enable</obj_property>
|
||
<obj_property name="ObjectShortName">spi_enable</obj_property>
|
||
</wvobject>
|
||
<wvobject fp_name="/data_io_tb/data_io/cmd_reg" type="array" db_ref_id="1">
|
||
<obj_property name="ElementShortName">cmd_reg[7:0]</obj_property>
|
||
<obj_property name="ObjectShortName">cmd_reg[7:0]</obj_property>
|
||
<obj_property name="Radix">HEXRADIX</obj_property>
|
||
</wvobject>
|
||
<wvobject fp_name="/data_io_tb/data_io/cnt_reg" type="array" db_ref_id="1">
|
||
<obj_property name="ElementShortName">cnt_reg[15:0]</obj_property>
|
||
<obj_property name="ObjectShortName">cnt_reg[15:0]</obj_property>
|
||
<obj_property name="Radix">HEXRADIX</obj_property>
|
||
</wvobject>
|
||
<wvobject fp_name="/data_io_tb/data_io/sbuf_reg" type="array" db_ref_id="1">
|
||
<obj_property name="ElementShortName">sbuf_reg[6:0]</obj_property>
|
||
<obj_property name="ObjectShortName">sbuf_reg[6:0]</obj_property>
|
||
<obj_property name="Radix">HEXRADIX</obj_property>
|
||
</wvobject>
|
||
<wvobject fp_name="/data_io_tb/addr" type="array" db_ref_id="1">
|
||
<obj_property name="ElementShortName">addr[8:0]</obj_property>
|
||
<obj_property name="ObjectShortName">addr[8:0]</obj_property>
|
||
<obj_property name="Radix">HEXRADIX</obj_property>
|
||
</wvobject>
|
||
<wvobject fp_name="/data_io_tb/data_out" type="array" db_ref_id="1">
|
||
<obj_property name="ElementShortName">data_out[7:0]</obj_property>
|
||
<obj_property name="ObjectShortName">data_out[7:0]</obj_property>
|
||
<obj_property name="Radix">HEXRADIX</obj_property>
|
||
</wvobject>
|
||
<wvobject fp_name="/data_io_tb/data_in" type="array" db_ref_id="1">
|
||
<obj_property name="ElementShortName">data_in[7:0]</obj_property>
|
||
<obj_property name="ObjectShortName">data_in[7:0]</obj_property>
|
||
<obj_property name="Radix">HEXRADIX</obj_property>
|
||
</wvobject>
|
||
<wvobject fp_name="/data_io_tb/wr_en" type="logic" db_ref_id="1">
|
||
<obj_property name="ElementShortName">wr_en</obj_property>
|
||
<obj_property name="ObjectShortName">wr_en</obj_property>
|
||
</wvobject>
|
||
<wvobject fp_name="/data_io_tb/spi_ss_io" type="array" db_ref_id="1">
|
||
<obj_property name="ElementShortName">spi_ss_io[1:0]</obj_property>
|
||
<obj_property name="ObjectShortName">spi_ss_io[1:0]</obj_property>
|
||
</wvobject>
|
||
</wave_config>
|
mist_5200_sdcard/atari800core.qpf | ||
---|---|---|
# -------------------------------------------------------------------------- #
|
||
#
|
||
# Copyright (C) 1991-2012 Altera Corporation
|
||
# Your use of Altera Corporation's design tools, logic functions
|
||
# and other software and tools, and its AMPP partner logic
|
||
# functions, and any output files from any of the foregoing
|
||
# (including device programming or simulation files), and any
|
||
# associated documentation or information are expressly subject
|
||
# to the terms and conditions of the Altera Program License
|
||
# Subscription Agreement, Altera MegaCore Function License
|
||
# Agreement, or other applicable license agreement, including,
|
||
# without limitation, that your use is for the sole purpose of
|
||
# programming logic devices manufactured by Altera and sold by
|
||
# Altera or its authorized distributors. Please refer to the
|
||
# applicable agreement for further details.
|
||
#
|
||
# -------------------------------------------------------------------------- #
|
||
#
|
||
# Quartus II 64-Bit
|
||
# Version 12.1 Build 243 01/31/2013 Service Pack 1 SJ Web Edition
|
||
# Date created = 13:58:38 April 11, 2013
|
||
#
|
||
# -------------------------------------------------------------------------- #
|
||
|
||
QUARTUS_VERSION = "12.1"
|
||
DATE = "13:58:38 April 11, 2013"
|
||
|
||
# Revisions
|
||
|
||
PROJECT_REVISION = "atari800core"
|
mist_5200_sdcard/makeqsf | ||
---|---|---|
#!/usr/bin/perl -w
|
||
use strict;
|
||
|
||
my $qsf_in = shift @ARGV;
|
||
my $qsf_out = $qsf_in;
|
||
$qsf_out =~ s/.*\///;
|
||
|
||
open (QSF_IN,$qsf_in) or die "Failed to open $qsf_in";
|
||
my @qsf_base = <QSF_IN>;
|
||
close (QSF_IN);
|
||
|
||
open (QSF_OUT,">$qsf_out") or die "Failed to open $qsf_out";
|
||
print QSF_OUT @qsf_base;
|
||
print QSF_OUT "\n";
|
||
|
||
foreach (@ARGV)
|
||
{
|
||
my @vhdl = glob ("$_/*.vhd");
|
||
push @vhdl, glob ("$_/*.vhdl");
|
||
my @verilog = glob ("$_/*.v");
|
||
my @qip = glob ("$_/*.qip");
|
||
|
||
foreach (@verilog)
|
||
{
|
||
print QSF_OUT "set_global_assignment -name VERILOG_FILE $_\n";
|
||
}
|
||
|
||
foreach (@vhdl)
|
||
{
|
||
print QSF_OUT "set_global_assignment -name VHDL_FILE $_\n";
|
||
}
|
||
|
||
foreach (@qip)
|
||
{
|
||
print QSF_OUT "set_global_assignment -name QIP_FILE $_\n";
|
||
}
|
||
}
|
||
|
||
close (QSF_OUT);
|
||
|
||
mist_5200_sdcard/pll_ntsc.cmp | ||
---|---|---|
--Copyright (C) 1991-2013 Altera Corporation
|
||
--Your use of Altera Corporation's design tools, logic functions
|
||
--and other software and tools, and its AMPP partner logic
|
||
--functions, and any output files from any of the foregoing
|
||
--(including device programming or simulation files), and any
|
||
--associated documentation or information are expressly subject
|
||
--to the terms and conditions of the Altera Program License
|
||
--Subscription Agreement, Altera MegaCore Function License
|
||
--Agreement, or other applicable license agreement, including,
|
||
--without limitation, that your use is for the sole purpose of
|
||
--programming logic devices manufactured by Altera and sold by
|
||
--Altera or its authorized distributors. Please refer to the
|
||
--applicable agreement for further details.
|
||
|
||
|
||
component pll_ntsc
|
||
PORT
|
||
(
|
||
inclk0 : IN STD_LOGIC := '0';
|
||
c0 : OUT STD_LOGIC ;
|
||
c1 : OUT STD_LOGIC ;
|
||
c2 : OUT STD_LOGIC ;
|
||
c3 : OUT STD_LOGIC ;
|
||
locked : OUT STD_LOGIC
|
||
);
|
||
end component;
|
mist_5200_sdcard/tb_data/data_io_tb.vhd | ||
---|---|---|
library ieee;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.std_logic_unsigned.all;
|
||
use ieee.numeric_std.all;
|
||
use ieee.std_logic_textio.all;
|
||
|
||
library std_developerskit ; -- used for to_string
|
||
-- use std_developerskit.std_iopak.all;
|
||
|
||
entity data_io_tb is
|
||
end;
|
||
|
||
architecture rtl of data_io_tb is
|
||
|
||
constant CLK_A_PERIOD : time := 1 us / (1.79*32);
|
||
|
||
signal CLK_A : std_logic;
|
||
|
||
signal reset_n : std_logic;
|
||
|
||
signal spi_clk : std_logic;
|
||
signal spi_ss_io : std_logic_vector(1 downto 0);
|
||
signal spi_miso : std_logic;
|
||
signal spi_mosi : std_logic;
|
||
|
||
signal request : std_logic;
|
||
signal write : std_logic;
|
||
signal ready : std_logic;
|
||
signal sector : std_logic_vector(23 downto 0);
|
||
|
||
signal addr : std_logic_vector(8 downto 0);
|
||
signal data_out : std_logic_vector(7 downto 0);
|
||
signal data_in : std_logic_vector(7 downto 0);
|
||
signal wr_en : std_logic;
|
||
|
||
signal spi_enable : std_logic;
|
||
signal spi_tx_data : std_logic_vector(7 downto 0);
|
||
signal spi_rx_data : std_logic_vector(7 downto 0);
|
||
signal spi_busy : std_logic;
|
||
|
||
signal spi_addr : integer;
|
||
|
||
begin
|
||
p_clk_gen_a : process
|
||
begin
|
||
clk_a <= '1';
|
||
wait for CLK_A_PERIOD/2;
|
||
clk_a <= '0';
|
||
wait for CLK_A_PERIOD - (CLK_A_PERIOD/2 );
|
||
end process;
|
||
|
||
reset_n <= '0', '1' after 1000ns;
|
||
|
||
|
||
spi_master1 : entity work.spi_master
|
||
generic map(slaves=>2,d_width=>8)
|
||
port map (clock=>clk_a,reset_n=>reset_n,enable=>spi_enable,cpol=>'0',cpha=>'0',cont=>'0',clk_div=>4,addr=>spi_addr,
|
||
tx_data=>spi_tx_data, miso=>spi_miso,sclk=>spi_clk,ss_n=>spi_ss_io,mosi=>spi_mosi,
|
||
rx_data=>spi_rx_data,busy=>spi_busy);
|
||
|
||
spi_fake : process
|
||
variable type_conv : std_logic_vector(8 downto 0);
|
||
begin
|
||
spi_enable <= '0';
|
||
spi_addr <= 0;
|
||
wait for 1500us;
|
||
|
||
spi_tx_data <= x"50";
|
||
spi_enable <= '1';
|
||
wait for CLK_A_PERIOD*2;
|
||
spi_tx_data <= x"FF";
|
||
spi_enable <= '0';
|
||
wait until spi_busy='0';
|
||
|
||
for i in 0 to 3 loop
|
||
spi_tx_data <= x"ff";
|
||
spi_enable <= '1';
|
||
wait for CLK_A_PERIOD*2;
|
||
spi_tx_data <= x"FF";
|
||
spi_enable <= '0';
|
||
wait until spi_busy='0';
|
||
end loop;
|
||
|
||
spi_addr <= 1;
|
||
spi_tx_data <= x"ff";
|
||
spi_enable <= '1';
|
||
wait for CLK_A_PERIOD*2;
|
||
spi_tx_data <= x"FF";
|
||
spi_enable <= '0';
|
||
wait until spi_busy='0';
|
||
spi_addr <= 0;
|
||
wait for 20us;
|
||
|
||
spi_tx_data <= x"51";
|
||
spi_enable <= '1';
|
||
wait for CLK_A_PERIOD*2;
|
||
spi_tx_data <= x"FF";
|
||
spi_enable <= '0';
|
||
wait until spi_busy='0';
|
||
|
||
for i in 0 to 511 loop
|
||
type_conv := std_logic_vector(to_unsigned(i,9));
|
||
spi_tx_data <= type_conv(7 downto 0);
|
||
spi_enable <= '1';
|
||
wait for CLK_A_PERIOD*4;
|
||
spi_tx_data <= x"FF";
|
||
spi_enable <= '0';
|
||
wait until spi_busy='0';
|
||
end loop;
|
||
|
||
spi_tx_data <= x"ff";
|
||
spi_enable <= '1';
|
||
wait for CLK_A_PERIOD*2;
|
||
spi_tx_data <= x"FF";
|
||
spi_enable <= '0';
|
||
wait until spi_busy='0';
|
||
|
||
-- NEXT
|
||
|
||
spi_addr <= 1;
|
||
spi_tx_data <= x"ff";
|
||
spi_enable <= '1';
|
||
wait for CLK_A_PERIOD*2;
|
||
spi_tx_data <= x"FF";
|
||
spi_enable <= '0';
|
||
wait until spi_busy='0';
|
||
spi_addr <= 0;
|
||
wait for 20us;
|
||
|
||
spi_tx_data <= x"50";
|
||
spi_enable <= '1';
|
||
wait for CLK_A_PERIOD*2;
|
||
spi_tx_data <= x"FF";
|
||
spi_enable <= '0';
|
||
wait until spi_busy='0';
|
||
|
||
for i in 0 to 3 loop
|
||
spi_tx_data <= x"ff";
|
||
spi_enable <= '1';
|
||
wait for CLK_A_PERIOD*2;
|
||
spi_tx_data <= x"FF";
|
||
spi_enable <= '0';
|
||
wait until spi_busy='0';
|
||
end loop;
|
||
|
||
spi_addr <= 1;
|
||
spi_tx_data <= x"ff";
|
||
spi_enable <= '1';
|
||
wait for CLK_A_PERIOD*2;
|
||
spi_tx_data <= x"FF";
|
||
spi_enable <= '0';
|
||
wait until spi_busy='0';
|
||
spi_addr <= 0;
|
||
wait for 20us;
|
||
|
||
spi_tx_data <= x"51";
|
||
spi_enable <= '1';
|
||
wait for CLK_A_PERIOD*2;
|
||
spi_tx_data <= x"FF";
|
||
spi_enable <= '0';
|
||
wait until spi_busy='0';
|
||
|
||
for i in 0 to 511 loop
|
||
type_conv := std_logic_vector(to_unsigned(511-i,9));
|
||
spi_tx_data <= type_conv(7 downto 0);
|
||
spi_enable <= '1';
|
||
wait for CLK_A_PERIOD*4;
|
||
spi_tx_data <= x"FF";
|
||
spi_enable <= '0';
|
||
wait until spi_busy='0';
|
||
end loop;
|
||
|
||
spi_tx_data <= x"ff";
|
||
spi_enable <= '1';
|
||
wait for CLK_A_PERIOD*2;
|
||
spi_tx_data <= x"FF";
|
||
spi_enable <= '0';
|
||
wait until spi_busy='0';
|
||
|
||
-- NEXT - WRITE...
|
||
|
||
spi_addr <= 1;
|
||
spi_tx_data <= x"ff";
|
||
spi_enable <= '1';
|
||
wait for CLK_A_PERIOD*2;
|
||
spi_tx_data <= x"FF";
|
||
spi_enable <= '0';
|
||
wait until spi_busy='0';
|
||
spi_addr <= 0;
|
||
wait for 20us;
|
||
|
||
spi_tx_data <= x"50";
|
||
spi_enable <= '1';
|
||
wait for CLK_A_PERIOD*2;
|
||
spi_tx_data <= x"FF";
|
||
spi_enable <= '0';
|
||
wait until spi_busy='0';
|
||
|
||
for i in 0 to 3 loop
|
||
spi_tx_data <= x"ff";
|
||
spi_enable <= '1';
|
||
wait for CLK_A_PERIOD*2;
|
||
spi_tx_data <= x"FF";
|
||
spi_enable <= '0';
|
||
wait until spi_busy='0';
|
||
end loop;
|
||
|
||
spi_addr <= 1;
|
||
spi_tx_data <= x"ff";
|
||
spi_enable <= '1';
|
||
wait for CLK_A_PERIOD*2;
|
||
spi_tx_data <= x"FF";
|
||
spi_enable <= '0';
|
||
wait until spi_busy='0';
|
||
spi_addr <= 0;
|
||
wait for 20us;
|
||
|
||
spi_tx_data <= x"52";
|
||
spi_enable <= '1';
|
||
wait for CLK_A_PERIOD*2;
|
||
spi_tx_data <= x"FF";
|
||
spi_enable <= '0';
|
||
wait until spi_busy='0';
|
||
|
||
for i in 0 to 511 loop
|
||
spi_tx_data <= x"FF";
|
||
spi_enable <= '1';
|
||
wait for CLK_A_PERIOD*4;
|
||
spi_tx_data <= x"FF";
|
||
spi_enable <= '0';
|
||
wait until spi_busy='0';
|
||
end loop;
|
||
|
||
spi_tx_data <= x"ff";
|
||
spi_enable <= '1';
|
||
wait for CLK_A_PERIOD*2;
|
||
spi_tx_data <= x"FF";
|
||
spi_enable <= '0';
|
||
wait until spi_busy='0';
|
||
|
||
wait for 100ms;
|
||
|
||
end process;
|
||
|
||
spi_request : process
|
||
begin
|
||
sector <= (others=>'0');
|
||
request <= '0';
|
||
write <= '0';
|
||
wait for 1500us;
|
||
|
||
sector <= x"123456";
|
||
request <= '1';
|
||
wait until ready = '1';
|
||
request <= '0';
|
||
wait for CLK_A_PERIOD*20;
|
||
wait until ready = '0';
|
||
|
||
|
||
sector <= x"654321";
|
||
request <= '1';
|
||
wait until ready = '1';
|
||
request <= '0';
|
||
wait for CLK_A_PERIOD*20;
|
||
wait until ready = '0';
|
||
|
||
sector <= x"111111";
|
||
write <= '1';
|
||
wait until ready = '1';
|
||
write <= '0';
|
||
wait for CLK_A_PERIOD*20;
|
||
wait until ready = '0';
|
||
|
||
wait for 100ms;
|
||
end process;
|
||
|
||
ram : entity work.generic_ram_infer
|
||
generic map
|
||
(
|
||
ADDRESS_WIDTH => 9,
|
||
SPACE => 512,
|
||
DATA_WIDTH => 8
|
||
)
|
||
PORT map
|
||
(
|
||
clock => spi_clk,
|
||
data => data_out,
|
||
address => addr,
|
||
we => wr_en,
|
||
q => data_in
|
||
);
|
||
|
||
data_io : entity work.data_io
|
||
PORT MAP
|
||
(
|
||
CLK => spi_clk,
|
||
RESET_n =>reset_n,
|
||
|
||
-- SPI connection - up to upstream to make miso 'Z' on ss_io going high
|
||
SPI_CLK => spi_clk,
|
||
SPI_SS_IO => spi_ss_io(0),
|
||
SPI_MISO => spi_miso,
|
||
SPI_MOSI => spi_mosi,
|
||
|
||
-- Sector access request
|
||
read_request => request,
|
||
write_request => write,
|
||
sector => sector,
|
||
ready => ready,
|
||
|
||
-- DMA to RAM
|
||
ADDR => addr,
|
||
DATA_OUT => data_out,
|
||
DATA_IN => data_in,
|
||
WR_EN => wr_en
|
||
);
|
||
|
||
end rtl;
|
||
|
mist_5200_sdcard/sd_card.v | ||
---|---|---|
//
|
||
// sd_card.v
|
||
//
|
||
// This file implelents a sd card for the MIST board since on the board
|
||
// the SD card is connected to the ARM IO controller and the FPGA has no
|
||
// direct connection to the SD card. This file provides a SD card like
|
||
// interface to the IO controller easing porting of cores that expect
|
||
// a direct interface to the SD card.
|
||
//
|
||
// Copyright (c) 2014 Till Harbaum <till@harbaum.org>
|
||
//
|
||
// This source file is free software: you can redistribute it and/or modify
|
||
// it under the terms of the Lesser GNU General Public License as published
|
||
// by the Free Software Foundation, either version 3 of the License, or
|
||
// (at your option) any later version.
|
||
//
|
||
// This source file 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, see <http://www.gnu.org/licenses/>.
|
||
//
|
||
// http://elm-chan.org/docs/mmc/mmc_e.html
|
||
|
||
// TODO:
|
||
// - CMD9: SEND_CSD (requires device capacity)
|
||
// - CMD10: SEND_CID
|
||
|
||
module sd_card (
|
||
// link to user_io for io controller
|
||
output [31:0] io_lba,
|
||
output reg io_rd,
|
||
output reg io_wr,
|
||
input io_ack,
|
||
output io_conf,
|
||
output io_sdhc,
|
||
|
||
// data coming in from io controller
|
||
input [7:0] io_din,
|
||
input io_din_strobe,
|
||
|
||
// data going out to io controller
|
||
output [7:0] io_dout,
|
||
input io_dout_strobe,
|
||
|
||
// configuration input
|
||
input allow_sdhc,
|
||
|
||
input sd_cs,
|
||
input sd_sck,
|
||
input sd_sdi,
|
||
output reg sd_sdo
|
||
);
|
||
|
||
// set io_rd once read_state machine starts waiting (rising edge of req_io_rd)
|
||
// and clear it once io controller uploads something (io_ack==1)
|
||
wire req_io_rd = (read_state == RD_STATE_WAIT_IO);
|
||
always @(posedge req_io_rd or posedge io_ack) begin
|
||
if(io_ack) io_rd <= 1'b0;
|
||
else io_rd <= 1'b1;
|
||
end
|
||
|
||
wire req_io_wr = (write_state == WR_STATE_BUSY);
|
||
always @(posedge req_io_wr or posedge io_ack) begin
|
||
if(io_ack) io_wr <= 1'b0;
|
||
else io_wr <= 1'b1;
|
||
end
|
||
|
||
wire [31:0] OCR = { 1'b0, io_sdhc, 30'h0 }; // bit30 = 1 -> high capaciry card (sdhc)
|
||
wire [7:0] READ_DATA_TOKEN = 8'hfe;
|
||
|
||
localparam NCR=4;
|
||
|
||
// 0=idle, 1=wait for io ctrl, 2=wait for byte start, 3=send token, 4=send data, 5/6=send crc[0..1]
|
||
localparam RD_STATE_IDLE = 3'd0;
|
||
localparam RD_STATE_WAIT_IO = 3'd1;
|
||
localparam RD_STATE_WAIT_START = 3'd2;
|
||
localparam RD_STATE_SEND_TOKEN = 3'd3;
|
||
localparam RD_STATE_SEND_DATA = 3'd4;
|
||
localparam RD_STATE_SEND_CRC0 = 3'd5;
|
||
localparam RD_STATE_SEND_CRC1 = 3'd6;
|
||
reg [2:0] read_state = RD_STATE_IDLE;
|
||
|
||
// 0=idle
|
||
localparam WR_STATE_IDLE = 3'd0;
|
||
localparam WR_STATE_EXP_DTOKEN = 3'd1;
|
||
localparam WR_STATE_RECV_DATA = 3'd2;
|
||
localparam WR_STATE_RECV_CRC0 = 3'd3;
|
||
localparam WR_STATE_RECV_CRC1 = 3'd4;
|
||
localparam WR_STATE_SEND_DRESP = 3'd5;
|
||
localparam WR_STATE_BUSY = 3'd6;
|
||
reg [2:0] write_state = WR_STATE_IDLE;
|
||
|
||
reg [6:0] sbuf;
|
||
reg cmd55;
|
||
reg new_cmd_rcvd;
|
||
reg [7:0] cmd;
|
||
reg [2:0] bit_cnt; // counts bits 0-7 0-7 ...
|
||
reg [3:0] byte_cnt= 4'd15; // counts bytes
|
||
|
||
reg [31:0] lba;
|
||
assign io_lba = io_sdhc?lba:{9'd0, lba[31:9]};
|
||
|
||
// the command crc is actually never evaluated
|
||
reg [7:0] crc;
|
||
|
||
reg [7:0] reply;
|
||
reg [7:0] reply0, reply1, reply2, reply3;
|
||
reg [3:0] reply_len;
|
||
|
||
// signals to address buffer on SD card write (data coming from SD spi)
|
||
reg write_strobe;
|
||
reg [7:0] write_data;
|
||
|
||
// falling edge of io_ack signals that a sector to be read has been written into
|
||
// the sector bufffer by the io controller. This signal is kept set as long
|
||
// as the read state machine is in the "wait for io controller" state (state 1)
|
||
wire rd_wait_io = (read_state == RD_STATE_WAIT_IO);
|
||
reg rd_io_ack = 1'b0 /* synthesis noprune */;
|
||
always @(negedge io_ack or negedge rd_wait_io) begin
|
||
if(!rd_wait_io) rd_io_ack <= 1'b0;
|
||
else rd_io_ack <= 1'b1;
|
||
end
|
||
|
||
wire wr_wait_io = (write_state == WR_STATE_BUSY);
|
||
reg wr_io_ack = 1'b0 /* synthesis noprune */;
|
||
always @(negedge io_ack or negedge wr_wait_io) begin
|
||
if(!wr_wait_io) wr_io_ack <= 1'b0;
|
||
else wr_io_ack <= 1'b1;
|
||
end
|
||
|
||
// ------------------------- SECTOR BUFFER -----------------------
|
||
|
||
// access to the sector buffer is multiplexed. When reading sectors
|
||
// the io controller writes into the buffer and the sd card implementation
|
||
// reads. And vice versa when writing sectors
|
||
wire reading = (read_state != RD_STATE_IDLE);
|
||
wire writing = (write_state != WR_STATE_IDLE);
|
||
|
||
// the buffer itself. Can hold one sector
|
||
reg [8:0] buffer_wptr;
|
||
reg [8:0] buffer_rptr;
|
||
reg [7:0] buffer [511:0];
|
||
reg [7:0] buffer_byte;
|
||
|
||
// ---------------- buffer read engine -----------------------
|
||
reg core_buffer_read_strobe;
|
||
wire buffer_read_latch = reading?sd_sck:io_dout_strobe;
|
||
wire buffer_read_strobe = reading?core_buffer_read_strobe:!io_dout_strobe;
|
||
assign io_dout = buffer_byte;
|
||
|
||
// sdo is sampled on negative sd clock so set it on positive edge
|
||
always @(posedge buffer_read_latch)
|
||
buffer_byte <= buffer[buffer_rptr];
|
||
|
||
always @(posedge buffer_read_strobe or posedge new_cmd_rcvd) begin
|
||
if(new_cmd_rcvd == 1) buffer_rptr <= 9'd0;
|
||
else buffer_rptr <= buffer_rptr + 9'd1;
|
||
end
|
||
|
||
// ---------------- buffer write engine -----------------------
|
||
wire [7:0] buffer_din = reading?io_din:write_data;
|
||
wire buffer_din_strobe = reading?io_din_strobe:write_strobe;
|
||
|
||
always @(negedge buffer_din_strobe or posedge new_cmd_rcvd) begin
|
||
if(new_cmd_rcvd == 1) begin
|
||
buffer_wptr <= 9'd0;
|
||
end else begin
|
||
buffer[buffer_wptr] <= buffer_din;
|
||
buffer_wptr <= buffer_wptr + 9'd1;
|
||
end
|
||
end
|
||
|
||
wire [7:0] WRITE_DATA_RESPONSE = 8'h05;
|
||
|
||
// ------------------------- CSD/CID BUFFER ----------------------
|
||
assign io_conf = (csd_wptr == 0); // csd_wptr still 0 -> configuration required
|
||
|
||
// the 32 bytes as sent from the io controller
|
||
reg [7:0] cid [15:0];
|
||
reg [7:0] csd [15:0];
|
||
reg [7:0] conf;
|
||
|
||
reg [7:0] cid_byte;
|
||
reg [7:0] csd_byte;
|
||
reg [5:0] csd_wptr = 6'd0;
|
||
|
||
// conf[0]==1 -> io controller is using an sdhc card
|
||
wire io_has_sdhc = conf[0];
|
||
assign io_sdhc = allow_sdhc && io_has_sdhc;
|
||
|
||
always @(negedge io_din_strobe) begin
|
||
// if io controller sends data without asserting io_ack, then it's
|
||
// updating the config
|
||
if(!io_ack && (csd_wptr <= 32)) begin
|
||
|
||
if(csd_wptr < 16) // first 16 bytes are cid
|
||
cid[csd_wptr] <= io_din;
|
||
if((csd_wptr >= 16) && (csd_wptr < 32)) // then comes csd
|
||
csd[csd_wptr-16] <= io_din;
|
||
if(csd_wptr == 32) // finally a config byte
|
||
conf <= io_din;
|
||
|
||
csd_wptr <= csd_wptr + 1;
|
||
end
|
||
end
|
||
|
||
always @(posedge buffer_read_latch)
|
||
cid_byte <= cid[buffer_rptr];
|
||
|
||
always @(posedge buffer_read_latch)
|
||
csd_byte <= csd[buffer_rptr];
|
||
|
||
// ----------------- spi transmitter --------------------
|
||
reg rd_io_ackD, wr_io_ackD;
|
||
|
||
always@(negedge sd_sck or posedge sd_cs) begin
|
||
if(sd_cs == 1) begin
|
||
// sd_sdo <= 1'b1;
|
||
// read_state <= RD_STATE_IDLE;
|
||
end else begin
|
||
core_buffer_read_strobe <= 1'b0;
|
||
|
||
// using rd_io_ack directly brings the read state machine into an
|
||
// non-existing state every now and then. For unknown reason
|
||
rd_io_ackD <= rd_io_ack;
|
||
|
||
// -------- catch read commmand and reset read state machine ------
|
||
if(bit_cnt == 7) begin
|
||
if(byte_cnt == 4) begin
|
||
// CMD17: READ_SINGLE_BLOCK
|
||
if(cmd == 8'h51)
|
||
read_state <= RD_STATE_WAIT_IO; // start waiting for data from io controller
|
||
end
|
||
end
|
||
|
||
if(byte_cnt < 5+NCR) begin
|
||
sd_sdo <= 1'b1; // reply $ff -> wait
|
||
end else begin
|
||
|
||
if(byte_cnt == 5+NCR) begin
|
||
sd_sdo <= reply[~bit_cnt];
|
||
|
||
if(bit_cnt == 7) begin
|
||
// CMD9: SEND_CSD
|
||
// CMD10: SEND_CID
|
||
if((cmd == 8'h49)||(cmd == 8'h4a))
|
||
read_state <= RD_STATE_SEND_TOKEN; // jump directly to data transmission
|
||
end
|
||
end
|
||
else if((reply_len > 0) && (byte_cnt == 5+NCR+1))
|
||
sd_sdo <= reply0[~bit_cnt];
|
||
else if((reply_len > 1) && (byte_cnt == 5+NCR+2))
|
||
sd_sdo <= reply1[~bit_cnt];
|
||
else if((reply_len > 2) && (byte_cnt == 5+NCR+3))
|
||
sd_sdo <= reply2[~bit_cnt];
|
||
else if((reply_len > 3) && (byte_cnt == 5+NCR+4))
|
||
sd_sdo <= reply3[~bit_cnt];
|
||
else
|
||
sd_sdo <= 1'b1;
|
||
|
||
// falling edge of io_ack signals end of incoming data stream
|
||
if((read_state == RD_STATE_WAIT_IO) && rd_io_ackD)
|
||
read_state <= RD_STATE_WAIT_START;
|
||
|
||
// wait for begin of new byte
|
||
else if((read_state == RD_STATE_WAIT_START) && (bit_cnt == 7))
|
||
read_state <= RD_STATE_SEND_TOKEN;
|
||
|
||
// send data token
|
||
else if(read_state == RD_STATE_SEND_TOKEN) begin
|
||
sd_sdo <= READ_DATA_TOKEN[~bit_cnt];
|
||
|
||
if(bit_cnt == 7)
|
||
read_state <= RD_STATE_SEND_DATA; // next: send data
|
||
end
|
||
|
||
// send data
|
||
else if(read_state == RD_STATE_SEND_DATA) begin
|
||
if(cmd == 8'h51) // CMD17: READ_SINGLE_BLOCK
|
||
sd_sdo <= buffer_byte[~bit_cnt];
|
||
else if(cmd == 8'h49) // CMD9: SEND_CSD
|
||
sd_sdo <= csd_byte[~bit_cnt];
|
||
else if(cmd == 8'h4a) // CMD10: SEND_CID
|
||
sd_sdo <= cid_byte[~bit_cnt];
|
||
|
||
if(bit_cnt == 7) begin
|
||
core_buffer_read_strobe <= 1'b1;
|
||
|
||
// send 512 sector data bytes?
|
||
if((cmd == 8'h51) && (buffer_rptr == 511))
|
||
read_state <= RD_STATE_SEND_CRC0; // next: send crc
|
||
|
||
// send 16 cid/csd data bytes?
|
||
if(((cmd == 8'h49)||(cmd == 8'h4a)) && (buffer_rptr == 15))
|
||
read_state <= RD_STATE_IDLE; // return to idle state
|
||
end
|
||
end
|
||
|
||
// send crc[0]
|
||
else if(read_state == RD_STATE_SEND_CRC0) begin
|
||
sd_sdo <= 1'b1;
|
||
if(bit_cnt == 7)
|
||
read_state <= RD_STATE_SEND_CRC1; // send second crc byte
|
||
end
|
||
|
||
// send crc[1]
|
||
else if(read_state == RD_STATE_SEND_CRC1) begin
|
||
sd_sdo <= 1'b1;
|
||
if(bit_cnt == 7)
|
||
read_state <= RD_STATE_IDLE; // return to idle state
|
||
end
|
||
|
||
// ------------------ write support ----------------------
|
||
// send write data response
|
||
if(write_state == WR_STATE_SEND_DRESP)
|
||
sd_sdo <= WRITE_DATA_RESPONSE[~bit_cnt];
|
||
|
||
// busy after write until the io controller sends ack
|
||
if(write_state == WR_STATE_BUSY)
|
||
sd_sdo <= 1'b0;
|
||
end
|
||
end
|
||
end
|
||
|
||
// spi receiver
|
||
always @(posedge sd_sck or posedge sd_cs) begin
|
||
// cs is active low
|
||
if(sd_cs == 1) begin
|
||
bit_cnt <= 3'd0;
|
||
// byte_cnt <= 4'd15;
|
||
// write_state <= WR_STATE_IDLE;
|
||
// write_strobe <= 1'b0;
|
||
end else begin
|
||
new_cmd_rcvd <= 1'b0;
|
||
write_strobe <= 1'b0;
|
||
sbuf[6:0] <= { sbuf[5:0], sd_sdi };
|
||
bit_cnt <= bit_cnt + 3'd1;
|
||
|
||
// using wr_io_ack directly brings the write state machine into an
|
||
// non-existing state every now and then. For unknown reason
|
||
wr_io_ackD <= wr_io_ack;
|
||
|
||
// finished reading command byte
|
||
if(bit_cnt == 7) begin
|
||
// byte counter runs against 15 byte boundary
|
||
if(byte_cnt != 15)
|
||
byte_cnt <= byte_cnt + 8'd1;
|
||
|
||
// byte_cnt > 6 -> complete command received
|
||
// first byte of valid command is 01xxxxxx
|
||
if((byte_cnt > 5) && (write_state == WR_STATE_IDLE) && sbuf[6:5] == 2'b01)
|
||
byte_cnt <= 4'd0;
|
||
|
||
// don't accept new commands once a write command has been accepted
|
||
if((write_state == WR_STATE_IDLE) && (byte_cnt > 5)&&(sbuf[6:5] == 2'b01)) begin
|
||
cmd <= { sbuf, sd_sdi};
|
||
new_cmd_rcvd <= 1'b1;
|
||
|
||
// set cmd55 flag if previous command was 55
|
||
cmd55 <= (cmd == 8'h77);
|
||
end
|
||
|
||
// parse additional command bytes
|
||
if(byte_cnt == 0) lba[31:24] <= { sbuf, sd_sdi};
|
||
if(byte_cnt == 1) lba[23:16] <= { sbuf, sd_sdi};
|
||
if(byte_cnt == 2) lba[15:8] <= { sbuf, sd_sdi};
|
||
if(byte_cnt == 3) lba[7:0] <= { sbuf, sd_sdi};
|
||
|
||
// last byte received, evaluate
|
||
if(byte_cnt == 4) begin
|
||
// crc is currently unused
|
||
crc <= { sbuf, sd_sdi};
|
||
|
||
// default:
|
||
reply <= 8'h04; // illegal command
|
||
reply_len <= 4'd0; // no extra reply bytes
|
||
|
||
// CMD0: GO_IDLE_STATE
|
||
if(cmd == 8'h40)
|
||
reply <= 8'h01; // ok, busy
|
||
|
||
// CMD1: SEND_OP_COND
|
||
else if(cmd == 8'h41)
|
||
reply <= 8'h00; // ok, not busy
|
||
|
||
// CMD8: SEND_IF_COND (V2 only)
|
||
else if(cmd == 8'h48) begin
|
||
reply <= 8'h01; // ok, busy
|
||
reply0 <= 8'h00;
|
||
reply1 <= 8'h00;
|
||
reply2 <= 8'h01;
|
||
reply3 <= 8'hAA;
|
||
reply_len <= 4'd4;
|
||
end
|
||
|
||
// CMD9: SEND_CSD
|
||
else if(cmd == 8'h49)
|
||
reply <= 8'h00; // ok
|
||
|
||
// CMD10: SEND_CID
|
||
else if(cmd == 8'h4a)
|
||
reply <= 8'h00; // ok
|
||
|
||
// CMD16: SET_BLOCKLEN
|
||
else if(cmd == 8'h50) begin
|
||
// we only support a block size of 512
|
||
if(io_lba == 32'd512)
|
||
reply <= 8'h00; // ok
|
||
else
|
||
reply <= 8'h40; // parmeter error
|
||
end
|
||
|
||
// CMD17: READ_SINGLE_BLOCK
|
||
else if(cmd == 8'h51)
|
||
reply <= 8'h00; // ok
|
||
|
||
// CMD24: WRITE_BLOCK
|
||
else if(cmd == 8'h58) begin
|
||
reply <= 8'h00; // ok
|
||
write_state <= WR_STATE_EXP_DTOKEN; // expect data token
|
||
end
|
||
|
||
// ACMD41: APP_SEND_OP_COND
|
||
else if(cmd55 && (cmd == 8'h69))
|
||
reply <= 8'h00; // ok, not busy
|
||
|
||
// CMD55: APP_COND
|
||
else if(cmd == 8'h77)
|
||
reply <= 8'h01; // ok, busy
|
||
|
||
// CMD58: READ_OCR
|
||
else if(cmd == 8'h7a) begin
|
||
reply <= 8'h00; // ok
|
||
|
||
reply0 <= OCR[31:24]; // bit 30 = 1 -> high capacity card
|
||
reply1 <= OCR[23:16];
|
||
reply2 <= OCR[15:8];
|
||
reply3 <= OCR[7:0];
|
||
reply_len <= 4'd4;
|
||
end
|
||
end
|
||
|
||
// ---------- handle write -----------
|
||
|
||
// waiting for data token
|
||
if(write_state == WR_STATE_EXP_DTOKEN) begin
|
||
if({ sbuf, sd_sdi} == 8'hfe )
|
||
write_state <= WR_STATE_RECV_DATA;
|
||
end
|
||
|
||
// transfer 512 bytes
|
||
if(write_state == WR_STATE_RECV_DATA) begin
|
||
// push one byte into local buffer
|
||
write_strobe <= 1'b1;
|
||
write_data <= { sbuf, sd_sdi};
|
||
|
||
if(buffer_wptr == 511)
|
||
write_state <= WR_STATE_RECV_CRC0;
|
||
end
|
||
|
||
// transfer 1st crc byte
|
||
if(write_state == WR_STATE_RECV_CRC0)
|
||
write_state <= WR_STATE_RECV_CRC1;
|
||
|
||
// transfer 2nd crc byte
|
||
if(write_state == WR_STATE_RECV_CRC1)
|
||
write_state <= WR_STATE_SEND_DRESP;
|
||
|
||
// send data response
|
||
if(write_state == WR_STATE_SEND_DRESP)
|
||
write_state <= WR_STATE_BUSY;
|
||
end
|
||
|
||
// wait for io controller to accept data
|
||
// this happens outside the bit_cnt == 7 test as the
|
||
// transition may happen at any time
|
||
if(write_state == WR_STATE_BUSY && wr_io_ackD)
|
||
write_state <= WR_STATE_IDLE;
|
||
end
|
||
end
|
||
|
||
endmodule
|
mist_5200_sdcard/mist_sector_buffer.vhd | ||
---|---|---|
-- megafunction wizard: %RAM: 2-PORT%
|
||
-- GENERATION: STANDARD
|
||
-- VERSION: WM1.0
|
||
-- MODULE: altsyncram
|
||
|
||
-- ============================================================
|
||
-- File Name: mist_sector_buffer.vhd
|
||
-- Megafunction Name(s):
|
||
-- altsyncram
|
||
--
|
||
-- Simulation Library Files(s):
|
||
-- altera_mf
|
||
-- ============================================================
|
||
-- ************************************************************
|
||
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||
--
|
||
-- 12.1 Build 243 01/31/2013 SP 1.33 SJ Web Edition
|
||
-- ************************************************************
|
||
|
||
|
||
--Copyright (C) 1991-2012 Altera Corporation
|
||
--Your use of Altera Corporation's design tools, logic functions
|
||
--and other software and tools, and its AMPP partner logic
|
||
--functions, and any output files from any of the foregoing
|
||
--(including device programming or simulation files), and any
|
||
--associated documentation or information are expressly subject
|
||
--to the terms and conditions of the Altera Program License
|
||
--Subscription Agreement, Altera MegaCore Function License
|
||
--Agreement, or other applicable license agreement, including,
|
||
--without limitation, that your use is for the sole purpose of
|
||
--programming logic devices manufactured by Altera and sold by
|
||
--Altera or its authorized distributors. Please refer to the
|
||
--applicable agreement for further details.
|
||
|
||
|
||
LIBRARY ieee;
|
||
USE ieee.std_logic_1164.all;
|
||
|
||
LIBRARY altera_mf;
|
||
USE altera_mf.all;
|
||
|
||
ENTITY mist_sector_buffer IS
|
||
PORT
|
||
(
|
||
address_a : IN STD_LOGIC_VECTOR (8 DOWNTO 0);
|
||
address_b : IN STD_LOGIC_VECTOR (6 DOWNTO 0);
|
||
clock_a : IN STD_LOGIC := '1';
|
||
clock_b : IN STD_LOGIC ;
|
||
data_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
|
||
data_b : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
|
||
wren_a : IN STD_LOGIC := '0';
|
||
wren_b : IN STD_LOGIC := '0';
|
||
q_a : OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
|
||
q_b : OUT STD_LOGIC_VECTOR (31 DOWNTO 0)
|
||
);
|
||
END mist_sector_buffer;
|
||
|
||
|
||
ARCHITECTURE SYN OF mist_sector_buffer IS
|
||
|
||
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (7 DOWNTO 0);
|
||
SIGNAL sub_wire1 : STD_LOGIC_VECTOR (31 DOWNTO 0);
|
||
|
||
|
||
|
||
COMPONENT altsyncram
|
||
GENERIC (
|
||
address_reg_b : STRING;
|
||
clock_enable_input_a : STRING;
|
||
clock_enable_input_b : STRING;
|
||
clock_enable_output_a : STRING;
|
||
clock_enable_output_b : STRING;
|
||
indata_reg_b : STRING;
|
||
intended_device_family : STRING;
|
||
lpm_type : STRING;
|
||
numwords_a : NATURAL;
|
||
numwords_b : NATURAL;
|
||
operation_mode : STRING;
|
||
outdata_aclr_a : STRING;
|
||
outdata_aclr_b : STRING;
|
||
outdata_reg_a : STRING;
|
||
outdata_reg_b : STRING;
|
||
power_up_uninitialized : STRING;
|
||
read_during_write_mode_port_a : STRING;
|
||
read_during_write_mode_port_b : STRING;
|
||
widthad_a : NATURAL;
|
||
widthad_b : NATURAL;
|
||
width_a : NATURAL;
|
||
width_b : NATURAL;
|
||
width_byteena_a : NATURAL;
|
||
width_byteena_b : NATURAL;
|
||
wrcontrol_wraddress_reg_b : STRING
|
||
);
|
||
PORT (
|
||
clock0 : IN STD_LOGIC ;
|
||
wren_a : IN STD_LOGIC ;
|
||
address_b : IN STD_LOGIC_VECTOR (6 DOWNTO 0);
|
||
clock1 : IN STD_LOGIC ;
|
||
data_b : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
|
||
q_a : OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
|
||
wren_b : IN STD_LOGIC ;
|
||
address_a : IN STD_LOGIC_VECTOR (8 DOWNTO 0);
|
||
data_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
|
||
q_b : OUT STD_LOGIC_VECTOR (31 DOWNTO 0)
|
||
);
|
||
END COMPONENT;
|
||
|
||
BEGIN
|
||
q_a <= sub_wire0(7 DOWNTO 0);
|
||
q_b <= sub_wire1(31 DOWNTO 0);
|
||
|
||
altsyncram_component : altsyncram
|
||
GENERIC MAP (
|
||
address_reg_b => "CLOCK1",
|
||
clock_enable_input_a => "BYPASS",
|
||
clock_enable_input_b => "BYPASS",
|
||
clock_enable_output_a => "BYPASS",
|
||
clock_enable_output_b => "BYPASS",
|
||
indata_reg_b => "CLOCK1",
|
||
intended_device_family => "Cyclone III",
|
||
lpm_type => "altsyncram",
|
||
numwords_a => 512,
|
||
numwords_b => 128,
|
||
operation_mode => "BIDIR_DUAL_PORT",
|
||
outdata_aclr_a => "NONE",
|
||
outdata_aclr_b => "NONE",
|
||
outdata_reg_a => "UNREGISTERED",
|
||
outdata_reg_b => "UNREGISTERED",
|
||
power_up_uninitialized => "FALSE",
|
||
read_during_write_mode_port_a => "NEW_DATA_NO_NBE_READ",
|
||
read_during_write_mode_port_b => "NEW_DATA_NO_NBE_READ",
|
||
widthad_a => 9,
|
||
widthad_b => 7,
|
||
width_a => 8,
|
||
width_b => 32,
|
||
width_byteena_a => 1,
|
||
width_byteena_b => 1,
|
||
wrcontrol_wraddress_reg_b => "CLOCK1"
|
||
)
|
||
PORT MAP (
|
||
clock0 => clock_a,
|
||
wren_a => wren_a,
|
||
address_b => address_b,
|
||
clock1 => clock_b,
|
||
data_b => data_b,
|
||
wren_b => wren_b,
|
||
address_a => address_a,
|
||
data_a => data_a,
|
||
q_a => sub_wire0,
|
||
q_b => sub_wire1
|
||
);
|
||
|
||
|
||
|
||
END SYN;
|
||
|
||
-- ============================================================
|
||
-- CNX file retrieval info
|
||
-- ============================================================
|
||
-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
|
||
-- Retrieval info: PRIVATE: BlankMemory NUMERIC "1"
|
||
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: CLRdata NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: CLRq NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: CLRrren NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: CLRwraddress NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: CLRwren NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: Clock NUMERIC "5"
|
||
-- Retrieval info: PRIVATE: Clock_A NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: Clock_B NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "1"
|
||
-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
|
||
-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
|
||
-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
|
||
-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: MEMSIZE NUMERIC "4096"
|
||
-- Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: MIFfilename STRING ""
|
||
-- Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "3"
|
||
-- Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2"
|
||
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3"
|
||
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3"
|
||
-- Retrieval info: PRIVATE: REGdata NUMERIC "1"
|
||
-- Retrieval info: PRIVATE: REGq NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: REGrdaddress NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: REGrren NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: REGwraddress NUMERIC "1"
|
||
-- Retrieval info: PRIVATE: REGwren NUMERIC "1"
|
||
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
|
||
-- Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: UseDPRAM NUMERIC "1"
|
||
-- Retrieval info: PRIVATE: VarWidth NUMERIC "1"
|
||
-- Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "8"
|
||
-- Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "32"
|
||
-- Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "8"
|
||
-- Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "32"
|
||
-- Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "1"
|
||
-- Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: enable NUMERIC "0"
|
||
-- Retrieval info: PRIVATE: rden NUMERIC "0"
|
||
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
|
||
-- Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK1"
|
||
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
|
||
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS"
|
||
-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS"
|
||
-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS"
|
||
-- Retrieval info: CONSTANT: INDATA_REG_B STRING "CLOCK1"
|
||
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
|
||
-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
|
||
-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "512"
|
||
-- Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "128"
|
||
-- Retrieval info: CONSTANT: OPERATION_MODE STRING "BIDIR_DUAL_PORT"
|
||
-- Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
|
||
-- Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE"
|
||
-- Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED"
|
||
-- Retrieval info: CONSTANT: OUTDATA_REG_B STRING "UNREGISTERED"
|
||
-- Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
|
||
-- Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_A STRING "NEW_DATA_NO_NBE_READ"
|
||
-- Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_B STRING "NEW_DATA_NO_NBE_READ"
|
||
-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "9"
|
||
-- Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "7"
|
||
-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
|
||
-- Retrieval info: CONSTANT: WIDTH_B NUMERIC "32"
|
||
-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
|
||
-- Retrieval info: CONSTANT: WIDTH_BYTEENA_B NUMERIC "1"
|
||
-- Retrieval info: CONSTANT: WRCONTROL_WRADDRESS_REG_B STRING "CLOCK1"
|
||
-- Retrieval info: USED_PORT: address_a 0 0 9 0 INPUT NODEFVAL "address_a[8..0]"
|
||
-- Retrieval info: USED_PORT: address_b 0 0 7 0 INPUT NODEFVAL "address_b[6..0]"
|
||
-- Retrieval info: USED_PORT: clock_a 0 0 0 0 INPUT VCC "clock_a"
|
||
-- Retrieval info: USED_PORT: clock_b 0 0 0 0 INPUT NODEFVAL "clock_b"
|
||
-- Retrieval info: USED_PORT: data_a 0 0 8 0 INPUT NODEFVAL "data_a[7..0]"
|
||
-- Retrieval info: USED_PORT: data_b 0 0 32 0 INPUT NODEFVAL "data_b[31..0]"
|
||
-- Retrieval info: USED_PORT: q_a 0 0 8 0 OUTPUT NODEFVAL "q_a[7..0]"
|
||
-- Retrieval info: USED_PORT: q_b 0 0 32 0 OUTPUT NODEFVAL "q_b[31..0]"
|
||
-- Retrieval info: USED_PORT: wren_a 0 0 0 0 INPUT GND "wren_a"
|
||
-- Retrieval info: USED_PORT: wren_b 0 0 0 0 INPUT GND "wren_b"
|
||
-- Retrieval info: CONNECT: @address_a 0 0 9 0 address_a 0 0 9 0
|
||
-- Retrieval info: CONNECT: @address_b 0 0 7 0 address_b 0 0 7 0
|
||
-- Retrieval info: CONNECT: @clock0 0 0 0 0 clock_a 0 0 0 0
|
||
-- Retrieval info: CONNECT: @clock1 0 0 0 0 clock_b 0 0 0 0
|
||
-- Retrieval info: CONNECT: @data_a 0 0 8 0 data_a 0 0 8 0
|
||
-- Retrieval info: CONNECT: @data_b 0 0 32 0 data_b 0 0 32 0
|
||
-- Retrieval info: CONNECT: @wren_a 0 0 0 0 wren_a 0 0 0 0
|
||
-- Retrieval info: CONNECT: @wren_b 0 0 0 0 wren_b 0 0 0 0
|
||
-- Retrieval info: CONNECT: q_a 0 0 8 0 @q_a 0 0 8 0
|
||
-- Retrieval info: CONNECT: q_b 0 0 32 0 @q_b 0 0 32 0
|
||
-- Retrieval info: GEN_FILE: TYPE_NORMAL mist_sector_buffer.vhd TRUE
|
||
-- Retrieval info: GEN_FILE: TYPE_NORMAL mist_sector_buffer.inc FALSE
|
||
-- Retrieval info: GEN_FILE: TYPE_NORMAL mist_sector_buffer.cmp TRUE
|
||
-- Retrieval info: GEN_FILE: TYPE_NORMAL mist_sector_buffer.bsf FALSE
|
||
-- Retrieval info: GEN_FILE: TYPE_NORMAL mist_sector_buffer_inst.vhd FALSE
|
||
-- Retrieval info: LIB_FILE: altera_mf
|
mist_5200_sdcard/output_file.cof | ||
---|---|---|
<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>
|
||
<cof>
|
||
<eprom_name>CFI_128Mb</eprom_name>
|
||
<output_filename>output_files/atari800core.rbf</output_filename>
|
||
<n_pages>1</n_pages>
|
||
<width>1</width>
|
||
<mode>0</mode>
|
||
<sof_data>
|
||
<user_name>Page_0</user_name>
|
||
<page_flags>1</page_flags>
|
||
<bit0>
|
||
<sof_filename>output_files/atari800core.sof<compress_bitstream>1</compress_bitstream></sof_filename>
|
||
</bit0>
|
||
</sof_data>
|
||
<version>5</version>
|
||
<create_cvp_file>0</create_cvp_file>
|
||
<options>
|
||
</options>
|
||
</cof>
|
mist_5200_sdcard/pll_ntsc.qip | ||
---|---|---|
set_global_assignment -name IP_TOOL_NAME "ALTPLL"
|
||
set_global_assignment -name IP_TOOL_VERSION "13.0"
|
||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "pll_ntsc.vhd"]
|
||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_ntsc.cmp"]
|
||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_ntsc.ppf"]
|
mist_5200_sdcard/pll_pal_post.vhd | ||
---|---|---|
-- megafunction wizard: %ALTPLL%
|
||
-- GENERATION: STANDARD
|
||
-- VERSION: WM1.0
|
||
-- MODULE: altpll
|
||
|
||
-- ============================================================
|
||
-- File Name: pll_pal_post.vhd
|
||
-- Megafunction Name(s):
|
||
-- altpll
|
||
--
|
||
-- Simulation Library Files(s):
|
||
-- altera_mf
|
||
-- ============================================================
|
||
-- ************************************************************
|
||
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||
--
|
||
-- 13.0.1 Build 232 06/12/2013 SP 1 SJ Web Edition
|
||
-- ************************************************************
|
||
|
||
|
||
--Copyright (C) 1991-2013 Altera Corporation
|
||
--Your use of Altera Corporation's design tools, logic functions
|
||
--and other software and tools, and its AMPP partner logic
|
||
--functions, and any output files from any of the foregoing
|
||
--(including device programming or simulation files), and any
|
||
--associated documentation or information are expressly subject
|
||
--to the terms and conditions of the Altera Program License
|
||
--Subscription Agreement, Altera MegaCore Function License
|
||
--Agreement, or other applicable license agreement, including,
|
||
--without limitation, that your use is for the sole purpose of
|
||
--programming logic devices manufactured by Altera and sold by
|
||
--Altera or its authorized distributors. Please refer to the
|
||
--applicable agreement for further details.
|
||
|
||
|
||
LIBRARY ieee;
|
||
USE ieee.std_logic_1164.all;
|
||
|
||
LIBRARY altera_mf;
|
||
USE altera_mf.all;
|
||
|
||
ENTITY pll_pal_post IS
|
||
PORT
|
||
(
|
||
areset : IN STD_LOGIC := '0';
|
||
inclk0 : IN STD_LOGIC := '0';
|
||
c0 : OUT STD_LOGIC ;
|
||
c1 : OUT STD_LOGIC ;
|
||
c2 : OUT STD_LOGIC ;
|
||
c3 : OUT STD_LOGIC ;
|
||
locked : OUT STD_LOGIC
|
||
);
|
||
END pll_pal_post;
|
||
|
||
|
||
ARCHITECTURE SYN OF pll_pal_post IS
|
||
|
||
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (4 DOWNTO 0);
|
||
SIGNAL sub_wire1 : STD_LOGIC ;
|
||
SIGNAL sub_wire2 : STD_LOGIC ;
|
||
SIGNAL sub_wire3 : STD_LOGIC ;
|
||
SIGNAL sub_wire4 : STD_LOGIC ;
|
||
SIGNAL sub_wire5 : STD_LOGIC ;
|
||
SIGNAL sub_wire6 : STD_LOGIC ;
|
||
SIGNAL sub_wire7 : STD_LOGIC_VECTOR (1 DOWNTO 0);
|
||
SIGNAL sub_wire8_bv : BIT_VECTOR (0 DOWNTO 0);
|
||
SIGNAL sub_wire8 : STD_LOGIC_VECTOR (0 DOWNTO 0);
|
||
|
||
|
||
|
||
COMPONENT altpll
|
||
GENERIC (
|
||
bandwidth_type : STRING;
|
||
clk0_divide_by : NATURAL;
|
||
clk0_duty_cycle : NATURAL;
|
||
clk0_multiply_by : NATURAL;
|
||
clk0_phase_shift : STRING;
|
||
clk1_divide_by : NATURAL;
|
||
clk1_duty_cycle : NATURAL;
|
||
clk1_multiply_by : NATURAL;
|
||
clk1_phase_shift : STRING;
|
||
clk2_divide_by : NATURAL;
|
||
clk2_duty_cycle : NATURAL;
|
||
clk2_multiply_by : NATURAL;
|
||
clk2_phase_shift : STRING;
|
||
clk3_divide_by : NATURAL;
|
||
clk3_duty_cycle : NATURAL;
|
||
clk3_multiply_by : NATURAL;
|
||
clk3_phase_shift : STRING;
|
||
compensate_clock : STRING;
|
||
inclk0_input_frequency : NATURAL;
|
||
intended_device_family : STRING;
|
||
lpm_hint : STRING;
|
||
lpm_type : STRING;
|
||
operation_mode : STRING;
|
||
pll_type : STRING;
|
||
port_activeclock : STRING;
|
||
port_areset : STRING;
|
||
port_clkbad0 : STRING;
|
||
port_clkbad1 : STRING;
|
||
port_clkloss : STRING;
|
||
port_clkswitch : STRING;
|
||
port_configupdate : STRING;
|
||
port_fbin : STRING;
|
||
port_inclk0 : STRING;
|
||
port_inclk1 : STRING;
|
||
port_locked : STRING;
|
||
port_pfdena : STRING;
|
||
port_phasecounterselect : STRING;
|
||
port_phasedone : STRING;
|
||
port_phasestep : STRING;
|
||
port_phaseupdown : STRING;
|
||
port_pllena : STRING;
|
||
port_scanaclr : STRING;
|
||
port_scanclk : STRING;
|
||
port_scanclkena : STRING;
|
Made the sdcard one the main one - should be stable now with pll fix