rtl/lm32_ram.v

Sat, 06 Aug 2011 01:34:41 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Sat, 06 Aug 2011 01:34:41 +0100
changeset 30
614f58128bcc
parent 28
da23ab8ef7b4
permissions
-rw-r--r--

Merge LM32 v3.8 docs in

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