lm32_ram.v

Sun, 04 Apr 2010 20:40:03 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Sun, 04 Apr 2010 20:40:03 +0100
changeset 0
cd0b58aa6f83
child 2
a61bb364ae1f
child 26
73de224304c1
permissions
-rw-r--r--

add lm32 source

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