OpenCores
URL https://opencores.org/ocsvn/fat_32_file_parser/fat_32_file_parser/trunk

Subversion Repositories fat_32_file_parser

[/] [fat_32_file_parser/] [trunk/] [SdCardInit.vhd] - Rev 2

Compare with Previous | Blame | View Log

----------------------------------------------------------------------------------
-- Company: 
-- Engineer: CW
-- 
-- Create Date:    12:30:20 11/16/2014 
-- Design Name: 
-- Module Name:    SdCardInit - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
 
library UNISIM;
use UNISIM.VComponents.all;
 
entity SdCardInit is
    Port ( CLK_IN 				: in  STD_LOGIC;
           RESET_IN 				: in  STD_LOGIC;
 
			  SD_PRESENT_BAR_IN 	: in  STD_LOGIC;
           SD_INIT_OUT 			: out STD_LOGIC;
           SD_BLOCK_RD_OUT 	: out STD_LOGIC;
           SD_BLOCK_ADDR_OUT 	: out STD_LOGIC_VECTOR (31 downto 0);
           SD_DATA_IN 			: in  STD_LOGIC_VECTOR (7 downto 0);
           SD_BUSY_IN 			: in  STD_LOGIC;
           SD_BYTE_RD_OUT 		: out STD_LOGIC;
           SD_BYTE_RD_ACK_IN 	: in  STD_LOGIC;
           SD_ERROR_IN 			: in  STD_LOGIC_VECTOR (15 downto 0);
           SD_INIT_CMPLT_OUT 	: out STD_LOGIC;
 
           FAT_BEGIN_ADDR_OUT 			: out  STD_LOGIC_VECTOR (31 downto 0);
			  SECTORS_PER_FAT_OUT			: out  STD_LOGIC_VECTOR (31 downto 0);
           CLUSTER_BEGIN_ADDR_OUT 		: out  STD_LOGIC_VECTOR (31 downto 0);
           SECTORS_PER_CLUSTER_OUT 		: out  STD_LOGIC_VECTOR (7 downto 0);
           ROOT_DIR_FIRST_CLUSTER_OUT 	: out  STD_LOGIC_VECTOR (31 downto 0));
end SdCardInit;
 
architecture Behavioral of SdCardInit is
 
	COMPONENT TDP_RAM
		Generic (G_DATA_A_SIZE 	:natural :=32;
					G_ADDR_A_SIZE	:natural :=9;
					G_RELATION		:natural :=3;
					G_INIT_FILE		:string :="");--log2(SIZE_A/SIZE_B)
		Port ( CLK_A_IN 	: in  STD_LOGIC;
				 WE_A_IN 	: in  STD_LOGIC;
				 ADDR_A_IN 	: in  STD_LOGIC_VECTOR (G_ADDR_A_SIZE-1 downto 0);
				 DATA_A_IN	: in  STD_LOGIC_VECTOR (G_DATA_A_SIZE-1 downto 0);
				 DATA_A_OUT	: out STD_LOGIC_VECTOR (G_DATA_A_SIZE-1 downto 0);
				 CLK_B_IN 	: in  STD_LOGIC;
				 WE_B_IN 	: in  STD_LOGIC;
				 ADDR_B_IN 	: in  STD_LOGIC_VECTOR (G_ADDR_A_SIZE+G_RELATION-1 downto 0);
				 DATA_B_IN 	: in  STD_LOGIC_VECTOR (G_DATA_A_SIZE/(2**G_RELATION)-1 downto 0);
				 DATA_B_OUT : out STD_LOGIC_VECTOR (G_DATA_A_SIZE/(2**G_RELATION)-1 downto 0));
	END COMPONENT;
 
subtype slv is std_logic_vector;
 
------------------------ INIT FSM -----------------------------------
 
constant C_500_ms_startup_delay 	: unsigned(25 downto 0) := "10"&X"FAF080"; -- zero indexed
constant C_sd_init_attempts		: unsigned(3 downto 0) 	:= X"2"; -- zero indexed
constant C_mbr_veracity				: std_logic_vector(15 downto 0) 	:= X"AA55";
constant C_bytes_per_sector		: std_logic_vector(15 downto 0) := X"0200";
constant C_volume_signature		: std_logic_vector(15 downto 0) 	:= X"AA55";
 
signal startup_delay_counter 	: unsigned(25 downto 0) := C_500_ms_startup_delay;
signal startup_delay_cmplt 	: std_logic := '0';
signal sd_busy, sd_present, sd_init, sd_rd_block, rd_byte, rd_byte_ack : std_logic := '0';
signal sd_init_attempts_counter 			: unsigned(3 downto 0) := X"0";
signal sd_error 								: std_logic_vector(15 downto 0) := (others => '0');
signal sd_data, block_rd_data				: std_logic_vector(7 downto 0) := (others => '0');
signal sd_block_addr 						: std_logic_vector(31 downto 0) := (others => '0');
signal init_cmplt		: std_logic;
 
signal mbr_veracity									: std_logic_vector(15 downto 0) := (others => '0');
signal lba_block_addr								: std_logic_vector(31 downto 0) := (others => '0');
signal num_reserved_sectors, vol_signature 	: std_logic_vector(15 downto 0);
signal bytes_per_sector 							: std_logic_vector(15 downto 0);
signal sectors_per_fat  							: std_logic_vector(30 downto 0);
 
signal sectors_per_cluster 						: unsigned(7 downto 0);
signal fat_begin_lba, cluster_begin_lba		: unsigned(31 downto 0);
signal root_dir_cluster								: unsigned(31 downto 0);
 
type MAIN_ROUTINE is (	REPORT_ERROR,
								WAIT_FOR_SD_UNPLUGGED,
								IDLE, 
								SD_INIT0,
								SD_INIT1,
								SD_INIT2,
								SD_INIT3,
								CHECK_FILE_SYS_VERACITY0,
								CHECK_FILE_SYS_VERACITY1,
								CHECK_FILE_SYS_VERACITY2,
								CHECK_FILE_SYS_VERACITY3,
								CHECK_FILE_SYS_VERACITY4,
								CHECK_FILE_SYS_VERACITY5,
								CHECK_FILE_SYS_VERACITY6,
								GET_LBA_START_ADDR0,
								GET_LBA_START_ADDR1,
								GET_LBA_START_ADDR2,
								GET_LBA_START_ADDR3,
								GET_LBA_START_ADDR4,
								GET_LBA_START_ADDR5,
								GET_LBA_START_ADDR6,
								GET_VOLUME_ID_DATA0,
								GET_VOLUME_ID_DATA1,
								GET_VOLUME_ID_DATA2,
								GET_VOLUME_ID_DATA3,
								GET_VOLUME_ID_DATA4,
								GET_VOLUME_ID_DATA5,
								GET_VOLUME_ID_DATA6,
								GET_VOLUME_ID_DATA7,
								GET_VOLUME_ID_DATA8,
								GET_VOLUME_ID_DATA9,
								GET_VOLUME_ID_DATA10,
								GET_VOLUME_ID_DATA11,
								GET_VOLUME_ID_DATA12,
								GET_VOLUME_ID_DATA13,
								GET_VOLUME_ID_DATA14,
								GET_VOLUME_ID_DATA15,
								GET_VOLUME_ID_DATA16,
								GET_VOLUME_ID_DATA17,
								GET_VOLUME_ID_DATA18,
								GET_VOLUME_ID_DATA19,
								GET_VOLUME_ID_DATA20,
								GET_VOLUME_ID_DATA21,
								GET_VOLUME_ID_DATA22,
								GET_VOLUME_ID_DATA23,
								SD_INIT_CMPLT);
 
signal ir_state, ir_next_state : MAIN_ROUTINE := IDLE;
 
------------------------ BLOCK RD -----------------------------------
 
signal perform_block_rd, block_rd_we : std_logic := '0';
signal block_wr_addr, block_rd_addr : unsigned(8 downto 0);
 
type BLOCK_RD_ROUTINE is (	IDLE,
									READ_BYTE0,
									READ_BYTE1,
									READ_BYTE2,
									READ_BYTE3 );
signal br_state, br_next_state : BLOCK_RD_ROUTINE;
 
begin
 
	SD_INIT_OUT <= sd_init;
	SD_BLOCK_RD_OUT <= sd_rd_block;
	SD_BLOCK_ADDR_OUT <= sd_block_addr;
	sd_data <= SD_DATA_IN;
	sd_busy <= SD_BUSY_IN;
	SD_BYTE_RD_OUT <= rd_byte;
	rd_byte_ack <= SD_BYTE_RD_ACK_IN;
	sd_error <= SD_ERROR_IN;
	SD_INIT_CMPLT_OUT <= init_cmplt;
 
	SECTORS_PER_FAT_OUT <= '0'&sectors_per_fat;
	FAT_BEGIN_ADDR_OUT <= slv(fat_begin_lba);
	CLUSTER_BEGIN_ADDR_OUT <= slv(cluster_begin_lba);
	SECTORS_PER_CLUSTER_OUT <= slv(sectors_per_cluster);
	ROOT_DIR_FIRST_CLUSTER_OUT <= slv(root_dir_cluster);
 
	STARTUP_DELAY: process(CLK_IN)
	begin
		if rising_edge(CLK_IN) then
			if ir_state = IDLE then
				if sd_present = '1' and startup_delay_counter /= "00"&X"000000" then
					startup_delay_counter <= startup_delay_counter - 1;
				else
					startup_delay_counter <= C_500_ms_startup_delay;
				end if;
			else
				startup_delay_counter <= C_500_ms_startup_delay;
			end if;
			if startup_delay_counter = X"000000" then
				startup_delay_cmplt <= '1';
			else
				startup_delay_cmplt <= '0';
			end if;
		end if;
	end process;
 
	SD_CARD_PRESENT: process(CLK_IN)
	begin
		if rising_edge(CLK_IN) then
			sd_present <= not SD_PRESENT_BAR_IN;
		end if;
	end process;
 
	SD_INIT_FLAGS: process(CLK_IN)
	begin
		if rising_edge(CLK_IN) then
			if ir_state = SD_INIT0 then
				sd_init <= '1';
			else
				sd_init <= '0';
			end if;
			if ir_state = SD_INIT2 then
				sd_init_attempts_counter <= sd_init_attempts_counter + 1;
			end if;
		end if;
	end process;	
 
	SD_RD_BLOCK_FLAGS: process(CLK_IN)
	begin
		if rising_edge(CLK_IN) then
			if ir_state = CHECK_FILE_SYS_VERACITY0 then
				sd_rd_block <= '1';
			elsif ir_state = GET_LBA_START_ADDR6 then
				sd_rd_block <= '1';
			else
				sd_rd_block <= '0';
			end if;
			if ir_state = CHECK_FILE_SYS_VERACITY0 then
				sd_block_addr <= X"00000000";
			elsif ir_state = GET_LBA_START_ADDR6 then
				sd_block_addr <= lba_block_addr;
			else
				sd_block_addr <= X"00000000";
			end if;
			if ir_state = CHECK_FILE_SYS_VERACITY2 then
				block_rd_addr <= "1"&X"FE";
			elsif ir_state = CHECK_FILE_SYS_VERACITY3 then
				block_rd_addr <= "1"&X"FF";
			elsif ir_state = GET_LBA_START_ADDR0 then
				block_rd_addr <= "1"&X"C6";
			elsif ir_state = GET_LBA_START_ADDR1 then
				block_rd_addr <= "1"&X"C7";
			elsif ir_state = GET_LBA_START_ADDR2 then
				block_rd_addr <= "1"&X"C8";
			elsif ir_state = GET_LBA_START_ADDR3 then
				block_rd_addr <= "1"&X"C9";
			elsif ir_state = GET_VOLUME_ID_DATA2 then
				block_rd_addr <= "0"&X"0D";
			elsif ir_state = GET_VOLUME_ID_DATA3 then
				block_rd_addr <= "0"&X"0E";
			elsif ir_state = GET_VOLUME_ID_DATA4 then
				block_rd_addr <= "0"&X"0F";
			elsif ir_state = GET_VOLUME_ID_DATA5 then
				block_rd_addr <= "0"&X"24";
			elsif ir_state = GET_VOLUME_ID_DATA6 then
				block_rd_addr <= "0"&X"25";
			elsif ir_state = GET_VOLUME_ID_DATA7 then
				block_rd_addr <= "0"&X"26";
			elsif ir_state = GET_VOLUME_ID_DATA8 then
				block_rd_addr <= "0"&X"27";
			elsif ir_state = GET_VOLUME_ID_DATA9 then
				block_rd_addr <= "0"&X"2C";
			elsif ir_state = GET_VOLUME_ID_DATA10 then
				block_rd_addr <= "0"&X"2D";
			elsif ir_state = GET_VOLUME_ID_DATA11 then
				block_rd_addr <= "0"&X"2E";
			elsif ir_state = GET_VOLUME_ID_DATA12 then
				block_rd_addr <= "0"&X"2F";
			elsif ir_state = GET_VOLUME_ID_DATA13 then
				block_rd_addr <= "1"&X"FE";
			elsif ir_state = GET_VOLUME_ID_DATA14 then
				block_rd_addr <= "1"&X"FF";
			elsif ir_state = GET_VOLUME_ID_DATA15 then
				block_rd_addr <= "0"&X"0B";
			elsif ir_state = GET_VOLUME_ID_DATA16 then
				block_rd_addr <= "0"&X"0C";
			else
				block_rd_addr <= (others => '0');
			end if;
			if ir_state = CHECK_FILE_SYS_VERACITY4 then
				mbr_veracity(7 downto 0) <= block_rd_data;
			elsif ir_state = CHECK_FILE_SYS_VERACITY5 then
				mbr_veracity(15 downto 8) <= block_rd_data;
			end if;
		end if;
	end process;
 
	LBA_SETUP: process(CLK_IN)
	begin
		if rising_edge(CLK_IN) then
			if ir_state = GET_LBA_START_ADDR2 then
				lba_block_addr(7 downto 0) <= block_rd_data;
			elsif ir_state = GET_LBA_START_ADDR3 then
				lba_block_addr(15 downto 8) <= block_rd_data;
			elsif ir_state = GET_LBA_START_ADDR4 then
				lba_block_addr(23 downto 16) <= block_rd_data;
			elsif ir_state = GET_LBA_START_ADDR5 then
				lba_block_addr(31 downto 24) <= block_rd_data;
			end if;
		end if;
	end process;
 
	VOLUME_DATA: process(CLK_IN)
	begin
		if rising_edge(CLK_IN) then
			if ir_state = GET_VOLUME_ID_DATA4 then
				sectors_per_cluster <= unsigned(block_rd_data);
			elsif ir_state = GET_VOLUME_ID_DATA5 then
				num_reserved_sectors(7 downto 0) <= block_rd_data;
			elsif ir_state = GET_VOLUME_ID_DATA6 then
				num_reserved_sectors(15 downto 8) <= block_rd_data;
			elsif ir_state = GET_VOLUME_ID_DATA7 then
				sectors_per_fat(7 downto 0) <= block_rd_data;
			elsif ir_state = GET_VOLUME_ID_DATA8 then
				sectors_per_fat(15 downto 8) <= block_rd_data;
			elsif ir_state = GET_VOLUME_ID_DATA9 then
				sectors_per_fat(23 downto 16) <= block_rd_data;
			elsif ir_state = GET_VOLUME_ID_DATA10 then
				sectors_per_fat(30 downto 24) <= block_rd_data(6 downto 0);
			elsif ir_state = GET_VOLUME_ID_DATA11 then
				root_dir_cluster(7 downto 0) <= unsigned(block_rd_data);
			elsif ir_state = GET_VOLUME_ID_DATA12 then
				root_dir_cluster(15 downto 8) <= unsigned(block_rd_data);
			elsif ir_state = GET_VOLUME_ID_DATA13 then
				root_dir_cluster(23 downto 16) <= unsigned(block_rd_data);
			elsif ir_state = GET_VOLUME_ID_DATA14 then
				root_dir_cluster(31 downto 24) <= unsigned(block_rd_data);
			elsif ir_state = GET_VOLUME_ID_DATA15 then
				vol_signature(7 downto 0) <= block_rd_data; 
			elsif ir_state = GET_VOLUME_ID_DATA16 then
				vol_signature(15 downto 8) <= block_rd_data;
			elsif ir_state = GET_VOLUME_ID_DATA17 then
				bytes_per_sector(7 downto 0) <= block_rd_data;
			elsif ir_state = GET_VOLUME_ID_DATA18 then
				bytes_per_sector(15 downto 8) <= block_rd_data; 
			end if;
			if ir_state = GET_VOLUME_ID_DATA20 then
				fat_begin_lba <= unsigned(lba_block_addr) + RESIZE(unsigned(num_reserved_sectors), 32);
			end if;
			if ir_state = GET_VOLUME_ID_DATA21 then
				cluster_begin_lba <= fat_begin_lba;
			elsif ir_state = GET_VOLUME_ID_DATA22 then
				cluster_begin_lba <= cluster_begin_lba + unsigned(sectors_per_fat&"0");
			end if;
		end if;
	end process;
 
	CMPLT_FLAG: process(CLK_IN)
	begin
		if rising_edge(CLK_IN) then
			if ir_state = SD_INIT_CMPLT then
				init_cmplt <= '1';
			else
				init_cmplt <= '0';
			end if;
		end if;
	end process;
 
   INIT_ROUTINE_SYNC: process(CLK_IN)
   begin
		if rising_edge(CLK_IN) then
			if RESET_IN = '0' then
				ir_state <= ir_next_state;
			else
				ir_state <= IDLE;
			end if;
      end if;
   end process;
 
   INIT_ROUTINE_DECODE: process (	ir_state,
												sd_error,
												sd_present,
												startup_delay_cmplt, 
												sd_busy, 
												sd_init_attempts_counter,
												mbr_veracity,
												bytes_per_sector,
												vol_signature	)
   begin
      ir_next_state <= ir_state;  -- default is to stay in current state
      case (ir_state) is
			when REPORT_ERROR =>
				ir_next_state <= WAIT_FOR_SD_UNPLUGGED;
			when WAIT_FOR_SD_UNPLUGGED =>
				if sd_present = '0' then
               ir_next_state <= IDLE;
            end if;
         when IDLE =>
            if startup_delay_cmplt = '1' then
               ir_next_state <= SD_INIT0;
            end if;
         when SD_INIT0 =>
				if sd_busy = '1' then
					ir_next_state <= SD_INIT1;
				end if;
			when SD_INIT1 =>
				if sd_busy = '0' then
					if sd_error = X"0000" then
						ir_next_state <= CHECK_FILE_SYS_VERACITY0;
					else
						ir_next_state <= SD_INIT2;
					end if;
				end if;
			when SD_INIT2 =>
				if sd_init_attempts_counter = C_sd_init_attempts then
					ir_next_state <= SD_INIT3;
				else
					ir_next_state <= SD_INIT0;
				end if;
			when SD_INIT3 =>
				ir_next_state <= REPORT_ERROR;
			when CHECK_FILE_SYS_VERACITY0 =>
				if sd_busy = '1' then
					ir_next_state <= CHECK_FILE_SYS_VERACITY1;
				end if;
			when CHECK_FILE_SYS_VERACITY1 =>
					ir_next_state <= CHECK_FILE_SYS_VERACITY2;
			when CHECK_FILE_SYS_VERACITY2 =>
				if sd_busy = '0' then
					ir_next_state <= CHECK_FILE_SYS_VERACITY3;
				end if;
			when CHECK_FILE_SYS_VERACITY3 =>
				ir_next_state <= CHECK_FILE_SYS_VERACITY4;
			when CHECK_FILE_SYS_VERACITY4 =>
				ir_next_state <= CHECK_FILE_SYS_VERACITY5;
			when CHECK_FILE_SYS_VERACITY5 =>
				ir_next_state <= CHECK_FILE_SYS_VERACITY6;
			when CHECK_FILE_SYS_VERACITY6 =>
				if mbr_veracity = C_mbr_veracity then
					ir_next_state <= GET_LBA_START_ADDR0;
				else
					ir_next_state <= REPORT_ERROR;
				end if;
			when GET_LBA_START_ADDR0 =>
				ir_next_state <= GET_LBA_START_ADDR1;
			when GET_LBA_START_ADDR1 =>
				ir_next_state <= GET_LBA_START_ADDR2;
			when GET_LBA_START_ADDR2 =>
				ir_next_state <= GET_LBA_START_ADDR3;
			when GET_LBA_START_ADDR3 =>
				ir_next_state <= GET_LBA_START_ADDR4;
			when GET_LBA_START_ADDR4 =>
				ir_next_state <= GET_LBA_START_ADDR5;
			when GET_LBA_START_ADDR5 =>
				ir_next_state <= GET_LBA_START_ADDR6;
			when GET_LBA_START_ADDR6 =>
				if sd_busy = '1' then
					ir_next_state <= GET_VOLUME_ID_DATA0;
				end if;
			when GET_VOLUME_ID_DATA0 =>
					ir_next_state <= GET_VOLUME_ID_DATA1;
			when GET_VOLUME_ID_DATA1 =>
				if sd_busy = '0' then
					ir_next_state <= GET_VOLUME_ID_DATA2;
				end if;
			when GET_VOLUME_ID_DATA2 =>
				ir_next_state <= GET_VOLUME_ID_DATA3;
			when GET_VOLUME_ID_DATA3 =>
				ir_next_state <= GET_VOLUME_ID_DATA4;
			when GET_VOLUME_ID_DATA4 =>
				ir_next_state <= GET_VOLUME_ID_DATA5;
			when GET_VOLUME_ID_DATA5 =>
				ir_next_state <= GET_VOLUME_ID_DATA6;
			when GET_VOLUME_ID_DATA6 =>
				ir_next_state <= GET_VOLUME_ID_DATA7;
			when GET_VOLUME_ID_DATA7 =>
				ir_next_state <= GET_VOLUME_ID_DATA8;
			when GET_VOLUME_ID_DATA8 =>
				ir_next_state <= GET_VOLUME_ID_DATA9;
			when GET_VOLUME_ID_DATA9 =>
				ir_next_state <= GET_VOLUME_ID_DATA10;
			when GET_VOLUME_ID_DATA10 =>
				ir_next_state <= GET_VOLUME_ID_DATA11;
			when GET_VOLUME_ID_DATA11 =>
				ir_next_state <= GET_VOLUME_ID_DATA12;
			when GET_VOLUME_ID_DATA12 =>
				ir_next_state <= GET_VOLUME_ID_DATA13;
			when GET_VOLUME_ID_DATA13 =>
				ir_next_state <= GET_VOLUME_ID_DATA14;
			when GET_VOLUME_ID_DATA14 =>
				ir_next_state <= GET_VOLUME_ID_DATA15;
			when GET_VOLUME_ID_DATA15 =>
				ir_next_state <= GET_VOLUME_ID_DATA16;
			when GET_VOLUME_ID_DATA16 =>
				ir_next_state <= GET_VOLUME_ID_DATA17;
			when GET_VOLUME_ID_DATA17 =>
				ir_next_state <= GET_VOLUME_ID_DATA18;
			when GET_VOLUME_ID_DATA18 =>
				ir_next_state <= GET_VOLUME_ID_DATA19;
			when GET_VOLUME_ID_DATA19 =>
				if bytes_per_sector /= C_bytes_per_sector or vol_signature /= C_volume_signature then
					ir_next_state <= REPORT_ERROR;
				else
					ir_next_state <= GET_VOLUME_ID_DATA20;
				end if;
			when GET_VOLUME_ID_DATA20 =>
				ir_next_state <= GET_VOLUME_ID_DATA21;
			when GET_VOLUME_ID_DATA21 =>
				ir_next_state <= GET_VOLUME_ID_DATA22;
			when GET_VOLUME_ID_DATA22 =>
				ir_next_state <= GET_VOLUME_ID_DATA23;
			when GET_VOLUME_ID_DATA23 =>
				ir_next_state <= SD_INIT_CMPLT;
			when SD_INIT_CMPLT =>
				ir_next_state <= SD_INIT_CMPLT;
      end case;
   end process;
 
   BLOCK_READ_SYNC: process(CLK_IN)
   begin
		if rising_edge(CLK_IN) then
			br_state <= br_next_state;  
      end if;
   end process;
 
	BLOCK_READ_TRIG: process(CLK_IN)
	begin
		if rising_edge(CLK_IN) then
			if ir_state = CHECK_FILE_SYS_VERACITY0 and sd_busy = '1' then
				perform_block_rd <= '1';
			elsif ir_state = GET_LBA_START_ADDR6 and sd_busy = '1' then
				perform_block_rd <= '1';
			else
				perform_block_rd <= '0';			
			end if;
		end if;
	end process;
 
	BLOCK_READ_FLAGS: process(CLK_IN)
   begin
		if rising_edge(CLK_IN) then
			if br_state = READ_BYTE0 and rd_byte_ack = '1' then
				block_rd_we <= '1';
			else
				block_rd_we <= '0';
			end if;
			if br_state = READ_BYTE1 then
				rd_byte <= '1';
			elsif br_state = READ_BYTE2 and rd_byte_ack = '0' then
				rd_byte <= '0';
			end if;
			if br_state = IDLE then
				block_wr_addr <= (others => '0');
			elsif br_state = READ_BYTE1 then
				block_wr_addr <= block_wr_addr + 1;
			end if;
      end if;
   end process;
 
	BLOCK_READ_DECODE: process (br_state, perform_block_rd, rd_byte_ack, block_wr_addr)
   begin
      br_next_state <= br_state;  -- default is to stay in current state
      case (br_state) is
			when IDLE =>
				if perform_block_rd = '1' then
					br_next_state <= READ_BYTE0;
				end if;
			when READ_BYTE0 =>
				if rd_byte_ack = '1' then
					br_next_state <= READ_BYTE1;
				end if;
			when READ_BYTE1 =>
				br_next_state <= READ_BYTE2;
			when READ_BYTE2 =>
				if rd_byte_ack = '0' then
					br_next_state <= READ_BYTE3;
				end if;
			when READ_BYTE3 =>
				if block_wr_addr = "000000000" then
					br_next_state <= IDLE;
				else
					br_next_state <= READ_BYTE0;
				end if;
		end case;
	end process;
 
	TDP_RAM_Inst : TDP_RAM
		Generic Map (	G_DATA_A_SIZE 	=> sd_data'length,
							G_ADDR_A_SIZE	=> block_wr_addr'length,
							G_RELATION		=> 0,
							G_INIT_FILE		=> "") --log2(SIZE_A/SIZE_B)
		Port Map ( 	CLK_A_IN 	=> CLK_IN, 
						WE_A_IN 		=> block_rd_we,
						ADDR_A_IN 	=> slv(block_wr_addr),
						DATA_A_IN	=> sd_data,
						DATA_A_OUT	=> open,
						CLK_B_IN 	=> CLK_IN,
						WE_B_IN 		=> '0',
						ADDR_B_IN 	=> slv(block_rd_addr),
						DATA_B_IN 	=> X"00",
						DATA_B_OUT 	=> block_rd_data);
 
end Behavioral;
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.