Selaa lähdekoodia

Wire up Smartaid Magnum in the FPGA

H. Peter Anvin 1 vuosi sitten
vanhempi
commit
09273c35a8

BIN
esp32/output/max80.ino.bin


+ 71 - 60
fpga/abcbus.sv

@@ -3,6 +3,7 @@ module abcbus (
 	       input		 sys_clk,
 	       input		 sdram_clk, // Assumed to be a multiple of sys_clk
 	       input		 stb_1mhz, // 1-2 MHz sys_clk strobe
+	       input		 stb_50us, // 10-20 kHz sdram_clk strobe
 
 	       // CPU interface
 	       input		 abc_valid, // Control/status registers
@@ -297,9 +298,10 @@ module abcbus (
    //
    // Accesses from RV32 supports 32-bit accesses only!
    //
-   logic [2:0] abc_a_map;
-   wire [17:0] rdata_abcmemmap;		// RV32 access port
-   wire [17:0] abc_memmap_rd;		// ABC-bus access port
+   logic  [2:0] abc_a_map;
+   logic [15:0]	abc_a_addr;
+   wire  [17:0] rdata_abcmemmap;	// RV32 access port
+   wire  [17:0] abc_memmap_rd;		// ABC-bus access port
 
    abcmapram
    (
@@ -307,7 +309,7 @@ module abcbus (
 
     .clock     ( sdram_clk ),
 
-    .address_a ( { abc_a_map, abc_a_s[15:10] } ),
+    .address_a ( { abc_a_map, abc_a_addr } ),
     .data_a    ( 18'bx ),
     .wren_a    ( 1'b0 ),
     .q_a       ( abc_memmap_rd ),
@@ -331,6 +333,7 @@ module abcbus (
    reg	      abc_memwr_en;
    reg	      abc_do_memrd;
    reg	      abc_do_memwr;
+   reg	      abc_mem_ready;
 
    always @(posedge sdram_clk or negedge rst_n)
      if (~rst_n)
@@ -342,17 +345,20 @@ module abcbus (
 	  sdram_valid    <= 1'b0;
 	  sdram_wstrb    <= 1'b0;
 	  abc_xm         <= 1'b0;
+	  abc_mem_ready  <= 1'b0;
        end
      else
        begin
 	  // Careful with the registering here: need to make sure
-	  // abcmapram is caught up for I/O; for memory the address
-	  // will have been stable for some time
+	  // abcmapram is caught up with the address. If sam is in use
+	  // then the address can change after XMEMRD# is asserted.
+
 	  abc_memwr_en  <= abc_xmemwr;
 	  abc_memrd_en  <= abc_xmemrd;
+	  abc_mem_ready <= abc_memwr_en | abc_memrd_en;
 
-	  abc_do_memrd  <= abc_rden & abc_memrd_en;
-	  abc_do_memwr  <= abc_wren & abc_memwr_en;
+	  abc_do_memrd  <= abc_rden & abc_memrd_en & abc_mem_ready;
+	  abc_do_memwr  <= abc_wren & abc_memwr_en & abc_mem_ready;
 
 	  sdram_valid   <= abc_do_memrd | abc_do_memwr;
 	  sdram_wstrb   <= abc_do_memwr;
@@ -441,6 +447,11 @@ module abcbus (
 	  end // if (|busy_io[7:0])
      end // always @ (posedge sdram_clk)
 
+   //
+   // Default memory map
+   //
+   reg [2:0] abc_mem_map = 3'b000;
+
    //
    // ABC800 non-4680 I/O ports
    //
@@ -466,37 +477,30 @@ module abcbus (
      end // always @ (posedge sdram_clk)
 
    //
-   // "ROM hack" map control logic
+   // Smartaid Magnum
    //
-   localparam romhack_regs  = 2;
-   localparam romhack_rmax  = romhack_regs - 1;
-   reg [2:0]  romhack_mask [0:romhack_rmax];
-   reg [5:0]  romhack_addr [0:romhack_rmax];
-   reg [2:0]  romhack_map   = 3'b0;     // Current map
-   wire	      cpu_romhackmap = rst_n && abc_valid && cpu_addr[6:2] == 5'd11;
-
-   // The control registers are handled elsewhere
-   always @(negedge rst_n or posedge sdram_clk)
-     if (~rst_n)
-       begin
-	  romhack_map <= 3'b000;
-       end
-     else
-       begin
-	  logic [2:0] new_map;
-
-	  new_map = romhack_map;
-	  if (cpu_romhackmap & cpu_wstrb[0])
-	    new_map = cpu_wdata[2:0];
-
-	  for (int i = 0; i < romhack_regs; i++)
-	    begin
-	       if (abc_xmemwr && abc_a_s[15:0] == romhack_addr[i])
-		 new_map = (new_map & ~romhack_map[i]) | (abc_a_s[2:0] & romhack_map[i]);
-	    end
-
-	  romhack_map <= new_map;
-       end // else: !if(~rst_n)
+   reg sam_en = 1'b0;
+   reg [2:0] sam_mem_map = 3'b000;
+   wire	     sam_resin_n;
+   wire [15:0] sam_a_out;
+   wire	       sam_map;
+   wire [7:0]  sam_do;
+   wire	       sam_dout_oe;
+
+   samagnum sam (
+		 .fast_clk		( sdram_clk ),
+		 .stb_50us		( stb_50us ),
+		 .clk			( abc_clk_s ),
+		 .xmemwr_n		( ~abc_xmemwr ),
+		 .xmemfl_n		( ~abc_xmemrd ),
+		 .xmemfl_out_n		( ),
+		 .resin_n		( sam_resin_n ),
+		 .a			( abc_a_s ),
+		 .a_out			( sam_a_out ),
+		 .a_map			( sam_map ),
+		 .dout			( sam_dout ),
+		 .dout_oe		( sam_dout_oe )
+	    );
 
    //
    // ABC data out (= ABC host read) logic
@@ -512,10 +516,15 @@ module abcbus (
 	  abc_d_oe <= 1'b0;
 	  abc_do   <= sdram_rd;
 
-	  if (abc_do_memrd)
+	  if (sam_en & sam_dout_oe)
+	    begin
+	       abc_d_oe <= 1'b1;
+	       abc_do   <= sam_dout;
+	    end
+	  else if (abc_do_memrd)
 	    begin
 	       // Drive the output bus even if sdram_rd doesn't yet have
-	       // valid data (i.e. sdram_ready = 0).
+	       // valid data yet (i.e. sdram_ready = 0).
 	       // The propagation delay for OE#/DIR for 74HC245 is about
 	       // twice what it is for data.
 	       abc_d_oe <= 1'b1;
@@ -546,8 +555,16 @@ module abcbus (
    //
    always_comb
      begin
-	abc_a_map = romhack_map;
+	abc_a_map = abc_mem_map;
 	abc_a_map[0] ^= abc800mac_en & abc800mac_xmmask[abc_a_s[15:12]];
+
+	abc_a_addr = abc_a_s;
+
+	if ( sam_en & sam_map )
+	  begin
+	     abc_a_map  = sam_mem_map;
+	     abc_a_addr = sam_a_out;
+	  end
      end
 
    // Memory read latency counter
@@ -604,9 +621,9 @@ module abcbus (
 	  abc800mac_en      <= 1'b0;
 	  abc80_force       <= 1'b0;
 	  abc800_force      <= 1'b0;
-
-	  for (int i = 0; i < romhack_regs; i++)
-	    romhack_mask[i] <= 3'b0;
+	  abc_mem_map       <= 3'b0;
+	  sam_mem_map       <= 3'b0;
+	  sam_en            <= 1'b0;
 
 	  // abc_resin, nmi, int and force_wait are deliberately not affected
 	  // by an internal CPU reset. They are, however, inherently asserted
@@ -668,16 +685,14 @@ module abcbus (
 		      abc800mac_en <= cpu_wdata[31];
 		 end
 		   // 5'b01001: abc800mac_xmdata - handled elsewhere
-		   // 5'b01011: romhack_map - handled elsewhere
-		 5'b10???: begin
-		    for (int i = 0; i < romhack_regs; i++)
-		      if (i == cpu_addr[4:2])
-			begin
-			   if (cpu_wstrb[0])
-			     romhack_mask[i] <= cpu_wdata[2:0];
-			   if (cpu_wstrb[1])
-			     romhack_addr[i] <= cpu_wdata[15:10];
-			end
+		 5'b01010: begin
+		    if (cpu_wstrb[0])
+		      abc_mem_map <= cpu_wdata[2:0];
+		    if (cpu_wstrb[1])
+		      begin
+			 sam_mem_map <= cpu_wdata[10:8];
+			 sam_en <= cpu_wdata[15];
+		      end
 		 end
 		 default: begin
 		   /* do nothing */
@@ -706,12 +721,8 @@ module abcbus (
 	  5'b00111: cpu_rdata = { 23'b0, memrd_latency_err, memrd_latency_max };
 	  5'b01000: cpu_rdata = { abc800mac_en, 23'b0, abc800mac_iobase, 1'b0 };
 	  5'b01001: cpu_rdata = { 16'b0, abc800mac_xmmask };
-	  5'b01011: cpu_rdata = { 31'b0, romhack_map };
-	  5'b10???: begin
-	     for (int i = 0; i < romhack_regs; i++)
-	       if (i == cpu_addr[4:2])
-		 cpu_rdata = { 16'b0, romhack_addr[i], 7'b0, romhack_mask[i] };
-	  end
+	  5'b01010: cpu_rdata = { 16'b0, sam_en, 4'b0, sam_mem_map, 5'b0, abc_mem_map };
+	  default:  cpu_rdata = 32'b0;
 	endcase // casez (cpu_addr[6:2])
      end
 

+ 3 - 3
fpga/max80.qpf

@@ -19,14 +19,14 @@
 #
 # Quartus Prime
 # Version 22.1std.2 Build 922 07/20/2023 SC Lite Edition
-# Date created = 14:30:02  December 06, 2023
+# Date created = 15:32:51  December 06, 2023
 #
 # -------------------------------------------------------------------------- #
 
 QUARTUS_VERSION = "22.1"
-DATE = "14:30:02  December 06, 2023"
+DATE = "15:32:51  December 06, 2023"
 
 # Revisions
 
-PROJECT_REVISION = "v2"
 PROJECT_REVISION = "v1"
+PROJECT_REVISION = "v2"

+ 11 - 8
fpga/max80.sv

@@ -207,9 +207,10 @@ module max80
    //
    localparam reset_pow2 = 12;
 
-   reg [31:0] sys_clk_ctr;
-   reg [31:0] sys_clk_ctr_q;
-   reg [31:1] sys_clk_stb;
+   reg  [31:0] sys_clk_ctr;
+   wire [31:0] sys_clk_ctr_next = sys_clk_ctr + 1'b1;
+   reg  [31:1] sys_clk_stb;
+   reg  [31:1] sdram_clk_stb;	// == sys_clk_stb for the sdram clk
 
    // 3 types of reset: system, hard, and reconfig
    wire [3:1] cpu_reset_cmd;	// CPU-originated reset command
@@ -228,7 +229,6 @@ module max80
 	  cpu_reset_cmd_q[0] <= 3'b0;
 	  cpu_reset_cmd_q[1] <= 3'b0;
 	  sys_clk_ctr        <= (-'sb1) << reset_pow2;
-	  sys_clk_ctr_q      <= 'b0;
 	  sys_clk_stb        <= 'b0;
        end
      else
@@ -247,21 +247,23 @@ module max80
 	    begin
 	       // Soft or hard reset
 	       sys_clk_ctr   <= (-'sb1) << reset_pow2;
-	       sys_clk_ctr_q <= 1'b0;
 	       sys_clk_stb   <= 1'b0;
 	       rst_n         <= 1'b0;
 	       hard_rst_n    <= hard_rst_n & ~|reset_cmd_q[3:2];
 	    end
 	  else
 	    begin
-	       sys_clk_ctr   <= sys_clk_ctr + 1'b1;
-	       sys_clk_ctr_q <= ~rst_n ? 'b0 : sys_clk_ctr;
-	       sys_clk_stb   <= ~sys_clk_ctr & sys_clk_ctr_q;
+	       sys_clk_ctr   <= sys_clk_ctr_next;
+	       sys_clk_stb   <= ~sys_clk_ctr_next & sys_clk_ctr;
 	       rst_n         <= rst_n      | ~sys_clk_ctr[reset_pow2];
 	       hard_rst_n    <= hard_rst_n | ~sys_clk_ctr[reset_pow2];
 	    end
        end
 
+   // This code assumes sdram_clk == 2 x sys_clk
+   always @(posedge sdram_clk)
+     sdram_clk_stb <= sys_clk ? sys_clk_stb : 'b0;
+
    // Reset in the video clock domain
    reg vid_rst_n;
    always @(negedge all_plls_locked or posedge vid_clk)
@@ -450,6 +452,7 @@ module max80
 	   .sys_clk ( sys_clk ),
 	   .sdram_clk ( sdram_clk ),
 	   .stb_1mhz ( sys_clk_stb[6] ),
+	   .stb_50us ( sdram_clk_stb[13] ),
 
 	   .abc_valid ( iodev_valid_abc ),
 	   .map_valid ( iodev_valid_abcmemmap ),

BIN
fpga/output/bypass.jic


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


+ 3 - 1
rv32/abcmem.c

@@ -136,6 +136,7 @@ static void abc_init_memmap800(uint32_t memmap[MAPS][PERMAP])
     abc_map_list(memmap[1], mem_init_abc800mac);
 
     /* XXX: enable abc800mac if desired */
+    ABC_MAP_CFG = 0;
 }
 
 static void abc_init_memmap80(uint32_t memmap[MAPS][PERMAP])
@@ -150,7 +151,8 @@ static void abc_init_memmap80(uint32_t memmap[MAPS][PERMAP])
 
     abc_map_list(memmap[0], mem_init_abc80);
 
-    /* XXX: enable romhack if needed */
+    /* XXX: Until such time as SAM is supported... */
+    ABC_MAP_CFG = 0;
 }
 
 void __cold abc_init_memmap(void)

+ 1 - 1
rv32/checksum.h

@@ -1,4 +1,4 @@
 #ifndef CHECKSUM_H
 #define CHECKSUM_H
-#define SDRAM_SUM 0x2fb0610d
+#define SDRAM_SUM 0xcdd99e87
 #endif

+ 3 - 2
rv32/ioregs.h

@@ -134,8 +134,9 @@
 #define ABC_LATENCY_ERR		IODEVRB1(ABC,7)
 #define ABC_MAP_MAC800_CFG	IODEVL(ABC,8)
 #define ABC_MAP_MAC800_MAPS	IODEVL(ABC,9)
-#define ABC_MAP_ROMHACK_MAP	IODEVL(ABC,11)
-#define ABC_MAP_ROMHACK_CFG	IODEVL(ABC,16) /* Multiple registers */
+#define ABC_MAP_CFG		IODEVL(ABC,10)
+#define ABC_MAP_CFG_MAP		IODEVB0(ABC,10)
+#define ABC_MAP_CFG_SAM		IODEVB1(ABC,10)
 
 /* n = 0 ... 511 for one of 8 64x1K maps */
 #define ABCMEMMAP_PAGE(n)	IODEVL(ABCMEMMAP,n)