|
@@ -284,13 +284,16 @@ module abcbus (
|
|
|
{ ~cpu_addr[9] | ~cpu_addr[2],
|
|
|
~cpu_addr[9] | cpu_addr[2] };
|
|
|
|
|
|
+ wire [8:0] next_dma_count = abc_dma_count - 1'b1;
|
|
|
+ wire next_dma_empty = ~&next_dma_count;
|
|
|
+
|
|
|
abcmapram abcmapram (
|
|
|
.aclr ( ~rst_n ),
|
|
|
|
|
|
.clock ( sdram_clk ),
|
|
|
|
|
|
.address_a ( abc_map_addr ),
|
|
|
- .data_a ( { abc_dma_count - 1'b1,
|
|
|
+ .data_a ( { next_dma_count,
|
|
|
abc_rden, abc_wren,
|
|
|
abc_memaddr + 1'b1 } ),
|
|
|
.wren_a ( abc_dma_update ),
|
|
@@ -301,7 +304,7 @@ module abcbus (
|
|
|
.data_b ( { cpu_wdata[8:0],
|
|
|
abcmap_masked_rdwr,
|
|
|
cpu_wdata[24:0] } ),
|
|
|
- .wren_b ( map_valid & cpu_wstrb[0] ),
|
|
|
+ .wren_b ( map_valid & ~cpu_addr[11] & cpu_wstrb[0] ),
|
|
|
.byteena_b ( { cpu_addr[10],
|
|
|
{3{~cpu_addr[10]}} } ),
|
|
|
|
|
@@ -330,7 +333,42 @@ module abcbus (
|
|
|
abc_dma_nzero <= |abc_memmap_rd[35:27]; // -> |abc_dma_count
|
|
|
end
|
|
|
|
|
|
- assign cpu_rdata_map = cpu_addr[10] ?
|
|
|
+ //
|
|
|
+ // RAM for the status register (INP 1). This is in a separate SRAM
|
|
|
+ // so that it can be adjusted for certain DMA events.
|
|
|
+ // bit [7:0] - status register value
|
|
|
+ // bit [8] - clear bit 0 on read DMA empty
|
|
|
+ // bit [9] - clear bit 0 on write DMA empty
|
|
|
+ // bit [10] - clear bit 1 on write DMA empty
|
|
|
+ // bit [11] - clear bit 7 on any DMA event
|
|
|
+ //
|
|
|
+ wire [15:0] status_out;
|
|
|
+ wire [15:0] rdata_status;
|
|
|
+
|
|
|
+ statusram statusram (
|
|
|
+ .aclr ( ~rst_n ),
|
|
|
+ .clock ( sdram_clk ),
|
|
|
+
|
|
|
+ .address_a ( iosel ),
|
|
|
+ .data_a ( status_out &
|
|
|
+ ~{ 4'hf0, status_out[11], 5'b00000,
|
|
|
+ status_out[10] & abc_out_s[0]
|
|
|
+ & next_dma_empty,
|
|
|
+ ((status_out[9] & abc_out_s[0]) |
|
|
|
+ (status_out[8] & abc_inp_s[0]))
|
|
|
+ & next_dma_empty } ),
|
|
|
+ .wren_a ( abc_dma_update ),
|
|
|
+ .q_a ( status_out ),
|
|
|
+
|
|
|
+ .address_b ( cpu_addr[7:2] ),
|
|
|
+ .data_b ( cpu_wdata[11:0] ),
|
|
|
+ .q_b ( rdata_status ),
|
|
|
+ .wren_b ( map_valid & cpu_addr[11] & cpu_wstrb[0] )
|
|
|
+ );
|
|
|
+
|
|
|
+ assign cpu_rdata_map = cpu_addr[11] ?
|
|
|
+ { 16'b0, rdata_status } :
|
|
|
+ cpu_addr[10] ?
|
|
|
{ 23'b0, rdata_abcmemmap[35:27] } :
|
|
|
{ rdata_abcmemmap[26:25], 5'b0,
|
|
|
rdata_abcmemmap[24:0] };
|
|
@@ -378,7 +416,8 @@ module abcbus (
|
|
|
abc_iowr_en <= iosel_en & |abc_out & abc_stb[3];
|
|
|
abc_iord_en <= iosel_en & |abc_inp & abc_stb[3];
|
|
|
|
|
|
- abc_do_memrd <= abc_rden & (abc_memrd_en | abc_iord_en);
|
|
|
+ abc_do_memrd <= abc_rden & (abc_memrd_en |
|
|
|
+ (abc_iord_en & abc_inp[0]));
|
|
|
abc_do_memwr <= abc_wren & (abc_memwr_en | abc_iowr_en);
|
|
|
abc_racked <= abc_do_memrd & (sdram_rack | abc_racked);
|
|
|
abc_wacked <= abc_do_memwr & (sdram_wack | abc_wacked);
|
|
@@ -392,7 +431,6 @@ module abcbus (
|
|
|
(sdram_wrq & abc_wacked));
|
|
|
end // else: !if(~rst_n)
|
|
|
|
|
|
-
|
|
|
assign sdram_addr =
|
|
|
(abc_dma_en & |abc_dma_count) ? abc_memaddr :
|
|
|
(abc_iord_en|abc_iowr_en) ? { abc_iobase, |abc_inp_s, abc_a_s[2:0] } :
|
|
@@ -406,17 +444,17 @@ module abcbus (
|
|
|
// set the bit once the DMA counter reaches or already is zero.
|
|
|
|
|
|
wire [7:0] abc_inpflag = { abc_rst, 5'b00000,
|
|
|
- abc_iord_en & abc_inp[1],
|
|
|
- abc_iord_en & ~abc_dma_nzero & abc_inp[0] };
|
|
|
+ abc_iord_en & abc_rden & abc_inp[1],
|
|
|
+ abc_iord_en & abc_rden & ~abc_dma_nzero & abc_inp[0] };
|
|
|
wire [7:0] abc_outflag = { 2'b00,
|
|
|
- {4{abc_iowr_en}} & abc_out[4:1],
|
|
|
+ {4{abc_iowr_en & abc_wren}} & abc_out[4:1],
|
|
|
abc_cs,
|
|
|
- abc_iowr_en & ~abc_dma_nzero & abc_out[0] };
|
|
|
+ abc_iowr_en & abc_wren & ~abc_dma_nzero & abc_out[0] };
|
|
|
|
|
|
// DMA status register: set on *any* DMA access.
|
|
|
// bit 0 = out DMA; bit 1 = in DMA.
|
|
|
- wire [1:0] abc_dmaflag = { abc_iord_en & abc_dma_en,
|
|
|
- abc_iowr_en & abc_dma_en };
|
|
|
+ wire [1:0] abc_dmaflag = { abc_iord_en & abc_rden & abc_dma_en,
|
|
|
+ abc_iowr_en & abc_wren & abc_dma_en };
|
|
|
//
|
|
|
// ABC-bus data bus handling
|
|
|
//
|
|
@@ -426,6 +464,11 @@ module abcbus (
|
|
|
abc_do <= 8'hxx;
|
|
|
abc_d_oe <= 1'b0;
|
|
|
end
|
|
|
+ else if (abc_inp[1] & abc_iord_en & abc_rden)
|
|
|
+ begin
|
|
|
+ abc_do <= status_out;
|
|
|
+ abc_d_oe <= 1'b1;
|
|
|
+ end
|
|
|
else if (abc_racked & sdram_rready)
|
|
|
begin
|
|
|
abc_do <= sdram_rd;
|
|
@@ -504,7 +547,7 @@ module abcbus (
|
|
|
always_comb
|
|
|
casez (cpu_addr[5:2])
|
|
|
5'b00000: cpu_rdata = { 24'b0, abc_status[0] };
|
|
|
- 5'b00001: cpu_rdata = ioselx[7:0];
|
|
|
+ 5'b00001: cpu_rdata = { 23'b0, ~iosel_en, ioselx[7:0] };
|
|
|
5'b00010: cpu_rdata = abc_iobase;
|
|
|
5'b00100: cpu_rdata = irq_mask & irq_status_mask;
|
|
|
5'b00101: cpu_rdata = irq_status;
|