rspbusses.v 5.75 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.7 2003/01/25 01:06:32 berndt Exp $

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

`timescale 1ns / 10ps

module rspbusses (clk, reset_l,
 	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, 
	cbus_din, cbus_dout, dbus_din, dbus_dout, xbus_data,
	ex_dma_rd_to_dm, ex_dma_dm_to_rd,  
	mem_write_data, imem_datain, 
 	dma_wen, imem_csb, 
        debug_pc);

    input		clk;
    input		reset_l;

    // 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
    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 	[31:0] 	cbus_din;
    output 	[31:0] 	cbus_dout;
    input 	[63:0] 	dbus_din;		// DMA bus
    output 	[63:0] 	dbus_dout;		// 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	[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);
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_din : mem_read_data;
asdff #(64,0) rsp_dma_dbus_in_ff (dbus_data_reg, next_dbus_data,clk,reset_l);

assign	dbus_dout = dbus_write_enable ? dbus_data_reg : 64'b0;

// 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_din : mem_load_data;
asdff #(32, 0) dma_cbus_ff (cbus_data_reg, next_cbus_data, clk, reset_l);

assign	cbus_dout = cbus_write_enable ? cbus_data_reg : 32'b0;

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;

assign final_pc = imem_dma_cycle ? imem_dma_address : pc[11:3];
assign imem_datain = rd_to_im_data;
assign imem_web = !(rd_to_im_if || !reset_l_lat);
assign imem_csb = 1'b0;

assign debug_pc = {final_pc, 3'b0};

endmodule