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

Subversion Repositories theia_gpu

[/] [theia_gpu/] [branches/] [beta_1.2/] [rtl/] [MEM/] [Unit_MEM.v] - Blame information for rev 199

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
output wire [`INSTRUCTION_WIDTH-1:0]    oInstruction2,
65 74 diegovalve
 
66
 
67
//Control Register
68 19 diegovalve
input wire[15:0]                       iControlRegister,
69
output wire[15:0]                       oControlRegister
70
 
71 74 diegovalve
 
72 19 diegovalve
);
73
 
74
wire [`ROM_ADDRESS_WIDTH-1:0] wROMInstructionAddress,wRAMInstructionAddress;
75 60 diegovalve
wire [`INSTRUCTION_WIDTH-1:0] wIMEM2_IMUX__DataOut1,wIMEM2_IMUX__DataOut2,
76
wIROM2_IMUX__DataOut1,wIROM2_IMUX__DataOut2;
77 19 diegovalve
 
78
 
79 60 diegovalve
wire wInstructionSelector;
80
FFD_POSEDGE_SYNCRONOUS_RESET # ( 1 ) FFD1
81
(
82
        .Clock(Clock),
83
        .Reset(Reset),
84
        .Enable( 1'b1 ),
85
        .D( iInstructionReadAddress1[`ROM_ADDRESS_WIDTH-1]  ),
86
        .Q( wInstructionSelector )
87
);
88 19 diegovalve
 
89 60 diegovalve
assign oInstruction1 = (wInstructionSelector == 1) ?
90
        wIMEM2_IMUX__DataOut1 : wIROM2_IMUX__DataOut1;
91
 
92
 
93
assign oInstruction2 = (wInstructionSelector == 1) ?
94
        wIMEM2_IMUX__DataOut2 : wIROM2_IMUX__DataOut2;
95 19 diegovalve
//-------------------------------------------------------------------
96
/*
97
Data memory.
98
*/
99 74 diegovalve
`define SMEM_START_ADDR `DATA_ADDRESS_WIDTH'd32
100
`define RMEM_START_ADDR `DATA_ADDRESS_WIDTH'd64
101
`define OMEM_START_ADDR `DATA_ADDRESS_WIDTH'd128
102
 
103
wire wDataWriteEnable_RMEM,wDataWriteEnable_SMEM,wDataWriteEnable_IMEM,wDataWriteEnable_OMEM;
104
wire [`DATA_ADDRESS_WIDTH-1:0] wDataWriteAddress_RMEM,wDataWriteAddress_SMEM;
105
wire [`DATA_ADDRESS_WIDTH-1:0] wDataReadAddress_RMEM1,wDataReadAddress_RMEM2;
106
wire [`DATA_ADDRESS_WIDTH-1:0] wDataReadAddress_SMEM1,wDataReadAddress_SMEM2;
107
wire [`DATA_ROW_WIDTH-1:0] wData_SMEM1,wData_SMEM2,wData_RMEM1,wData_RMEM2,wData_IMEM1,wData_IMEM2;
108
wire [`DATA_ROW_WIDTH-1:0] wIOData_SMEM1,wIOData_SMEM2,wData_OMEM1,wData_OMEM2;
109
/*
110
always @ (posedge Clock)
111
begin
112
        if (wDataWriteEnable_OMEM)
113
        $display("%dns OMEM Writting %h to Addr %d (%h)",
114
        $time,iData_EXE,iDataWriteAddress_EXE,iDataWriteAddress_EXE);
115
 
116
        //if (iDataReadAddress1_IO >= 130)
117
        //$display("%dns OMEM Readin %h from %d (%h)",
118
        //$time,wData_OMEM1,iDataReadAddress1_IO,iDataReadAddress1_IO);
119
 
120
end
121
*/
122
assign wDataWriteEnable_OMEM =
123
(iDataWriteAddress_EXE >= `OMEM_START_ADDR )
124
?       iDataWriteEnable_EXE : 1'b0;
125
 
126
assign wDataWriteEnable_IMEM =
127
(iDataWriteAddress_IO <  `SMEM_START_ADDR )
128
?       iDataWriteEnable_IO :  1'b0;
129
 
130
assign wDataWriteEnable_SMEM  =
131
(iDataWriteAddress_EXE >= `SMEM_START_ADDR && iDataWriteAddress_EXE < `RMEM_START_ADDR)
132
?       iDataWriteEnable_EXE : 1'b0;
133
 
134
 
135
assign wDataWriteEnable_RMEM  =
136
(iDataWriteAddress_EXE  >= `RMEM_START_ADDR && iDataWriteAddress_EXE < `OMEM_START_ADDR)
137
?       iDataWriteEnable_EXE : 1'b0;
138
 
139
 
140
assign wDataWriteAddress_RMEM = iDataWriteAddress_EXE;
141
assign wDataReadAddress_RMEM1 = iDataReadAddress1_EXE;
142
assign wDataReadAddress_RMEM2 = iDataReadAddress2_EXE;
143
assign wDataWriteAddress_SMEM = iDataWriteAddress_EXE;
144
assign wDataReadAddress_SMEM1 = iDataReadAddress1_EXE;
145
assign wDataReadAddress_SMEM2 = iDataReadAddress2_EXE;
146
 
147
//assign oData1_EXE = ( iDataReadAddress1_EXE < `RMEM_START_ADDR ) ? wData_SMEM1 : wData_RMEM1;
148
assign oData1_EXE = ( iDataReadAddress1_EXE < `RMEM_START_ADDR ) ?
149
( ( iDataReadAddress1_EXE < `SMEM_START_ADDR ) ? wData_IMEM1 : wData_SMEM1  )
150
: wData_RMEM1;
151
 
152
//assign oData2_EXE = ( iDataReadAddress2_EXE < `RMEM_START_ADDR ) ? wData_SMEM2 : wData_RMEM2;
153
assign oData2_EXE = ( iDataReadAddress2_EXE < `RMEM_START_ADDR ) ?
154
( ( iDataReadAddress2_EXE < `SMEM_START_ADDR ) ? wData_IMEM2 : wData_SMEM2  )
155
: wData_RMEM2;
156
 
157
 
158
assign oData1_IO = ( iDataReadAddress1_IO < `OMEM_START_ADDR ) ? wIOData_SMEM1 : wData_OMEM1;
159
assign oData2_IO = ( iDataReadAddress2_IO < `OMEM_START_ADDR ) ? wIOData_SMEM2 : wData_OMEM2;
160
 
161
//assign oData1_IO = wIOData_SMEM1;
162
//assign oData2_IO = wIOData_SMEM2;
163
 
164
//Output registers written by EXE, Read by IO
165
RAM_DUAL_READ_PORT  # (`DATA_ROW_WIDTH,`DATA_ADDRESS_WIDTH,512) OMEM
166 19 diegovalve
(
167
        .Clock( Clock ),
168 74 diegovalve
        .iWriteEnable( wDataWriteEnable_OMEM ),
169
        .iReadAddress0( iDataReadAddress1_IO ),
170
        .iReadAddress1( iDataReadAddress2_IO ),
171
        .iWriteAddress( iDataWriteAddress_EXE ),
172
        .iDataIn( iData_EXE ),
173
        .oDataOut0( wData_OMEM1 ),
174
        .oDataOut1( wData_OMEM2 )
175 19 diegovalve
);
176 74 diegovalve
 
177
//Input Registers, Written by IO, Read by EXE
178
RAM_DUAL_READ_PORT  # (`DATA_ROW_WIDTH,`DATA_ADDRESS_WIDTH,42) IMEM
179
(
180
        .Clock( Clock ),
181
        .iWriteEnable( wDataWriteEnable_IMEM ),
182
        .iReadAddress0( iDataReadAddress1_EXE ),
183
        .iReadAddress1( iDataReadAddress2_EXE ),
184
        .iWriteAddress( iDataWriteAddress_IO ),
185
        .iDataIn( iData_IO ),
186
        .oDataOut0( wData_IMEM1 ),
187
        .oDataOut1( wData_IMEM2 )
188
);
189
 
190
//Swap registers, while IO writes/write values, EXE reads/write values
191
//the pointers get filped in the next iteration
192
SWAP_MEM  # (`DATA_ROW_WIDTH,`DATA_ADDRESS_WIDTH,512) SMEM
193
(
194
        .Clock( Clock ),
195
        .iSelect( wFlipSelect ),
196
 
197
        .iWriteEnableA( wDataWriteEnable_SMEM ),
198
        .iReadAddressA0( wDataReadAddress_SMEM1 ),
199
        .iReadAddressA1( wDataReadAddress_SMEM2 ),
200
        .iWriteAddressA( wDataWriteAddress_SMEM ),
201
        .iDataInA( iData_EXE ),
202
        .oDataOutA0( wData_SMEM1 ),
203
        .oDataOutA1( wData_SMEM2 ),
204
 
205
        .iWriteEnableB( iDataWriteEnable_IO ),
206
        .iReadAddressB0( iDataReadAddress1_IO ),
207
        .iReadAddressB1( iDataReadAddress2_IO ),
208
        .iWriteAddressB( iDataWriteAddress_IO ),
209
        .iDataInB( iData_IO ),
210
        .oDataOutB0( wIOData_SMEM1 ),
211
        .oDataOutB1( wIOData_SMEM2 )
212
 
213
);
214
 
215
//General purpose registers, EXE can R/W, IO can not see these sections
216
//of the memory
217
RAM_DUAL_READ_PORT  # (`DATA_ROW_WIDTH,`DATA_ADDRESS_WIDTH,256) RMEM
218
(
219
        .Clock( Clock ),
220
        .iWriteEnable( wDataWriteEnable_RMEM ),
221
        .iReadAddress0( wDataReadAddress_RMEM1 ),
222
        .iReadAddress1( wDataReadAddress_RMEM2 ),
223
        .iWriteAddress( wDataWriteAddress_RMEM ),
224
        .iDataIn( iData_EXE ),
225
        .oDataOut0( wData_RMEM1 ),
226
        .oDataOut1( wData_RMEM2 )
227
);
228
 
229
wire wFlipSelect;
230
UPCOUNTER_POSEDGE # (1) UPC1
231
(
232
.Clock(Clock),
233
.Reset( Reset ),
234
.Initial(1'b0),
235
.Enable(iFlipMemory),
236
.Q(wFlipSelect)
237
);
238
 
239
 
240
 
241 19 diegovalve
//-------------------------------------------------------------------
242
/*
243
Instruction memory.
244
*/
245 74 diegovalve
RAM_DUAL_READ_PORT  # (`INSTRUCTION_WIDTH,`ROM_ADDRESS_WIDTH,512) INST_MEM
246 19 diegovalve
(
247
        .Clock( Clock ),
248
        .iWriteEnable( iInstructionWriteEnable ),
249 60 diegovalve
        .iReadAddress0( {1'b0,iInstructionReadAddress1[`ROM_ADDRESS_WIDTH-2:0]} ),
250
        .iReadAddress1( {1'b0,iInstructionReadAddress2[`ROM_ADDRESS_WIDTH-2:0]} ),
251 19 diegovalve
        .iWriteAddress( iInstructionWriteAddress ),
252
        .iDataIn( iInstruction ),
253 60 diegovalve
        .oDataOut0( wIMEM2_IMUX__DataOut1 ),
254
        .oDataOut1( wIMEM2_IMUX__DataOut2 )
255 19 diegovalve
 
256
);
257
//-------------------------------------------------------------------
258
/*
259
 Default code stored in ROM.
260
*/
261 60 diegovalve
wire [`INSTRUCTION_WIDTH-1:0] wRomDelay1,wRomDelay2;
262
//In real world ROM will take at least 1 clock cycle,
263
//since ROMs are not syhtethizable, I won't hurt to put
264
//this delay
265
 
266
FFD_POSEDGE_SYNCRONOUS_RESET # ( `INSTRUCTION_WIDTH ) FFDA
267
(
268
        .Clock(Clock),
269
        .Reset(Reset),
270
        .Enable(1'b1),
271
        .D(wRomDelay1),
272
        .Q(wIROM2_IMUX__DataOut1 )
273
);
274
 
275
 
276
FFD_POSEDGE_SYNCRONOUS_RESET # ( `INSTRUCTION_WIDTH ) FFDB
277
(
278
        .Clock(Clock),
279
        .Reset(Reset),
280
        .Enable(1'b1),
281
        .D(wRomDelay2),
282
        .Q(wIROM2_IMUX__DataOut2 )
283
);
284
 
285
//The reason I put two ROMs is because I need to read 2 different Instruction 
286
//addresses at the same time (branch-taken and branch-not-taken) and not sure
287
//hpw to write dual read channel ROM this way...
288
 
289 19 diegovalve
ROM IROM
290
(
291 60 diegovalve
        .Address( {1'b0,iInstructionReadAddress1[`ROM_ADDRESS_WIDTH-2:0]} ),
292
        .I( wRomDelay1 )
293 19 diegovalve
);
294 60 diegovalve
 
295
ROM IROM2
296
(
297
        .Address( {1'b0,iInstructionReadAddress2[`ROM_ADDRESS_WIDTH-2:0]} ),
298
        .I( wRomDelay2 )
299
);
300 19 diegovalve
//--------------------------------------------------------
301
ControlRegister CR
302
(
303
        .Clock( Clock ),
304
        .Reset( Reset ),
305
        .iControlRegister( iControlRegister ),
306
        .oControlRegister( oControlRegister )
307
);
308
 
309
 
310
endmodule
311
//-------------------------------------------------------------------

powered by: WebSVN 2.1.0

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