|
@@ -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
|