rspbusses.v
5.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/**************************************************************************
* *
* 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