OpenCores
URL https://opencores.org/ocsvn/theia_gpu/theia_gpu/trunk

Subversion Repositories theia_gpu

[/] [theia_gpu/] [branches/] [gpu_8_cores/] [rtl/] [GPU/] [CORES/] [MEM/] [Unit_MEM.v] - Blame information for rev 138

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 19 diegovalve
`timescale 1ns / 1ps
2
`include "aDefinitions.v"
3
/**********************************************************************************
4
Theia, Ray Cast Programable graphic Processing Unit.
5
Copyright (C) 2010  Diego Valverde (diego.valverde.g@gmail.com)
6
 
7
This program is free software; you can redistribute it and/or
8
modify it under the terms of the GNU General Public License
9
as published by the Free Software Foundation; either version 2
10
of the License, or (at your option) any later version.
11
 
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20
 
21
***********************************************************************************/
22
/*
23
The memory unit has all the memory related modules for THEIA.
24
There a 3 memories in the core:
25 60 diegovalve
DMEM: The data memory, it is a R/W dual channel RAM, stores the data locations.
26
IMEM: The instruction memory, R/W dual channel RAM, stores user shaders.
27 19 diegovalve
IROM: RO instruction memory, stores default shaders and other internal code.
28 60 diegovalve
I use two ROMs with the same data, so that simulates dual channel.
29 19 diegovalve
This unit also has a Control register.
30
*/
31 60 diegovalve
`define USER_CODE_ENABLED 2
32 19 diegovalve
//-------------------------------------------------------------------
33
module MemoryUnit
34
(
35
input wire                              Clock,
36
input wire                              Reset,
37 74 diegovalve
input wire                                  iFlipMemory,
38
 
39
//Data bus for EXE Unit
40
input wire                              iDataWriteEnable_EXE,
41
input wire[`DATA_ADDRESS_WIDTH-1:0]     iDataReadAddress1_EXE,
42
output wire[`DATA_ROW_WIDTH-1:0]        oData1_EXE,
43
input wire[`DATA_ADDRESS_WIDTH-1:0]     iDataReadAddress2_EXE,
44
output wire[`DATA_ROW_WIDTH-1:0]        oData2_EXE,
45
input wire[`DATA_ADDRESS_WIDTH-1:0]     iDataWriteAddress_EXE,
46
input wire[`DATA_ROW_WIDTH-1:0]         iData_EXE,
47
 
48
//Data bus for IO Unit
49
input wire                              iDataWriteEnable_IO,
50
input wire[`DATA_ADDRESS_WIDTH-1:0]     iDataReadAddress1_IO,
51
output wire[`DATA_ROW_WIDTH-1:0]        oData1_IO,
52
input wire[`DATA_ADDRESS_WIDTH-1:0]     iDataReadAddress2_IO,
53
output wire[`DATA_ROW_WIDTH-1:0]        oData2_IO,
54
input wire[`DATA_ADDRESS_WIDTH-1:0]     iDataWriteAddress_IO,
55
input wire[`DATA_ROW_WIDTH-1:0]         iData_IO,
56
 
57
//Instruction bus
58 19 diegovalve
input wire                              iInstructionWriteEnable,
59 60 diegovalve
input  wire [`ROM_ADDRESS_WIDTH-1:0]    iInstructionReadAddress1,
60
input  wire [`ROM_ADDRESS_WIDTH-1:0]    iInstructionReadAddress2,
61 19 diegovalve
input wire [`ROM_ADDRESS_WIDTH-1:0]     iInstructionWriteAddress,
62 74 diegovalve
input wire [`INSTRUCTION_WIDTH-1:0]     iInstruction,
63 60 diegovalve
output wire [`INSTRUCTION_WIDTH-1:0]    oInstruction1,
64 105 diegovalve
output wire [`INSTRUCTION_WIDTH-1:0]    oInstruction2,
65
 
66
`ifdef DEBUG
67
input wire [`MAX_CORES-1:0]            iDebug_CoreID,
68
`endif
69 74 diegovalve
 
70
 
71
//Control Register
72 19 diegovalve
input wire[15:0]                       iControlRegister,
73
output wire[15:0]                       oControlRegister
74
 
75 74 diegovalve
 
76 19 diegovalve
);
77
 
78
wire [`ROM_ADDRESS_WIDTH-1:0] wROMInstructionAddress,wRAMInstructionAddress;
79 60 diegovalve
wire [`INSTRUCTION_WIDTH-1:0] wIMEM2_IMUX__DataOut1,wIMEM2_IMUX__DataOut2,
80
wIROM2_IMUX__DataOut1,wIROM2_IMUX__DataOut2;
81 19 diegovalve
 
82
 
83 105 diegovalve
wire wInstructionSelector,wInstructionSelector2;
84 60 diegovalve
FFD_POSEDGE_SYNCRONOUS_RESET # ( 1 ) FFD1
85
(
86
        .Clock(Clock),
87
        .Reset(Reset),
88
        .Enable( 1'b1 ),
89
        .D( iInstructionReadAddress1[`ROM_ADDRESS_WIDTH-1]  ),
90
        .Q( wInstructionSelector )
91 105 diegovalve
);
92
 
93
FFD_POSEDGE_SYNCRONOUS_RESET # ( 1 ) FFD2
94
(
95
        .Clock(Clock),
96
        .Reset(Reset),
97
        .Enable( 1'b1 ),
98
        .D( iInstructionReadAddress2[`ROM_ADDRESS_WIDTH-1]  ),
99
        .Q( wInstructionSelector2 )
100 60 diegovalve
);
101 19 diegovalve
 
102 60 diegovalve
assign oInstruction1 = (wInstructionSelector == 1) ?
103
        wIMEM2_IMUX__DataOut1 : wIROM2_IMUX__DataOut1;
104
 
105
 
106 105 diegovalve
assign oInstruction2 = (wInstructionSelector2 == 1) ?
107 60 diegovalve
        wIMEM2_IMUX__DataOut2 : wIROM2_IMUX__DataOut2;
108 19 diegovalve
//-------------------------------------------------------------------
109
/*
110
Data memory.
111
*/
112 74 diegovalve
`define SMEM_START_ADDR `DATA_ADDRESS_WIDTH'd32
113
`define RMEM_START_ADDR `DATA_ADDRESS_WIDTH'd64
114
`define OMEM_START_ADDR `DATA_ADDRESS_WIDTH'd128
115
 
116
wire wDataWriteEnable_RMEM,wDataWriteEnable_SMEM,wDataWriteEnable_IMEM,wDataWriteEnable_OMEM;
117
wire [`DATA_ADDRESS_WIDTH-1:0] wDataWriteAddress_RMEM,wDataWriteAddress_SMEM;
118
wire [`DATA_ADDRESS_WIDTH-1:0] wDataReadAddress_RMEM1,wDataReadAddress_RMEM2;
119
wire [`DATA_ADDRESS_WIDTH-1:0] wDataReadAddress_SMEM1,wDataReadAddress_SMEM2;
120
wire [`DATA_ROW_WIDTH-1:0] wData_SMEM1,wData_SMEM2,wData_RMEM1,wData_RMEM2,wData_IMEM1,wData_IMEM2;
121
wire [`DATA_ROW_WIDTH-1:0] wIOData_SMEM1,wIOData_SMEM2,wData_OMEM1,wData_OMEM2;
122
/*
123
always @ (posedge Clock)
124
begin
125
        if (wDataWriteEnable_OMEM)
126
        $display("%dns OMEM Writting %h to Addr %d (%h)",
127
        $time,iData_EXE,iDataWriteAddress_EXE,iDataWriteAddress_EXE);
128
 
129
        //if (iDataReadAddress1_IO >= 130)
130
        //$display("%dns OMEM Readin %h from %d (%h)",
131
        //$time,wData_OMEM1,iDataReadAddress1_IO,iDataReadAddress1_IO);
132
 
133
end
134
*/
135
assign wDataWriteEnable_OMEM =
136
(iDataWriteAddress_EXE >= `OMEM_START_ADDR )
137
?       iDataWriteEnable_EXE : 1'b0;
138
 
139
assign wDataWriteEnable_IMEM =
140
(iDataWriteAddress_IO <  `SMEM_START_ADDR )
141
?       iDataWriteEnable_IO :  1'b0;
142
 
143
assign wDataWriteEnable_SMEM  =
144
(iDataWriteAddress_EXE >= `SMEM_START_ADDR && iDataWriteAddress_EXE < `RMEM_START_ADDR)
145
?       iDataWriteEnable_EXE : 1'b0;
146
 
147
 
148
assign wDataWriteEnable_RMEM  =
149
(iDataWriteAddress_EXE  >= `RMEM_START_ADDR && iDataWriteAddress_EXE < `OMEM_START_ADDR)
150
?       iDataWriteEnable_EXE : 1'b0;
151
 
152
 
153
assign wDataWriteAddress_RMEM = iDataWriteAddress_EXE;
154
assign wDataReadAddress_RMEM1 = iDataReadAddress1_EXE;
155
assign wDataReadAddress_RMEM2 = iDataReadAddress2_EXE;
156
assign wDataWriteAddress_SMEM = iDataWriteAddress_EXE;
157
assign wDataReadAddress_SMEM1 = iDataReadAddress1_EXE;
158
assign wDataReadAddress_SMEM2 = iDataReadAddress2_EXE;
159
 
160
//assign oData1_EXE = ( iDataReadAddress1_EXE < `RMEM_START_ADDR ) ? wData_SMEM1 : wData_RMEM1;
161
assign oData1_EXE = ( iDataReadAddress1_EXE < `RMEM_START_ADDR ) ?
162
( ( iDataReadAddress1_EXE < `SMEM_START_ADDR ) ? wData_IMEM1 : wData_SMEM1  )
163
: wData_RMEM1;
164
 
165
//assign oData2_EXE = ( iDataReadAddress2_EXE < `RMEM_START_ADDR ) ? wData_SMEM2 : wData_RMEM2;
166
assign oData2_EXE = ( iDataReadAddress2_EXE < `RMEM_START_ADDR ) ?
167
( ( iDataReadAddress2_EXE < `SMEM_START_ADDR ) ? wData_IMEM2 : wData_SMEM2  )
168
: wData_RMEM2;
169
 
170
 
171
assign oData1_IO = ( iDataReadAddress1_IO < `OMEM_START_ADDR ) ? wIOData_SMEM1 : wData_OMEM1;
172
assign oData2_IO = ( iDataReadAddress2_IO < `OMEM_START_ADDR ) ? wIOData_SMEM2 : wData_OMEM2;
173
 
174
 
175
//Output registers written by EXE, Read by IO
176
RAM_DUAL_READ_PORT  # (`DATA_ROW_WIDTH,`DATA_ADDRESS_WIDTH,512) OMEM
177 19 diegovalve
(
178
        .Clock( Clock ),
179 74 diegovalve
        .iWriteEnable( wDataWriteEnable_OMEM ),
180
        .iReadAddress0( iDataReadAddress1_IO ),
181
        .iReadAddress1( iDataReadAddress2_IO ),
182
        .iWriteAddress( iDataWriteAddress_EXE ),
183
        .iDataIn( iData_EXE ),
184
        .oDataOut0( wData_OMEM1 ),
185
        .oDataOut1( wData_OMEM2 )
186 19 diegovalve
);
187 74 diegovalve
 
188
//Input Registers, Written by IO, Read by EXE
189
RAM_DUAL_READ_PORT  # (`DATA_ROW_WIDTH,`DATA_ADDRESS_WIDTH,42) IMEM
190
(
191
        .Clock( Clock ),
192
        .iWriteEnable( wDataWriteEnable_IMEM ),
193
        .iReadAddress0( iDataReadAddress1_EXE ),
194
        .iReadAddress1( iDataReadAddress2_EXE ),
195
        .iWriteAddress( iDataWriteAddress_IO ),
196
        .iDataIn( iData_IO ),
197
        .oDataOut0( wData_IMEM1 ),
198
        .oDataOut1( wData_IMEM2 )
199
);
200
 
201 105 diegovalve
//Swap registers, while IO reads/write values, EXE reads/write values
202 74 diegovalve
//the pointers get filped in the next iteration
203
SWAP_MEM  # (`DATA_ROW_WIDTH,`DATA_ADDRESS_WIDTH,512) SMEM
204
(
205
        .Clock( Clock ),
206
        .iSelect( wFlipSelect ),
207
 
208
        .iWriteEnableA( wDataWriteEnable_SMEM ),
209
        .iReadAddressA0( wDataReadAddress_SMEM1 ),
210
        .iReadAddressA1( wDataReadAddress_SMEM2 ),
211
        .iWriteAddressA( wDataWriteAddress_SMEM ),
212
        .iDataInA( iData_EXE ),
213
        .oDataOutA0( wData_SMEM1 ),
214
        .oDataOutA1( wData_SMEM2 ),
215
 
216
        .iWriteEnableB( iDataWriteEnable_IO ),
217
        .iReadAddressB0( iDataReadAddress1_IO ),
218
        .iReadAddressB1( iDataReadAddress2_IO ),
219
        .iWriteAddressB( iDataWriteAddress_IO ),
220
        .iDataInB( iData_IO ),
221
        .oDataOutB0( wIOData_SMEM1 ),
222
        .oDataOutB1( wIOData_SMEM2 )
223
 
224
);
225
 
226
//General purpose registers, EXE can R/W, IO can not see these sections
227
//of the memory
228
RAM_DUAL_READ_PORT  # (`DATA_ROW_WIDTH,`DATA_ADDRESS_WIDTH,256) RMEM
229
(
230
        .Clock( Clock ),
231
        .iWriteEnable( wDataWriteEnable_RMEM ),
232
        .iReadAddress0( wDataReadAddress_RMEM1 ),
233
        .iReadAddress1( wDataReadAddress_RMEM2 ),
234
        .iWriteAddress( wDataWriteAddress_RMEM ),
235
        .iDataIn( iData_EXE ),
236
        .oDataOut0( wData_RMEM1 ),
237
        .oDataOut1( wData_RMEM2 )
238
);
239
 
240
wire wFlipSelect;
241
UPCOUNTER_POSEDGE # (1) UPC1
242
(
243
.Clock(Clock),
244
.Reset( Reset ),
245
.Initial(1'b0),
246
.Enable(iFlipMemory),
247
.Q(wFlipSelect)
248
);
249
 
250
 
251
 
252 19 diegovalve
//-------------------------------------------------------------------
253
/*
254
Instruction memory.
255
*/
256 74 diegovalve
RAM_DUAL_READ_PORT  # (`INSTRUCTION_WIDTH,`ROM_ADDRESS_WIDTH,512) INST_MEM
257 19 diegovalve
(
258
        .Clock( Clock ),
259
        .iWriteEnable( iInstructionWriteEnable ),
260 60 diegovalve
        .iReadAddress0( {1'b0,iInstructionReadAddress1[`ROM_ADDRESS_WIDTH-2:0]} ),
261
        .iReadAddress1( {1'b0,iInstructionReadAddress2[`ROM_ADDRESS_WIDTH-2:0]} ),
262 19 diegovalve
        .iWriteAddress( iInstructionWriteAddress ),
263
        .iDataIn( iInstruction ),
264 60 diegovalve
        .oDataOut0( wIMEM2_IMUX__DataOut1 ),
265
        .oDataOut1( wIMEM2_IMUX__DataOut2 )
266 19 diegovalve
 
267
);
268
//-------------------------------------------------------------------
269
/*
270
 Default code stored in ROM.
271
*/
272 60 diegovalve
wire [`INSTRUCTION_WIDTH-1:0] wRomDelay1,wRomDelay2;
273
//In real world ROM will take at least 1 clock cycle,
274
//since ROMs are not syhtethizable, I won't hurt to put
275
//this delay
276
 
277
FFD_POSEDGE_SYNCRONOUS_RESET # ( `INSTRUCTION_WIDTH ) FFDA
278
(
279
        .Clock(Clock),
280
        .Reset(Reset),
281
        .Enable(1'b1),
282
        .D(wRomDelay1),
283
        .Q(wIROM2_IMUX__DataOut1 )
284
);
285
 
286
 
287
FFD_POSEDGE_SYNCRONOUS_RESET # ( `INSTRUCTION_WIDTH ) FFDB
288
(
289
        .Clock(Clock),
290
        .Reset(Reset),
291
        .Enable(1'b1),
292
        .D(wRomDelay2),
293
        .Q(wIROM2_IMUX__DataOut2 )
294
);
295
 
296
//The reason I put two ROMs is because I need to read 2 different Instruction 
297
//addresses at the same time (branch-taken and branch-not-taken) and not sure
298
//hpw to write dual read channel ROM this way...
299
 
300 19 diegovalve
ROM IROM
301
(
302 105 diegovalve
        .Address( {1'b0,iInstructionReadAddress1[`ROM_ADDRESS_WIDTH-2:0]} ),
303
        `ifdef DEBUG
304
        .iDebug_CoreID(iDebug_CoreID),
305
        `endif
306 60 diegovalve
        .I( wRomDelay1 )
307 19 diegovalve
);
308 60 diegovalve
 
309
ROM IROM2
310
(
311 105 diegovalve
        .Address( {1'b0,iInstructionReadAddress2[`ROM_ADDRESS_WIDTH-2:0]} ),
312
        `ifdef DEBUG
313
        .iDebug_CoreID(iDebug_CoreID),
314
        `endif
315 60 diegovalve
        .I( wRomDelay2 )
316
);
317 19 diegovalve
//--------------------------------------------------------
318
ControlRegister CR
319
(
320
        .Clock( Clock ),
321
        .Reset( Reset ),
322
        .iControlRegister( iControlRegister ),
323
        .oControlRegister( oControlRegister )
324
);
325
 
326
 
327
endmodule
328
//-------------------------------------------------------------------

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.