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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [soc/] [rtl/] [altera_ddr_ctrl/] [altera_ddr_top.v] - Rev 12

Compare with Previous | Blame | View Log

//===============================================================================
//
//          FILE:  altera_ddr_top.v
// 
//         USAGE:  
// 
//   DESCRIPTION:  WishBone interface for Altera DDR SDRAM Controller
//   		   This verion is just for 32MB SDRAM
//   		   wb_err_o will be asserted while wb_add_i > 32MB
//
//   		   Read proformance is very low because we have to
//   		   wait for the local_rdata_vaild available, and then
//   		   generate the wb_ack_o. In fact, we have not use the
//   		   buast read, I don't know how to implement it currently.
// 
//       OPTIONS:  ---
//  REQUIREMENTS:  ---
//          BUGS:  ---
//         NOTES:  ---
//        AUTHOR:  Xianfeng Zeng (ZXF), xianfeng.zeng@gmail.com
//                                      xianfeng.zeng@SierraAtlantic.com
//       COMPANY:  
//       VERSION:  1.0
//       CREATED:  10/09/2009 12:58:10 PM HKT
//      REVISION:  ---
//===============================================================================
 
module altera_ddr_top (
  // Wishbine interface
  wb_clk_i, wb_rst_i,
 
  wb_dat_i, wb_dat_o, wb_adr_i, wb_sel_i, wb_we_i, wb_cyc_i,
  wb_stb_i, wb_ack_o, wb_err_o,
 
 
  // reset to ddr core
  global_reset_n_i,
 
  // global output
  reset_request_n_o,
 
  // to DDR SDRAM
 
  ddr_pll_clk_i,
 
  mem_cs_n_o,
  mem_cke_o,
  mem_addr_o,
  mem_ba_o,
  mem_ras_n_o,
  mem_cas_n_o,
  mem_we_n_o,
  mem_dm_o,
  mem_clk_io,
  mem_clk_n_io,
  mem_dq_io,
  mem_dqs_io
);
 
//
// Paraneters
//
parameter	wb_Idle  = 4'b1000,
		wb_Read  = 4'b0100,
		wb_Write = 4'b0010,
		wb_Ack   = 4'b0001;
 
parameter	ddr_Idle  		= 6'b100000,
		ddr_Read		= 6'b010000,
		ddr_Wait_data_vaild	= 6'b001000,
		ddr_Wait_wb_Ack		= 6'b000100,
		ddr_Write		= 6'b000010,	
		ddr_Set_locale_ready_reg= 6'b000001;
 
//
// I/O Ports
//
input			wb_clk_i;
input			wb_rst_i;
 
//
// WB slave i/f
//
input	[31:0]		wb_dat_i;
output	[31:0]		wb_dat_o;
input	[31:0]		wb_adr_i;
input	[3:0]		wb_sel_i;
input			wb_we_i;
input			wb_cyc_i;
input			wb_stb_i;
output			wb_ack_o;
output			wb_err_o;
 
//
// DDR I/O Ports
//
 
input		ddr_pll_clk_i;
input 		global_reset_n_i;
 
output	[0:0]	mem_cs_n_o;
output	[0:0]	mem_cke_o;
output	[12:0]	mem_addr_o;
output	[1:0]	mem_ba_o;
output		mem_ras_n_o;
output		mem_cas_n_o;
output		mem_we_n_o;
output	[1:0]	mem_dm_o;
 
output		reset_request_n_o;
 
inout	[0:0]	mem_clk_io;
inout	[0:0]	mem_clk_n_io;
inout	[15:0]	mem_dq_io;
inout	[1:0]	mem_dqs_io;
 
 
//
// Internal singal for DDR core
//
wire	[22:0]	local_address;
wire		local_write_req;
wire		local_read_req;
wire		local_burstbegin;
wire	[31:0]	local_wdata;
wire		local_ready;
wire	[31:0]	local_rdata;
wire		local_rdata_valid;
 
wire		local_refresh_ack;
wire		local_wdata_req;
wire		local_init_done;
wire		reset_phy_clk_n;
 
wire		phy_clk;
wire		aux_full_rate_clk;
wire		aux_half_rate_clk;
 
reg 		local_ready_reg;
reg		local_rdata_valid_reg;
 
//
// Internal regs and wires
//
 
reg [31:0]	data_save;
wire 		wb_err;
 
reg [3:0]	wb_State;
reg [5:0]	ddr_State;
 
 
//
// Altera DDR SDRAM Controller
// with
// 	1. Alvon interface
// 	2. Full speed
//
altera_ddr ddr(
	// input
	.local_address		(local_address),
	.local_write_req	(local_write_req),
	.local_read_req		(local_read_req),
	.local_burstbegin	(local_burstbegin),
	.local_wdata		(local_wdata),
 
	.local_be		(wb_sel_i),
	.local_size		(2'b01),
	.global_reset_n		(global_reset_n_i),
	.pll_ref_clk		(ddr_pll_clk_i),
	.soft_reset_n		(1'b1),
 
	//output
	.local_ready		(local_ready),
	.local_rdata		(local_rdata),
	.local_rdata_valid	(local_rdata_valid),
	.reset_request_n	(reset_request_n_o),
	.mem_cs_n		(mem_cs_n_o),
	.mem_cke		(mem_cke_o),
	.mem_addr		(mem_addr_o),
	.mem_ba			(mem_ba_o),
	.mem_ras_n		(mem_ras_n_o),
	.mem_cas_n		(mem_cas_n_o),
	.mem_we_n		(mem_we_n_o),
	.mem_dm			(mem_dm_o),
	.local_refresh_ack	(local_refresh_ack),
	.local_wdata_req	(local_wdata_req),
	.local_init_done	(local_init_done),
	.reset_phy_clk_n	(reset_phy_clk_n),
	.phy_clk		(phy_clk),
	.aux_full_rate_clk	(aux_full_rate_clk),
	.aux_half_rate_clk	(aux_half_rate_clk),
 
	//inout
	.mem_clk		(mem_clk_io),
	.mem_clk_n		(mem_clk_n_io),
	.mem_dq			(mem_dq_io),
	.mem_dqs		(mem_dqs_io)
);
 
//
// Aliases and simple assignments
//
assign wb_err = wb_cyc_i & wb_stb_i & (|wb_adr_i[26:25]);	// If Access to > 32MB (4-bit leading prefix ignored)
assign wb_err_o = wb_err;
 
//
// State Machine for Wishbone side
//
always @ (negedge wb_clk_i or posedge wb_rst_i)
begin
	if (wb_rst_i) begin
		wb_State <= wb_Idle;
	end
	else
		case (wb_State)
			wb_Idle: begin
				if (!local_init_done)
					wb_State <= wb_Idle;
				else if (wb_cyc_i & wb_stb_i) begin
					if (wb_we_i)
						wb_State <= wb_Write;
					else
						wb_State <= wb_Read;
				end
			end
 
			wb_Read: begin
				if (local_rdata_valid_reg)
					wb_State <= wb_Ack;
			end
 
			wb_Ack: begin
				wb_State <= wb_Idle;
			end
 
			wb_Write: begin
				if (local_ready_reg)
					wb_State <= wb_Ack;
			end
 
			default: wb_State <= wb_Idle;
		endcase
end
 
//
// State Machine for DDR SDRAM Core side
//
 
always @ (posedge phy_clk or posedge wb_rst_i)
begin
	if (wb_rst_i) begin
		ddr_State <= ddr_Idle;
		local_ready_reg <= 1'b0;
		local_rdata_valid_reg <= 1'b0;
	end
	else
		case (ddr_State)
			ddr_Idle: begin
 
//				local_address <= {23{1'b0}};
 
				if (!local_init_done)
					ddr_State <= ddr_Idle;
				else if (wb_State == wb_Write)
					ddr_State <= ddr_Write;
				else if (wb_State == wb_Read)
					ddr_State <= ddr_Read;
 
				// These signals are used to triger wb enter
				// ACK state, so they need to be reset when in
				// wb_Ack state 
				if (wb_State == wb_Ack) begin
					local_ready_reg <= 1'b0;
					local_rdata_valid_reg <= 1'b0;
				end
 
			end
 
			ddr_Read: begin
//				local_address <= wb_adr_i[24:2];
 
				if (local_ready)
					ddr_State <= ddr_Wait_data_vaild;
 
			end
			ddr_Wait_data_vaild: begin
				if (local_rdata_valid) begin
					data_save <= local_rdata;
 
					local_rdata_valid_reg <= 1'b1; // Triger wb_ack to happen
					ddr_State <= ddr_Wait_wb_Ack;
				end
			end
 
			ddr_Wait_wb_Ack: begin
				if (wb_State == wb_Ack)
					ddr_State <= ddr_Idle;
			end
 
			ddr_Write: begin
 
				if (local_ready)
					ddr_State <= ddr_Set_locale_ready_reg;
			end
 
			ddr_Set_locale_ready_reg: begin
 
				local_ready_reg <= 1'b1; // let wb State Machine enter wb_Ack state
 
				if (wb_State == wb_Ack)
					ddr_State <= ddr_Idle;
			end
 
			default: ddr_State <= ddr_Idle;
		endcase
end
 
 
assign wb_dat_o = data_save;
assign wb_ack_o = (wb_State == wb_Ack) ? 1'b1 : 1'b0;
 
assign local_burstbegin = (ddr_State == ddr_Write) ? 1'b1 : 
			  (ddr_State == ddr_Read)  ? 1'b1 : 1'b0;
assign local_write_req  = (ddr_State == ddr_Write) ? 1'b1 : 1'b0;
assign local_read_req   = (ddr_State == ddr_Read)  ? 1'b1 : 1'b0;
assign local_wdata      = (ddr_State == ddr_Write) ? wb_dat_i       : {32{1'b0}};
assign local_address    = (ddr_State == ddr_Write) ? wb_adr_i[24:2] : 
			  (ddr_State == ddr_Read)  ? wb_adr_i[24:2] : {32{1'b0}};
 
 
//
// SDRAM i/f monitor
//
// synopsys translate_off
integer fsdram;
initial begin
	fsdram = $fopen("sdram.log");
end
always @(posedge wb_clk_i)
        if (wb_cyc_i)
                if (wb_State == wb_Ack)
			if (wb_we_i)
                        	$fdisplay(fsdram, "%t [%h] <- write %h, byte sel %b", $time, wb_adr_i, wb_dat_i, wb_sel_i);
                	else
                        	$fdisplay(fsdram, "%t [%h] -> read %h byte sel %b", $time, wb_adr_i, wb_dat_o, wb_sel_i);
// synopsys translate_on
 
endmodule
 
 
 

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.