rspbusses.v 6.54 KB
/**************************************************************************
 *                                                                        *
 *               Copyright (C) 1994, Silicon Graphics, Inc.               *
 *                                                                        *
 *  These coded instructions, statements, and computer programs  contain  *
 *  unpublished  proprietary  information of Silicon Graphics, Inc., and  *
 *  are protected by Federal copyright  law.  They  may not be disclosed  *
 *  to  third  parties  or copied or duplicated in any form, in whole or  *
 *  in part, without the prior written consent of Silicon Graphics, Inc.  *
 *                                                                        *
 *************************************************************************/
// $Id: rspbusses.v,v 1.1.1.1 2002/05/17 06:07:48 blythe Exp $

// rspbusses.v		interface between imem/dmem and outside world.

`timescale 1ns / 10ps

module rspbusses (clk, reset_l, iddq_test, 
 	cbus_write_enable, dbus_read_enable, dbus_write_enable, 
	io_load, io_read_select, io_write_select, 
	dma_imem_select, xbus_dmem_select, 
	dma_dm_to_rd, dma_rd_to_dm, dma_address, dma_mask,mem_load,  
	im_to_rd_data, dmem_rd_data, 
	pc, final_pc, imem_web, imem_dma_cycle, imem_chip_sel_l, 
	bist_go, bist_check, 
	cbus_data, dbus_data, xbus_data,
	ex_dma_rd_to_dm, ex_dma_dm_to_rd,  
	mem_write_data, imem_datain, 
 	dma_wen, imem_csb, bist_done, bist_fail, debug_pc);

    input		clk;
    input		reset_l;
    input		iddq_test;

    // DMA interface signals

    input 		cbus_write_enable;
    input 		dbus_read_enable;	// mess with dbus data
    input 		dbus_write_enable;	// enable dbus drivers
    input 		io_load;		// load cbus reg from cbus
    input		io_read_select;
    input		io_write_select;
    input		dma_imem_select;	// DMA is for IMem, not DMem
    input 		xbus_dmem_select;
    input 		dma_dm_to_rd;		// RD: enable dma write
    input 		dma_rd_to_dm;		// RD: enable dma read
    input	[11:3]	dma_address;
    input 	[1:0] 	dma_mask;		// 32-bit word  write enable
    input		mem_load;		// load cbus reg from imem/dmem
// *** im_to_rd_data is bound to rd_inst.  May want to buffer it.
    input	[63:0]	im_to_rd_data;		// dma data from imem
    input 	[63:0] 	dmem_rd_data;

    input	[11:2]	pc;
    input		imem_dma_cycle;
    input		imem_chip_sel_l;

    input		bist_go;
    input		bist_check;

    inout 	[31:0] 	cbus_data;
    inout 	[63:0] 	dbus_data;		// DMA bus

    output	[63:0]	xbus_data;
    output 		ex_dma_rd_to_dm;
    output 		ex_dma_dm_to_rd;
    output 	[63:0] 	mem_write_data;
    output	[63:0]	imem_datain;
    output	[3:0]	dma_wen;

    output	[11:3]	final_pc;
    output		imem_web;
    output		imem_csb;
    output		bist_done;
    output	[3:0]	bist_fail;
    output	[11:0]	debug_pc;		// for debug only

    wire		reset_l_lat;
    wire		im_to_rd_pre_pre_if;
    wire		im_to_rd_pre_if;
    wire		im_to_rd_if;
    wire		im_to_rd_rd;
    wire 		rd_to_im_pre_if;
    wire		rd_to_im_pre_pre_if;
    wire		rd_to_im_if;
    wire 	[11:3] 	imem_dma_address;	// IF stage

    wire	[1:0]	dma_mask_pl;
    wire		dma_rd_to_dm_d;
    wire		ex_dma_rd_to_dm;
    wire 		dma_dm_to_rd_d;
    wire 	[63:0] 	next_dbus_data;
    wire 	[63:0] 	dbus_data_reg;
    wire 	[63:0] 	mem_read_data;
    wire	[63:0]	mem_write_data_delayed;
    wire 	[63:0] 	rd_to_im_data;

    wire 	[31:0] 	io_read_data;
    wire 	[31:0] 	mem_load_data;
    wire 	[63:0] 	io_write_data;
    wire 	[31:0] 	next_cbus_data;
    wire 	[31:0] 	cbus_data_reg;


asdff #(1,0) sb_reset_ff (reset_l_lat, reset_l, clk, 1'b1);

// ******************* DMA Interface Logic *************************

assign im_to_rd_pre_pre_if = dma_dm_to_rd && dma_imem_select;
asdff #(1,0) rsp_ppipi_imtordff (im_to_rd_pre_if,im_to_rd_pre_pre_if,clk,reset_l);
asdff #(1,0) rsp_piif_im_to_rd_ff (im_to_rd_if,im_to_rd_pre_if,clk,reset_l);
asdff #(1,0) rsp_ir_im_to_rd_ff (im_to_rd_rd,im_to_rd_if,clk,reset_l);
	
asdff  #(2,0) rsp_dma_mask_ff (dma_mask_pl, dma_mask, clk, reset_l);
assign dma_wen = {4{ex_dma_rd_to_dm}} & {dma_mask_pl, dma_mask};

assign dma_rd_to_dm_d = dma_rd_to_dm && !dma_imem_select;
assign dma_dm_to_rd_d = dma_dm_to_rd && !dma_imem_select;
asdff #(1,0) rsp_re_rd_to_dm_ff (ex_dma_rd_to_dm, dma_rd_to_dm_d, clk,reset_l);
asdff #(1,0) rsp_re_dm_to_rd_ff (ex_dma_dm_to_rd, dma_dm_to_rd_d, clk,reset_l);

// DMem to RDP
assign xbus_data = xbus_dmem_select ? dmem_rd_data : dbus_data_reg;

// IMem to CBUS

assign rd_to_im_pre_pre_if = dma_rd_to_dm && dma_imem_select;
asdff #(1,0) rsp_ppipi_rdtoifff (rd_to_im_pre_if,rd_to_im_pre_pre_if,clk,reset_l);
asdff #(1,0) rsp_piif_rdtoifff (rd_to_im_if, rd_to_im_pre_if, clk, reset_l);
// *** Don't really need enable here (but maybe it saves power?):
asdff #(64,0) dma_wr_data_ff (mem_write_data_delayed, mem_write_data, clk, reset_l);
asdffen #(64,0) dma_imem_wr_ff (rd_to_im_data, mem_write_data_delayed, rd_to_im_pre_if, clk, reset_l);
asdff #(9,0) dma_im_addr_ff (imem_dma_address, dma_address ,clk, reset_l);

// DBus interface
assign mem_read_data = im_to_rd_rd ? im_to_rd_data : dmem_rd_data;
assign next_dbus_data = dbus_read_enable ? dbus_data : mem_read_data;
asdff #(64,0) rsp_dma_dbus_in_ff (dbus_data_reg, next_dbus_data,clk,reset_l);
dbus_driver dbus_driver_ls(
   .dbus_data_out(dbus_data_reg),
   .dbus_enable(dbus_write_enable),
   .dbus_data(dbus_data));

// CBus interface

assign io_read_data = io_read_select ? mem_read_data[31:0] : mem_read_data[63:32];
assign mem_load_data = mem_load ? io_read_data : cbus_data_reg;
assign next_cbus_data = io_load ? cbus_data : mem_load_data;
asdff #(32, 0) dma_cbus_ff (cbus_data_reg, next_cbus_data, clk, reset_l);
cbus_driver cbus_driver_ls(
   .cbus_data_out(cbus_data_reg),
   .cbus_enable(cbus_write_enable),
	.cbus_data(cbus_data));
assign io_write_data = io_read_select ? {mem_read_data[63:32], cbus_data_reg} :
				        {cbus_data_reg, mem_read_data[31:0]};
assign mem_write_data = io_write_select ? io_write_data : dbus_data_reg;

// BIST

ram_bist_imem ram_bist_imem (
	.clk		(clk),
	.reset_l	(reset_l),
	.iddq_test	(iddq_test),
	.bist_go	(bist_go),
	.bist_check	(bist_check),

	.sys_addr	(pc[11:3]),
	.sys_din	(rd_to_im_data),
	.dma_addr	(imem_dma_address),
	.dma_cycle	(imem_dma_cycle),
	.sys_web	(!(rd_to_im_if || !reset_l_lat)),
	.sys_csb	(imem_chip_sel_l),
	.ram_do		(im_to_rd_data),
	.ram_addr	(final_pc),
	.ram_din	(imem_datain),
	.ram_web	(imem_web),
	.ram_csb	(imem_csb),

	.bist_done	(bist_done),
	.bist3_fail	(bist_fail[3]),
	.bist2_fail	(bist_fail[2]),
	.bist1_fail	(bist_fail[1]),
	.bist0_fail	(bist_fail[0])
);

assign debug_pc = {final_pc, 3'b0};

endmodule