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

Subversion Repositories sdram_controller

[/] [sdram_controller/] [trunk/] [sdram_writer.vhd] - Rev 6

Go to most recent revision | Compare with Previous | Blame | View Log

----------------------------------------------------------------------------------
-- Company: OPL Aerospatiale AG
-- Engineer: Owen Lynn <lynn0p@hotmail.com>
-- 
-- Create Date:    13:08:21 08/30/2009 
-- Design Name: 
-- Module Name:    sdram_writer - impl 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: This module is responsible for generating the dqs, dq and dm waveforms
--  needed to tell the chip what to store.
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--  Copyright (c) 2009 Owen Lynn <lynn0p@hotmail.com>
--  Released under the GNU Lesser General Public License, Version 3
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
 
-- Uses ODDR2 registers to generate the required DDR signals. Don't have to be as careful with the
--  timings as with sdram_reader, but you need to be able to feed the ODDR2's within their setup
--  and hold windows. Or very very hilarious things will occur. Post-PAR simulation is good for
--  getting a feel for the (mis)timings.
entity sdram_writer is
	port(
		clk    : in std_logic;
		clk090 : in std_logic;
		clk180 : in std_logic;
		clk270 : in std_logic;
		rst    : in std_logic;
		addr   : in std_logic;
		data_o : in std_logic_vector(7 downto 0);
		dqs    : out std_logic_vector(1 downto 0);
		dm     : out std_logic_vector(1 downto 0);
		dq     : out std_logic_vector(15 downto 0)
	);
end sdram_writer;
 
architecture impl of sdram_writer is
 
	component oddr2_2 is
		port( 
			Q  : out std_logic_vector(1 downto 0);
			C0 : in std_logic;
			C1 : in std_logic;
			CE : in std_logic;
			D0 : in std_logic_vector(1 downto 0);
			D1 : in std_logic_vector(1 downto 0);
			R  : in std_logic;
			S  : in std_logic );
	end component;
 
	component oddr2_16 is
		port( 
			Q  : out std_logic_vector(15 downto 0);
			C0 : in std_logic;
			C1 : in std_logic;
			CE : in std_logic;
			D0 : in std_logic_vector(15 downto 0);
			D1 : in std_logic_vector(15 downto 0);
			R  : in std_logic;
			S  : in std_logic );
	end component;
 
	type WRITER_DQS_STATES is ( STATE_WRITER_DQS_0, STATE_WRITER_DQS_1, STATE_WRITER_DQS_DONE );
	type WRITER_DM_STATES is ( STATE_WRITER_DM_0, STATE_WRITER_DM_1, STATE_WRITER_DM_DONE );
 
	signal writer_dqs_state : WRITER_DQS_STATES := STATE_WRITER_DQS_0;
	signal writer_dm_state : WRITER_DM_STATES := STATE_WRITER_DM_0;
 
	signal dqs_rising : std_logic_vector(1 downto 0) := "00";
	signal dqs_falling : std_logic_vector(1 downto 0) := "00";
	signal dqs_fsm_r : std_logic;
	signal dqs_fsm_f : std_logic;
 
	signal dm_rising : std_logic_vector(1 downto 0) := "11";
	signal dm_falling : std_logic_vector(1 downto 0) := "11";
 
	signal dq_rising : std_logic_vector(15 downto 0) := x"0000";
	signal dq_falling : std_logic_vector(15 downto 0) := x"0000";
 
	signal data_out : std_logic_vector(15 downto 0);
	signal mask_out : std_logic_vector(1 downto 0);
 
begin
 
	ODDR2_dqs: oddr2_2
	port map(
		Q => dqs,
		C0 => clk,
		C1 => clk180,
		CE => '1',
		D0 => dqs_rising,
		D1 => dqs_falling,
		R => '0',
		S => '0'
	);
 
	ODDR2_dm: oddr2_2
	port map(
		Q => dm,
		C0 => clk090,
		C1 => clk270,
		CE => '1',
		D0 => dm_rising,
		D1 => dm_falling,
		R => '0',
		S => '0'
	);
 
	ODDR2_dq: oddr2_16
	port map(
		Q => dq,
		C0 => clk090,
		C1 => clk270,
		CE => '1',
		D0 => dq_rising,
		D1 => dq_falling,
		R => '0',
		S => '0'
	);
 
   dqs_rising(0)  <= dqs_fsm_r;
   dqs_rising(1)  <= dqs_fsm_r;
	dqs_falling(0) <= dqs_fsm_f;
	dqs_falling(1) <= dqs_fsm_f;
 
	-- this drives the oddr2_dqs
	process (clk180,rst)
	begin
		if (rst = '1') then
			dqs_fsm_r <= '0';
			dqs_fsm_f <= '0';
			writer_dqs_state <= STATE_WRITER_DQS_0;
		elsif (rising_edge(clk180)) then
			case writer_dqs_state is
				when STATE_WRITER_DQS_0 =>
					dqs_fsm_r <= '0';
					dqs_fsm_f <= '0';
					writer_dqs_state <= STATE_WRITER_DQS_1;
				when STATE_WRITER_DQS_1 =>
					dqs_fsm_r <= '1';
					dqs_fsm_f <= '0';
					writer_dqs_state <= STATE_WRITER_DQS_DONE;
				when STATE_WRITER_DQS_DONE =>
					dqs_fsm_r <= '0';
					dqs_fsm_f <= '0';
					writer_dqs_state <= STATE_WRITER_DQS_DONE;
			end case;
		end if;
	end process;
 
 
	data_out <= (x"00" & data_o) when addr = '0' else (data_o & x"00"); 
	mask_out <=             "10" when addr = '0' else "01";
 
	-- this drives the oddr2_dm and oddr2_dq
	process(clk,rst)
	begin
		if (rst = '1') then
			dm_rising <= "11";
			dq_rising <= x"0000";
			dm_falling <= "11";
			dq_falling <= x"0000";
			writer_dm_state <= STATE_WRITER_DM_0;
		elsif (rising_edge(clk)) then
			case writer_dm_state is
				when STATE_WRITER_DM_0 =>					
					dm_rising <= "11";
					dq_rising <= x"0000";
					dm_falling <= mask_out;
					dq_falling <= data_out;
					writer_dm_state <= STATE_WRITER_DM_1;
 
				when STATE_WRITER_DM_1 =>
					dm_rising <= "11";
					dq_rising <= x"0000";
					dm_falling <= "11";
					dq_falling <= x"0000";
					writer_dm_state <= STATE_WRITER_DM_DONE;
 
				when STATE_WRITER_DM_DONE =>
					dm_rising <= "00";
					dm_falling <= "00";
					writer_dm_state <= STATE_WRITER_DM_DONE;
			end case;
		end if;
	end process;
 
end impl;
 

Go to most recent revision | 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.