Sat, 06 Aug 2011 01:32:07 +0100
Merge LM32 v3.8 into local mainline
Changes in this release:
FEATURE: Support for dynamically switching EBA to DEBA via a GPIO
BUGFIX: EA now reports instruction which caused the data abort, rather than the instruction following it
STYLE: Update comments to refer to latest Lattice license
1 // ==================================================================
2 // >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
3 // ------------------------------------------------------------------
4 // Copyright (c) 2006-2011 by Lattice Semiconductor Corporation
5 // ALL RIGHTS RESERVED
6 // ------------------------------------------------------------------
7 //
8 // IMPORTANT: THIS FILE IS AUTO-GENERATED BY THE LATTICEMICO SYSTEM.
9 //
10 // Permission:
11 //
12 // Lattice Semiconductor grants permission to use this code
13 // pursuant to the terms of the Lattice Semiconductor Corporation
14 // Open Source License Agreement.
15 //
16 // Disclaimer:
17 //
18 // Lattice Semiconductor provides no warranty regarding the use or
19 // functionality of this code. It is the user's responsibility to
20 // verify the user’s design for consistency and functionality through
21 // the use of formal verification methods.
22 //
23 // --------------------------------------------------------------------
24 //
25 // Lattice Semiconductor Corporation
26 // 5555 NE Moore Court
27 // Hillsboro, OR 97214
28 // U.S.A
29 //
30 // TEL: 1-800-Lattice (USA and Canada)
31 // 503-286-8001 (other locations)
32 //
33 // web: http://www.latticesemi.com/
34 // email: techsupport@latticesemi.com
35 //
36 // --------------------------------------------------------------------
37 // FILE DETAILS
38 // Project : LatticeMico32
39 // File : lm32_ram.v
40 // Title : Pseudo dual-port RAM.
41 // Version : 6.1.17
42 // : Initial Release
43 // Version : 7.0SP2, 3.0
44 // : No Change
45 // Version : 3.1
46 // : Options added to select EBRs (True-DP, Psuedo-DP, DQ, or
47 // : Distributed RAM).
48 // Version : 3.2
49 // : EBRs use SYNC resets instead of ASYNC resets.
50 // Version : 3.5
51 // : Added read-after-write hazard resolution when using true
52 // : dual-port EBRs
53 // =============================================================================
55 `include "lm32_include.v"
57 /////////////////////////////////////////////////////
58 // Module interface
59 /////////////////////////////////////////////////////
61 module lm32_ram
62 (
63 // ----- Inputs -------
64 read_clk,
65 write_clk,
66 reset,
67 enable_read,
68 read_address,
69 enable_write,
70 write_address,
71 write_data,
72 write_enable,
73 // ----- Outputs -------
74 read_data
75 );
77 /*----------------------------------------------------------------------
78 Parameters
79 ----------------------------------------------------------------------*/
80 parameter data_width = 1; // Width of the data ports
81 parameter address_width = 1; // Width of the address ports
82 `ifdef PLATFORM_LATTICE
83 parameter RAM_IMPLEMENTATION = "AUTO"; // Implement memory in EBRs, else
84 // let synthesis tool select best
85 // possible solution (EBR or LUT)
86 parameter RAM_TYPE = "RAM_DP"; // Type of EBR to be used
87 `endif
89 /*----------------------------------------------------------------------
90 Inputs
91 ----------------------------------------------------------------------*/
92 input read_clk; // Read clock
93 input write_clk; // Write clock
94 input reset; // Reset
96 input enable_read; // Access enable
97 input [address_width-1:0] read_address; // Read/write address
98 input enable_write; // Access enable
99 input [address_width-1:0] write_address;// Read/write address
100 input [data_width-1:0] write_data; // Data to write to specified address
101 input write_enable; // Write enable
103 /*----------------------------------------------------------------------
104 Outputs
105 ----------------------------------------------------------------------*/
106 output [data_width-1:0] read_data; // Data read from specified addess
107 wire [data_width-1:0] read_data;
109 `ifdef PLATFORM_LATTICE
110 generate
112 if ( RAM_IMPLEMENTATION == "EBR" )
113 begin
114 if ( RAM_TYPE == "RAM_DP" )
115 begin
116 pmi_ram_dp
117 #(
118 // ----- Parameters -----
119 .pmi_wr_addr_depth(1<<address_width),
120 .pmi_wr_addr_width(address_width),
121 .pmi_wr_data_width(data_width),
122 .pmi_rd_addr_depth(1<<address_width),
123 .pmi_rd_addr_width(address_width),
124 .pmi_rd_data_width(data_width),
125 .pmi_regmode("noreg"),
126 .pmi_gsr("enable"),
127 .pmi_resetmode("sync"),
128 .pmi_init_file("none"),
129 .pmi_init_file_format("binary"),
130 .pmi_family(`LATTICE_FAMILY),
131 .module_type("pmi_ram_dp")
132 )
133 lm32_ram_inst
134 (
135 // ----- Inputs -----
136 .Data(write_data),
137 .WrAddress(write_address),
138 .RdAddress(read_address),
139 .WrClock(write_clk),
140 .RdClock(read_clk),
141 .WrClockEn(enable_write),
142 .RdClockEn(enable_read),
143 .WE(write_enable),
144 .Reset(reset),
145 // ----- Outputs -----
146 .Q(read_data)
147 );
148 end
149 else
150 begin
151 // True Dual-Port EBR
152 wire [data_width-1:0] read_data_A, read_data_B;
153 reg [data_width-1:0] raw_data, raw_data_nxt;
154 reg raw, raw_nxt;
156 /*----------------------------------------------------------------------
157 Is a read being performed in the same cycle as a write? Indicate this
158 event with a RAW hazard signal that is released only when a new read
159 or write occurs later.
160 ----------------------------------------------------------------------*/
161 always @(/*AUTOSENSE*/enable_read or enable_write
162 or raw or raw_data or read_address
163 or write_address or write_data
164 or write_enable)
165 if (// Read
166 enable_read
167 // Write
168 && enable_write && write_enable
169 // Read and write address match
170 && (read_address == write_address))
171 begin
172 raw_data_nxt = write_data;
173 raw_nxt = 1'b1;
174 end
175 else
176 if (raw && (enable_read == 1'b0) && (enable_write == 1'b0))
177 begin
178 raw_data_nxt = raw_data;
179 raw_nxt = 1'b1;
180 end
181 else
182 begin
183 raw_data_nxt = raw_data;
184 raw_nxt = 1'b0;
185 end
187 // Send back write data in case of a RAW hazard; else send back
188 // data from memory
189 assign read_data = raw ? raw_data : read_data_B;
191 /*----------------------------------------------------------------------
192 Sequential Logic
193 ----------------------------------------------------------------------*/
194 always @(posedge read_clk)
195 if (reset)
196 begin
197 raw_data <= 0;
198 raw <= 1'b0;
199 end
200 else
201 begin
202 raw_data <= raw_data_nxt;
203 raw <= raw_nxt;
204 end
206 pmi_ram_dp_true
207 #(
208 // ----- Parameters -----
209 .pmi_addr_depth_a(1<<address_width),
210 .pmi_addr_width_a(address_width),
211 .pmi_data_width_a(data_width),
212 .pmi_addr_depth_b(1<<address_width),
213 .pmi_addr_width_b(address_width),
214 .pmi_data_width_b(data_width),
215 .pmi_regmode_a("noreg"),
216 .pmi_regmode_b("noreg"),
217 .pmi_gsr("enable"),
218 .pmi_resetmode("sync"),
219 .pmi_init_file("none"),
220 .pmi_init_file_format("binary"),
221 .pmi_family(`LATTICE_FAMILY),
222 .module_type("pmi_ram_dp_true")
223 )
224 lm32_ram_inst
225 (
226 // ----- Inputs -----
227 .DataInA(write_data),
228 .DataInB(write_data),
229 .AddressA(write_address),
230 .AddressB(read_address),
231 .ClockA(write_clk),
232 .ClockB(read_clk),
233 .ClockEnA(enable_write),
234 .ClockEnB(enable_read),
235 .WrA(write_enable),
236 .WrB(`FALSE),
237 .ResetA(reset),
238 .ResetB(reset),
239 // ----- Outputs -----
240 .QA(read_data_A),
241 .QB(read_data_B)
242 );
243 end
244 end
245 else if ( RAM_IMPLEMENTATION == "SLICE" )
246 begin
247 reg [address_width-1:0] ra; // Registered read address
249 pmi_distributed_dpram
250 #(
251 // ----- Parameters -----
252 .pmi_addr_depth(1<<address_width),
253 .pmi_addr_width(address_width),
254 .pmi_data_width(data_width),
255 .pmi_regmode("noreg"),
256 .pmi_init_file("none"),
257 .pmi_init_file_format("binary"),
258 .pmi_family(`LATTICE_FAMILY),
259 .module_type("pmi_distributed_dpram")
260 )
261 pmi_distributed_dpram_inst
262 (
263 // ----- Inputs -----
264 .WrAddress(write_address),
265 .Data(write_data),
266 .WrClock(write_clk),
267 .WE(write_enable),
268 .WrClockEn(enable_write),
269 .RdAddress(ra),
270 .RdClock(read_clk),
271 .RdClockEn(enable_read),
272 .Reset(reset),
273 // ----- Outputs -----
274 .Q(read_data)
275 );
277 always @(posedge read_clk)
278 if (enable_read)
279 ra <= read_address;
280 end
282 else
283 begin
284 `endif
285 /*----------------------------------------------------------------------
286 Internal nets and registers
287 ----------------------------------------------------------------------*/
288 reg [data_width-1:0] mem[0:(1<<address_width)-1]; // The RAM
289 reg [address_width-1:0] ra; // Registered read address
291 /*----------------------------------------------------------------------
292 Combinational Logic
293 ----------------------------------------------------------------------*/
294 // Read port
295 assign read_data = mem[ra];
297 /*----------------------------------------------------------------------
298 Sequential Logic
299 ----------------------------------------------------------------------*/
300 // Write port
301 always @(posedge write_clk)
302 if ((write_enable == `TRUE) && (enable_write == `TRUE))
303 mem[write_address] <= write_data;
305 // Register read address for use on next cycle
306 always @(posedge read_clk)
307 if (enable_read)
308 ra <= read_address;
310 `ifdef PLATFORM_LATTICE
311 end
313 endgenerate
314 `endif
315 endmodule