|
@@ -147,11 +147,11 @@ module abcbus (
|
|
|
ioselx <= { 1'b1, abc_di };
|
|
|
|
|
|
// Open drain signals with optional MOSFETs
|
|
|
- reg abc_wait = 1'b0;
|
|
|
- reg abc_int = 1'b0;
|
|
|
- reg abc_nmi = 1'b0;
|
|
|
- reg abc_resin = 1'b0;
|
|
|
- reg abc_xm = 1'b0;
|
|
|
+ reg abc_wait = 1'b0;
|
|
|
+ reg abc_int = 1'b0;
|
|
|
+ reg abc_nmi = 1'b0;
|
|
|
+ reg abc_resin = 1'b0;
|
|
|
+ reg abc_xm = 1'b0;
|
|
|
|
|
|
function reg opt_mosfet(input signal, input mosfet);
|
|
|
if (mosfet)
|
|
@@ -247,7 +247,7 @@ module abcbus (
|
|
|
assign exth_q = 6'b0;
|
|
|
assign exth_oe = 6'b0;
|
|
|
|
|
|
- // ABC SDRAM interface
|
|
|
+ // ABC SDRAM interface
|
|
|
//
|
|
|
// Memory map for ABC-bus memory references.
|
|
|
// 512 byte granularity for memory (registers 0-127),
|
|
@@ -256,19 +256,9 @@ module abcbus (
|
|
|
// bit [24:0] = SDRAM address.
|
|
|
// bit [25] = write enable ( bit 30 from CPU )
|
|
|
// bit [26] = read enable ( bit 31 from CPU )
|
|
|
- // bit [35:27] = DMA count for I/O ( separate register 384-511 from CPU )
|
|
|
//
|
|
|
// Accesses from the internal CPU supports 32-bit accesses only!
|
|
|
//
|
|
|
- // If the DMA counter is exhausted, or I/O operations other than port 0,
|
|
|
- // I/O is instead directed to a memory area pointed to by the iomem_base
|
|
|
- // register as:
|
|
|
- // bit [24:4] = iomem_base
|
|
|
- // bit [3] = read
|
|
|
- // bit [2:0] = port
|
|
|
- //
|
|
|
- // However, the rd and wr enable bits in the I/O map still apply.
|
|
|
- //
|
|
|
wire [7:0] abc_map_addr = { 1'b0, abc_a_s[15:9] };
|
|
|
wire [35:0] rdata_abcmemmap;
|
|
|
wire [35:0] abc_memmap_rd;
|
|
@@ -349,21 +339,22 @@ module abcbus (
|
|
|
|
|
|
assign sdram_addr = { abc_memaddr[24:9], abc_a_s[8:0] };
|
|
|
assign sdram_wd = abc_di;
|
|
|
-
|
|
|
+
|
|
|
// I/O data registers; RST# is considered OUT 7 even through
|
|
|
// it is an IN from the ABC point of view.
|
|
|
//
|
|
|
// OUT register, written from ABC: <addr 2:0> <data 7:0>
|
|
|
// IN register, written from CPU: <enable 1:0> <status 7:0> <inp 7:0>
|
|
|
- // Busy register:
|
|
|
+ // Busy register:
|
|
|
//
|
|
|
// [7:0] - busy OUT status (write-1-clear)
|
|
|
// [9:8] - busy IN status (write-1-clear)
|
|
|
- // [15] - bus status change (write-1-clear)
|
|
|
+ // [15:12] - bus status change (write-1-clear)
|
|
|
+ // same bit positions as the bus status register
|
|
|
//
|
|
|
// [23:16] - busy OUT mask
|
|
|
// [25:24] - busy IN mask
|
|
|
- // [31] - bus status change IRQ enable
|
|
|
+ // [31:28] - bus status change IRQ enable
|
|
|
//
|
|
|
// Assert WAIT# (deassert RDY) if the masked busy status is nonzero
|
|
|
// and an busy-unmasked I/O comes in.
|
|
@@ -373,8 +364,8 @@ module abcbus (
|
|
|
reg [9:0] busy_status;
|
|
|
reg [9:0] busy_mask;
|
|
|
reg [1:0] inp_en;
|
|
|
- reg bus_change_status;
|
|
|
- reg bus_change_mask;
|
|
|
+ reg [3:0] bus_change_status;
|
|
|
+ reg [3:0] bus_change_mask;
|
|
|
|
|
|
wire [9:0] busy_io = { abc_inp[1:0], abc_rst, 1'b0,
|
|
|
abc_out[4:1], abc_cs, abc_out[0] };
|
|
@@ -382,8 +373,10 @@ module abcbus (
|
|
|
wire [9:0] set_busy = busy_io & busy_mask;
|
|
|
wire is_busy = |(busy_status & busy_mask);
|
|
|
|
|
|
+ wire [9:0] busy_valid = 10'b11_1011_1111;
|
|
|
+
|
|
|
// WAIT# logic
|
|
|
- reg abc_wait_force = 1'b0; // Not cleared on internal reset!
|
|
|
+ reg abc_wait_force = 1'b0; // Not cleared on internal reset!
|
|
|
|
|
|
always @(posedge sys_clk)
|
|
|
abc_wait <= abc_wait_force | (rst_n & |set_busy & is_busy);
|
|
@@ -428,7 +421,7 @@ module abcbus (
|
|
|
begin
|
|
|
abc_d_oe <= 1'b0;
|
|
|
abc_do <= 8'bx;
|
|
|
-
|
|
|
+
|
|
|
if (abc_xmemrd & sdram_rready)
|
|
|
begin
|
|
|
abc_d_oe <= 1'b1;
|
|
@@ -445,18 +438,20 @@ module abcbus (
|
|
|
abc_do <= reg_inp_data[1];
|
|
|
end
|
|
|
end // else: !if(~rst_n)
|
|
|
-
|
|
|
+
|
|
|
// Bus status
|
|
|
- reg [31:0] abc_status[0:1];
|
|
|
+ reg [3:0] abc_status[0:1];
|
|
|
|
|
|
always @(posedge sys_clk)
|
|
|
begin
|
|
|
- abc_status[0] <= { 29'b0, abc800, abc_rst_s, abc_clk_active };
|
|
|
+ abc_status[0] <= { 1'b0, abc800, abc_rst_s, abc_clk_active };
|
|
|
abc_status[1] <= abc_status[0];
|
|
|
end
|
|
|
|
|
|
- wire bus_change = |(abc_status[0] ^ abc_status[1]);
|
|
|
-
|
|
|
+ wire [3:0] bus_change = (abc_status[0] ^ abc_status[1]) & bus_change_mask;
|
|
|
+ wire [3:0] bus_change_valid = 4'b0111;
|
|
|
+
|
|
|
+
|
|
|
//
|
|
|
// Busy/IRQ status and CPU register writes
|
|
|
//
|
|
@@ -466,8 +461,8 @@ module abcbus (
|
|
|
busy_status <= 10'b0;
|
|
|
busy_mask <= 10'b0;
|
|
|
inp_en <= 2'b00;
|
|
|
- bus_change_status <= 1'b0;
|
|
|
- bus_change_mask <= 1'b0;
|
|
|
+ bus_change_status <= 4'b0;
|
|
|
+ bus_change_mask <= 4'b0;
|
|
|
|
|
|
// abc_resin, nmi, int and force_wait are deliberately not affected
|
|
|
// by an internal CPU reset. They are, however, initialized
|
|
@@ -477,7 +472,7 @@ module abcbus (
|
|
|
begin
|
|
|
busy_status <= busy_status | set_busy;
|
|
|
bus_change_status <= bus_change_status | bus_change;
|
|
|
-
|
|
|
+
|
|
|
if (abc_valid)
|
|
|
begin
|
|
|
casez (cpu_addr[5:2] )
|
|
@@ -487,14 +482,14 @@ module abcbus (
|
|
|
if (cpu_wstrb[1])
|
|
|
begin
|
|
|
busy_status[9:8] <= set_busy[9:8] | (busy_status[9:8] & ~cpu_wdata[9:8]);
|
|
|
- bus_change_status <= bus_change | (bus_change_status & ~cpu_wdata[15]);
|
|
|
+ bus_change_status <= bus_change | (bus_change_status & ~cpu_wdata[15:12]);
|
|
|
end
|
|
|
if (cpu_wstrb[2])
|
|
|
- busy_mask[7:0] <= cpu_wdata[23:16] & ~8'h40;
|
|
|
+ busy_mask[7:0] <= cpu_wdata[23:16] & busy_valid[7:0];
|
|
|
if (cpu_wstrb[3])
|
|
|
begin
|
|
|
- busy_mask[9:8] <= cpu_wdata[25:24];
|
|
|
- bus_change_mask <= cpu_wdata[31];
|
|
|
+ busy_mask[9:8] <= cpu_wdata[25:24] & busy_valid[9:8];
|
|
|
+ bus_change_mask <= cpu_wdata[31:28] & bus_change_valid;
|
|
|
end
|
|
|
end
|
|
|
5'b???011: begin
|
|
@@ -527,9 +522,10 @@ module abcbus (
|
|
|
// Read MUX
|
|
|
always_comb
|
|
|
casez (cpu_addr[5:2])
|
|
|
- 5'b00000: cpu_rdata = abc_status[0];
|
|
|
+ 5'b00000: cpu_rdata = { 28'b0, abc_status[0] };
|
|
|
5'b00001: cpu_rdata = { 23'b0, ~iosel_en, ioselx[7:0] };
|
|
|
- 5'b00010: cpu_rdata = { 6'b0, busy_mask, 6'b0, busy_status };
|
|
|
+ 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] };
|