Sun, 06 Mar 2011 19:22:27 +0000
Make interrupts active high
Original-Author: lekernel
Original-Source: milkymist 5e8c03b53aaa820f3b43
1 // =============================================================================
2 // COPYRIGHT NOTICE
3 // Copyright 2006 (c) Lattice Semiconductor Corporation
4 // ALL RIGHTS RESERVED
5 // This confidential and proprietary software may be used only as authorised by
6 // a licensing agreement from Lattice Semiconductor Corporation.
7 // The entire notice above must be reproduced on all authorized copies and
8 // copies may only be made to the extent permitted by a licensing agreement from
9 // Lattice Semiconductor Corporation.
10 //
11 // Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada)
12 // 5555 NE Moore Court 408-826-6000 (other locations)
13 // Hillsboro, OR 97124 web : http://www.latticesemi.com/
14 // U.S.A email: techsupport@latticesemi.com
15 // =============================================================================/
16 // FILE DETAILS
17 // Project : LatticeMico32
18 // File : lm32_ram.v
19 // Title : Pseudo dual-port RAM.
20 // Version : 6.1.17
21 // : Initial Release
22 // Version : 7.0SP2, 3.0
23 // : No Change
24 // Version : 3.1
25 // : Options added to select EBRs (True-DP, Psuedo-DP, DQ, or
26 // : Distributed RAM).
27 // Version : 3.2
28 // : EBRs use SYNC resets instead of ASYNC resets.
29 // Version : 3.5
30 // : Added read-after-write hazard resolution when using true
31 // : dual-port EBRs
32 // =============================================================================
34 `include "lm32_include.v"
36 /////////////////////////////////////////////////////
37 // Module interface
38 /////////////////////////////////////////////////////
40 module lm32_ram
41 (
42 // ----- Inputs -------
43 read_clk,
44 write_clk,
45 reset,
46 enable_read,
47 read_address,
48 enable_write,
49 write_address,
50 write_data,
51 write_enable,
52 // ----- Outputs -------
53 read_data
54 );
56 /*----------------------------------------------------------------------
57 Parameters
58 ----------------------------------------------------------------------*/
59 parameter data_width = 1; // Width of the data ports
60 parameter address_width = 1; // Width of the address ports
61 `ifdef PLATFORM_LATTICE
62 parameter RAM_IMPLEMENTATION = "AUTO"; // Implement memory in EBRs, else
63 // let synthesis tool select best
64 // possible solution (EBR or LUT)
65 parameter RAM_TYPE = "RAM_DP"; // Type of EBR to be used
66 `endif
68 /*----------------------------------------------------------------------
69 Inputs
70 ----------------------------------------------------------------------*/
71 input read_clk; // Read clock
72 input write_clk; // Write clock
73 input reset; // Reset
75 input enable_read; // Access enable
76 input [address_width-1:0] read_address; // Read/write address
77 input enable_write; // Access enable
78 input [address_width-1:0] write_address;// Read/write address
79 input [data_width-1:0] write_data; // Data to write to specified address
80 input write_enable; // Write enable
82 /*----------------------------------------------------------------------
83 Outputs
84 ----------------------------------------------------------------------*/
85 output [data_width-1:0] read_data; // Data read from specified addess
86 wire [data_width-1:0] read_data;
88 `ifdef PLATFORM_LATTICE
89 generate
91 if ( RAM_IMPLEMENTATION == "EBR" )
92 begin
93 if ( RAM_TYPE == "RAM_DP" )
94 begin
95 pmi_ram_dp
96 #(
97 // ----- Parameters -----
98 .pmi_wr_addr_depth(1<<address_width),
99 .pmi_wr_addr_width(address_width),
100 .pmi_wr_data_width(data_width),
101 .pmi_rd_addr_depth(1<<address_width),
102 .pmi_rd_addr_width(address_width),
103 .pmi_rd_data_width(data_width),
104 .pmi_regmode("noreg"),
105 .pmi_gsr("enable"),
106 .pmi_resetmode("sync"),
107 .pmi_init_file("none"),
108 .pmi_init_file_format("binary"),
109 .pmi_family(`LATTICE_FAMILY),
110 .module_type("pmi_ram_dp")
111 )
112 lm32_ram_inst
113 (
114 // ----- Inputs -----
115 .Data(write_data),
116 .WrAddress(write_address),
117 .RdAddress(read_address),
118 .WrClock(write_clk),
119 .RdClock(read_clk),
120 .WrClockEn(enable_write),
121 .RdClockEn(enable_read),
122 .WE(write_enable),
123 .Reset(reset),
124 // ----- Outputs -----
125 .Q(read_data)
126 );
127 end
128 else
129 begin
130 // True Dual-Port EBR
131 wire [data_width-1:0] read_data_A, read_data_B;
132 reg [data_width-1:0] raw_data, raw_data_nxt;
133 reg raw, raw_nxt;
135 /*----------------------------------------------------------------------
136 Is a read being performed in the same cycle as a write? Indicate this
137 event with a RAW hazard signal that is released only when a new read
138 or write occurs later.
139 ----------------------------------------------------------------------*/
140 always @(/*AUTOSENSE*/enable_read or enable_write
141 or raw or raw_data or read_address
142 or write_address or write_data
143 or write_enable)
144 if (// Read
145 enable_read
146 // Write
147 && enable_write && write_enable
148 // Read and write address match
149 && (read_address == write_address))
150 begin
151 raw_data_nxt = write_data;
152 raw_nxt = 1'b1;
153 end
154 else
155 if (raw && (enable_read == 1'b0) && (enable_write == 1'b0))
156 begin
157 raw_data_nxt = raw_data;
158 raw_nxt = 1'b1;
159 end
160 else
161 begin
162 raw_data_nxt = raw_data;
163 raw_nxt = 1'b0;
164 end
166 // Send back write data in case of a RAW hazard; else send back
167 // data from memory
168 assign read_data = raw ? raw_data : read_data_B;
170 /*----------------------------------------------------------------------
171 Sequential Logic
172 ----------------------------------------------------------------------*/
173 always @(posedge read_clk)
174 if (reset)
175 begin
176 raw_data <= #1 0;
177 raw <= #1 1'b0;
178 end
179 else
180 begin
181 raw_data <= #1 raw_data_nxt;
182 raw <= #1 raw_nxt;
183 end
185 pmi_ram_dp_true
186 #(
187 // ----- Parameters -----
188 .pmi_addr_depth_a(1<<address_width),
189 .pmi_addr_width_a(address_width),
190 .pmi_data_width_a(data_width),
191 .pmi_addr_depth_b(1<<address_width),
192 .pmi_addr_width_b(address_width),
193 .pmi_data_width_b(data_width),
194 .pmi_regmode_a("noreg"),
195 .pmi_regmode_b("noreg"),
196 .pmi_gsr("enable"),
197 .pmi_resetmode("sync"),
198 .pmi_init_file("none"),
199 .pmi_init_file_format("binary"),
200 .pmi_family(`LATTICE_FAMILY),
201 .module_type("pmi_ram_dp_true")
202 )
203 lm32_ram_inst
204 (
205 // ----- Inputs -----
206 .DataInA(write_data),
207 .DataInB(write_data),
208 .AddressA(write_address),
209 .AddressB(read_address),
210 .ClockA(write_clk),
211 .ClockB(read_clk),
212 .ClockEnA(enable_write),
213 .ClockEnB(enable_read),
214 .WrA(write_enable),
215 .WrB(`FALSE),
216 .ResetA(reset),
217 .ResetB(reset),
218 // ----- Outputs -----
219 .QA(read_data_A),
220 .QB(read_data_B)
221 );
222 end
223 end
224 else if ( RAM_IMPLEMENTATION == "SLICE" )
225 begin
226 reg [address_width-1:0] ra; // Registered read address
228 pmi_distributed_dpram
229 #(
230 // ----- Parameters -----
231 .pmi_addr_depth(1<<address_width),
232 .pmi_addr_width(address_width),
233 .pmi_data_width(data_width),
234 .pmi_regmode("noreg"),
235 .pmi_init_file("none"),
236 .pmi_init_file_format("binary"),
237 .pmi_family(`LATTICE_FAMILY),
238 .module_type("pmi_distributed_dpram")
239 )
240 pmi_distributed_dpram_inst
241 (
242 // ----- Inputs -----
243 .WrAddress(write_address),
244 .Data(write_data),
245 .WrClock(write_clk),
246 .WE(write_enable),
247 .WrClockEn(enable_write),
248 .RdAddress(ra),
249 .RdClock(read_clk),
250 .RdClockEn(enable_read),
251 .Reset(reset),
252 // ----- Outputs -----
253 .Q(read_data)
254 );
256 always @(posedge read_clk)
257 if (enable_read)
258 ra <= read_address;
259 end
261 else
262 begin
263 `endif
264 /*----------------------------------------------------------------------
265 Internal nets and registers
266 ----------------------------------------------------------------------*/
267 reg [data_width-1:0] mem[0:(1<<address_width)-1]; // The RAM
268 reg [address_width-1:0] ra; // Registered read address
270 /*----------------------------------------------------------------------
271 Combinational Logic
272 ----------------------------------------------------------------------*/
273 // Read port
274 assign read_data = mem[ra];
276 /*----------------------------------------------------------------------
277 Sequential Logic
278 ----------------------------------------------------------------------*/
279 // Write port
280 always @(posedge write_clk)
281 if ((write_enable == `TRUE) && (enable_write == `TRUE))
282 mem[write_address] <= write_data;
284 // Register read address for use on next cycle
285 always @(posedge read_clk)
286 if (enable_read)
287 ra <= read_address;
289 `ifdef PLATFORM_LATTICE
290 end
292 endgenerate
293 `endif
294 endmodule