Browse Source

fpga: map SDRAM to 0x20000000...0x7fffffff for esp32 compatibility

ESP32 RAM is at 0x3f500000...0x3fffffff, and flash at
0x40000000+. Make all those addresses map to SDRAM; this means that
pointers in ESP32 address space will have 1:1 equivalents in RV32
space. This hopefully could make implementing RPC calls from ESP32 to
RV32 simpler.
H. Peter Anvin 1 year ago
parent
commit
b2d20857f6
10 changed files with 40 additions and 26 deletions
  1. BIN
      esp32/output/max80.ino.bin
  2. 3 4
      fpga/max80.qpf
  3. 37 22
      fpga/max80.sv
  4. BIN
      fpga/output/max80.fw
  5. BIN
      fpga/output/v1.fw
  6. BIN
      fpga/output/v1.jic
  7. BIN
      fpga/output/v1.sof
  8. BIN
      fpga/output/v2.fw
  9. BIN
      fpga/output/v2.jic
  10. BIN
      fpga/output/v2.sof

BIN
esp32/output/max80.ino.bin


+ 3 - 4
fpga/max80.qpf

@@ -19,15 +19,14 @@
 #
 # Quartus Prime
 # Version 22.1std.2 Build 922 07/20/2023 SC Lite Edition
-# Date created = 15:23:27  September 17, 2023
+# Date created = 16:00:14  September 17, 2023
 #
 # -------------------------------------------------------------------------- #
 
 QUARTUS_VERSION = "22.1"
-DATE = "15:23:27  September 17, 2023"
+DATE = "16:00:14  September 17, 2023"
 
 # Revisions
 
-PROJECT_REVISION = "v1"
 PROJECT_REVISION = "v2"
-PROJECT_REVISION = "bypass"
+PROJECT_REVISION = "v1"

+ 37 - 22
fpga/max80.sv

@@ -299,22 +299,38 @@ module max80
    wire [31:0]		      cpu_la_wdata;
    wire [ 3:0]		      cpu_la_wstrb;
 
-   // cpu_mem_valid by address quadrant, using a bit of lookahead
+   // cpu_mem_valid by address space, using a bit of lookahead
    // decoding for speed.
-   reg  [3:0]		      mem_quad;
-
+   //
+   // Address space 0 = SRAM
+   //               1 = SDRAM
+   //               2 = I/O
+   typedef enum {
+	 AS_SRAM  = 0,
+	 AS_SDRAM = 1,
+	 AS_IO    = 2
+   } as_enum_t;
+   localparam as_enum_t AS_MAX = AS_IO;
+   function logic [AS_MAX:0] mem_as_decode(logic [31:0] addr);
+      mem_as_decode[AS_SRAM]  = addr[31:29] == 3'b000;
+      mem_as_decode[AS_SDRAM] = !addr[31] && addr[30:29] != 2'b00;
+      mem_as_decode[AS_IO]    = addr[31];
+   endfunction
+
+   reg  [AS_MAX:0] mem_as;
    always @(negedge rst_n or posedge sys_clk)
      if (~rst_n)
-       mem_quad <= 4'b0;
+       mem_as <= 'b0;
      else if (cpu_mem_valid)
-       mem_quad <= 1'b1 << cpu_mem_addr[31:30];
+       mem_as <= mem_as_decode(cpu_mem_addr);
      else
-       mem_quad <= 1'b1 << cpu_la_addr[31:30];
+       mem_as <= mem_as_decode(cpu_la_addr);
+
+   wire [AS_MAX:0] cpu_mem_as = cpu_mem_valid ? mem_as : 'b0;
 
-   wire [3:0] cpu_mem_quad = cpu_mem_valid ? mem_quad : 4'b0;
 
    // I/O device map from iodevs.conf
-   wire        iodev_mem_valid = cpu_mem_quad[3];
+   wire		   iodev_mem_valid = cpu_mem_as[AS_IO];
 `include "iodevs.vh"
 
    //
@@ -344,7 +360,7 @@ module max80
 		  );
 
    // CPU interface
-   wire        sdram_valid = cpu_mem_quad[1];
+   wire	       sdram_valid = cpu_mem_as[AS_SDRAM];
    wire [31:0] sdram_mem_rdata;
    wire        sdram_ready;
    reg	       sdram_ready_q;
@@ -360,9 +376,7 @@ module max80
    // to the sdram core while asserting ready to the CPU.
    //
    always @(posedge sys_clk)
-     begin
-	sdram_mem_ready <= sdram_ready & sdram_valid;
-     end
+     sdram_mem_ready <= sdram_ready & sdram_valid;
 
    dram_port #(32)
    cpu_dram_port (
@@ -548,12 +562,11 @@ module max80
    // of the CPU memory input MUX (it hurts timing on memory
    // accesses...)
    reg	       iodev_mem_ready;
+   wire	       sram_mem_ready;
 
-   assign cpu_mem_ready =
-			 (cpu_mem_quad[0] & 1'b1) |
-			 (cpu_mem_quad[1] & sdram_mem_ready) |
-			 (cpu_mem_quad[2] & 1'b1) |
-			 (cpu_mem_quad[3] & iodev_mem_ready);
+   assign cpu_mem_ready = (cpu_mem_as[AS_SRAM] & sram_mem_ready) |
+			  (cpu_mem_as[AS_SDRAM] & sdram_mem_ready) |
+			  (cpu_mem_as[AS_IO] & iodev_mem_ready);
    //
    // Fast memory. This runs on the SDRAM clock, i.e. 2x the speed
    // of the CPU. The .bits parameter gives the number of dwords
@@ -588,16 +601,18 @@ module max80
 	    .rdata1 ( vjtag_sram_rdata )
 	    );
 
+   assign sram_mem_ready = 1'b1; // Always ready
+
    // Register I/O data to reduce the size of the read data MUX
    reg [31:0]  iodev_rdata_q;
 
    // Read data MUX
    always_comb
-     case ( cpu_mem_quad )
-       4'b0001: cpu_mem_rdata = fast_mem_rdata;
-       4'b0010: cpu_mem_rdata = sdram_mem_rdata;
-       4'b1000: cpu_mem_rdata = iodev_rdata_q;
-       default: cpu_mem_rdata = 32'hxxxx_xxxx;
+     case ( cpu_mem_as )
+       1'b1 << AS_SRAM:  cpu_mem_rdata = fast_mem_rdata;
+       1'b1 << AS_SDRAM: cpu_mem_rdata = sdram_mem_rdata;
+       1'b1 << AS_IO:    cpu_mem_rdata = iodev_rdata_q;
+       default:		 cpu_mem_rdata = 32'hxxxx_xxxx;
      endcase
 
    // Miscellaneous system control/status registers

BIN
fpga/output/max80.fw


BIN
fpga/output/v1.fw


BIN
fpga/output/v1.jic


BIN
fpga/output/v1.sof


BIN
fpga/output/v2.fw


BIN
fpga/output/v2.jic


BIN
fpga/output/v2.sof