module chip (
	/********** Ê±ÖÓÓë¸´Î» **********/
	input  wire						 clk,		  // Ê±ÖÓ
	input  wire						 clk_,		  // ·´ÏàÊ±ÖÓ
	input  wire						 reset		  // ¸´Î»
	/********** UART  **********/
`ifdef IMPLEMENT_UART //  UARTÊµÏÖ
	, input	 wire					 uart_rx	  // UART½ÓÊÕÐÅºÅ
	, output wire					 uart_tx	  // UART·¢ËÍÐÅºÅ
`endif
	/********** Í¨ÓÃI/ O¶Ë¿Ú **********/
`ifdef IMPLEMENT_GPIO //GPIOÊµÏÖ
`ifdef GPIO_IN_CH	 // ÊäÈë½Ó¿ÚÊµÏÖ
	, input wire [`GPIO_IN_CH-1:0]	 gpio_in	  // ÊäÈë½Ó¿Ú
`endif
`ifdef GPIO_OUT_CH	 //  Êä³ö½Ó¿ÚÊµÏÖ
	, output wire [`GPIO_OUT_CH-1:0] gpio_out	  // Êä³ö½Ó¿Ú
`endif
`ifdef GPIO_IO_CH	 // ÊäÈëÊä³ö½Ó¿ÚÊµÏÖ
	, inout wire [`GPIO_IO_CH-1:0]	 gpio_io	  // ÊäÈëÊä³ö½Ó¿Ú
`endif
`endif
);

	/********** ×ÜÏßÐÅºÅ **********/
	// ×ÜÏßÖ÷¿ØÐÅºÅ
	wire [`WordDataBus] m_rd_data;				  // ¶ÁÈ¡Êý¾Ý
	wire				m_rdy_;					  // ¥ì¥Ç¥£
	// ×ÜÏßÖ÷¿Ø0
	wire				m0_req_;				  // ×ÜÏßÇëÇó
	wire [`WordAddrBus] m0_addr;				  // µØÖ·
	wire				m0_as_;					  // µØÖ·Ñ¡Í¨
	wire				m0_rw;					  // ¶Á/Ð´
	wire [`WordDataBus] m0_wr_data;				  // Êý¾Ý
	wire				m0_grnt_;				  // ×ÜÏßÊÚÈ¨
	// ×ÜÏßÖ÷¿Ø1
	wire				m1_req_;				  // ×ÜÏßÇëÇó
	wire [`WordAddrBus] m1_addr;				  // µØÖ·
	wire				m1_as_;					  // µØÖ·Ñ¡Í¨
	wire				m1_rw;					  // ¶Á/Ð´
	wire [`WordDataBus] m1_wr_data;				  // Êý¾Ý
	wire				m1_grnt_;				  // ×ÜÏßÊÚÈ¨
	// ×ÜÏßÖ÷¿Ø2
	wire				m2_req_;				  // ×ÜÏßÇëÇó
	wire [`WordAddrBus] m2_addr;				  // µØÖ·
	wire				m2_as_;					  // µØÖ·Ñ¡Í¨
	wire				m2_rw;					  // ¶Á/Ð´
	wire [`WordDataBus] m2_wr_data;				  // Êý¾Ý
	wire				m2_grnt_;				  // ×ÜÏßÊÚÈ¨
	// ×ÜÏßÖ÷¿Ø3
	wire				m3_req_;				  // ×ÜÏßÇëÇó
	wire [`WordAddrBus] m3_addr;				  // µØÖ·
	wire				m3_as_;					  // µØÖ·Ñ¡Í¨
	wire				m3_rw;					  // ¶Á/Ð´
	wire [`WordDataBus] m3_wr_data;				  // Êý¾Ý
	wire				m3_grnt_;				  // ×ÜÏßÊÚÈ¨
	/********** ×ÜÏß´ÓÉè±¸ÐÅºÅ**********/
	//ËùÓÐ´ÓÉè±¸¹²ÓÃÐÅºÅ
	wire [`WordAddrBus] s_addr;					  // µØÖ·
	wire				s_as_;					  // µØÖ·Ñ¡Í¨
	wire				s_rw;					  // ¶Á/Ð´
	wire [`WordDataBus] s_wr_data;				  // Ð´ÈëÊý¾Ý
	// 0ºÅ×ÜÏß´ÓÉè±¸
	wire [`WordDataBus] s0_rd_data;				  // ¶ÁÈ¡Êý¾Ý
	wire				s0_rdy_;				  // ¾ÍÐ÷
	wire				s0_cs_;					  // Æ¬Ñ¡
	// 1ºÅ×ÜÏß´ÓÉè±¸
	wire [`WordDataBus] s1_rd_data;				  // ¶ÁÈ¡Êý¾Ý
	wire				s1_rdy_;				  // ¾ÍÐ÷
	wire				s1_cs_;					  // Æ¬Ñ¡
	// 2ºÅ×ÜÏß´ÓÉè±¸
	wire [`WordDataBus] s2_rd_data;				  // ¶ÁÈ¡Êý¾Ý
	wire				s2_rdy_;				  // ¾ÍÐ÷
	wire				s2_cs_;					  // Æ¬Ñ¡
	// 3ºÅ×ÜÏß´ÓÉè±¸
	wire [`WordDataBus] s3_rd_data;				  // ¶ÁÈ¡Êý¾Ý
	wire				s3_rdy_;				  // ¾ÍÐ÷
	wire				s3_cs_;					  // Æ¬Ñ¡
	// 4ºÅ×ÜÏß´ÓÉè±¸
	wire [`WordDataBus] s4_rd_data;				  // ¶ÁÈ¡Êý¾Ý
	wire				s4_rdy_;				  // ¾ÍÐ÷
	wire				s4_cs_;					  // Æ¬Ñ¡
	// 5ºÅ×ÜÏß´ÓÉè±¸
	wire [`WordDataBus] s5_rd_data;				  // ¶ÁÈ¡Êý¾Ý
	wire				s5_rdy_;				  // ¾ÍÐ÷
	wire				s5_cs_;					  // Æ¬Ñ¡
	// 6ºÅ×ÜÏß´ÓÉè±¸
	wire [`WordDataBus] s6_rd_data;				  // ¶ÁÈ¡Êý¾Ý
	wire				s6_rdy_;				  // ¾ÍÐ÷
	wire				s6_cs_;					  // Æ¬Ñ¡
	// 7ºÅ×ÜÏß´ÓÉè±¸
	wire [`WordDataBus] s7_rd_data;				  // ¶ÁÈ¡Êý¾Ý
	wire				s7_rdy_;				  // ¾ÍÐ÷
	wire				s7_cs_;					  // Æ¬Ñ¡
	/**********ÖÐ¶ÏÇëÇóÐÅºÅ **********/
	wire				   irq_timer;			  // ¶¨Ê±Æ÷ÖÐ¶Ï
	wire				   irq_uart_rx;			  // UART IRQ£¨¶ÁÈ¡£©
	wire				   irq_uart_tx;			  // UART IRQ£¨·¢ËÍ£©
	wire [`CPU_IRQ_CH-1:0] cpu_irq;				  // CPU IRQ

	assign cpu_irq = {{`CPU_IRQ_CH-3{`LOW}}, 
					  irq_uart_rx, irq_uart_tx, irq_timer};

	/********** CPU **********/
	cpu cpu (
		/********** Ê±ÖÓÓë¸´Î» **********/
		.clk			 (clk),					  // Ê±ÖÓ
		.clk_			 (clk_),				  // ·´ÏàÊ±ÖÓ
		.reset			 (reset),				  // ¸´Î»
		/********** ×ÜÏß½Ó¿Ú **********/
		// IF Stage Ö¸Áî¶ÁÈ¡--×ÜÏßÖ÷¿Ø0
		.if_bus_rd_data	 (m_rd_data),			  // ¶Á³öµÄÊý¾Ý
		.if_bus_rdy_	 (m_rdy_),				  // ¾ÍÐ÷
		.if_bus_grnt_	 (m0_grnt_),			  // ×ÜÏßÊÚÈ¨
		.if_bus_req_	 (m0_req_),				  // ÇëÇó×ÜÏß
		.if_bus_addr	 (m0_addr),				  // µØÖ·
		.if_bus_as_		 (m0_as_),				  // µØÖ·Ñ¡Í¨
		.if_bus_rw		 (m0_rw),				  // ¶Á/Ð´
		.if_bus_wr_data	 (m0_wr_data),			  // Ð´ÈëµÄÊý¾Ý
		// MEM Stage ÄÚ´æ·ÃÎÊ--×ÜÏßÖ÷¿Ø1
		.mem_bus_rd_data (m_rd_data),			  // ¶Á³öµÄÊý¾Ý
		.mem_bus_rdy_	 (m_rdy_),				  // ¾ÍÐ÷
		.mem_bus_grnt_	 (m1_grnt_),			  // ×ÜÏßÊÚÈ¨
		.mem_bus_req_	 (m1_req_),				  // ÇëÇó×ÜÏß
		.mem_bus_addr	 (m1_addr),				  // µØÖ·
		.mem_bus_as_	 (m1_as_),				  // µØÖ·Ñ¡Í¨
		.mem_bus_rw		 (m1_rw),				  // ¶Á/Ð´
		.mem_bus_wr_data (m1_wr_data),			  // Ð´ÈëµÄÊý¾Ý
		/********** ÖÐ¶Ï **********/
		.cpu_irq		 (cpu_irq)				  // ÖÐ¶ÏÇëÇó
	);

	/********** ×ÜÏßÖ÷¿Ø2 : Î´g×° **********/
	assign m2_addr	  = `WORD_ADDR_W'h0;
	assign m2_as_	  = `DISABLE_;
	assign m2_rw	  = `READ;
	assign m2_wr_data = `WORD_DATA_W'h0;
	assign m2_req_	  = `DISABLE_;

	/********** ×ÜÏßÖ÷¿Ø 3 : Î´g×° **********/
	assign m3_addr	  = `WORD_ADDR_W'h0;
	assign m3_as_	  = `DISABLE_;
	assign m3_rw	  = `READ;
	assign m3_wr_data = `WORD_DATA_W'h0;
	assign m3_req_	  = `DISABLE_;
   
	/********** ×ÜÏß´ÓÉè±¸ 0 : ROM **********/
	rom rom (
		/********** Clock & Reset **********/
		.clk			 (clk),					  // Ê±ÖÓ
		.reset			 (reset),				  // Òì²½¸´Î»
		/**********×ÜÏß½Ó¿Ú **********/
		.cs_			 (s0_cs_),				  // Æ¬Ñ¡
		.as_			 (s_as_),				  // µØÖ·Ñ¡Í¨
		.addr			 (s_addr[`RomAddrLoc]),	  // µØÖ·
		.rd_data		 (s0_rd_data),			  // ¶Á³öµÄÊý¾Ý
		.rdy_			 (s0_rdy_)				  // ¾ÍÐ÷
	);

	/********** ×ÜÏß´ÓÉè±¸ 1 : Scratch Pad Memory£¬±¾·½°¸ÖÐRAM²»Í¨¹ý×ÜÏßÖ±½Ó·½·¨ **********/
	assign s1_rd_data = `WORD_DATA_W'h0;
	assign s1_rdy_	  = `DISABLE_;

	/********** ×ÜÏß´ÓÉè±¸ 2 : ¶¨Ê±Æ÷ **********/
`ifdef IMPLEMENT_TIMER // ¶¨Ê±Æ÷Ñ¡×°
	timer timer (
		/********** Ê±ÖÓÓë¸´Î» **********/
		.clk			 (clk),					  // Ê±ÖÓ
		.reset			 (reset),				  // Òì²½¸´Î»
		/********** ×ÜÏß½Ó¿Ú **********/
		.cs_			 (s2_cs_),				  // Æ¬Ñ¡
		.as_			 (s_as_),				  // µØÖ·Ñ¡Í¨
		.addr			 (s_addr[`TimerAddrLoc]), // µØÖ·
		.rw				 (s_rw),				  // ¶Á/Ð´
		.wr_data		 (s_wr_data),			  // Ð´ÈëµÄÊý¾Ý
		.rd_data		 (s2_rd_data),			  // ¶Á³öµÄÊý¾Ý
		.rdy_			 (s2_rdy_),				  // ¾ÍÐ÷
		/********** ÖÐ¶Ï **********/
		.irq			 (irq_timer)			  // ¶¨Ê±Æ÷ÖÐ¶ÏÇëÇó
	 );
`else				   // ¶¨Ê±Æ÷Î´Ñ¡×°
	assign s2_rd_data = `WORD_DATA_W'h0;
	assign s2_rdy_	  = `DISABLE_;
	assign irq_timer  = `DISABLE;
`endif

	/********** ×ÜÏß´ÓÉè±¸ 3 : UART **********/
`ifdef IMPLEMENT_UART // UARTÑ¡×°
	uart uart (
		/********** Ê±ÖÓÓë¸´Î» **********/
		.clk			 (clk),					  // Ê±ÖÓ
		.reset			 (reset),				  // Òì²½¸´Î»
		/********** ×ÜÏß½Ó¿Ú **********/
		.cs_			 (s3_cs_),				  // Æ¬Ñ¡
		.as_			 (s_as_),				  // µØÖ·Ñ¡Í¨
		.rw				 (s_rw),				  // ¶Á/Ð´
		.addr			 (s_addr[`UartAddrLoc]),  //  µØÖ·
		.wr_data		 (s_wr_data),			  // Ð´ÈëµÄÊý¾Ý
		.rd_data		 (s3_rd_data),			  // ¶Á³öµÄÊý¾Ý
		.rdy_			 (s3_rdy_),				  // ¾ÍÐ÷
		/********** ÖÐ¶Ï **********/
		.irq_rx			 (irq_uart_rx),			  // ½ÓÊÕÍê³ÉÖÐ¶ÏÇëÇó
		.irq_tx			 (irq_uart_tx),			  // ·¢ËÍÍê³ÉÖÐ¶ÏÇëÇó
		/********** UARTÊÕ·¢ÐÅºÅ£¬Í¨¹ýFPGAÒý½ÅÎªTTLµçÆ½£¬Èç¹ûÍ¨¹ý´®¿Ú½ÓÔòÎªRS232µçÆ½	**********/
		.rx				 (uart_rx),				  // UART½ÓÊÕÐÅºÅ£¬Òý½ÅÔ¼ÊøÊ±×¢Òâ
		.tx				 (uart_tx)				  // UART·¢ËÍÐÅºÅ£¬Òý½ÅÔ¼ÊøÊ±×¢Òâ
	);
`else				  // UARTÎ´Ñ¡×°
	assign s3_rd_data  = `WORD_DATA_W'h0;
	assign s3_rdy_	   = `DISABLE_;
	assign irq_uart_rx = `DISABLE;
	assign irq_uart_tx = `DISABLE;
`endif

	/********** ×ÜÏß´ÓÉè±¸ 4 : GPIO **********/
`ifdef IMPLEMENT_GPIO // GPIOÑ¡×°
	gpio gpio (
		/********** Ê±ÖÓÓë¸´Î» **********/
		.clk			 (clk),					 // Ê±ÖÓ
		.reset			 (reset),				 // Òì²½¸´Î»
		/********** ×ÜÏß½Ó¿Ú **********/
		.cs_			 (s4_cs_),				 // Æ¬Ñ¡
		.as_			 (s_as_),				 // µØÖ·Ñ¡Í¨
		.rw				 (s_rw),				 // ¶Á/Ð´
		.addr			 (s_addr[`GpioAddrLoc]), // µØÖ·
		.wr_data		 (s_wr_data),			 // Ð´ÈëµÄÊý¾Ý
		.rd_data		 (s4_rd_data),			 // ¶Á³öµÄÊý¾Ý
		.rdy_			 (s4_rdy_)				 // ¾ÍÐ÷
		/********** GPIO ¶Ë¿Ú **********/
`ifdef GPIO_IN_CH	 // Ñ¡×°ÊäÈë¿Ú
		, .gpio_in		 (~gpio_in)				 // ÊäÈë¿Ú,zhangly×¢£º±©·ç°åÉÏÒý½ÅÔ¼Êøµ½ËÄ¸ö¸ºÂß¼­µÄ°´Å¥£¬¹ÊÈ¡·´
`endif
`ifdef GPIO_OUT_CH	 // Ñ¡×°Êä³ö¿Ú
		, .gpio_out		 (gpio_out)				 // Êä³ö¿Ú
`endif
`ifdef GPIO_IO_CH	 // Ñ¡×°ÁËÊäÈëÊä³ö
		, .gpio_io		 (gpio_io)				 // ÊäÈëÊä³ö¿Ú
`endif
	);
`else				  // GPIOÃ»Ñ¡×°
	assign s4_rd_data = `WORD_DATA_W'h0;
	assign s4_rdy_	  = `DISABLE_;
`endif

	/********** ×ÜÏß´ÓÉè±¸ 5 : Ã»Ñ¡×° **********/
	assign s5_rd_data = `WORD_DATA_W'h0;
	assign s5_rdy_	  = `DISABLE_;
  
	/********** ×ÜÏß´ÓÉè±¸ 6 :  Ã»Ñ¡×° **********/
	assign s6_rd_data = `WORD_DATA_W'h0;
	assign s6_rdy_	  = `DISABLE_;
  
	/********** ×ÜÏß´ÓÉè±¸ 7 :  Ã»Ñ¡×° **********/
	assign s7_rd_data = `WORD_DATA_W'h0;
	assign s7_rdy_	  = `DISABLE_;

	/********** ×ÜÏß **********/
	bus bus (
		/********** Ê±ÖÓÓë¸´Î» **********/
		.clk			 (clk),					 // Ê±ÖÓ
		.reset			 (reset),				 // Òì²½¸´Î»
		/********** ×ÜÏßÖ÷¿ØÐÅºÅ **********/
		// ËùÓÐ×ÜÏßÖ÷¿Ø¹²ÓÃÐÅºÅ
		.m_rd_data		 (m_rd_data),			 // ¶Á³öµÄÊý¾Ý
		.m_rdy_			 (m_rdy_),				 // ¾ÍÐ÷
		// 0ºÅ×ÜÏßÖ÷¿Ø
		.m0_req_		 (m0_req_),				 // ÇëÇó×ÜÏß
		.m0_addr		 (m0_addr),				 // µØÖ·
		.m0_as_			 (m0_as_),				 // µØÖ·Ñ¡Í¨
		.m0_rw			 (m0_rw),				 // ¶Á/Ð´
		.m0_wr_data		 (m0_wr_data),			 // Ð´ÈëµÄÊý¾Ý
		.m0_grnt_		 (m0_grnt_),			 // ×ÜÏßÊÚÈ¨
		// 1ºÅ×ÜÏßÖ÷¿Ø
		.m1_req_		 (m1_req_),				 // ¥Ð¥¹¥ê¥¯¥¨¥¹¥È
		.m1_addr		 (m1_addr),				 // ¥¢¥É¥ì¥¹
		.m1_as_			 (m1_as_),				 // ¥¢¥É¥ì¥¹¥¹¥È¥í©`¥Ö
		.m1_rw			 (m1_rw),				 // Õi¤ß£¯ø¤­
		.m1_wr_data		 (m1_wr_data),			 // ø¤­Þz¤ß¥Ç©`¥¿
		.m1_grnt_		 (m1_grnt_),			 // ¥Ð¥¹¥°¥é¥ó¥È
		// 2ºÅ×ÜÏßÖ÷¿Ø
		.m2_req_		 (m2_req_),				 // ¥Ð¥¹¥ê¥¯¥¨¥¹¥È
		.m2_addr		 (m2_addr),				 // ¥¢¥É¥ì¥¹
		.m2_as_			 (m2_as_),				 // ¥¢¥É¥ì¥¹¥¹¥È¥í©`¥Ö
		.m2_rw			 (m2_rw),				 // Õi¤ß£¯ø¤­
		.m2_wr_data		 (m2_wr_data),			 // ø¤­Þz¤ß¥Ç©`¥¿
		.m2_grnt_		 (m2_grnt_),			 // ¥Ð¥¹¥°¥é¥ó¥È
		// 3ºÅ×ÜÏßÖ÷¿Ø
		.m3_req_		 (m3_req_),				 // ¥Ð¥¹¥ê¥¯¥¨¥¹¥È
		.m3_addr		 (m3_addr),				 // ¥¢¥É¥ì¥¹
		.m3_as_			 (m3_as_),				 // ¥¢¥É¥ì¥¹¥¹¥È¥í©`¥Ö
		.m3_rw			 (m3_rw),				 // Õi¤ß£¯ø¤­
		.m3_wr_data		 (m3_wr_data),			 // ø¤­Þz¤ß¥Ç©`¥¿
		.m3_grnt_		 (m3_grnt_),			 // ¥Ð¥¹¥°¥é¥ó¥È
		/********** ×ÜÏß´ÓÉè±¸ÐÅºÅ **********/
		// ËùÓÐ×ÜÏß´ÓÊôÉè±¸¹²ÓÃÐÅºÅ
		.s_addr			 (s_addr),				 // µØÖ·
		.s_as_			 (s_as_),				 // µØÖ·Ñ¡Í¨
		.s_rw			 (s_rw),				 // ¶Á/Ð´
		.s_wr_data		 (s_wr_data),			 // Ð´ÈëµÄÊý¾Ý
		// 0ºÅ×ÜÏß´ÓÊô
		.s0_rd_data		 (s0_rd_data),			 // ¶Á³öµÄÊý¾Ý
		.s0_rdy_		 (s0_rdy_),				 // ¾ÍÐ÷
		.s0_cs_			 (s0_cs_),				 // Æ¬Ñ¡
		// 1ºÅ×ÜÏß´ÓÊô
		.s1_rd_data		 (s1_rd_data),			 // Õi¤ß³ö¤·¥Ç©`¥¿
		.s1_rdy_		 (s1_rdy_),				 // ¥ì¥Ç¥£
		.s1_cs_			 (s1_cs_),				 // ¥Á¥Ã¥×¥»¥ì¥¯¥È
		// 2ºÅ×ÜÏß´ÓÊô
		.s2_rd_data		 (s2_rd_data),			 // Õi¤ß³ö¤·¥Ç©`¥¿
		.s2_rdy_		 (s2_rdy_),				 // ¥ì¥Ç¥£
		.s2_cs_			 (s2_cs_),				 // ¥Á¥Ã¥×¥»¥ì¥¯¥È
		// 3ºÅ×ÜÏß´ÓÊô
		.s3_rd_data		 (s3_rd_data),			 // Õi¤ß³ö¤·¥Ç©`¥¿
		.s3_rdy_		 (s3_rdy_),				 // ¥ì¥Ç¥£
		.s3_cs_			 (s3_cs_),				 // ¥Á¥Ã¥×¥»¥ì¥¯¥È
		// 4ºÅ×ÜÏß´ÓÊô
		.s4_rd_data		 (s4_rd_data),			 // Õi¤ß³ö¤·¥Ç©`¥¿
		.s4_rdy_		 (s4_rdy_),				 // ¥ì¥Ç¥£
		.s4_cs_			 (s4_cs_),				 // ¥Á¥Ã¥×¥»¥ì¥¯¥È
		// 5ºÅ×ÜÏß´ÓÊô
		.s5_rd_data		 (s5_rd_data),			 // Õi¤ß³ö¤·¥Ç©`¥¿
		.s5_rdy_		 (s5_rdy_),				 // ¥ì¥Ç¥£
		.s5_cs_			 (s5_cs_),				 // ¥Á¥Ã¥×¥»¥ì¥¯¥È
		// 6ºÅ×ÜÏß´ÓÊô
		.s6_rd_data		 (s6_rd_data),			 // Õi¤ß³ö¤·¥Ç©`¥¿
		.s6_rdy_		 (s6_rdy_),				 // ¥ì¥Ç¥£
		.s6_cs_			 (s6_cs_),				 // ¥Á¥Ã¥×¥»¥ì¥¯¥È
		// 7ºÅ×ÜÏß´ÓÊô
		.s7_rd_data		 (s7_rd_data),			 // Õi¤ß³ö¤·¥Ç©`¥¿
		.s7_rdy_		 (s7_rdy_),				 // ¥ì¥Ç¥£
		.s7_cs_			 (s7_cs_)				 // ¥Á¥Ã¥×¥»¥ì¥¯¥È
	);

endmodule