lm32_ram.v

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