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