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

Subversion Repositories adv_debug_sys

[/] [adv_debug_sys/] [trunk/] [Hardware/] [adv_dbg_if/] [bench/] [full_system/] [onchip_ram_top.v] - Blame information for rev 56

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 56 nyawn
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  onchip_ram_top.v                                            ////
4
////                                                              ////
5
////                                                              ////
6
////                                                              ////
7
////  Author(s):                                                  ////
8
////       De Nayer Instituut (emsys.denayer.wenk.be)             ////
9
////       Nathan Yawn (nathan.yawn@epfl.ch)                      ////
10
////                                                              ////
11
////                                                              ////
12
////                                                              ////
13
//////////////////////////////////////////////////////////////////////
14
////                                                              ////
15
//// Copyright (C) 2003-2008 Authors                              ////
16
////                                                              ////
17
//// This source file may be used and distributed without         ////
18
//// restriction provided that this copyright statement is not    ////
19
//// removed from the file and that any derivative work contains  ////
20
//// the original copyright notice and the associated disclaimer. ////
21
////                                                              ////
22
//// This source file is free software; you can redistribute it   ////
23
//// and/or modify it under the terms of the GNU Lesser General   ////
24
//// Public License as published by the Free Software Foundation; ////
25
//// either version 2.1 of the License, or (at your option) any   ////
26
//// later version.                                               ////
27
////                                                              ////
28
//// This source is distributed in the hope that it will be       ////
29
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
30
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
31
//// PURPOSE.  See the GNU Lesser General Public License for more ////
32
//// details.                                                     ////
33
////                                                              ////
34
//// You should have received a copy of the GNU Lesser General    ////
35
//// Public License along with this source; if not, download it   ////
36
//// from http://www.opencores.org/lgpl.shtml                     ////
37
////                                                              ////
38
//////////////////////////////////////////////////////////////////////
39
//                                                                  //
40
// This file is a simple wrapper for on-chip (FPGA) RAM blocks,     //
41
// coupled with a simple WISHBONE bus interface.  It supports 2-    //
42
// cycle writes, and 1-cycle reads.  Bursts using bus tags (for     //
43
// registered-feedback busses) are not supported at present.        //
44
// Altera ALTSYNCRAM blocks are instantiated directly.  Xilinx      //
45
// BRAM blocks are not as easy to declare for a wide range of       //
46
// devices, they are implied instead of declared directly.          //
47
//                                                                  //
48
//////////////////////////////////////////////////////////////////////
49
//
50
// CVS Revision History
51
//
52
// $Log: onchip_ram_top.v,v $
53
// Revision 1.1  2010-03-29 19:34:52  Nathan
54
// The onchip_ram memory unit is not distributed on the OpenCores website as of this checkin; this version of the core may be used with the advanced debug system testbench until it is.
55
//
56
// Revision 1.1  2008/07/18 20:13:48  Nathan
57
// Changed directory structure to match existing projects.
58
//
59
// Revision 1.2  2008/05/22 19:56:36  Nathan
60
// Added implied BRAM for Xilinx FPGAs.  Also added copyright, CVS log, and brief description.
61
//
62
 
63
 
64
`define ALTERA
65
 
66
 
67
module onchip_ram_top (
68
wb_clk_i, wb_rst_i,
69
wb_dat_i, wb_dat_o, wb_adr_i, wb_sel_i, wb_we_i, wb_cyc_i,
70
wb_stb_i, wb_ack_o, wb_err_o
71
);
72
 
73
// Function to calculate width of address signal.
74
function integer log2;
75
input [31:0] value;
76
for (log2=0; value>0; log2=log2+1)
77
value = value>>1;
78
endfunction
79
 
80
//
81
// Parameters
82
//
83
parameter dwidth = 32;
84
parameter size_bytes = 4096;
85
parameter initfile = "NONE";
86
parameter words = (size_bytes / (dwidth/8));  // Don't override this.  Really.
87
parameter awidth = log2(size_bytes)-1;  // Don't override this either.
88
parameter bewidth = (dwidth/8);  // Or this.
89
 
90
//
91
// I/O Ports
92
//
93
input wb_clk_i;
94
input wb_rst_i;
95
//
96
// WB slave i/f
97
//
98
input [dwidth-1:0] wb_dat_i;
99
output [dwidth-1:0] wb_dat_o;
100
input [awidth-1:0] wb_adr_i;
101
input [bewidth-1:0] wb_sel_i;
102
input wb_we_i;
103
input wb_cyc_i;
104
input wb_stb_i;
105
output wb_ack_o;
106
output wb_err_o;
107
//
108
// Internal regs and wires
109
//
110
wire we;
111
wire [bewidth-1:0] be_i;
112
wire [dwidth-1:0] wb_dat_o;
113
wire ack_we;
114
reg ack_we1;
115
reg ack_we2;
116
reg ack_re;
117
 
118
//
119
// Aliases and simple assignments
120
//
121
assign wb_ack_o = ack_re | ack_we;
122
assign wb_err_o = 1'b0;  //wb_cyc_i & wb_stb_i & ???; 
123
assign we = wb_cyc_i & wb_stb_i & wb_we_i & (|wb_sel_i[bewidth-1:0]);
124
assign be_i = (wb_cyc_i & wb_stb_i) * wb_sel_i;
125
 
126
//
127
// Write acknowledge
128
// Little trick to keep the writes single-cycle:
129
// set the write ack signal on the falling clk edge, so it will be set halfway through the
130
// cycle and be registered at the end of the first clock cycle.  To prevent contention for
131
// the next half-cycle, latch the ack_we1 signal on the next rising edge, and force the
132
// bus output low when that latched signal is high.
133
always @ (negedge wb_clk_i or posedge wb_rst_i)
134
begin
135
        if (wb_rst_i)
136
                ack_we1 <= 1'b0;
137
        else
138
                if (wb_cyc_i & wb_stb_i & wb_we_i & ~ack_we)
139
                        ack_we1 <= #1 1'b1;
140
                else
141
                        ack_we1 <= #1 1'b0;
142
end
143
 
144
always @ (posedge wb_clk_i or posedge wb_rst_i)
145
begin
146
        if (wb_rst_i)
147
                ack_we2 <= 1'b0;
148
        else
149
                ack_we2 <= ack_we1;
150
end
151
 
152
assign ack_we = ack_we1 & ~ack_we2;
153
 
154
 
155
//
156
// read acknowledge
157
//
158
always @ (posedge wb_clk_i or posedge wb_rst_i)
159
begin
160
        if (wb_rst_i)
161
                ack_re <= 1'b0;
162
        else
163
                if (wb_cyc_i & wb_stb_i & ~wb_err_o & ~wb_we_i & ~ack_re)
164
                        ack_re <= 1'b1;
165
                else
166
                        ack_re <= 1'b0;
167
end
168
 
169
 
170
`ifdef ALTERA
171
//
172
// change intended_device_family according to the FPGA device (Stratix or Cyclone)
173
//
174
altsyncram altsyncram_component (
175
.wren_a (we),
176
.clock0 (wb_clk_i),
177
.byteena_a (be_i),
178
.address_a (wb_adr_i[awidth-1:2]),
179
.data_a (wb_dat_i),
180
.q_a (wb_dat_o));
181
defparam
182
altsyncram_component.intended_device_family = "CycloneII",
183
altsyncram_component.width_a = dwidth,
184
altsyncram_component.widthad_a = (awidth-2),
185
altsyncram_component.numwords_a = (words),
186
altsyncram_component.operation_mode = "SINGLE_PORT",
187
altsyncram_component.outdata_reg_a = "UNREGISTERED",
188
altsyncram_component.indata_aclr_a = "NONE",
189
altsyncram_component.wrcontrol_aclr_a = "NONE",
190
altsyncram_component.address_aclr_a = "NONE",
191
altsyncram_component.outdata_aclr_a = "NONE",
192
altsyncram_component.width_byteena_a = bewidth,
193
altsyncram_component.byte_size = 8,
194
altsyncram_component.byteena_aclr_a = "NONE",
195
altsyncram_component.ram_block_type = "AUTO",
196
altsyncram_component.lpm_type = "altsyncram",
197
altsyncram_component.init_file = initfile;
198
 
199
 
200
`else
201
// Xilinx does not have anything so neat as a resizable memory array.
202
// We use generic code, which will imply a BRAM array.
203
// This will also work for non-Xilinx architectures, but be warned that
204
// it will not be recognized as an implied RAM block by the current Altera
205
// tools.
206
 
207
// The actual memory array...4 banks, for 4 separate byte lanes
208
reg [7:0] mem_bank0 [0:(words-1)];
209
reg [7:0] mem_bank1 [0:(words-1)];
210
reg [7:0] mem_bank2 [0:(words-1)];
211
reg [7:0] mem_bank3 [0:(words-1)];
212
 
213
// Write enables, qualified with byte lane enables
214
wire we_0, we_1, we_2, we_3;
215
 
216
// Enable, indicates any read or write operation
217
wire en;
218
 
219
// Yes, separate address registers, which will hold identical data.  This
220
// is necessary to correctly imply a Xilinx BRAM.  Because that's just
221
// how they roll.
222
reg [(awidth-3):0] addr_reg0;
223
reg [(awidth-3):0] addr_reg1;
224
reg [(awidth-3):0] addr_reg2;
225
reg [(awidth-3):0] addr_reg3;
226
 
227
assign we_0 = be_i[0] & wb_we_i;
228
assign we_1 = be_i[1] & wb_we_i;
229
assign we_2 = be_i[2] & wb_we_i;
230
assign we_3 = be_i[3] & wb_we_i;
231
 
232
assign en = (|be_i);
233
 
234
// Sequential bits.  Setting of the address registers, and memory array writes.
235
always @ (posedge wb_clk_i)
236
begin
237
        if (en)
238
                begin
239
                addr_reg0 <= wb_adr_i[(awidth-1):2];
240
                if (we_0)
241
                begin
242
                        mem_bank0[wb_adr_i[(awidth-1):2]] <= wb_dat_i[7:0];
243
                end
244
        end
245
 
246
        if (en)
247
                begin
248
                addr_reg1 <= wb_adr_i[(awidth-1):2];
249
                if (we_1)
250
                begin
251
                        mem_bank1[wb_adr_i[(awidth-1):2]] <= wb_dat_i[15:8];
252
                end
253
        end
254
 
255
        if (en)
256
                begin
257
                addr_reg2 <= wb_adr_i[(awidth-1):2];
258
                if (we_2)
259
                begin
260
                        mem_bank2[wb_adr_i[(awidth-1):2]] <= wb_dat_i[23:16];
261
                end
262
        end
263
 
264
        if (en)
265
                begin
266
                addr_reg3 <= wb_adr_i[(awidth-1):2];
267
                if (we_3)
268
                begin
269
                        mem_bank3[wb_adr_i[(awidth-1):2]] <= wb_dat_i[31:24];
270
                end
271
        end
272
 
273
end
274
 
275
 
276
// Data output.  Combinatorial, no output register.
277
assign wb_dat_o = {mem_bank3[addr_reg2], mem_bank2[addr_reg2], mem_bank1[addr_reg1], mem_bank0[addr_reg0]};
278
 
279
`endif
280
 
281
endmodule

powered by: WebSVN 2.1.0

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