Sat, 06 Aug 2011 00:02:46 +0100
[UPSTREAM PULL] Update baseline to LatticeMico32 v3.8 from Diamond 1.3-lm32 distribution package (datestamp May 2011)
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 parameter RAM_IMPLEMENTATION = "AUTO"; // Implement memory in EBRs, else
83 // let synthesis tool select best
84 // possible solution (EBR or LUT)
85 parameter RAM_TYPE = "RAM_DP"; // Type of EBR to be used
87 /*----------------------------------------------------------------------
88 Inputs
89 ----------------------------------------------------------------------*/
90 input read_clk; // Read clock
91 input write_clk; // Write clock
92 input reset; // Reset
94 input enable_read; // Access enable
95 input [address_width-1:0] read_address; // Read/write address
96 input enable_write; // Access enable
97 input [address_width-1:0] write_address;// Read/write address
98 input [data_width-1:0] write_data; // Data to write to specified address
99 input write_enable; // Write enable
101 /*----------------------------------------------------------------------
102 Outputs
103 ----------------------------------------------------------------------*/
104 output [data_width-1:0] read_data; // Data read from specified addess
105 wire [data_width-1:0] read_data;
107 generate
109 if ( RAM_IMPLEMENTATION == "EBR" )
110 begin
111 if ( RAM_TYPE == "RAM_DP" )
112 begin
113 pmi_ram_dp
114 #(
115 // ----- Parameters -----
116 .pmi_wr_addr_depth(1<<address_width),
117 .pmi_wr_addr_width(address_width),
118 .pmi_wr_data_width(data_width),
119 .pmi_rd_addr_depth(1<<address_width),
120 .pmi_rd_addr_width(address_width),
121 .pmi_rd_data_width(data_width),
122 .pmi_regmode("noreg"),
123 .pmi_gsr("enable"),
124 .pmi_resetmode("sync"),
125 .pmi_init_file("none"),
126 .pmi_init_file_format("binary"),
127 .pmi_family(`LATTICE_FAMILY),
128 .module_type("pmi_ram_dp")
129 )
130 lm32_ram_inst
131 (
132 // ----- Inputs -----
133 .Data(write_data),
134 .WrAddress(write_address),
135 .RdAddress(read_address),
136 .WrClock(write_clk),
137 .RdClock(read_clk),
138 .WrClockEn(enable_write),
139 .RdClockEn(enable_read),
140 .WE(write_enable),
141 .Reset(reset),
142 // ----- Outputs -----
143 .Q(read_data)
144 );
145 end
146 else
147 begin
148 // True Dual-Port EBR
149 wire [data_width-1:0] read_data_A, read_data_B;
150 reg [data_width-1:0] raw_data, raw_data_nxt;
151 reg raw, raw_nxt;
153 /*----------------------------------------------------------------------
154 Is a read being performed in the same cycle as a write? Indicate this
155 event with a RAW hazard signal that is released only when a new read
156 or write occurs later.
157 ----------------------------------------------------------------------*/
158 always @(/*AUTOSENSE*/enable_read or enable_write
159 or raw or raw_data or read_address
160 or write_address or write_data
161 or write_enable)
162 if (// Read
163 enable_read
164 // Write
165 && enable_write && write_enable
166 // Read and write address match
167 && (read_address == write_address))
168 begin
169 raw_data_nxt = write_data;
170 raw_nxt = 1'b1;
171 end
172 else
173 if (raw && (enable_read == 1'b0) && (enable_write == 1'b0))
174 begin
175 raw_data_nxt = raw_data;
176 raw_nxt = 1'b1;
177 end
178 else
179 begin
180 raw_data_nxt = raw_data;
181 raw_nxt = 1'b0;
182 end
184 // Send back write data in case of a RAW hazard; else send back
185 // data from memory
186 assign read_data = raw ? raw_data : read_data_B;
188 /*----------------------------------------------------------------------
189 Sequential Logic
190 ----------------------------------------------------------------------*/
191 always @(posedge read_clk)
192 if (reset)
193 begin
194 raw_data <= #1 0;
195 raw <= #1 1'b0;
196 end
197 else
198 begin
199 raw_data <= #1 raw_data_nxt;
200 raw <= #1 raw_nxt;
201 end
203 pmi_ram_dp_true
204 #(
205 // ----- Parameters -----
206 .pmi_addr_depth_a(1<<address_width),
207 .pmi_addr_width_a(address_width),
208 .pmi_data_width_a(data_width),
209 .pmi_addr_depth_b(1<<address_width),
210 .pmi_addr_width_b(address_width),
211 .pmi_data_width_b(data_width),
212 .pmi_regmode_a("noreg"),
213 .pmi_regmode_b("noreg"),
214 .pmi_gsr("enable"),
215 .pmi_resetmode("sync"),
216 .pmi_init_file("none"),
217 .pmi_init_file_format("binary"),
218 .pmi_family(`LATTICE_FAMILY),
219 .module_type("pmi_ram_dp_true")
220 )
221 lm32_ram_inst
222 (
223 // ----- Inputs -----
224 .DataInA(write_data),
225 .DataInB(write_data),
226 .AddressA(write_address),
227 .AddressB(read_address),
228 .ClockA(write_clk),
229 .ClockB(read_clk),
230 .ClockEnA(enable_write),
231 .ClockEnB(enable_read),
232 .WrA(write_enable),
233 .WrB(`FALSE),
234 .ResetA(reset),
235 .ResetB(reset),
236 // ----- Outputs -----
237 .QA(read_data_A),
238 .QB(read_data_B)
239 );
240 end
241 end
242 else if ( RAM_IMPLEMENTATION == "SLICE" )
243 begin
244 reg [address_width-1:0] ra; // Registered read address
246 pmi_distributed_dpram
247 #(
248 // ----- Parameters -----
249 .pmi_addr_depth(1<<address_width),
250 .pmi_addr_width(address_width),
251 .pmi_data_width(data_width),
252 .pmi_regmode("noreg"),
253 .pmi_init_file("none"),
254 .pmi_init_file_format("binary"),
255 .pmi_family(`LATTICE_FAMILY),
256 .module_type("pmi_distributed_dpram")
257 )
258 pmi_distributed_dpram_inst
259 (
260 // ----- Inputs -----
261 .WrAddress(write_address),
262 .Data(write_data),
263 .WrClock(write_clk),
264 .WE(write_enable),
265 .WrClockEn(enable_write),
266 .RdAddress(ra),
267 .RdClock(read_clk),
268 .RdClockEn(enable_read),
269 .Reset(reset),
270 // ----- Outputs -----
271 .Q(read_data)
272 );
274 always @(posedge read_clk)
275 if (enable_read)
276 ra <= #1 read_address;
277 end
279 else
280 begin
281 /*----------------------------------------------------------------------
282 Internal nets and registers
283 ----------------------------------------------------------------------*/
284 reg [data_width-1:0] mem[0:(1<<address_width)-1]; // The RAM
285 reg [address_width-1:0] ra; // Registered read address
287 /*----------------------------------------------------------------------
288 Combinational Logic
289 ----------------------------------------------------------------------*/
290 // Read port
291 assign read_data = mem[ra];
293 /*----------------------------------------------------------------------
294 Sequential Logic
295 ----------------------------------------------------------------------*/
296 // Write port
297 always @(posedge write_clk)
298 if ((write_enable == `TRUE) && (enable_write == `TRUE))
299 mem[write_address] <= #1 write_data;
301 // Register read address for use on next cycle
302 always @(posedge read_clk)
303 if (enable_read)
304 ra <= #1 read_address;
306 end
308 endgenerate
310 endmodule