1.1 diff -r 252df75c8f67 -r c336e674a37e lm32_ram.v 1.2 --- a/lm32_ram.v Sun Mar 06 21:17:31 2011 +0000 1.3 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 1.4 @@ -1,294 +0,0 @@ 1.5 -// ============================================================================= 1.6 -// COPYRIGHT NOTICE 1.7 -// Copyright 2006 (c) Lattice Semiconductor Corporation 1.8 -// ALL RIGHTS RESERVED 1.9 -// This confidential and proprietary software may be used only as authorised by 1.10 -// a licensing agreement from Lattice Semiconductor Corporation. 1.11 -// The entire notice above must be reproduced on all authorized copies and 1.12 -// copies may only be made to the extent permitted by a licensing agreement from 1.13 -// Lattice Semiconductor Corporation. 1.14 -// 1.15 -// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) 1.16 -// 5555 NE Moore Court 408-826-6000 (other locations) 1.17 -// Hillsboro, OR 97124 web : http://www.latticesemi.com/ 1.18 -// U.S.A email: techsupport@latticesemi.com 1.19 -// =============================================================================/ 1.20 -// FILE DETAILS 1.21 -// Project : LatticeMico32 1.22 -// File : lm32_ram.v 1.23 -// Title : Pseudo dual-port RAM. 1.24 -// Version : 6.1.17 1.25 -// : Initial Release 1.26 -// Version : 7.0SP2, 3.0 1.27 -// : No Change 1.28 -// Version : 3.1 1.29 -// : Options added to select EBRs (True-DP, Psuedo-DP, DQ, or 1.30 -// : Distributed RAM). 1.31 -// Version : 3.2 1.32 -// : EBRs use SYNC resets instead of ASYNC resets. 1.33 -// Version : 3.5 1.34 -// : Added read-after-write hazard resolution when using true 1.35 -// : dual-port EBRs 1.36 -// ============================================================================= 1.37 - 1.38 -`include "lm32_include.v" 1.39 - 1.40 -///////////////////////////////////////////////////// 1.41 -// Module interface 1.42 -///////////////////////////////////////////////////// 1.43 - 1.44 -module lm32_ram 1.45 - ( 1.46 - // ----- Inputs ------- 1.47 - read_clk, 1.48 - write_clk, 1.49 - reset, 1.50 - enable_read, 1.51 - read_address, 1.52 - enable_write, 1.53 - write_address, 1.54 - write_data, 1.55 - write_enable, 1.56 - // ----- Outputs ------- 1.57 - read_data 1.58 - ); 1.59 - 1.60 - /*---------------------------------------------------------------------- 1.61 - Parameters 1.62 - ----------------------------------------------------------------------*/ 1.63 - parameter data_width = 1; // Width of the data ports 1.64 - parameter address_width = 1; // Width of the address ports 1.65 -`ifdef PLATFORM_LATTICE 1.66 - parameter RAM_IMPLEMENTATION = "AUTO"; // Implement memory in EBRs, else 1.67 - // let synthesis tool select best 1.68 - // possible solution (EBR or LUT) 1.69 - parameter RAM_TYPE = "RAM_DP"; // Type of EBR to be used 1.70 -`endif 1.71 - 1.72 - /*---------------------------------------------------------------------- 1.73 - Inputs 1.74 - ----------------------------------------------------------------------*/ 1.75 - input read_clk; // Read clock 1.76 - input write_clk; // Write clock 1.77 - input reset; // Reset 1.78 - 1.79 - input enable_read; // Access enable 1.80 - input [address_width-1:0] read_address; // Read/write address 1.81 - input enable_write; // Access enable 1.82 - input [address_width-1:0] write_address;// Read/write address 1.83 - input [data_width-1:0] write_data; // Data to write to specified address 1.84 - input write_enable; // Write enable 1.85 - 1.86 - /*---------------------------------------------------------------------- 1.87 - Outputs 1.88 - ----------------------------------------------------------------------*/ 1.89 - output [data_width-1:0] read_data; // Data read from specified addess 1.90 - wire [data_width-1:0] read_data; 1.91 - 1.92 -`ifdef PLATFORM_LATTICE 1.93 - generate 1.94 - 1.95 - if ( RAM_IMPLEMENTATION == "EBR" ) 1.96 - begin 1.97 - if ( RAM_TYPE == "RAM_DP" ) 1.98 - begin 1.99 - pmi_ram_dp 1.100 - #( 1.101 - // ----- Parameters ----- 1.102 - .pmi_wr_addr_depth(1<<address_width), 1.103 - .pmi_wr_addr_width(address_width), 1.104 - .pmi_wr_data_width(data_width), 1.105 - .pmi_rd_addr_depth(1<<address_width), 1.106 - .pmi_rd_addr_width(address_width), 1.107 - .pmi_rd_data_width(data_width), 1.108 - .pmi_regmode("noreg"), 1.109 - .pmi_gsr("enable"), 1.110 - .pmi_resetmode("sync"), 1.111 - .pmi_init_file("none"), 1.112 - .pmi_init_file_format("binary"), 1.113 - .pmi_family(`LATTICE_FAMILY), 1.114 - .module_type("pmi_ram_dp") 1.115 - ) 1.116 - lm32_ram_inst 1.117 - ( 1.118 - // ----- Inputs ----- 1.119 - .Data(write_data), 1.120 - .WrAddress(write_address), 1.121 - .RdAddress(read_address), 1.122 - .WrClock(write_clk), 1.123 - .RdClock(read_clk), 1.124 - .WrClockEn(enable_write), 1.125 - .RdClockEn(enable_read), 1.126 - .WE(write_enable), 1.127 - .Reset(reset), 1.128 - // ----- Outputs ----- 1.129 - .Q(read_data) 1.130 - ); 1.131 - end 1.132 - else 1.133 - begin 1.134 - // True Dual-Port EBR 1.135 - wire [data_width-1:0] read_data_A, read_data_B; 1.136 - reg [data_width-1:0] raw_data, raw_data_nxt; 1.137 - reg raw, raw_nxt; 1.138 - 1.139 - /*---------------------------------------------------------------------- 1.140 - Is a read being performed in the same cycle as a write? Indicate this 1.141 - event with a RAW hazard signal that is released only when a new read 1.142 - or write occurs later. 1.143 - ----------------------------------------------------------------------*/ 1.144 - always @(/*AUTOSENSE*/enable_read or enable_write 1.145 - or raw or raw_data or read_address 1.146 - or write_address or write_data 1.147 - or write_enable) 1.148 - if (// Read 1.149 - enable_read 1.150 - // Write 1.151 - && enable_write && write_enable 1.152 - // Read and write address match 1.153 - && (read_address == write_address)) 1.154 - begin 1.155 - raw_data_nxt = write_data; 1.156 - raw_nxt = 1'b1; 1.157 - end 1.158 - else 1.159 - if (raw && (enable_read == 1'b0) && (enable_write == 1'b0)) 1.160 - begin 1.161 - raw_data_nxt = raw_data; 1.162 - raw_nxt = 1'b1; 1.163 - end 1.164 - else 1.165 - begin 1.166 - raw_data_nxt = raw_data; 1.167 - raw_nxt = 1'b0; 1.168 - end 1.169 - 1.170 - // Send back write data in case of a RAW hazard; else send back 1.171 - // data from memory 1.172 - assign read_data = raw ? raw_data : read_data_B; 1.173 - 1.174 - /*---------------------------------------------------------------------- 1.175 - Sequential Logic 1.176 - ----------------------------------------------------------------------*/ 1.177 - always @(posedge read_clk) 1.178 - if (reset) 1.179 - begin 1.180 - raw_data <= #1 0; 1.181 - raw <= #1 1'b0; 1.182 - end 1.183 - else 1.184 - begin 1.185 - raw_data <= #1 raw_data_nxt; 1.186 - raw <= #1 raw_nxt; 1.187 - end 1.188 - 1.189 - pmi_ram_dp_true 1.190 - #( 1.191 - // ----- Parameters ----- 1.192 - .pmi_addr_depth_a(1<<address_width), 1.193 - .pmi_addr_width_a(address_width), 1.194 - .pmi_data_width_a(data_width), 1.195 - .pmi_addr_depth_b(1<<address_width), 1.196 - .pmi_addr_width_b(address_width), 1.197 - .pmi_data_width_b(data_width), 1.198 - .pmi_regmode_a("noreg"), 1.199 - .pmi_regmode_b("noreg"), 1.200 - .pmi_gsr("enable"), 1.201 - .pmi_resetmode("sync"), 1.202 - .pmi_init_file("none"), 1.203 - .pmi_init_file_format("binary"), 1.204 - .pmi_family(`LATTICE_FAMILY), 1.205 - .module_type("pmi_ram_dp_true") 1.206 - ) 1.207 - lm32_ram_inst 1.208 - ( 1.209 - // ----- Inputs ----- 1.210 - .DataInA(write_data), 1.211 - .DataInB(write_data), 1.212 - .AddressA(write_address), 1.213 - .AddressB(read_address), 1.214 - .ClockA(write_clk), 1.215 - .ClockB(read_clk), 1.216 - .ClockEnA(enable_write), 1.217 - .ClockEnB(enable_read), 1.218 - .WrA(write_enable), 1.219 - .WrB(`FALSE), 1.220 - .ResetA(reset), 1.221 - .ResetB(reset), 1.222 - // ----- Outputs ----- 1.223 - .QA(read_data_A), 1.224 - .QB(read_data_B) 1.225 - ); 1.226 - end 1.227 - end 1.228 - else if ( RAM_IMPLEMENTATION == "SLICE" ) 1.229 - begin 1.230 - reg [address_width-1:0] ra; // Registered read address 1.231 - 1.232 - pmi_distributed_dpram 1.233 - #( 1.234 - // ----- Parameters ----- 1.235 - .pmi_addr_depth(1<<address_width), 1.236 - .pmi_addr_width(address_width), 1.237 - .pmi_data_width(data_width), 1.238 - .pmi_regmode("noreg"), 1.239 - .pmi_init_file("none"), 1.240 - .pmi_init_file_format("binary"), 1.241 - .pmi_family(`LATTICE_FAMILY), 1.242 - .module_type("pmi_distributed_dpram") 1.243 - ) 1.244 - pmi_distributed_dpram_inst 1.245 - ( 1.246 - // ----- Inputs ----- 1.247 - .WrAddress(write_address), 1.248 - .Data(write_data), 1.249 - .WrClock(write_clk), 1.250 - .WE(write_enable), 1.251 - .WrClockEn(enable_write), 1.252 - .RdAddress(ra), 1.253 - .RdClock(read_clk), 1.254 - .RdClockEn(enable_read), 1.255 - .Reset(reset), 1.256 - // ----- Outputs ----- 1.257 - .Q(read_data) 1.258 - ); 1.259 - 1.260 - always @(posedge read_clk) 1.261 - if (enable_read) 1.262 - ra <= read_address; 1.263 - end 1.264 - 1.265 - else 1.266 - begin 1.267 -`endif 1.268 - /*---------------------------------------------------------------------- 1.269 - Internal nets and registers 1.270 - ----------------------------------------------------------------------*/ 1.271 - reg [data_width-1:0] mem[0:(1<<address_width)-1]; // The RAM 1.272 - reg [address_width-1:0] ra; // Registered read address 1.273 - 1.274 - /*---------------------------------------------------------------------- 1.275 - Combinational Logic 1.276 - ----------------------------------------------------------------------*/ 1.277 - // Read port 1.278 - assign read_data = mem[ra]; 1.279 - 1.280 - /*---------------------------------------------------------------------- 1.281 - Sequential Logic 1.282 - ----------------------------------------------------------------------*/ 1.283 - // Write port 1.284 - always @(posedge write_clk) 1.285 - if ((write_enable == `TRUE) && (enable_write == `TRUE)) 1.286 - mem[write_address] <= write_data; 1.287 - 1.288 - // Register read address for use on next cycle 1.289 - always @(posedge read_clk) 1.290 - if (enable_read) 1.291 - ra <= read_address; 1.292 - 1.293 -`ifdef PLATFORM_LATTICE 1.294 - end 1.295 - 1.296 - endgenerate 1.297 -`endif 1.298 -endmodule