lm32_ram.v

Sat, 06 Aug 2011 01:26:56 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Sat, 06 Aug 2011 01:26:56 +0100
changeset 27
d6c693415d59
parent 26
73de224304c1
permissions
-rwxr-xr-x

remove synthesis delay entities to ease merge

     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 <= 0;
   195 		       raw <= 1'b0;
   196 		    end
   197 		  else
   198 		    begin
   199 		       raw_data <= raw_data_nxt;
   200 		       raw <= 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 <= 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] <= write_data; 
   301 	     // Register read address for use on next cycle
   302 	     always @(posedge read_clk)
   303 	       if (enable_read)
   304 		 ra <= read_address;
   306 	  end
   308    endgenerate
   310 endmodule