lm32_ram.v

Mon, 05 Apr 2010 21:00:31 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Mon, 05 Apr 2010 21:00:31 +0100
changeset 6
a8e459b24c31
parent 2
a61bb364ae1f
permissions
-rw-r--r--

reduce size of caches to fit in DE1 FPGA

The default cache size makes the Icache and Dcache "just a bit" too big to
fit in the EP2C20 FPGA on the DE1 board. This commit reduces the Icache and
Dcache sizes to the defaults shown in the LatticeMico32 Processor Reference
Manual (pages 36 and 37).

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