|
@@ -297,7 +297,7 @@ module abcbus (
|
|
|
//
|
|
|
// Accesses from RV32 supports 32-bit accesses only!
|
|
|
//
|
|
|
- logic abc_a_map;
|
|
|
+ logic [2:0] abc_a_map;
|
|
|
wire [17:0] rdata_abcmemmap; // RV32 access port
|
|
|
wire [17:0] abc_memmap_rd; // ABC-bus access port
|
|
|
|
|
@@ -312,7 +312,7 @@ module abcbus (
|
|
|
.wren_a ( 1'b0 ),
|
|
|
.q_a ( abc_memmap_rd ),
|
|
|
|
|
|
- .address_b ( cpu_addr[8:2] ),
|
|
|
+ .address_b ( cpu_addr[10:2] ),
|
|
|
.data_b ( { cpu_wdata[2:0], cpu_wdata[24:10] } ),
|
|
|
.wren_b ( map_valid & cpu_wstrb[0] ),
|
|
|
|
|
@@ -468,18 +468,35 @@ module abcbus (
|
|
|
//
|
|
|
// "ROM hack" map control logic
|
|
|
//
|
|
|
- reg romhack_en = 1'b0; // Enable
|
|
|
- reg [5:0] romhack_addr = 6'b0; // Address mask (1K granular)
|
|
|
- reg romhack_map = 1'b0; // Current map
|
|
|
- wire cpu_romhackmap = rst_n && abc_valid && cpu_addr[6:2] == 5'b01011;
|
|
|
+ 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;
|
|
|
|
|
|
- always @(posedge sdram_clk)
|
|
|
- begin
|
|
|
- if (abc_xmemwr & romhack_en & (abc_a_s[15:10] == romhack_addr))
|
|
|
- romhack_map <= abc_a_s[0];
|
|
|
- else if (cpu_romhackmap & cpu_wstrb[0])
|
|
|
- romhack_map <= cpu_wdata[0];
|
|
|
- end
|
|
|
+ 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)
|
|
|
|
|
|
//
|
|
|
// ABC data out (= ABC host read) logic
|
|
@@ -529,11 +546,8 @@ module abcbus (
|
|
|
//
|
|
|
always_comb
|
|
|
begin
|
|
|
- abc_a_map = 1'b0;
|
|
|
- if (abc800mac_en)
|
|
|
- abc_a_map |= abc800mac_xmmask[abc_a_s[15:12]];
|
|
|
- if (romhack_en)
|
|
|
- abc_a_map |= romhack_map;
|
|
|
+ abc_a_map = romhack_map;
|
|
|
+ abc_a_map[0] ^= abc800mac_en & abc800mac_xmmask[abc_a_s[15:12]];
|
|
|
end
|
|
|
|
|
|
// Memory read latency counter
|
|
@@ -588,10 +602,12 @@ module abcbus (
|
|
|
bus_change_status <= 4'b0;
|
|
|
bus_change_mask <= 4'b0;
|
|
|
abc800mac_en <= 1'b0;
|
|
|
- romhack_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_resin, nmi, int and force_wait are deliberately not affected
|
|
|
// by an internal CPU reset. They are, however, inherently asserted
|
|
|
// when the FPGA is configured, and initialized to fixed values
|
|
@@ -644,23 +660,28 @@ module abcbus (
|
|
|
reg_inp_data[1] <= cpu_wdata[15:8];
|
|
|
if (cpu_wstrb[2])
|
|
|
inp_en <= cpu_wdata[17:16];
|
|
|
- end
|
|
|
+ end
|
|
|
5'b01000: begin
|
|
|
if (cpu_wstrb[0])
|
|
|
abc800mac_iobase <= cpu_wdata[7:1];
|
|
|
if (cpu_wstrb[3])
|
|
|
abc800mac_en <= cpu_wdata[31];
|
|
|
- end
|
|
|
+ end
|
|
|
// 5'b01001: abc800mac_xmdata - handled elsewhere
|
|
|
- 5'b01010: begin
|
|
|
- if (cpu_wstrb[1])
|
|
|
- romhack_addr <= cpu_wdata[15:10];
|
|
|
- if (cpu_wstrb[3])
|
|
|
- romhack_en <= cpu_wdata[31];
|
|
|
- end
|
|
|
// 5'b01011: romhack_map - handled elsewhere
|
|
|
- default:
|
|
|
- /* do nothing */ ;
|
|
|
+ 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
|
|
|
+ end
|
|
|
+ default: begin
|
|
|
+ /* do nothing */
|
|
|
+ end
|
|
|
endcase // casez (cpu_addr[6:2])
|
|
|
end // if (abc_valid & cpu_wstrb[0])
|
|
|
end
|
|
@@ -671,21 +692,27 @@ module abcbus (
|
|
|
|
|
|
// Read MUX
|
|
|
always_comb
|
|
|
- casez (cpu_addr[6:2])
|
|
|
- 5'b00000: cpu_rdata = { 22'b0, abc800_force, abc80_force,
|
|
|
- 4'b0, abc_status[0] };
|
|
|
- 5'b00001: cpu_rdata = { 23'b0, ~iosel_en, ioselx[7:0] };
|
|
|
- 5'b00010: cpu_rdata = { bus_change_mask, 2'b0, busy_mask,
|
|
|
- bus_change_status, 2'b0, busy_status };
|
|
|
- 5'b00011: cpu_rdata = { 28'b0, abc_resin, abc_nmi, abc_int, abc_wait };
|
|
|
- 5'b00100: cpu_rdata = { 21'b0, reg_out_addr, reg_out_data };
|
|
|
- 5'b00101: cpu_rdata = { 14'b0, inp_en, reg_inp_data[1], reg_inp_data[0] };
|
|
|
- 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'b01010: cpu_rdata = { romhack_en, 15'b0, romhack_addr, 10'b0 };
|
|
|
- 5'b01011: cpu_rdata = { 31'b0, romhack_map };
|
|
|
- default: cpu_rdata = 32'bx;
|
|
|
- endcase // casez (cpu_addr[6:2])
|
|
|
+ begin
|
|
|
+ cpu_rdata = 32'b0;
|
|
|
+ casez (cpu_addr[6:2])
|
|
|
+ 5'b00000: cpu_rdata = { 22'b0, abc800_force, abc80_force,
|
|
|
+ 4'b0, abc_status[0] };
|
|
|
+ 5'b00001: cpu_rdata = { 23'b0, ~iosel_en, ioselx[7:0] };
|
|
|
+ 5'b00010: cpu_rdata = { bus_change_mask, 2'b0, busy_mask,
|
|
|
+ bus_change_status, 2'b0, busy_status };
|
|
|
+ 5'b00011: cpu_rdata = { 28'b0, abc_resin, abc_nmi, abc_int, abc_wait };
|
|
|
+ 5'b00100: cpu_rdata = { 21'b0, reg_out_addr, reg_out_data };
|
|
|
+ 5'b00101: cpu_rdata = { 14'b0, inp_en, reg_inp_data[1], reg_inp_data[0] };
|
|
|
+ 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
|
|
|
+ endcase // casez (cpu_addr[6:2])
|
|
|
+ end
|
|
|
|
|
|
endmodule // abcbus
|