Lynx-EyEDの電音鍵盤 新館

広帯域制御屋の駄文とか

Spartan-6 LX9 MicroBoardを使ったLPDDR SDRAMのハードマクロ実装(その4)

MIGが生成したuser_designを使って、MCBラッパーと分散メモリのインスタンシエートをしているわけですが、ふと、違和感を感じました。user_designのトップファイルのモジュール宣言。

module mymig #
( 
   //(中略) 
)	

(

   inout  [C3_NUM_DQ_PINS-1:0]                      mcb3_dram_dq,
   output [C3_MEM_ADDR_WIDTH-1:0]                   mcb3_dram_a,
   output [C3_MEM_BANKADDR_WIDTH-1:0]               mcb3_dram_ba,
   output                                           mcb3_dram_cke,
   output                                           mcb3_dram_ras_n,
   output                                           mcb3_dram_cas_n,
   output                                           mcb3_dram_we_n,
   output                                           mcb3_dram_dm,
   inout                                            mcb3_dram_udqs,
   inout                                            mcb3_rzq,
   output                                           mcb3_dram_udm,
   input                                            c3_sys_clk,
   input                                            c3_sys_rst_i,
   output                                           c3_calib_done,
   output                                           c3_clk0,
   output                                           c3_rst0,
   inout                                            mcb3_dram_dqs,
   output                                           mcb3_dram_ck,
   output                                           mcb3_dram_ck_n,
      input		c3_p0_cmd_clk,
      input		c3_p0_cmd_en,
      input [2:0]	c3_p0_cmd_instr,
      input [5:0]	c3_p0_cmd_bl,
      input [29:0]	c3_p0_cmd_byte_addr,
      output		c3_p0_cmd_empty,
      output		c3_p0_cmd_full,
      input		c3_p0_wr_clk,
      input		c3_p0_wr_en,
      input [C3_P0_MASK_SIZE - 1:0]	c3_p0_wr_mask,
      input [C3_P0_DATA_PORT_SIZE - 1:0]	c3_p0_wr_data,
      output		c3_p0_wr_full,
      output		c3_p0_wr_empty,
      output [6:0]	c3_p0_wr_count,
      output		c3_p0_wr_underrun,
      output		c3_p0_wr_error,
      input		c3_p0_rd_clk,
      input		c3_p0_rd_en,
      output [C3_P0_DATA_PORT_SIZE - 1:0]	c3_p0_rd_data,
      output		c3_p0_rd_full,
      output		c3_p0_rd_empty,
      output [6:0]	c3_p0_rd_count,
      output		c3_p0_rd_overflow,
      output		c3_p0_rd_error
);

example_designをずっと参考にしていたので、このモジュールをガシガシ改造していかなくてはならないのかなと思い込んでいましたが、ここでどうやら違うということをようやく理解しました。
よくよく考えると、このモジュールを改造したらLPDDR以外のDDR2 SDRAMなどのMCBラッパーを生成したときに使いまわせなくなっちゃいますねorz

で、こんなヒエラルキーになるように構成しました。
f:id:Lynx-EyED:20111010212047j:image


ufcファイルの階層が一段階深くなってしまうので、そこを注意しないといけません。もし、ucfのこのモジュール無いよ、というエラーが出たらそれが原因です。

そして、トップファイルtop.vはこんな構成にしました。(長いので注意)

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:			Lynx-EyED WORKS and it's Klavier Craft 
// Engineer:			lynxeyed_atsu 
// 
// Create Date:    11:13:45 10/08/2011 
// Design Name: 
// Module Name:    top 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
(* X_CORE_INFO = "mig_v3_8_lpddr_lpddr_s6, Coregen 13.2" , CORE_GENERATION_INFO = "lpddr_lpddr_s6,mig_v3_8,{component_name=mymig, C3_MEM_INTERFACE_TYPE=LPDDR, C3_CLK_PERIOD=5000, C3_MEMORY_PART=mt46h32m16xxxx-5, C3_MEMORY_DEVICE_WIDTH=16, C3_PA_SR=FULL, C3_OUTPUT_DRV=FULL, C3_PORT_CONFIG=Two 32-bit bi-directional and four 32-bit unidirectional ports, C3_MEM_ADDR_ORDER=ROW_BANK_COLUMN, C3_PORT_ENABLE=Port0, C3_INPUT_PIN_TERMINATION=EXTERN_TERM, C3_DATA_TERMINATION=25 Ohms, C3_CLKFBOUT_MULT_F=4, C3_CLKOUT_DIVIDE=2, C3_DEBUG_PORT=0, C3_INPUT_CLK_TYPE=Single-Ended, LANGUAGE=Verilog, SYNTHESIS_TOOL=Foundation_ISE, NO_OF_CONTROLLERS=1}" *)
module top #(
   parameter C3_P0_MASK_SIZE           = 4,
   parameter C3_P0_DATA_PORT_SIZE      = 32,
   parameter C3_P1_MASK_SIZE           = 4,
   parameter C3_P1_DATA_PORT_SIZE      = 32,
   parameter DEBUG_EN                = 0,       
                                       // # = 1, Enable debug signals/controls,
                                       //   = 0, Disable debug signals/controls.
   parameter C3_MEMCLK_PERIOD        = 15000,       
                                       // Memory data transfer clock period
   parameter C3_CALIB_SOFT_IP        = "TRUE",       
                                       // # = TRUE, Enables the soft calibration logic,
                                       // # = FALSE, Disables the soft calibration logic.
   parameter C3_SIMULATION           = "FALSE",       
                                       // # = TRUE, Simulating the design. Useful to reduce the simulation time,
                                       // # = FALSE, Implementing the design.
   parameter C3_RST_ACT_LOW          = 0,       
                                       // # = 1 for active low reset,
                                       // # = 0 for active high reset.
   parameter C3_INPUT_CLK_TYPE       = "SINGLE_ENDED",       
                                       // input clock type DIFFERENTIAL or SINGLE_ENDED
   parameter C3_MEM_ADDR_ORDER       = "ROW_BANK_COLUMN",       
                                       // The order in which user address is provided to the memory controller,
                                       // ROW_BANK_COLUMN or BANK_ROW_COLUMN
   parameter C3_NUM_DQ_PINS          = 16,       
                                       // External memory data width
   parameter C3_MEM_ADDR_WIDTH       = 13,       
                                       // External memory address width
   parameter C3_MEM_BANKADDR_WIDTH   = 2        
                                       // External memory bank address width
)
(
   output [3:0]					GPIO_LED,		//Spartan-6 LX9 MB上のLED
   output					calib_done,
   output					error,
   inout  [C3_NUM_DQ_PINS-1:0]			mcb3_dram_dq,
   output [C3_MEM_ADDR_WIDTH-1:0]		mcb3_dram_a,
   output [C3_MEM_BANKADDR_WIDTH-1:0]		mcb3_dram_ba,
   output					mcb3_dram_cke,
   output					mcb3_dram_ras_n,
   output					mcb3_dram_cas_n,
   output					mcb3_dram_we_n,
   output					mcb3_dram_dm,
   inout					mcb3_dram_udqs,
   inout					mcb3_rzq,
   output					mcb3_dram_udm,
   input					c3_sys_clk,
   input					c3_sys_rst_i,
   inout					mcb3_dram_dqs,
   output					mcb3_dram_ck,
   output					mcb3_dram_ck_n
);

	wire					mainclk;	// topモジュールで使うメインクロック。実態はMCBから供給されるc3_clk0
	
	wire					user_wire_cmd_en;
	wire[2:0]				user_wire_cmd_instr;
	wire[5:0]				user_wire_cmd_bl;
	wire[29:0]				user_wire_cmd_byte_addr;
	wire					user_wire_cmd_empty;
	wire					user_wire_cmd_full;
		
	wire					user_wire_wr_en;
	wire[C3_P0_MASK_SIZE - 1:0]		user_wire_wr_mask;
	wire[C3_P0_DATA_PORT_SIZE - 1:0]	user_wire_wr_data;
	wire					user_wire_wr_full;
	wire					user_wire_wr_empty;
	wire[6:0]				user_wire_wr_count;
	wire					user_wire_wr_underrun;
	wire					user_wire_wr_error;
	
	wire					user_wire_rd_en;
	wire[C3_P0_DATA_PORT_SIZE - 1:0]	user_wire_rd_data;
	wire					user_wire_rd_full;
	wire					user_wire_rd_empty;
	wire[6:0]				user_wire_rd_count;
	wire					user_wire_rd_overflow;
	wire					user_wire_rd_error;		

	// MCB module instantiation
	mymig #(
		.C3_P0_MASK_SIZE		(C3_P0_MASK_SIZE),
		.C3_P0_DATA_PORT_SIZE		(C3_P0_DATA_PORT_SIZE),
		.C3_P1_MASK_SIZE		(C3_P1_MASK_SIZE),
		.C3_P1_DATA_PORT_SIZE		(C3_P1_DATA_PORT_SIZE),
		.DEBUG_EN			(DEBUG_EN),
		.C3_MEMCLK_PERIOD		(C3_MEMCLK_PERIOD),
		.C3_CALIB_SOFT_IP		(C3_CALIB_SOFT_IP),       
		.C3_SIMULATION			(C3_SIMULATION),
		.C3_RST_ACT_LOW			(C3_RST_ACT_LOW),
		.C3_INPUT_CLK_TYPE		(C3_INPUT_CLK_TYPE),       
		.C3_MEM_ADDR_ORDER		(C3_MEM_ADDR_ORDER),       
		.C3_NUM_DQ_PINS			(C3_NUM_DQ_PINS),       
		.C3_MEM_ADDR_WIDTH		(C3_MEM_ADDR_WIDTH),       
		.C3_MEM_BANKADDR_WIDTH		(C3_MEM_BANKADDR_WIDTH)        								
	)
	lpddr_mig(
		.mcb3_dram_dq			(mcb3_dram_dq),
		.mcb3_dram_a			(mcb3_dram_a),
		.mcb3_dram_ba			(mcb3_dram_ba),
		.mcb3_dram_cke			(mcb3_dram_cke),
		.mcb3_dram_ras_n		(mcb3_dram_ras_n),
		.mcb3_dram_cas_n		(mcb3_dram_cas_n),
		.mcb3_dram_we_n			(mcb3_dram_we_n),
		.mcb3_dram_dm			(mcb3_dram_dm),
		.mcb3_dram_udqs			(mcb3_dram_udqs),
		.mcb3_rzq			(mcb3_rzq),
		.mcb3_dram_udm			(mcb3_dram_udm),	
		.c3_sys_clk			(c3_sys_clk),
		.c3_sys_rst_i			(c3_sys_rst_i),
		.c3_calib_done			(c3_calib_done),
		.c3_clk0			(mainclk),
		.c3_rst0			(c3_rst0),
		.mcb3_dram_dqs			(mcb3_dram_dqs),
		.mcb3_dram_ck			(mcb3_dram_ck),
		.mcb3_dram_ck_n			(mcb3_dram_ck_n),

		//ここからMCBラッパーで取り扱う信号
		.c3_p0_cmd_clk		(mainclk),
		.c3_p0_cmd_en		(user_wire_cmd_en),
		.c3_p0_cmd_instr	(user_wire_cmd_instr),
		.c3_p0_cmd_bl		(user_wire_cmd_bl),
		.c3_p0_cmd_byte_addr	(user_wire_cmd_byte_addr),
		.c3_p0_cmd_empty	(user_wire_cmd_empty),
		.c3_p0_cmd_full		(user_wire_cmd_full),
		.c3_p0_wr_clk		(mainclk),
		.c3_p0_wr_en		(user_wire_wr_en),
		.c3_p0_wr_mask		(user_wire_wr_mask),
		.c3_p0_wr_data		(user_wire_wr_data),
		.c3_p0_wr_full		(user_wire_wr_full),
		.c3_p0_wr_empty		(user_wire_wr_empty),
		.c3_p0_wr_count		(user_wire_wr_count),
		.c3_p0_wr_underrun	(user_wire_wr_underrun),
		.c3_p0_wr_error		(user_wire_wr_error),
		.c3_p0_rd_clk		(mainclk),
		.c3_p0_rd_en		(user_wire_rd_en),
		.c3_p0_rd_data		(user_wire_rd_data),
		.c3_p0_rd_full		(user_wire_rd_full),
		.c3_p0_rd_empty		(user_wire_rd_empty),
		.c3_p0_rd_count		(user_wire_rd_count),
		.c3_p0_rd_overflow	(user_wire_rd_overflow),
		.c3_p0_rd_error		(user_wire_rd_error)
	); 



reg						user_reg_cmd_en;
reg[2:0]					user_reg_cmd_instr;
reg[5:0]					user_reg_cmd_bl;
reg[29:0]					user_reg_cmd_byte_addr;
reg						user_reg_wr_clk;
reg						user_reg_wr_en;
reg[C3_P0_MASK_SIZE - 1:0]			user_reg_wr_mask;
reg[C3_P0_DATA_PORT_SIZE - 1:0]			user_reg_wr_data;
reg						user_reg_rd_en;

assign	user_wire_cmd_en			= user_reg_cmd_en;
assign	user_wire_cmd_instr			= user_reg_cmd_instr;
assign	user_wire_cmd_bl			= user_reg_cmd_bl;
assign	user_wire_cmd_byte_addr			= user_reg_cmd_byte_addr;
assign	user_wire_wr_clk			= user_reg_wr_clk;
assign	user_wire_wr_en				= user_reg_wr_en;
assign	user_wire_wr_mask			= user_reg_wr_mask;
assign	user_wire_wr_data			= user_reg_wr_data;
assign	user_wire_rd_en				= user_reg_rd_en;
	

//^^^^^^^^^^^^^^^^
// ここからステートマシンもろもろを記述
//^^^^^^^^^^^^^^^^



endmodule